package com.androidcookbook.sensorshakedetection;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.Toast;
/**
* Detect if the user has shaken the device.
* @author Thomas Manthey
*/
public class ShakeActivity extends Activity {
/* The connection to the hardware */
private SensorManager mySensorManager;
/* Here we store the current values of acceleration, one for each axis */
private float xAccel;
private float yAccel;
private float zAccel;
/* And here the previous ones */
private float xPreviousAccel;
private float yPreviousAccel;
private float zPreviousAccel;
/* Used to suppress the first shaking */
private boolean firstUpdate = true;
/* What acceleration difference would we assume as a rapid movement? */
private final float shakeThreshold = 1.5f;
/* Has a shaking motion been started (one direction) */
private boolean shakeInitiated = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mySensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mySensorManager.registerListener(mySensorEventListener, mySensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
/* The SensorEventListener lets us wire up to the real hardware events */
private final SensorEventListener mySensorEventListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent se) {
updateAccelParameters(se.values[0], se.values[1], se.values[2]);
if ((!shakeInitiated) && isAccelerationChanged()) {
shakeInitiated = true;
} else if ((shakeInitiated) && isAccelerationChanged()) {
executeShakeAction();
} else if ((shakeInitiated) && (!isAccelerationChanged())) {
shakeInitiated = false;
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
/* not used in this example */
}
};
/* Store acceleration values from sensor */
private void updateAccelParameters(float xNewAccel, float yNewAccel, float zNewAccel) {
/* we have to suppress the first change of acceleration, as
* it results from first values being initialized with 0
*/
if (firstUpdate) {
xPreviousAccel = xNewAccel;
yPreviousAccel = yNewAccel;
zPreviousAccel = zNewAccel;
firstUpdate = false;
} else {
xPreviousAccel = xAccel;
yPreviousAccel = yAccel;
zPreviousAccel = zAccel;
}
xAccel = xNewAccel;
yAccel = yNewAccel;
zAccel = zNewAccel;
}
/*
* If the values of acceleration have changed on at least two axes,
* we are probably in a shake motion
*/
private boolean isAccelerationChanged() {
float deltaX = Math.abs(xPreviousAccel - xAccel);
float deltaY = Math.abs(yPreviousAccel - yAccel);
float deltaZ = Math.abs(zPreviousAccel - zAccel);
return (deltaX > shakeThreshold && deltaY > shakeThreshold)
|| (deltaX > shakeThreshold && deltaZ > shakeThreshold)
|| (deltaY > shakeThreshold && deltaZ > shakeThreshold);
}
/**
* Do the action that we wanted to do when shaking of the device is detected.
*/
private void executeShakeAction() {
Toast.makeText(this, "Shaking detected!", Toast.LENGTH_SHORT).show();
}
}