(请阅读最后的更新 3)我正在开发一个应用程序,该应用程序可以持续与设备的传感器一起工作,Accelerometer
与传感器一起工作以检索设备的方向(此处Magnetic
提到了目的)。换句话说,我的应用程序需要实时知道设备的方向(但是这是不可能的,所以要尽可能快,但要尽可能快!)。正如Reto Meier 在专业的 Android 4 应用程序开发中提到的:
加速度计每秒可以更新数百次……
我不能丢失传感器报告的任何数据,并且我还想对这些数据进行耗时的操作(检索方向然后进行计算......)。我决定使用以下方法解决我的问题LinkedBlockingQueue
:
public void startSensors() {
LinkedBlockingQueue<float[][]> array=new LinkedBlockingQueue();
sensorListenerForOrientation = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
aValues = (event.values.clone());
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mValues = (event.values.clone());
if (aValues != null && mValues != null) {
try {
array.put(new float[][] { aValues, mValues });
} catch (InterruptedException e) {
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
Sensor aSensor = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(
sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() - 1);
Sensor mSensor = sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get(
sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).size() - 1);
sm.registerListener(sensorListenerForOrientation, aSensor,
SensorManager.SENSOR_DELAY_FASTEST);
sm.registerListener(sensorListenerForOrientation, mSensor,
SensorManager.SENSOR_DELAY_FASTEST);
executor.execute(new Runnable() {
@Override
public void run() {
doCalculations();
}
});
}
和
public void doCalculations() {
for (;;) {
float[][] result = null;
try {
result = array.take();
} catch (InterruptedException e) {
}
float[] aValues, mValues;
aValues = result[0];
mValues = result[1];
int[] degrees=getOrientation(aValues,mValues);
Log.e("",String.valueOf(degrees[0]));
//other calculations...
}
}
现在我拿起我的设备并将其向右旋转约 90 度,然后将其快速返回到第一个位置(例如在 1.5 秒内)但是当我查看设备中注册的方向时,我看到例如:0,1 ,2,3,4,5.......,40,39,38,37,....,0
我只想说,我的结果中看不到大范围的度数。根据我所做的和我的研究,我可以确定我没有丢失任何数据,传感器报告的任何新数据都会被记录下来。
任何想法,解决方案?!
问候!
更新 1:我用我的设备做了另一个实验,得到了令人震惊的结果!如果我将设备快速旋转 90 度(不到一秒),我可以在结果中看到所有度数:0,1,2,3,....,89,90(例如)但是如果我将其旋转 90 度,然后将其旋转回第一个位置,结果将是 0,1,2,...,36,37,36,...2,1,0(例如)...真的混乱!
更新 2:我更新了 doCalculations() 方法以更清楚我做了什么
更新3:我想也许我们可以用另一种方式解决问题!我对这段代码有明确的目的。请看看这个。我已经提到会发生什么,我需要检测一个特定的运动手势。所以也许我选择的整个方式(上面的技术)不是解决这个问题的好方法。也许最好通过使用其他传感器或以其他方式使用相同的传感器来检测该手势。你怎么看?