SensorManager
Decide if your device is static or not, using the accelerometer
Section titled “Decide if your device is static or not, using the accelerometer”Add the following code to the onCreate()/onResume() method:
SensorManager sensorManager;Sensor mAccelerometer;final float movementThreshold = 0.5f; // You may have to change this value.boolean isMoving = false;float[] prevValues = {1.0f, 1.0f, 1.0f};float[] currValues = new float[3];
sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);mAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);sensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);You may have to adjust the sensitivity by adapting the movementThreshold by trial and error. Then, override the onSensorChanged() method as follows:
@Overridepublic void onSensorChanged(SensorEvent event) { if (event.sensor == mAccelerometer) { System.arraycopy(event.values, 0, currValues, 0, event.values.length); if ((Math.abs(currValues[0] - prevValues[0]) > movementThreshold) || (Math.abs(currValues[1] - prevValues[1]) > movementThreshold) || (Math.abs(currValues[2] - prevValues[2]) > movementThreshold)) { isMoving = true; } else { isMoving = false; } System.arraycopy(currValues, 0, prevValues, 0, currValues.length); }}If you want to prevent your app from being installed on devices that do not have an accelerometer, you have to add the following line to your manifest:
<uses-feature android:name="android.hardware.sensor.accelerometer" />Retrieving sensor events
Section titled “Retrieving sensor events”Retrieving sensor information from the onboard sensors:
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager; private Sensor accelerometer; private Sensor gyroscope;
float[] accelerometerData = new float[3]; float[] gyroscopeData = new float[3];
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); gyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
}
@Override public void onResume() { //Register listeners for your sensors of interest mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST); mSensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_FASTEST); super.onResume(); }
@Override protected void onPause() { //Unregister any previously registered listeners mSensorManager.unregisterListener(this); super.onPause(); }
@Override public void onSensorChanged(SensorEvent event) { //Check the type of sensor data being polled and store into corresponding float array if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { accelerometerData = event.values; } else if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) { gyroscopeData = event.values; } }
@Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub }}Sensor transformation to world coordinate system
Section titled “Sensor transformation to world coordinate system”The sensor values returned by Android are with respective to the phone’s coordinate system (e.g. +Y points towards the top of the phone). We can transform these sensor values into a world coordinate system (e.g. +Y points towards magnetic North, tangential to the ground) using the sensor managers rotation matrix
First, you would need to declare and initialize the matrices/arrays where data will be stored (you can do this in the onCreate method, for example):
float[] accelerometerData = new float[3];float[] accelerometerWorldData = new float[3];float[] gravityData = new float[3];float[] magneticData = new float[3];float[] rotationMatrix = new float[9];Next, we need to detect changes in sensor values, store them into the corresponding arrays (if we want to use them later/elsewhere), then calculate the rotation matrix and resulting transformation into world coordinates:
public void onSensorChanged(SensorEvent event) { sensor = event.sensor; int i = sensor.getType();
if (i == Sensor.TYPE_ACCELEROMETER) { accelerometerData = event.values; } else if (i == Sensor.TYPE_GRAVITY) { gravityData = event.values; } else if (i == Sensor.TYPE_MAGNETIC) { magneticData = event.values; }
//Calculate rotation matrix from gravity and magnetic sensor data SensorManager.getRotationMatrix(rotationMatrix, null, gravityData, magneticData);
//World coordinate system transformation for acceleration accelerometerWorldData[0] = rotationMatrix[0] * accelerometerData[0] + rotationMatrix[1] * accelerometerData[1] + rotationMatrix[2] * accelerometerData[2]; accelerometerWorldData[1] = rotationMatrix[3] * accelerometerData[0] + rotationMatrix[4] * accelerometerData[1] + rotationMatrix[5] * accelerometerData[2]; accelerometerWorldData[2] = rotationMatrix[6] * accelerometerData[0] + rotationMatrix[7] * accelerometerData[1] + rotationMatrix[8] * accelerometerData[2];
}