Using an Android phone's sensors


SDK Version: 
M3

Accessing the sensor data of a phone, is not too complicated, but since API level 3, a lot of things got deprecated. Using only the emulator, you have only a few (here is one) options, to simulate sensor data. I would recommend the use of a physical phone. Keep in mind, that not all phones have the same sensors integrated! Cheaper phones might not have a temperature sensor, or a gyroscope, but I'm pretty sure, that all Android phones have at least an accelerometer, and an orientation sensor.

Here is an example, how to access acceleration and orientation sensor data (in API level 3 and above), without using any deprecated methods.

  1. public class SensorTest extends Activity implements SensorEventListener {
  2.  
  3. SensorManager sensorManager = null;
  4.  
  5. //for accelerometer values
  6. TextView outputX;
  7. TextView outputY;
  8. TextView outputZ;
  9.  
  10. //for orientation values
  11. TextView outputX2;
  12. TextView outputY2;
  13. TextView outputZ2;
  14.  
  15.  @Override
  16.  public void onCreate(Bundle savedInstanceState) {
  17.     super.onCreate(savedInstanceState);

Start with sensorManager setup

  1.     sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
  2.     setContentView(R.layout.main);
  3.  
  4.     //just some textviews, for data output
  5.     outputX = (TextView) findViewById(R.id.TextView01);
  6.     outputY = (TextView) findViewById(R.id.TextView02);
  7.     outputZ = (TextView) findViewById(R.id.TextView03);
  8.  
  9.     outputX2 = (TextView) findViewById(R.id.TextView04);
  10.     outputY2 = (TextView) findViewById(R.id.TextView05);
  11.     outputZ2 = (TextView) findViewById(R.id.TextView06);
  12.  }

Now register the required listeners, it is recommended, to put this part in onResume.
What's interesting here, is the refresh speed. Just like using a toast(short,long...), there is no easy way, to set up a proper time limit. There are 4 sensor delay settings: fastest, game, normal, and ui.
Try them all out, and check which one works the best for your application. Aim for the lowest required refresh speed!

  1. @Override
  2.  protected void onResume() {
  3.     super.onResume();
  4.     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), sensorManager.SENSOR_DELAY_GAME);
  5.     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), sensorManager.SENSOR_DELAY_GAME);
  6.  }

It is recommended, to stop using the sensor event listener, as soon as you don't need it, and it should not be left running in the background. It can drain the battery pretty fast.

  1. @Override
  2.  protected void onStop() {
  3.     super.onStop();
  4.     sensorManager.unregisterListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER));
  5.     sensorManager.unregisterListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION));
  6.  }

The event.sensor.getType() will tell us, what kind of event just happened.

  1. public void onSensorChanged(SensorEvent event) {
  2.     synchronized (this) {
  3.         switch (event.sensor.getType()){
  4.             case Sensor.TYPE_ACCELEROMETER:
  5.                 outputX.setText("x:"+Float.toString(event.values[0]));
  6.                 outputY.setText("y:"+Float.toString(event.values[1]));
  7.                 outputZ.setText("z:"+Float.toString(event.values[2]));
  8.             break;
  9.         case Sensor.TYPE_ORIENTATION:
  10.                 outputX2.setText("x:"+Float.toString(event.values[0]));
  11.                 outputY2.setText("y:"+Float.toString(event.values[1]));
  12.                 outputZ2.setText("z:"+Float.toString(event.values[2]));
  13.         break;
  14.  
  15.         }
  16.     }
  17.  }

There is also an onAccuracyChanged part, which we don't care about right now.

  1.  @Override
  2. public void onAccuracyChanged(Sensor sensor, int accuracy) {}  
  3. }

To sum things up, to access sensor data you have to do the following things:
1. Check sensor availability.
2. Register a listener to a sensorManager.
3. Catch the needed data , from onSensorChanged.
4. Unregister the sensorManager's listener.

screenshot

You can read more, about those seemingly random numbers on the above screenshot, in the official google documentation of Android here.