使用加速度计时,为什么在没有更改传感器值时会定期调用onSensorChanged()方法?

时间:2014-11-20 11:33:07

标签: android android-sensors

这就是应用中加速度计部件的工作方式:
单击应用程序中的按钮后,目标是读取加速度计值并播放音频剪辑。

我已从应用程序中隔离了有问题的代码。

AlarmActivity.java

public class AlarmActivity extends Activity implements SensorEventListener {
    ...
    private SensorManager sensorManager;
    private Sensor mAccelerometer;
    private AudioPlayer mPlayer = new AudioPlayer();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_alarm);
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    }

    @Override
    public void onResume() {
        super.onResume();
        sensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    public void onPause() {
        super.onPause();
        mPlayer.stop();
        sensorManager.unregisterListener(this);
    }

    @Override
    public void onStop() {
        super.onStop();
        mPlayer.stop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mPlayer.stop();
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        Log.d(TAG, "onSensor() called");

        class StartGuardingTask extends AsyncTask<Void, Void, Void> {
            @Override
            protected Void doInBackground(Void...params) {
                mPlayer.play(AlarmActivity.this);
                return null;
            }
        }

        if(mCurrentXVal != mOldXVal || mCurrentYVal != mOldYVal || mCurrentZVal != mOldZVal) {
            mOldXVal = mCurrentXVal;
            mOldYVal = mCurrentYVal;
            mOldZVal = mCurrentZVal;

            mXValue = (EditText)findViewById(R.id.editText1);
            mXValue.setText("x:" + mCurrentXVal);
            mYValue = (EditText)findViewById(R.id.editText2);
            mYValue.setText("y:" + mCurrentYVal);
            mZValue = (EditText)findViewById(R.id.editText3);
            mZValue.setText("z:" + mCurrentZVal);

            new StartGuardingTask().execute();
        }
    }
}

AudioPlayer.java

public class AudioPlayer {
    private MediaPlayer mPlayer;

    public void stop() {
        if(mPlayer != null) {
            mPlayer.release();
            mPlayer = null;
        }
    }

    public void play(Context c) {
        if(mPlayer == null) {
            mPlayer = MediaPlayer.create(c, R.raw.police_siren);

            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                public void onCompletion(MediaPlayer mp) {
                    stop();
                }
            });
            mPlayer.start();
        }
    }

    public MediaPlayer getPlayer() {
        return mPlayer;
    }
}

即使设备静止,我也能看到(使用logcat)定期调用的方法。

我已经阅读了OP面临类似情况的另一个postthis帖子表明该方法按预期工作 只有当方法按照宣传的方式工作时,我才能摆脱onSensorChanged()方法中的条件。

因此,如果我的设备静止,没有传感器值发生变化那么为什么会发生这种情况呢?

2 个答案:

答案 0 :(得分:0)

加速度计甚至可以检测到最小的变化值。例如,您将手机放在桌子上,然后播放音乐。来自音乐的振动足以引起加速度计的许多重复变化,但是值非常小。这就是为什么你必须在onSensorChanged()方法中放置一个条件,以便通知值只有足够大的变化。

答案 1 :(得分:0)

您怎么说传感器值没有改变?我想它应该。

由于重力加速,你会一直开火。根据Android手机的方向,您将看到在x / y / z轴上报告了一些值。例如,当你站在地球上的某个地方时,加速度9.8 m / s2向下作用。对于Android中的Accelerometer也是如此。