使用摇动动作从加速度计获取方向

Fetching direction from Accelerometer using shake action

我制作了 android 应用程序,当使用加速度计摇动一次时播放下一首歌曲。

现在我想要我的应用程序,如果摇动右侧的 phone 它应该播放下一首歌曲,或者如果摇动左边播放上一首,我可以用如果可能的话,在摇动动作时找到轴的逻辑 如何把坐标轴放到运动检测的方法中,才能知道手机晃动的方向。如果有人对此有逻辑,请帮助我被困在这里。

我对此进行了一些深入研究,并能够自行解决。但是在发布答案时,我 found this answer by Basil 这比我的实现解释得更好。所以,我发现它更有帮助。

what he did

onSensorChanged 中,每当设备接收到新值时,它都会在一些延迟后将值存储到变量中。之后 将新值与以前的值 进行漂亮的比较。这导致计算出设备震动的方向。如果答案仍然不清楚,请告诉我。

public class ShakeActivity extends Activity implements SensorListener {
// For shake motion detection.
private SensorManager sensorMgr;
private long lastUpdate = -1;
private float x, y, z;
private float last_x, last_y, last_z;
private static final int SHAKE_THRESHOLD = 800;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);
// start motion detection
sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
boolean accelSupported = sensorMgr.registerListener(this,
    SensorManager.SENSOR_ACCELEROMETER,
    SensorManager.SENSOR_DELAY_GAME);

    if (!accelSupported) {
        // on accelerometer on this device
        sensorMgr.unregisterListener(this,
                SensorManager.SENSOR_ACCELEROMETER);
    }
}

protected void onPause() {
    if (sensorMgr != null) {
        sensorMgr.unregisterListener(this,
                SensorManager.SENSOR_ACCELEROMETER);
        sensorMgr = null;
    }
    super.onPause();
}

public void onAccuracyChanged(int arg0, int arg1) {
// TODO Auto-generated method stub
}

public void onSensorChanged(int sensor, float[] values) {
    if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
        long curTime = System.currentTimeMillis();
        // only allow one update every 100ms.
        if ((curTime - lastUpdate) > 100) {
        long diffTime = (curTime - lastUpdate);
        lastUpdate = curTime;

        x = values[SensorManager.DATA_X];
        y = values[SensorManager.DATA_Y];
        z = values[SensorManager.DATA_Z];

        if(Round(x,4)>10.0000){
            Log.d("sensor", "X Right axis: " + x);
            Toast.makeText(this, "Right shake detected", Toast.LENGTH_SHORT).show();
        }
        else if(Round(x,4)<-10.0000){
            Log.d("sensor", "X Left axis: " + x);
            Toast.makeText(this, "Left shake detected", Toast.LENGTH_SHORT).show();
        }

        float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;

        // Log.d("sensor", "diff: " + diffTime + " - speed: " + speed);
        if (speed > SHAKE_THRESHOLD) {
            //Log.d("sensor", "shake detected w/ speed: " + speed);
            //Toast.makeText(this, "shake detected w/ speed: " + speed, Toast.LENGTH_SHORT).show();
        }
        last_x = x;
        last_y = y;
        last_z = z;
        }
    }
}

public static float Round(float Rval, int Rpl) {
float p = (float)Math.pow(10,Rpl);
Rval = Rval * p;
float tmp = Math.round(Rval);
return (float)tmp/p;
}
}