我有一个代码片段来检测加速度计的移动。通过正确检测轻微的动作,它可以工作一段时间,但有时它会在我保持设备闲置时检测到动作。 Android上的内置加速度计检测有问题吗?
我使用的是HTC G-1设备。我的代码片段如下。我如何解决它,以便我可以检测到小的设备移动,但在设备空闲时却没有检测到任何东西?
private static final int SHAKE_THRESHOLD = 50;
public void onSensorChanged(int sensor, float[] values) {
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// only allow one update every 100ms.
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x = values[SensorManager.DATA_X];
y = values[SensorManager.DATA_Y];
z = values[SensorManager.DATA_Z];
float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;
if (speed > SHAKE_THRESHOLD) {
long curTime = System.currentTimeMillis();
long diff = (curTime - shakeTime);
shakeTime = curTime;
if (myFlagIgnoreShakeDetection==true) //Caused unneccessary accelerometer
//notification looping when device is idle
return;
// Doing something...
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
答案 0 :(得分:1)
以下是一些代码差异......
关于last_x
,last_y
和last_z
的更新可能存在问题。我相信它们应该包含在里面 if ((curTime - lastUpdate) > 100) {
语句中。换句话说,每次调用onSensorChanged
时都会更新它们,而不是每100毫秒更新一次。您应该将这三个变量的更新移动到它们上面的大括号中。
在您计算speed
的行上,公式以... / diffTime * 10000;
结尾?您想要将diffTime
乘以10000,还是整个结果?由于/
和*
在我所知的大多数语言中通常具有相同的operator precedence(例如Java),因此您的等式将从左到右进行评估,首先除以diffTime
然后将该结果乘以10000。
我猜你的意思是将diffTime
乘以10000,因此将最终结果除以该数量。这是除以10000或乘以10000之间的差异,这意味着您可能获得的speed
值比您应该大10 ^ 8,因此即使设备处于空闲状态也会使阈值跳闸。你需要在乘法中加上括号,比如... / (diffTime * 10000);
,以确保它在分割之前执行。
此外,如果您打算将diffTime
从毫秒缩放到秒,则您的比例因子应为1000。
答案 1 :(得分:0)
我个人,在我的增强现实库中,使用滚动平均值进行更新:
float kFilteringFactor = (float)0.05;
rollingZ = (float) ((rawZValue * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor)));
这样可以很好地平滑数据,您可以调整过滤因子以获得所需的响应能力。
rawZValue是来自加速度计的原始值。