blob: 3c5e94c9b9927bdaffafbd9e8519626ae5598253 [file] [log] [blame]
Bill Gruberf8c029e2011-11-01 09:31:57 -07001page.title=Sensors Overview
2parent.title=Sensors
3parent.link=index.html
4@jd:body
5
6<div id="qv-wrapper">
7 <div id="qv">
8 <h2>Quickview</h2>
9 <ul>
10 <li>Learn about the sensors that Android supports and the Android sensor framework.</li>
11 <li>Find out how to list sensors, determine sensor capabilities, and monitor sensor data.</li>
12 <li>Learn about best practices for accessing and using sensors.</li>
13 </ul>
14 <h2>In this document</h2>
15 <ol>
16 <li><a href="#sensors-intro">Introduction to Sensors</a></li>
17 <li><a href="#sensors-identify">Identifying Sensors and Sensor Capabilities</a></li>
18 <li><a href="#sensors-monitor">Monitoring Sensor Events</a></li>
19 <li><a href="#sensors-configs">Handling Different Sensor Configurations</a></li>
20 <li><a href="#sensors-coords">Sensor Coordinate System</a></li>
21 <li><a href="#sensors-practices">Best Practices for Accessing and Using Sensors</a></li>
22 </ol>
23 <h2>Key classes and interfaces</h2>
24 <ol>
25 <li>{@link android.hardware.Sensor}</li>
26 <li>{@link android.hardware.SensorEvent}</li>
27 <li>{@link android.hardware.SensorManager}</li>
28 <li>{@link android.hardware.SensorEventListener}</li>
29 </ol>
30 <h2>Related samples</h2>
31 <ol>
32 <li><a href="{@docRoot}resources/samples/AccelerometerPlay/index.html">Accelerometer
33 Play</a></li>
34 <li><a
35href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/RotationVectorDemo.html">
36API Demos (OS - RotationVectorDemo)</a></li>
37 <li><a
38href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/Sensors.html">API Demos
39(OS - Sensors)</a></li>
40 </ol>
41 <h2>See also</h2>
42 <ol>
43 <li><a href="{@docRoot}guide/topics/sensors/index.html">Sensors</a></li>
44 <li><a href="{@docRoot}guide/topics/sensors/sensors_motion.html">Motion Sensors</a></li>
45 <li><a href="{@docRoot}guide/topics/sensors/sensors_position.html">Position
46 Sensors</a></li>
47 <li><a href="{@docRoot}guide/topics/sensors/sensors_environment.html">Environment
48 Sensors</a></li>
49 </ol>
50 </div>
51</div>
52
53<p>Most Android-powered devices have sensors that let you monitor changes in device
54position and motion. Many devices also have sensors that let you determine ambient environmental
55conditions, such as temperature, pressure, humidity, and lighting. You can access these
56sensors and acquire raw sensor data by using the Android sensor framework.</p>
57
58<p>The sensor framework provides several classes and interfaces that help you perform a wide variety
59of sensor-related tasks. For example, you can use the sensor framework to do the following:</p>
60
61<ul>
62 <li>Determine which sensors are available on a device.</li>
63 <li>Determine an individual sensor's capabilities, such as its maximum range, manufacturer, power
64 requirements, and resolution.</li>
65 <li>Acquire raw sensor data and define the minimum rate at which you acquire sensor data.</li>
66 <li>Register and unregister sensor event listeners that monitor sensor changes.</li>
67 </ul>
68
69<p>This topic provides an overview of the sensors that are available on the Android platform.
70It also provides an introduction to the sensor framework.</p>
71
72<h2 id="sensors-intro">Introduction to Sensors</h2>
73
74<p>The Android sensor framework lets you access many types of sensors. Some of these sensors are
75hardware-based and some are software-based. Hardware-based sensors are physical components built
76into a handset or tablet device. They derive their data by directly measuring specific environmental
77properties, such as acceleration, geomagnetic field strength, or angular change. Software-based
78sensors are not physical devices, although they mimic hardware-based sensors. Software-based sensors
79derive their data from one or more of the hardware-based sensors and are sometimes called virtual
80sensors or synthetic sensors. The linear acceleration sensor and the gravity sensor are examples of
81software-based sensors. Table 1 summarizes the sensors that are supported by the Android
82platform.</p>
83
84<p>Few Android-powered devices have every type of sensor. For example, most handset devices and
85tablets have an accelerometer and a magnetometer, but fewer devices have
86barometers or thermometers. Also, a device can have more than one sensor of a given type. For
87example, a device can have two gravity sensors, each one having a different range.</p>
88
89<p class="table-caption" id="table1">
90 <strong>Table 1.</strong> Sensor types supported by the Android platform.</p>
91<table>
92 <tr>
93 <th scope="col" style="white-space:nowrap">Sensor</th>
94 <th scope="col" style="white-space:nowrap">Type</th>
95 <th scope="col" style="white-space:nowrap">Description</th>
96 <th scope="col" style="white-space:nowrap">Common Uses</th>
97 </tr>
98 <tr>
99 <td>{@link android.hardware.Sensor#TYPE_ACCELEROMETER}</td>
100 <td>Hardware</td>
101 <td>Measures the acceleration force in m/s<sup>2</sup> that is applied to a device on
102all three physical axes (x, y, and z), including the force of gravity.</td>
103 <td>Motion detection (shake, tilt, etc.).</td>
104 </tr>
105 <tr>
106 <td>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}</td>
107 <td>Hardware</td>
108 <td>Measures the ambient room temperature in degrees Celsius (&deg;C). See note below.</td>
109 <td>Monitoring air temperatures.</td>
110 <tr>
111 <td>{@link android.hardware.Sensor#TYPE_GRAVITY}</td>
112 <td>Software or Hardware</td>
113 <td>Measures the force of gravity in m/s<sup>2</sup> that is applied to a device on all
114 three physical axes (x, y, z).</td>
115 <td>Motion detection (shake, tilt, etc.).</td>
116 </tr>
117 <tr>
118 <td>{@link android.hardware.Sensor#TYPE_GYROSCOPE}</td>
119 <td>Hardware</td>
120 <td>Measures a device's rate of rotation in rad/s around each of the three
121physical axes
122 (x, y, and z).</td>
123 <td>Rotation detection (spin, turn, etc.).</td>
124 </tr>
125 <tr>
126 <td>{@link android.hardware.Sensor#TYPE_LIGHT}</td>
127 <td>Hardware</td>
128 <td>Measures the ambient light level (illumination) in lx.</td>
129 <td>Controlling screen brightness.</td>
130 </tr>
131 <tr>
132 <td>{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}</td>
133 <td>Software or Hardware</td>
134 <td>Measures the acceleration force in m/s<sup>2</sup> that is
135applied to a device on
136 all three physical axes (x, y, and z), excluding the force of gravity.</td>
137 <td>Monitoring acceleration along a single axis.</td>
138 </tr>
139 <tr>
140 <td>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}</td>
141 <td>Hardware</td>
142 <td>Measures the ambient geomagnetic field for all three physical axes (x, y, z) in
143&mu;T.</td>
144 <td>Creating a compass.</td>
145 </tr>
146 <tr>
147 <td>{@link android.hardware.Sensor#TYPE_ORIENTATION}</td>
148 <td>Software</td>
149 <td>Measures degrees of rotation that a device makes around all three physical axes (x, y, z).
150 As of API level 3 you can obtain the inclination matrix and rotation matrix for
151 a device by using the gravity sensor and the geomagnetic field sensor in conjunction with
152 the {@link android.hardware.SensorManager#getRotationMatrix getRotationMatrix()}
153 method.</td>
154 <td>Determining device position.</td>
155 </tr>
156 <tr>
157 <td>{@link android.hardware.Sensor#TYPE_PRESSURE}</td>
158 <td>Hardware</td>
159 <td>Measures the ambient air pressure in hPa or mbar.</td>
160 <td>Monitoring air pressure changes.</td>
161 </tr>
162 <tr>
163 <td>{@link android.hardware.Sensor#TYPE_PROXIMITY}</td>
164 <td>Hardware</td>
165 <td>Measures the proximity of an object in cm relative to the view screen of a
166 device. This sensor is typically used to determine whether a handset is being held up to
167 a person's ear.</td>
168 <td>Phone position during a call.</td>
169 </tr>
170 <tr>
171 <td>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}</td>
172 <td>Hardware</td>
173 <td>Measures the relative ambient humidity in percent (%).</td>
174 <td>Monitoring dewpoint, absolute, and relative humidity.</td>
175 </tr>
176 <tr>
177 <td>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}</td>
178 <td>Software or Hardware</td>
179 <td>Measures the orientation of a device by providing the three elements of the device's
180 rotation vector.</td>
181 <td>Motion detection and rotation detection.</td>
182 </tr>
183 <tr>
184 <td>{@link android.hardware.Sensor#TYPE_TEMPERATURE}</td>
185 <td>Hardware</td>
186 <td>Measures the temperature of the device in degrees Celsius (&deg;C). This sensor
187implementation varies across devices and
188this sensor was replaced with the {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} sensor in
189API Level 14</td>
190 <td>Monitoring temperatures.</td>
191 </tr>
192</table>
193
194<h3>Sensor Framework</h3>
195
196<p>You can access these sensors and acquire raw sensor data by using the Android sensor framework.
197The sensor framework is part of the {@link android.hardware} package and includes the following
198classes and interfaces:</p>
199
200<dl>
201<dt>{@link android.hardware.SensorManager}</dt>
202<dd>You can use this class to create an instance of the sensor service. This class provides
203various methods for accessing and listing sensors, registering and unregistering sensor event
204listeners, and acquiring orientation information. This class also provides several sensor constants
205that are used to report sensor accuracy, set data acquisition rates, and calibrate sensors.</dd>
206<dt>{@link android.hardware.Sensor}</dt>
207<dd>You can use this class to create an instance of a specific sensor. This class provides various
208methods that let you determine a sensor's capabilities.</dd>
209<dt>{@link android.hardware.SensorEvent}</dt>
210<dd>The system uses this class to create a sensor event object, which provides information about a
211sensor event. A sensor event object includes the following information: the raw sensor data, the
212type of sensor that generated the event, the accuracy of the data, and the timestamp for the
213event.</dd>
214<dt>{@link android.hardware.SensorEventListener}</dt>
215<dd>You can use this interface to create two callback methods that receive notifications (sensor
216events) when sensor values change or when sensor accuracy changes.</dd>
217</dl>
218
219<p>In a typical application you use these sensor-related APIs to perform two basic tasks:</p>
220
221<ul>
222 <li><strong>Identifying sensors and sensor capabilities</strong>
223 <p>Identifying sensors and sensor capabilities at runtime is useful if your application has
224 features that rely on specific sensor types or capabilities. For example, you may want to
225 identify all of the sensors that are present on a device and disable any application features
226 that rely on sensors that are not present. Likewise, you may want to identify all of the sensors
227 of a given type so you can choose the sensor implementation that has the optimum performance
228 for your application.</p>
229 </li>
230 <li><strong>Monitor sensor events</strong>
231 <p>Monitoring sensor events is how you acquire raw sensor data. A sensor event occurs every time
232 a sensor detects a change in the parameters it is measuring. A sensor event provides you
233 with four pieces of information: the name of the sensor that triggered the event, the
234 timestamp for the event, the accuracy of the event, and the raw sensor data that triggered
235 the event.</p>
236 </li>
237</ul>
238
239<h3>Sensor Availability</h3>
240
241<p>While sensor availability varies from device to device, it can also vary between Android
242versions. This is because the Android sensors have been introduced over the course of several
243platform releases. For example, many sensors were introduced in Android 1.5 (API Level 3), but some
244were not implemented and were not available for use until Android 2.3 (API Level 9). Likewise,
245several sensors were introduced in Android 2.3 (API Level 9) and Android 4.0 (API Level 14). Two
246sensors have been deprecated and replaced by newer, better sensors.</p>
247
248<p>Table 2 summarizes the availability of each sensor on a platform-by-platform basis. Only four
249platforms are listed because those are the platforms that involved sensor changes. Sensors that are
250listed as deprecated are still available on subsequent platforms (provided the
251sensor is present on a device), which is in line with Android's forward compatibility policy.</p>
252
253<p class="table-caption" id="table2">
254 <strong>Table 2.</strong> Sensor availability by platform.</p>
255 <table>
256 <tr>
257 <th scope="col">Sensor</th>
258 <th scope="col">Android 4.0 <br>(API Level 14)</th>
259 <th scope="col">Android 2.3 <br>(API Level 9)</th>
260 <th scope="col">Android 2.2 <br>(API Level 8)</th>
261 <th scope="col">Android 1.5 <br>(API Level 3)</th>
262 </tr>
263 <tr>
264 <td>{@link android.hardware.Sensor#TYPE_ACCELEROMETER}</td>
265 <td><strong>Yes</strong></td>
266 <td><strong>Yes</strong></td>
267 <td><strong>Yes</strong></td>
268 <td><strong>Yes</strong></td>
269 </tr>
270 <tr>
271 <td>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}</td>
272 <td><strong>Yes</strong></td>
273 <td>n/a</td>
274 <td>n/a</td>
275 <td>n/a</td>
276 </tr>
277 <tr>
278 <td>{@link android.hardware.Sensor#TYPE_GRAVITY}</td>
279 <td><strong>Yes</strong></td>
280 <td><strong>Yes</strong></td>
281 <td>n/a</td>
282 <td>n/a</td>
283 </tr>
284 <tr>
285 <td>{@link android.hardware.Sensor#TYPE_GYROSCOPE}</td>
286 <td><strong>Yes</strong></td>
287 <td><strong>Yes</strong></td>
288 <td>n/a<sup>1</sup></td>
289 <td>n/a<sup>1</sup></td>
290 </tr>
291 <tr>
292 <td>{@link android.hardware.Sensor#TYPE_LIGHT}</td>
293 <td><strong>Yes</strong></td>
294 <td><strong>Yes</strong></td>
295 <td><strong>Yes</strong></td>
296 <td><strong>Yes</strong></td>
297 </tr>
298 <tr>
299 <td>{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}</td>
300 <td><strong>Yes</strong></td>
301 <td><strong>Yes</strong></td>
302 <td>n/a</td>
303 <td>n/a</td>
304 </tr>
305 <tr>
306 <td>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}</td>
307 <td><strong>Yes</strong></td>
308 <td><strong>Yes</strong></td>
309 <td><strong>Yes</strong></td>
310 <td><strong>Yes</strong></td>
311 </tr>
312 <tr>
313 <td>{@link android.hardware.Sensor#TYPE_ORIENTATION}</td>
314 <td><strong>Yes</strong><sup>2</sup></td>
315 <td><strong>Yes</strong><sup>2</sup></td>
316 <td><strong>Yes</strong><sup>2</sup></td>
317 <td><strong>Yes</strong></td>
318 </tr>
319 <tr>
320 <td>{@link android.hardware.Sensor#TYPE_PRESSURE}</td>
321 <td><strong>Yes</strong></td>
322 <td><strong>Yes</strong></td>
323 <td>n/a<sup>1</sup></td>
324 <td>n/a<sup>1</sup></td>
325 </tr>
326 <tr>
327 <td>{@link android.hardware.Sensor#TYPE_PROXIMITY}</td>
328 <td><strong>Yes</strong></td>
329 <td><strong>Yes</strong></td>
330 <td><strong>Yes</strong></td>
331 <td><strong>Yes</strong></td>
332 </tr>
333 <tr>
334 <td>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}</td>
335 <td><strong>Yes</strong></td>
336 <td>n/a</td>
337 <td>n/a</td>
338 <td>n/a</td>
339 </tr>
340 <tr>
341 <td>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}</td>
342 <td><strong>Yes</strong></td>
343 <td><strong>Yes</strong></td>
344 <td>n/a</td>
345 <td>n/a</td>
346 </tr>
347 <tr>
348 <td>{@link android.hardware.Sensor#TYPE_TEMPERATURE}</td>
349 <td><strong>Yes</strong><sup>2</sup></td>
350 <td><strong>Yes</strong></td>
351 <td><strong>Yes</strong></td>
352 <td><strong>Yes</strong></td>
353 </tr>
354</table>
355
356<p class="note"><strong><sup>1</sup></strong> This sensor type was added in Android 1.5 (API Level
3573),
358but it was not available for use until Android 2.3 (API Level 9).</p>
359
360<p class="note"><strong><sup>2</sup></strong> This sensor is available, but it has been
361deprecated.</p>
362
363<h2 id="sensors-identify">Identifying Sensors and Sensor Capabilities</h2>
364
365<p>The Android sensor framework provides several methods that make it easy for you to determine at
366runtime which sensors are on a device. The API also provides methods that let you determine the
367capabilities of each sensor, such as its maximum range, its resolution, and its power
368requirements.</p>
369
370<p>To identify the sensors that are on a device you first need to get a reference to the sensor
371service. To do this, you create an instance of the {@link android.hardware.SensorManager} class by
372calling the {@link android.content.Context#getSystemService getSystemService()} method and passing
373in the {@link android.content.Context#SENSOR_SERVICE SENSOR_SERVICE} argument. For example:</p>
374
375<pre>
376private SensorManager mSensorManager;
377...
378mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
379</pre>
380
381<p>Next, you can get a listing of every sensor on a device by calling the
382{@link android.hardware.SensorManager#getSensorList getSensorList()} method and using the {@link
383android.hardware.Sensor#TYPE_ALL} constant. For example:</p>
384<pre>
385List&lt;Sensor&gt; deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
386</pre>
387
388<p>If you want to list all of the sensors of a given type, you could use another constant instead of
389{@link android.hardware.Sensor#TYPE_ALL} such as {@link android.hardware.Sensor#TYPE_GYROSCOPE},
390{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}, or
391{@link android.hardware.Sensor#TYPE_GRAVITY}.
392</p>
393
394<p>You can also determine whether a specific type of sensor exists on a device by using the {@link
395android.hardware.SensorManager#getDefaultSensor getDefaultSensor()} method and passing in the type
396constant for a specific sensor. If a device has more than one sensor of a given type, one of the
397sensors must be designated as the default sensor. If a default sensor does not exist for a given
398type of sensor, the method call returns null, which means the device does not have that type of
399sensor. For example, the following code checks whether there's a magnetometer on a device:</p>
400<pre>
401private SensorManager mSensorManager;
402...
403mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
404if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){
405 // Success! There's a magnetometer.
406 }
407else {
408 // Failure! No magnetometer.
409 }
410</pre>
411
412<p class="note"><strong>Note:</strong> Android does not require device manufacturers to build any
413particular types of sensors into their Android-powered devices, so devices can have a wide range of
414sensor configurations.</p>
415
416<p>In addition to listing the sensors that are on a device, you can use the public methods of the
417{@link android.hardware.Sensor} class to determine the capabilities and attributes of individual
418sensors. This is useful if you want your application to behave differently based on which sensors or
419sensor capabilities are available on a device. For example, you can use the {@link
420android.hardware.Sensor#getResolution} and {@link android.hardware.Sensor#getMaximumRange}
421methods to obtain a sensor's resolution and maximum range of measurement. You can also use the
422{@link android.hardware.Sensor#getPower} method to obtain a sensor's power requirements.</p>
423
424<p>Two of the public methods are particularly useful if you want to optimize your application for
425different manufacturer's sensors or different versions of a sensor. For example, if your application
426needs to monitor user gestures such as tilt and shake, you could create one set of data filtering
427rules and optimizations for newer devices that have a specific vendor's gravity sensor, and another
428set of data filtering rules and optimizations for devices that do not have a gravity sensor and have
429only an accelerometer. The following code sample shows you how you can use the {@link
430android.hardware.Sensor#getVendor} and {@link android.hardware.Sensor#getVersion} methods to do
431this. In this sample, we're looking for a gravity sensor that lists Google Inc. as the vendor and
432has a version number of 3. If that particular sensor is not present on the device, we try to use the
433accelerometer.</p>
434
435<pre>
436private SensorManager mSensorManager;
437private Sensor mSensor;
438
439...
440
441mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
442
443if (mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){
444 List&lt;Sensor&gt; gravSensors = mSensorManager.getSensorList(Sensor.TYPE_GRAVITY);
445 for(int i=0; i&lt;gravSensors.size(); i++) {
446 if ((gravSensors.get(i).getVendor().contains("Google Inc.")) &&
447 (gravSensors.get(i).getVersion() == 3)){
448 // Use the version 3 gravity sensor.
449 mSensor = gravSensors.get(i);
450 }
451 }
452}
453else{
454 // Use the accelerometer.
455 if (mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
456 mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
457 }
458 else{
459 // Sorry, there are no accelerometers on your device.
460 // You can't play this game.
461 }
462}
463</pre>
464
465<p>Another useful method is the {@link android.hardware.Sensor#getMinDelay getMinDelay()} method,
466which returns the minimum time interval (in microseconds) a sensor can use to sense data. Any sensor
467that returns a non-zero value for the {@link android.hardware.Sensor#getMinDelay getMinDelay()}
468method is a streaming
469sensor. Streaming sensors sense data at regular intervals and were introduced in Android 2.3 (API
470Level 9). If a sensor returns zero when you call the {@link android.hardware.Sensor#getMinDelay
471getMinDelay()} method, it means the
472sensor is not a streaming sensor because it reports data only when there is a change in the
473parameters it is sensing.</p>
474
475<p>The {@link android.hardware.Sensor#getMinDelay getMinDelay()} method is useful because it lets
476you determine the maximum rate
477at which a sensor can acquire data. If certain features in your application require high data
478acquisition rates or a streaming sensor, you can use this method to determine whether a sensor
479meets those requirements and then enable or disable the relevant features in your application
480accordingly.</p>
481
482<p class="caution"><strong>Caution:</strong> A sensor's maximum data acquisition rate is not
483necessarily the rate at which the sensor framework delivers sensor data to your application. The
484sensor framework reports data through sensor events, and several factors influence the rate at which
485your application receives sensor events. For more information, see <a
486href="#sensors-monitor">Monitoring Sensor Events</a>.</p>
487
488<h2 id="sensors-monitor">Monitoring Sensor Events</h2>
489
490<p>To monitor raw sensor data you need to implement two callback methods that are exposed through
491the {@link android.hardware.SensorEventListener} interface: {@link
492android.hardware.SensorEventListener#onAccuracyChanged onAccuracyChanged()} and {@link
493android.hardware.SensorEventListener#onSensorChanged onSensorChanged()}. The Android system calls
494these methods whenever the following occurs:</p>
495
496<ul>
497 <li><strong>A sensor's accuracy changes.</strong>
498 <p>In this case the system invokes the {@link
499android.hardware.SensorEventListener#onAccuracyChanged onAccuracyChanged()} method, providing
500 you with a reference to the {@link android.hardware.Sensor Sensor} object that changed and the
501 new accuracy of the sensor. Accuracy is represented by one of four status constants:
502 {@link android.hardware.SensorManager#SENSOR_STATUS_ACCURACY_LOW},
503 {@link android.hardware.SensorManager#SENSOR_STATUS_ACCURACY_MEDIUM},
504 {@link android.hardware.SensorManager#SENSOR_STATUS_ACCURACY_HIGH},
505 or {@link android.hardware.SensorManager#SENSOR_STATUS_UNRELIABLE}.</p>
506 </li>
507 <li><strong>A sensor reports a new value.</strong>
508 <p>In this case the system invokes the {@link
509android.hardware.SensorEventListener#onSensorChanged onSensorChanged()} method, providing you with
510a {@link android.hardware.SensorEvent SensorEvent} object. A {@link android.hardware.SensorEvent
511SensorEvent} object
512 contains information about the new sensor data, including: the accuracy of the data, the
513 sensor that generated the data, the timestamp at which the data was generated, and the new
514 data that the sensor recorded.</p>
515 </li>
516</ul>
517
518<p>The following code shows how to use the {@link
519android.hardware.SensorEventListener#onSensorChanged onSensorChanged()} method to monitor data from
520the light sensor. This example displays the raw sensor data in a {@link android.widget.TextView}
521that is
522defined in the main.xml file as <code>sensor_data</code>.</p>
523
524<pre>
525public class SensorActivity extends Activity implements SensorEventListener {
526 private SensorManager mSensorManager;
527 private Sensor mLight;
528
529 &#64;Override
530 public final void onCreate(Bundle savedInstanceState) {
531 super.onCreate(savedInstanceState);
532 setContentView(R.layout.main);
533
534 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
535 mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
536 }
537
538 &#64;Override
539 public final void onAccuracyChanged(Sensor sensor, int accuracy) {
540 // Do something here if sensor accuracy changes.
541 }
542
543 &#64;Override
544 public final void onSensorChanged(SensorEvent event) {
545 // The light sensor returns a single value.
546 // Many sensors return 3 values, one for each axis.
547 float lux = event.values[0];
548 // Do something with this sensor value.
549 }
550
551 &#64;Override
552 protected void onResume() {
553 super.onResume();
554 mSensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
555 }
556
557 &#64;Override
558 protected void onPause() {
559 super.onPause();
560 mSensorManager.unregisterListener(this);
561 }
562}
563</pre>
564
565<p>In this example, the default data delay ({@link
566android.hardware.SensorManager#SENSOR_DELAY_NORMAL}) is specified when the {@link
567android.hardware.SensorManager#registerListener registerListener()} method is invoked. The data
568delay (or sampling rate) controls the interval at which sensor events are sent to your application
569via the {@link
570android.hardware.SensorEventListener#onSensorChanged onSensorChanged()} callback method. The default
571data delay is suitable for monitoring
572typical screen orientation changes and uses a delay of 200,000 microseconds. You can specify other
573data delays, such as {@link android.hardware.SensorManager#SENSOR_DELAY_GAME} (20,000 microsecond
574delay), {@link android.hardware.SensorManager#SENSOR_DELAY_UI} (60,000 microsecond delay), or {@link
575android.hardware.SensorManager#SENSOR_DELAY_FASTEST} (0 microsecond delay). As of Android 3.0 (API
576Level 11) you can also specify the delay as an absolute value (in microseconds).</p>
577
578<p>The delay that you specify is only a suggested delay. The Android system and other applications
579can alter this delay. As a best practice, you should specify the largest delay that you can because
580the system typically uses a smaller delay than the one you specify (that is, you should choose the
581slowest sampling rate that still meets the needs of your application). Using a larger delay imposes
582a lower load on the processor and therefore uses less power.</p>
583
584<p>There is no public method for determining the rate at which the sensor framework is sending
585sensor events to your application; however, you can use the timestamps that are associated with each
586sensor event to calculate the sampling rate over several events. You should not have to change the
587sampling rate (delay) once you set it. If for some reason you do need to change the delay, you will
588have to unregister and reregister the sensor listener.</p>
589
590<p>It's also important to note that this example uses the {@link android.app.Activity#onResume} and
591{@link android.app.Activity#onPause} callback methods to register and unregister the sensor event
592listener. As a best practice you should always disable sensors you don't need, especially when your
593activity is paused. Failing to do so can drain the battery in just a few hours because some sensors
594have substantial power requirements and can use up battery power quickly. The system
595will not disable sensors automatically when the screen turns off.</p>
596
597<h2 id="sensors-configs">Handling Different Sensor Configurations</h2>
598
599<p>Android does not specify a standard sensor configuration for devices,
600which means device manufacturers can incorporate any sensor configuration that they want into their
601Android-powered devices. As a result, devices can include a variety
602of sensors in a wide range of configurations. For example, the Motorola Xoom has a pressure sensor,
603but the Samsung Nexus S does not. Likewise, the Xoom and Nexus S have gyroscopes, but the HTC Nexus
604One does not. If your application relies on a specific type of sensor, you have to ensure that the
605sensor is present on a device so your app can run successfully. You have two options for ensuring
606that a given sensor is present on a device:</p>
607<ul>
608 <li>Detect sensors at runtime and enable or disable application features as appropriate.</li>
609 <li>Use Android Market filters to target devices with specific sensor configurations.</li>
610</ul>
611
612<p>Each option is discussed in the following sections.</p>
613
614<h4><strong>Detecting sensors at runtime</strong></h4>
615
616<p>If your application uses a specific type of sensor, but doesn't rely on it, you can use the
617sensor framework to detect the sensor at runtime and then disable or enable application features
618as appropriate. For example, a navigation application might use the temperature sensor,
619pressure sensor, GPS sensor, and geomagnetic field sensor to display the temperature, barometric
620pressure, location, and compass bearing. If a device doesn't have a pressure sensor, you can use the
621sensor framework to detect the absence of the pressure sensor at runtime and then disable the
622portion of your application's UI that displays pressure. For example, the following code checks
623whether there's a pressure sensor on a device:</p>
624<pre>
625 private SensorManager mSensorManager;
626 ...
627 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
628 if (mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){
629 // Success! There's a pressure sensor.
630 }
631 else {
632 // Failure! No pressure sensor.
633 }
634</pre>
635
636<h4>Using Android Market filters to target specific sensor configurations</h4>
637
638<p>If you are publishing your application on Android Market you can use the
639 <a href="{@docRoot}guide//topics/manifest/uses-feature-element.html"><code>&lt;uses-feature&gt;
640 </code></a> element in your manifest file to filter your application from devices that do not
641have the appropriate sensor configuration for your application. The
642<code>&lt;uses-feature&gt;</code> element has several hardware descriptors that let you filter
643applications based on the presence of specific sensors. The sensors you can list include:
644accelerometer, barometer, compass (geomagnetic field), gyroscope, light, and proximity. The
645following is an example manifest entry that filters apps that do not have an accelerometer:</p>
646
647<pre>
648&lt;uses-feature android:name="android.hardware.sensor.accelerometer"
649 android:required="true" /&gt;
650</pre>
651
652<p>If you add this element and descriptor to your application's manifest, users will see your
653application on Android Market only if their device has an accelerometer.</p>
654
655<p>You should set the descriptor to <code>android:required="true"</code> only if your application
656relies entirely on a specific sensor. If your application uses a sensor for some functionality, but
657still runs without the sensor, you should list the sensor in the <code>&lt;uses-feature&gt;</code>
658element, but set the descriptor to <code>android:required="false"</code>. This helps ensure that
659devices can install your app even if they do not have that particular sensor. This is also a
660project management best practice that helps you keep track of the features your application uses.
661Keep in mind, if your application uses a particular sensor, but still runs without the sensor,
662then you should detect the sensor at runtime and disable or enable application features as
663appropriate.</p>
664
665<h2 id="sensors-coords">Sensor Coordinate System</h2>
666
667<p>In general, the sensor framework uses a standard 3-axis coordinate system to express data values.
668For most sensors, the coordinate system is defined relative to the device's screen when the device
669is held in its default orientation (see figure 1). When a device is held in its default orientation,
670the X axis is horizontal and points to the right, the Y axis is vertical and points up, and the Z
671axis points toward the outside of the screen face. In this system, coordinates behind the screen
672have negative Z values. This coordinate system is used by the following sensors:</p>
673
674<div class="figure" style="width:269px">
675 <img src="{@docRoot}images/axis_device.png" alt="" height="225" />
676 <p class="img-caption">
677 <strong>Figure 1.</strong> Coordinate system (relative to a device) that's used by the Sensor
678 API.
679 </p>
680</div>
681
682<ul>
683 <li><a
684href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-accel">Acceleration
685sensor</a></li>
686<li><a
687href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-gravity">Gravity
688sensor</a></li>
689<li><a
690href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-gyro">Gyroscope</a></li>
691<li><a
692href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-linear">Linear acceleration
693sensor</a></li>
694<li><a
695href="{@docRoot}guide/topics/sensors/sensors_position.html#sensors-pos-mag">Geomagnetic field
696sensor</a></li>
697</ul>
698
699<p>The most important point to understand about this coordinate system is that the axes are not
700swapped when the device's screen orientation changes&mdash;that is, the sensor's coordinate system
701never changes as the device moves. This behavior is the same as the behavior of the OpenGL
702coordinate system.</p>
703
704<p>Another point to understand is that your application must not assume that a device's natural
705(default) orientation is portrait. The natural orientation for many tablet devices is landscape. And
706the sensor coordinate system is always based on the natural orientation of a device.</p>
707
708<p>Finally, if your application matches sensor data to the on-screen display, you need to use the
709{@link android.view.Display#getRotation} method to determine screen rotation, and then use the
710{@link android.hardware.SensorManager#remapCoordinateSystem remapCoordinateSystem()} method to map
711sensor coordinates to screen coordinates. You need to do this even if your manifest specifies
712portrait-only display.</p>
713
714<p>For more information about the sensor coordinate system, including information about how to
715handle screen rotations, see <a
716href="http://android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.html">One
717Screen Turn Deserves Another</a>.</p>
718
719<p class="note"><strong>Note:</strong> Some sensors and methods use a coordinate system that is
720relative to the world's frame of reference (as opposed to the device's frame of reference). These
721sensors and methods return data that represent device motion or device position relative to the
722earth. For more information, see the {@link android.hardware.SensorManager#getOrientation
723getOrientation()} method, the {@link android.hardware.SensorManager#getRotationMatrix
724getRotationMatrix()} method, <a
725href="{@docRoot}guide/topics/sensors/sensors_position.html#sensors-pos-orient">Orientation
726Sensor</a>, and <a
727href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-rotate">Rotation Vector
728Sensor</a>.</p>
729
730<h2 id="sensors-practices">Best Practices for Accessing and Using Sensors</h2>
731
732<p>As you design your sensor implementation, be sure to follow the guidelines that are discussed in
733this section. These guidelines are recommended best practices for anyone who is using the sensor
734framework to access sensors and acquire sensor data.</p>
735
736<h4>Unregister sensor listeners</h4>
737
738<p>Be sure to unregister a sensor's listener when you are done using the sensor or when the sensor
739activity pauses. If a sensor listener is registered and its activity is paused, the sensor will
740continue to acquire data and use battery resources unless you unregister the sensor. The following
741code shows how to use the {@link android.app.Activity#onPause} method to unregister a listener:</p>
742
743<pre>
744private SensorManager mSensorManager;
745 ...
746&#64;Override
747protected void onPause() {
748 super.onPause();
749 mSensorManager.unregisterListener(this);
750}
751</pre>
752
753<p>For more information, see {@link android.hardware.SensorManager#unregisterListener}.</p>
754
755<h4>Don't test your code on the emulator</h4>
756
757<p>You currently can't test sensor code on the emulator because the emulator cannot emulate sensors.
758You must test your sensor code on a physical device. There are, however, sensor simulators that you
759can use to simulate sensor output.</p>
760
761<h4>Don't block the onSensorChanged() method</h4>
762
763<p>Sensor data can change at a high rate, which means the system may call the {@link
764android.hardware.SensorEventListener#onSensorChanged} method quite often. As a best practice, you
765should do as little as possible within the {@link
766android.hardware.SensorEventListener#onSensorChanged} method so you don't block it. If your
767application requires you to do any data filtering or reduction of sensor data, you should perform
768that work outside of the {@link android.hardware.SensorEventListener#onSensorChanged} method.</p>
769
770<h4>Avoid using deprecated methods or sensor types</h4>
771
772<p>Several methods and constants have been deprecated.
773In particular, the {@link android.hardware.Sensor#TYPE_ORIENTATION}
774sensor type has been deprecated. To get orientation data you should use the {@link
775android.hardware.SensorManager#getOrientation getOrientation()} method instead. Likewise, the
776{@link android.hardware.Sensor#TYPE_TEMPERATURE} sensor type has been deprecated. You should use
777the {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} sensor type instead on devices
778that are running Android 4.0.</p>
779
780<h4>Verify sensors before you use them</h4>
781
782<p>Always verify that a sensor exists on a device before you attempt to acquire data from it. Don't
783assume that a sensor exists simply because it's a frequently-used sensor. Device manufacturers are
784not required to provide any particular sensors in their devices.</p>
785
786<h4>Choose sensor delays carefully</h4>
787
788<p>When you register a sensor with the {@link android.hardware.SensorManager#registerListener
789registerListener()} method, be sure you choose a delivery rate that is suitable for your
790application or use-case. Sensors can provide data at very high rates. Allowing the system to send
791extra data that you don't need wastes system resources and uses battery power.</p>