Java OnSensorChanged被调用的次数超出预期

Java OnSensorChanged被调用的次数超出预期,java,android,accelerometer,sensors,android-sensors,Java,Android,Accelerometer,Sensors,Android Sensors,我正在尝试开发一个应用程序来检测跌落,目前为止跌落的准确度在可接受的范围内,但问题是“OnSensorChanged”被频繁调用,导致toast不断出现在我的屏幕上 我认为问题在于,在自由落体期间,“OnSensorChanged”在落体期间不断被调用(因为值对应于落体),这就是导致我屏幕上出现吐司垃圾邮件的原因 我尝试过的一种解决方案是在跌倒后注销监听器,使其只出现一次,但问题是,除非我重新启动应用程序,否则监听器不会再次检测到跌倒(因为监听器显然停止工作) 这个问题有什么解决办法吗? 谢谢

我正在尝试开发一个应用程序来检测跌落,目前为止跌落的准确度在可接受的范围内,但问题是“OnSensorChanged”被频繁调用,导致toast不断出现在我的屏幕上

我认为问题在于,在自由落体期间,“OnSensorChanged”在落体期间不断被调用(因为值对应于落体),这就是导致我屏幕上出现吐司垃圾邮件的原因

我尝试过的一种解决方案是在跌倒后注销监听器,使其只出现一次,但问题是,除非我重新启动应用程序,否则监听器不会再次检测到跌倒(因为监听器显然停止工作)

这个问题有什么解决办法吗? 谢谢

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);

    }
}
private void checkFall(传感器事件XYZ值){
float[]值=xyzValues.values;
double rootSquare=Math.sqrt(Math.pow(值[0],2)+Math.pow(值[1],2)+Math.pow(值[2],2));
如果(平方根<1.5){
Toast Toast=Toast.makeText(这是“电话掉了!”,Toast.LENGTH\u LONG);
toast.show();
sensorManager.UnregistereListener(此);
sensorManager=null;
}
传感器更改时的公共无效(传感器事件){
if(event.sensor.getType()==sensor.TYPE\u加速计){
支票坠落(事件);
}
}

您可以使用一个成员布尔变量,
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。很抱歉,由于某些原因,我的评论没有发布:(…问题是我找不到一个固定阈值(最近的是触发方法2-3的阈值),所以我决定只映射布尔值(mFallen)单击按钮将重新启用坠落检测。因此,现在,用户必须手动重新启用坠落检测,因为它将在第一次方法调用时被禁用。但是,您的建议仍然是使用的主要想法,因此,谢谢:)还有一件事,没有发布的评论让我很困惑,为什么它会触发2-4次:DThere绝对是一个比重新启用侦听器更好的方法:)事实上,你应该看到
onSensorChanged()
多次调用,因为它不断检查传感器值的变化,其中一些可能是尖峰。请参阅我的更新答案,以了解更好的站立检测算法。
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;
}