我正在尝试开发一款可以检测跌倒的应用程序,到目前为止,跌幅的准确性在可接受的范围内,但问题是" OnSensorChanged"过于频繁地调用导致toast不断出现在我的屏幕上。
我认为问题在于,在自由落体期间," OnSensorChanged"在堕落期间继续被叫(因为这些值对应于跌倒),这是导致我的屏幕上的Toast垃圾邮件的原因。
我尝试的一个解决方案是在摔倒后取消注册监听器,这样它只出现一次,但问题是它不会再次检测到掉落,除非我重新启动应用程序(因为显然监听器停止工作)。
这个问题有什么解决方案吗? 谢谢
private void checkFall(SensorEvent xyzValues) {
float[] values = xyzValues.values;
double rootSquare = Math.sqrt(Math.pow(values[0],2)+Math.pow(values[1],2)+Math.pow(values[2],2));
if (rootSquare < 1.5){
Toast toast = Toast.makeText(this, "The Phone Fell!", Toast.LENGTH_LONG);
toast.show();
sensorManager.unregisterListener(this);
sensorManager = null;
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
checkFall(event);
}
}
答案 0 :(得分:1)
您可以使用成员布尔变量mFallen
来跟踪刚刚发生跌倒的时间。您可能还需要定义一些阈值以指示手机何时恢复到正常“站立”状态。请尝试以下方法:
if (rootSquare < 1.5 && !mFallen){
Toast toast = Toast.makeText(this, "The Phone Fell!", Toast.LENGTH_LONG);
toast.show();
mFallen = true;
} else if (rootSquare > STANDING_THRESHOLD) {
mFallen = false;
}
一旦mFallen的状态从false变为true,设备加速度矢量的大小(正如你在rootSquare
中计算和存储的那样)应该非常接近0.这是因为当设备在自由落体中(自身全部掉落),其加速度将是来自站立人物的参考系的重力加速度。但从理论上讲,加速度计只能测量相对于自由落体的值,因此它恰好为0。
由于重力加速度约为9.81 m / s ^ 2,为了检测设备何时不再移动,您需要检查加速度的大小何时接近。这是因为尽管如此,传感器仍将检测阻止其下落的力(取消由于重力引起的加速度),这是保持静止的力量。在这种情况下,由于这些力引起的加速度的总幅度必须精确地归因于由重力引起的加速度的大小。
您可以将常量GRAVITY
定义为9.81
,将GRAVITY_THRESHOLD
定义为容差值,您可以尝试将其设置为0.1
,然后再进行精炼。尝试使用以下代码替换您的代码:
if (rootSquare < 1.5 && !mFallen){
Toast toast = Toast.makeText(this, "The Phone Fell!", Toast.LENGTH_LONG);
toast.show();
mFallen = true;
} else if (Math.abs(rootSquare - GRAVITY) < GRAVITY_THRESHOLD) {
mFallen = false;
}
需要强调的是,此处的站立状态仅在设备停止移动时定义为 ,因此无法检测到手机何时达到某个高度地面。
请参阅https://developer.android.com/reference/android/hardware/SensorEvent.html#values,因为这可能有助于您更好地了解问题。