Sensors in Android

[Android] Sep 17, 2012

Introduction

Android provides support for hardware features such as cameras and sensors, through the android.hardware package. This document describes the use of android.hardware package and sensors in the development Android applications.

Examples of mobile device sensors include accelerometers, gyroscopes, and sensors for light, proximity, magnetic field, pressure, humidity, and temperature. Other sensors are developed and added over time, and the android.hardware package is updated as new sensors become available. Not all sensors are included in all Android devices. Access to these sensors is provided through the classes and interfaces present in the android.hardware package.

For information on sensors supported by Android, see:
http://developer.android.com/reference/android/hardware/Sensor.html
http://developer.android.com/guide/topics/sensors/sensors_overview.html#sensors-intro

SensorManager

In order to get access to sensor, get an instance of SensorManager, which is a system service running on Android. Using the getSystemService() method of the Context class with SENSOR_SERVICE as the argument.

SensorManager mSensorManager = 
(SensorManager)getSystemService(SENSOR_SERVICE);

Code 1: Getting a SensorManager Instance

Before using a particular type of sensor, use SensorManager.getDefaultSensor(int type) or the SensorManager.getSensorList(int type) method to see if the sensor is available.

The SensorManager.getSensorList(Sensor. TYPE_ALL) method provides a list of all the sensors present in the device. After verifying that a particular sensor is available, use SensorEventListener to receive sensor updates. Register the SensorEventListener listener with the SensorManager.registerListener() method. This method accepts the SensorEventListener callback interface to notify, or update, the calling application whenever a sensor event occurs.

Sensor accelerometer = 
SensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(*activity*,
	 accelerometer,    
	 SensorManager.SENSOR_DELAY_NORMAL);  

Code 2: Registering the SensorEventListener with the SensorManager.registerListener Method

where *activity* represents the activity in which SensorEventListener has been implemented.

 mSensorManager.unregisterListener(*activity*);

Code 3: Unregistering the SensorEventListener

All the hardware that an application requires should be declared using the manifest element. For more information on the hardware feature descriptor defined for sensors, see
http://developer.android.com/guide/topics/manifest/uses-feature-element.html#hw-features

SensorEventListener

The SensorEventListener callback interface has following methods:

abstract void onAccuracyChanged(Sensor sensor, int accuracy)
abstract void onSensorChanged(SensorEvent event)

Code 4: SensorEventListener Callback Interface Methods

The onAccuracyChanged(Sensor sensor, int accuracy) method is called when there is a change in the sensor accuracy.

Accuracy value can be one of the following:

  • SensorManager.SENSOR_STATUS_ACCURACY_HIGH - high accuracy
  • SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM - medium accuracy
  • SensorManager.SENSOR_STATUS_ACCURACY_LOW - low accuracy
  • SensorManager.SENSOR_STATUS_UNRELIABLE - accuracy is unreliable and cannot be trusted.

onSensorChanged(SensorEvent event) is called when sensor values are changed. SensorEvent, holds information about an event that has occurred. This includes information such as sensor values, type of sensor, timestamp, accuracy, course of sensor etc.

SensorEvent.values contains the sensor values. This is an array of float values representing the sensor values. The length and content of this array depends on the type of sensor used.

Samsung Sensor Simulator

The Samsung Sensor Simulator is a plug-in for Eclipse IDE that provides a visual model of a device along with its various sensor settings. By manipulating the position of the device, or the forces acting on the device, the user can see the sensor readings under a variety of conditions.

Samsung Sensor Simulator Script

Samsung Sensor Script is a text based script language. It is designed to automate testing of the UI widgets in the Samsung Sensor Simulator.

Example

Following is a simple sensor compass example. The example consists of single activity which will register Sensor implementations and call backs and does the necessary rendering of the output.

Complete code is provided in the attachment zip file.

In order for compass to work, get access to the TYPE_ACCELEROMETER and TYPE_MAGNETIC_FIELD sensors. To get the event from the sensors register the SensorEventListener listener and implement necessary onAccuracyChanged and onSensorChanged methods.

Once the data from the sensor is obtained, render the output. This is done using the View class. The output is rendered using the onDraw method of Canvas class.

