所以我一直在努力应对这一挑战,探索不同的可能性并缩小“排队”的位置。发生。我先解释一下我要做的事情。
我想做什么?
我正在使用可穿戴服务(在Sony Smartwatch 3上运行)编写一个Android应用程序(在Google Pixel上运行),以便尽快从智能手表中检索传感器数据,并将结果记录为详细信息。目前这种情况发生在150Hz左右,来自TYPE_ROTATION_VECTOR的数据。该数据使用PrintWriter通过信道(输出流)发送,并使用BufferReader在同一信道(输入流)上通过电话进行检索。我正在使用ChannelApi,因为DataApi确保了交付,但我的目标是尽可能快地将传感器数据传送到实时,其中数据丢失不太重要。我目前正在笔记本电脑上阅读ADB,以便在另一个应用程序中使用它。
问题/挑战是什么?
在我的程序中的几个阶段获得系统时间之后,我发现数据的排队不是ADB连接的错误,也不是输入或输出流以及打印机的错误。当onSensorChanged()
发生时,似乎不会立即调用函数sensorEvent
。为了说明,下面是每个onSensorChanged()
事件作为数据发送的时间,其中sensorListener设置为SENSOR_DELAY_GAME(但也考虑了SENSOR_DELAY_FASTEST。
System.currentTimeMillis()
在调用onSensorChanged()
时观看event.timestamp
sensorEvent
(除以1000000,从纳秒到毫秒)
这概述了一些传感器读数:
1479407287638; 687629;
1479407287638; 687649;
1479407287681; 687669;
1479407287681; 687689;
1479407287718; 687709;
1479407287718; 687729;
1479407287768; 687749;
1479407287768; 687769;
1479407287810; 687789;
1479407287811; 687809;
如果你看一下你得到的时间之间的差异:
- -
0; 20
49; 20
0; 20
37; 20
0; 20
50; 20
0; 20
42; 20
1; 20
如您所见,sensorTimestamp
表示每20毫秒有一个读数。但是,onSensorChanged()
不会以相同的间隔调用,或至少是一致性。要指出的是,即使在高速时,通道及其输入和输出写入器也能够跟上字节/消息的数量,即使在较长的时间段或时间内也是如此。
我尝试了什么?
我尝试从onSensorChanged
public void onSensorChanged(SensorEvent event) {
final int accuracy = event.accuracy;
final long timestamp = event.timestamp;
final float[] values = event.values;
final String sensorName = event.sensor.getStringType();
if (data_transfer) { // if interaction is initiated
printWriter.println(message);
}
}
我尝试从onSensorChanged
中移除所有任务,并在已启动的线程
if (data_transfer) { // if interaction is initiated
new Thread(new convertAndSend(sensorName,timestamp,accuracy,values)).run();
}
起初我将可穿戴应用程序编写为活动,但我也将其转换为服务(在后台运行)
public class SensorService extends Service implements SensorEventListener {
...
public void onSensorChanged(SensorEvent event) {
client.sendSensorData(event.sensor.getType(), event.accuracy, event.timestamp/1000000, event.values); //client takes care of outputstream
}
}
最后,我考虑在单独的线程中实现SensorEventListener
(基于this和this Stackoverflow Q& A,因此它不会受到Activity或Service线程的影响然而,这也表现出与前面提到的相同的问题/挑战。
public class SensorListenerThread implements Runnable {
private static final String TAG = "SensorService";
private final static int SENS_ROTATION_VECTOR = Sensor.TYPE_ROTATION_VECTOR;
SensorManager mSensorManager;
@Override
public void run() {
Log.d( "RunTag", Thread.currentThread().getName() ); // To display thread
mSensorManager = ((SensorManager)getSystemService(SENSOR_SERVICE));
Looper.prepare();
Handler handler = new Handler(){
// process incoming messages here??
};
Sensor rotationVectorSensor = mSensorManager.getDefaultSensor(SENS_ROTATION_VECTOR);
MySensorListener msl = new MySensorListener();
mSensorManager.registerListener(msl, rotationVectorSensor, SensorManager.SENSOR_DELAY_FASTEST, handler);
Looper.loop();
}
private class MySensorListener implements SensorEventListener {
public void onAccuracyChanged (Sensor sensor, int accuracy) {}
public void onSensorChanged(SensorEvent sensorEvent) {
Log.d( "ListenerTag", Thread.currentThread().getName() ); // To display thread
}
}
}
帮助!
我的理解是onSensorChanged
事件被调用,但不是与传感器的时间戳似乎表明的同时。速度和使用频道工作得很好,但我似乎无法解决这个问题。我脑子里有一个计划B:我可以使用传感器时间戳来计算/调整我在笔记本电脑上运行的程序。但是,我更喜欢只调整通信延迟(来自传感器 - >笔记本电脑应用程序,这可能是一个时不时改变的变量)而不是调整通信的不一致性(打印值的差异) ,需要为每次阅读计算。)
我希望这个漫长的(抱歉!)故事是有道理的,有人可以帮助我或指出我正确的方向!
答案 0 :(得分:0)
看起来,可能无法依赖onSensorChanged()的一致调用。因此,我使用时间戳而不是onSensorChanged的时间。我会建议别人也这样做!