java - 安卓跌倒检测问题

标签 java android android-studio timer scheduled-tasks

我正在尝试使用 android 的 accelerometer 实现一个简单的跌倒检测算法。

手机的当前加速度存储在 mAccel 中,如果检测到突然晃动,Timer t 开始计时。 Timer 内部有两个 CountDownTimers

如果用户在过去 5 秒内没有移动,firstTimer 用于记录“跌倒”,如果用户没有移动,secondTimer 用于确认跌倒'按下按钮(尚未实现)。

public void onSensorChanged(SensorEvent event) {

    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        mGravity = event.values.clone();

        float x = mGravity[0];
        float y = mGravity[1];
        float z = mGravity[2];
        mAccelLast = mAccelCurrent;
        mAccelCurrent = (float) Math.sqrt(x * x + y * y + z * z);
        float delta = mAccelCurrent - mAccelLast;
        mAccel = mAccel * 0.9f + delta;
        mAccel = abs(mAccel);
        textView.setText("a:"+mAccel);
        if (abs(mAccel) > 5.0f) { // Shake detection
            t();
        }
    }
}
public void t () {

    firstTimer = new CountDownTimer(5000, 1000) {  //fall registration timer

        @Override
        public void onTick(long millisUntilFinished) {
            //if there is movement before 5 seconds pass cancel the timer
            if (abs(mAccel) > 2.0f) {
                firstTimer.cancel();
                firstTimer = null;
            }
        }

        @Override
        public void onFinish() {
            toast.show();

            secondTimer = new CountDownTimer(30*1000, 1000) { //fall confirmation timer

                @Override
                public void onTick(long millisUntilFinished) {
                    textView2.setText("" + millisUntilFinished / 1000);
                }

                @Override
                public void onFinish() {
                    Toast toast = Toast.makeText(getApplicationContext(),
                                  "Fall Registered!", Toast.LENGTH_LONG);
                        toast.show();
                    }
                }.start();
            }
        }.start();
    }

主要问题是大多数时候 firstTimer 被访问,由于 mAccel 在减速时超过 2.0 阈值而被取消。

我尝试使用 Timer.schedule() 来延迟 firstTimer 的激活,直到加速度值“静止”之后,但它不起作用。

最佳答案

我创建了一个新的 Timer 对象 mTimer,这似乎适用于所有情况。

CountDownTimer firstTimer = new CountDownTimer(5000, 1000) {  //fall registration timer

        @Override
        public void onTick(long millisUntilFinished) {
            //if there is movement before 5 seconds pass cancel the timer
            if (abs(mAccel) > 2.0f) {
                Toast toast = Toast.makeText(getApplicationContext(),
                              "Fall not Detected", Toast.LENGTH_SHORT);
                toast.show();
                firstTimer.cancel();
            }
        }

        @Override
        public void onFinish() {
            Toast toast = Toast.makeText(getApplicationContext(),
                          "Fall Detected!", Toast.LENGTH_SHORT);
            toast.show();
            secondTimer.start();
        }
    };

    CountDownTimer secondTimer = new CountDownTimer(30*1000, 1000) {
    //fall confirmation timer

        @Override
        public void onTick(long millisUntilFinished) {
            textView2.setText("" + millisUntilFinished / 1000);
        }

        @Override
        public void onFinish() {
            Toast toast = Toast.makeText(getApplicationContext(),
            "Fall Registered!", Toast.LENGTH_LONG);
            toast.show();
        }
    };


@Override
public void onSensorChanged(SensorEvent event) {

    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        mGravity = event.values.clone();
        float x = mGravity[0];
        float y = mGravity[1];
        float z = mGravity[2];
        mAccelLast = mAccelCurrent;
        mAccelCurrent = (float) Math.sqrt(x * x + y * y + z * z);
        float delta = mAccelCurrent - mAccelLast;
        mAccel = mAccel * 0.9f + delta;
        mAccel = abs(mAccel);
        textView.setText("a:"+mAccel);
        if (abs(mAccel) > 5.0f) { // Shake detection
            mTimer.schedule(new TimerTask() { 
            //start after 2 second delay to make acceleration values "rest"

                @Override
                public void run() {
                    firstTimer.start();
                }

            }, 2000);
        }
    }
}

关于java - 安卓跌倒检测问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48362127/

相关文章:

java - 如何使用 Java 代码在框架布局底部添加 TextView

java - 如何在日期选择器编辑文本时永久隐藏键盘

java - 如何在此代码中跟踪多个异步任务

java - .net 和 java 之间通信的最佳方式

php - 在 Android 上使用 SSL 的 Json

android - HttpsURLConnection 和间歇性连接

android - 由于 newrelic 异常,应用程序在 onCreate 中崩溃

java - Android:抽屉导航 NullPointerException

java - 使用批处理脚本清除 Selenium 测试中的临时文件夹

android - 使用默认值插入sqlite