代码之家  ›  专栏  ›  技术社区  ›  Xenofonos

Android坠落检测问题

  •  3
  • Xenofonos  · 技术社区  · 8 年前

    我正在尝试使用android的 accelerometer .

    手机的当前加速度存储在 mAccel 如果检测到突然震动 Timer t 开始。内部 Timer 是两个 CountDownTimers .

    这个 firstTimer 如果用户在过去5秒内没有移动,并且 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();
        }
    

    主要问题是大多数时候 第一个计时器 被访问时,由于 mAccel公司 在减速时超过2.0阈值。

    我试着用 Timer.schedule() 延迟激活 第一个计时器 直到加速度值“静止”后,但它将不起作用。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Xenofonos    8 年前

    我创建了一个新的计时器对象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);
            }
        }
    }