Search code examples
androidandroid-sensors

Which sensor for rotating android phone?


Imagine you are pointing at the TV. You have your phone gripped in your hand. Now, rotate your wrist.

Which sensor would I need to manage to detect such a movement?

Gyroscope? Orientation? Accelerometer?


Solution

  • The sensors TYPE_MAGNETIC_FIELD and TYPE_ACCELEROMETER are fine to detect that (as TYPE_ORIENTATION is now deprecated).

    You will need:

    a few matrix:

    private float[] mValuesMagnet      = new float[3];
    private float[] mValuesAccel       = new float[3];
    private float[] mValuesOrientation = new float[3];
    
    private float[] mRotationMatrix    = new float[9];
    

    a listener to catch the values the sensors send (this will be an argument of SensorManager.registerListener() that you will have to call to setup your sensors):

    private final SensorEventListener mEventListener = new SensorEventListener() {
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    
        public void onSensorChanged(SensorEvent event) {
            // Handle the events for which we registered
            switch (event.sensor.getType()) {           
                case Sensor.TYPE_ACCELEROMETER: 
                    System.arraycopy(event.values, 0, mValuesAccel, 0, 3); 
                    break; 
    
                case Sensor.TYPE_MAGNETIC_FIELD: 
                    System.arraycopy(event.values, 0, mValuesMagnet, 0, 3); 
                    break; 
        }
    };
    

    And you'll need to compute the azimuth, pitch, and roll:

        SensorManager.getRotationMatrix(mRotationMatrix, null, mValuesAccel, mValuesMagnet);
        SensorManager.getOrientation(mRotationMatrix, mValuesOrientation);  
    

    mValuesOrientation is then filled with:

    • mValuesOrientation[0]: azimuth, rotation around the Z axis.
    • mValuesOrientation[1]: pitch, rotation around the X axis.
    • mValuesOrientation[2]: roll, rotation around the Y axis.

    Check the documentation of getOrientation() to know how the axis are defined. You may need to use SensorManager.remapCoordinateSystem() to redefine these axis.