Following code shows:

  • Getting the necessary TYPE_ACCELEROMETER and TYPE_MAGNETIC_FIELD Sensors.
  • Registering the Sensors
  • Implement the SensorEventListener interface and overriding the onAccuracyChanged and onSensorChanged callback method.
  • Setting the Activity view with CompassView.
 public class SensorCompassActivity extends Activity implements
	SensorEventListener {
private float azimut;
private float[] gravity;
private float[] geoMagnetic;
private CompassView drawableView;
private SensorManager mSensorManager;
private Sensor accSensor;
private Sensor magnetSensor;
 protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   /*Set the drawabale view for rendering compass*/
   drawableView = new CompassView(this);
   setContentView(drawableView); 
   /* Get the necessary sensor */
   mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
   accSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
   magnetSensor = mSensorManager
				.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
 }
 protected void onResume() {
  super.onResume();
  /* Register the sensor listeners */
  mSensorManager.registerListener(this, accSensor,
				SensorManager.SENSOR_DELAY_UI);
  mSensorManager.registerListener(this, magnetSensor,
				SensorManager.SENSOR_DELAY_UI);
 }
 protected void onPause() {
	super.onPause();
	mSensorManager.unregisterListener(this);
 }
 @Override
 public void onAccuracyChanged(Sensor sensor, int accuracy) {
 }
 @Override
 public void onSensorChanged(SensorEvent event) {
 }
}
Next the important part of the code is to calculate the azimuth value for rendering the compass. This is done 
in the onSensorChanged method as shown below.
@Override
public void onSensorChanged(SensorEvent event) {
/*get gravity value arrays from Accelerometer*/
	if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
		gravity = event.values;
/*get gravity value arrays from Magnet*/
	if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
		geoMagnetic = event.values;
	if (gravity != null && geoMagnetic != null) {
		/*Rotation matrix and Inclination matrix*/
		float R[] = new float[9];
		float I[] = new float[9];
/* Compute the inclination matrix I as well as the rotation matrix R transforming a vector from the device 
	coordinate system to the world's coordinate system 
R and I [Length 9]
gravity vector expressed in the device's coordinate [Length 3]
geoMagnetic vector expressed in the device's coordinate[Length 3]
*/
		boolean success = SensorManager.getRotationMatrix(R, I, 
gravity, geoMagnetic);

		if (success) {
		 /* Orientation has azimuth, pitch and roll */
		 float orientation[] = new float[3];
		 SensorManager.getOrientation(R, orientation);
		 azimut = orientation[0];
		}
	 }
	/*update the view */
	   drawableView.invalidate();
}

After obtaining the azimuth value, update the view. The View class consists of two lines showing north – south and west – east direction drawn from center of the canvas.
Based on the azimuth value the view is rotated as follows:

 protected void onDraw(Canvas canvas) {
 /* Get Width and Height of the canvas */
 int width = getWidth();
 int height = getHeight();
 /* Get center point of the canvas */
 int centerx = width / 2;
 int centery = height / 2;
 /* Rotate the canvas based on the angle using azimuth */
 canvas.rotate(-azimut * 360 / (2 * 3.14159f), centerx, centery);
 /* draw north - south line*/
 canvas.drawLine(centerx, centery - 300, centerx, centery + 300,
									paint);
/* draw east - west line*/
canvas.drawLine(centerx - 300, centery, centerx + 300, centery,
									paint);
/* draw names*/
canvas.drawText("North", centerx + 10, centery - 100, paint);
canvas.drawText("South", centerx + 10, centery + 100, paint);
canvas.drawText("East", centerx + 100, centery - 15, paint);
canvas.drawText("West", centerx - 150, centery - 15, paint);
}
The complete view class is shown below which does the compass rendering based on azimuth value.
public class CompassView extends View {
 Paint paint = new Paint();
 public CompassView(Context context) {
  super(context);
  /* Set Paint as White */
  paint.setColor(Color.BLACK);
  /* Set Stroke Width of 2 */
  paint.setStyle(Style.STROKE);
  paint.setStrokeWidth(2);
  /* Set Anitalias */
  paint.setAntiAlias(true);
  /* Set Text Size of 20f */
  paint.setTextSize(20f);
};
protected void onDraw(Canvas canvas) {
 /* Get Width and Height of the canvas */
 int width = getWidth();
 int height = getHeight();
 /* Get center point of the canvas */
 int centerx = width / 2;
 int centery = height / 2;
 /* Rotate the canvas based on the angle using azimuth */
 canvas.rotate(-azimut * 360 / (2 * 3.14159f), centerx, centery);
 /* draw north - south line*/
 canvas.drawLine(centerx, centery - 300, centerx, centery + 300,
									paint);
 /* draw east - west line*/
 canvas.drawLine(centerx - 300, centery, centerx + 300, centery,
									paint);
 /* draw direction text*/
 canvas.drawText("North", centerx + 10, centery - 100, paint);
 canvas.drawText("South", centerx + 10, centery + 100, paint);
 canvas.drawText("East", centerx + 100, centery - 15, paint);
 canvas.drawText("West", centerx - 150, centery - 15, paint);
 }
}

Code 5: Example Code for a Compass Sensor

The complete code is attached in a zip file.


COPY URL twitter facebook