有人能帮我弄到一条平滑的传感器流吗?
我正在尝试使用索尼智能手表2的加速度计数据来动画一个在android设备屏幕上挥舞的旗帜。使用索尼的传感器控制示例代码作为起点,我得到了一个很好的工作设置。但只有5-6秒钟!然后传感器数据开始大量进入,扰乱了我的动画。为了找出罪魁祸首,我把我的智能手表代码削减到了最基本的部分:
侦听器只记录上一次感应器之后的毫秒数:
private final AccessorySensorEventListener timeListener = new AccessorySensorEventListener() {
long lastTime = 0;
@Override
public void onSensorEvent(AccessorySensorEvent event) {
Log.i(TAG, "SmartWatch - onSensorEvent: " + (System.currentTimeMillis()-lastTime));
lastTime = System.currentTimeMillis();
}
};以及这位听众的登记
SW2SensorsControl(final String hostAppPackageName, final Context context) {
super(context, hostAppPackageName);
AccessorySensorManager manager = new AccessorySensorManager(context, hostAppPackageName);
if (DeviceInfoHelper.isSensorSupported(context, hostAppPackageName, SensorTypeValue.ACCELEROMETER)) {
accelerometer = manager.getSensor(SensorTypeValue.ACCELEROMETER);
}
if(accelerometer!=null) {
try {
accelerometer.registerFixedRateListener(timeListener, com.sonyericsson.extras.liveware.aef.sensor.Sensor.SensorRates.SENSOR_DELAY_NORMAL);
} catch (AccessorySensorException e) {
Log.d(TAG, "Failed to register listener", e);
}
}
}运行代码时,我看到感应器在10到70毫秒之间流动。但大约6秒后,我开始看到打嗝: 200毫秒,然后他们试图“追赶”,我得到5个读数间隔几毫秒。在这之后,它运行了几秒钟,然后我看到了另一个小问题: 500~100 ms,还有一些快速的“追赶”事件。-这个计划不断重复,而且越来越频繁,直到再过几秒钟,溪流就完全瘫痪了。我在三星星系S5、Nexus-4和Nexus-5上都进行了测试,所以它并不是特定于设备的,尽管在SG5上,逻辑猫被一种叫做"ServiceKeeper“的东西--显然是某种系统进程--乱发了出来。下面是一个450毫秒打嗝的例子,然后是简短的“追赶”:
06-30 11:47:23.208: I/SW2SensorsControl(5173): SmartWatch - onSensorEvent: 450
06-30 11:47:23.208: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.208: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.218: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.218: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.218: I/SW2SensorsControl(5173): SmartWatch - onSensorEvent: 9
06-30 11:47:23.218: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.218: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.228: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.228: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.228: I/SW2SensorsControl(5173): SmartWatch - onSensorEvent: 9
06-30 11:47:23.228: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.228: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.228: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.228: I/SW2SensorsControl(5173): SmartWatch - onSensorEvent: 3
06-30 11:47:23.228: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.238: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.238: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.238: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.238: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system正如您所看到的,这里的侦听器没有做任何工作-除了记录时间-但是当动画我的标志,打嗝开始更快(因为有更多的发生)。这就像传感器事件线程是预先设置的,事件队列在场景后面,或者可能是蓝牙接收缓冲区没有被读取。当我用另一种方法
accelerometer.registerInterruptListener(timeListener);事件发生得更快,打嗝的情况就更糟了!有人能告诉我这件事能否解决吗?是我的代码,是Android还是索尼?
问候
编辑:
传感器事件中的时间戳本身并不显示“追赶”行为,而是以39-41ms的稳定速率(时间戳以纳米秒irl为单位--为什么?)仍然有奇怪的打嗝-通常401或402毫秒。这将是更有用的时候,我做动画基于加速度计。但是听众并没有以几乎固定的速度接收到它们;有时在下一个“丛集”到来之前过了几秒钟.
编辑-2:
今天在三星Galaxy S-3上进行了测试。在此基础上,数据以比Nexus-4或SG S-5 (最差的)更平滑的速度进入。两个Samsungs都在发送logcat输出,在S5上这是一个没有有用信息的系统进程,但是在S3上它写着"BluetoothSocket.cpp;readNative“--我怀疑传感器读数的聚集行为可能是由蓝牙系统引起的:输入缓冲区可能?有没有人知道是否有可能改变蓝牙输入缓冲器的读取速率?
发布于 2014-07-02 00:20:19
我怀疑问题在于您多长时间更新一次显示。你的旗帜挥舞动画的时间间隔是多少?如果您每隔几毫秒更新一次显示,那么您可能会遇到一些滞后。
-编辑
很抱歉让您久等了。在再次查看您的问题后,我想知道问题是否与您如何注册手表传感器有关。您是否使用HelloSensors示例应用程序作为基础。如果没有,我建议你看一看。以下是传感器在示例中的注册方式。请试试这个,如果你还有问题,请告诉我。
/**
* Checks if the sensor currently being used supports interrupt mode and
* registers an interrupt listener if it does. If not, a fixed rate listener
* will be registered instead.
*/
private void register() {
Log.d(HelloSensorsExtensionService.LOG_TAG, "Register listener");
AccessorySensor sensor = getCurrentSensor();
if (sensor != null) {
try {
if (sensor.isInterruptModeSupported()) {
sensor.registerInterruptListener(mListener);
} else {
sensor.registerFixedRateListener(mListener, Sensor.SensorRates.SENSOR_DELAY_UI);
}
} catch (AccessorySensorException e) {
Log.d(HelloSensorsExtensionService.LOG_TAG, "Failed to register listener", e);
}
}
}https://stackoverflow.com/questions/24488208
复制相似问题