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