sensors_position.jd revision a7925384c32d103418198ca8e26ab3cc36b07097
1page.title=Position Sensors 2page.tags="sensorevent","orientation","proximity" 3@jd:body 4 5<div id="qv-wrapper"> 6 <div id="qv"> 7 <h2>In this document</h2> 8 <ol> 9 <li><a href="#sensors-pos-gamerot">Using the Game Rotation Vector Sensor</a></li> 10 <li><a href="#sensors-pos-geomrot">Using the Geomagnetic Rotation Vector Sensor</a></li> 11 <li><a href="#sensors-pos-orient">Using the Orientation Sensor</a></li> 12 <li><a href="#sensors-pos-mag">Using the Geomagnetic Field Sensor</a></li> 13 <li><a href="#sensors-pos-prox">Using the Proximity Sensor</a></li> 14 </ol> 15 <h2>Key classes and interfaces</h2> 16 <ol> 17 <li>{@link android.hardware.Sensor}</li> 18 <li>{@link android.hardware.SensorEvent}</li> 19 <li>{@link android.hardware.SensorManager}</li> 20 <li>{@link android.hardware.SensorEventListener}</li> 21 </ol> 22 <h2>Related samples</h2> 23 <ol> 24 <li><a href="{@docRoot}resources/samples/AccelerometerPlay/index.html">Accelerometer 25 Play</a></li> 26 <li><a 27href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/RotationVectorDemo.html"> 28API Demos (OS - RotationVectorDemo)</a></li> 29 <li><a 30href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/Sensors.html">API Demos 31(OS - Sensors)</a></li> 32 </ol> 33 <h2>See also</h2> 34 <ol> 35 <li><a href="{@docRoot}guide/topics/sensors/index.html">Sensors</a></li> 36 <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li> 37 <li><a href="{@docRoot}guide/topics/sensors/sensors_motion.html">Motion 38 Sensors</a></li> 39 <li><a href="{@docRoot}guide/topics/sensors/sensors_environment.html">Environment 40 Sensors</a></li> 41 </ol> 42 </div> 43</div> 44 45<p>The Android platform provides two sensors that let you determine the position of a device: the 46geomagnetic field sensor and the orientation sensor. The Android platform also 47provides a sensor that lets you determine how close the face of a device is to an object (known as 48the proximity sensor). The geomagnetic field sensor and the proximity sensor are hardware-based. 49Most 50handset and tablet manufacturers include a geomagnetic field sensor. Likewise, handset manufacturers 51usually include a proximity sensor to determine when a handset is being held close to a user's face 52(for example, during a phone call). The orientation sensor is software-based and derives its data 53from the accelerometer and the geomagnetic field sensor.</p> 54 55<p class="note"><strong>Note:</strong> The orientation sensor was deprecated in Android 2.2 (API 56Level 8).</p> 57 58<p>Position sensors are useful for determining a device's physical position in the 59world's frame of reference. For example, you can use the geomagnetic field sensor in 60combination with the accelerometer to determine a device's position relative to 61the magnetic North Pole. You can also use the orientation sensor (or similar sensor-based 62orientation methods) to determine a device's position in your application's frame of reference. 63Position sensors are not typically used to monitor device movement or motion, such as shake, tilt, 64or thrust (for more information, see <a 65href="{@docRoot}guide/topics/sensors/sensors_motion.html">Motion Sensors</a>).</p> 66 67<p>The geomagnetic field sensor and orientation sensor return multi-dimensional arrays of sensor 68values 69for each {@link android.hardware.SensorEvent}. For example, the orientation sensor provides 70geomagnetic 71field strength values for each of the three coordinate axes during a single sensor event. Likewise, 72the orientation sensor provides azimuth (yaw), pitch, and roll values during a single sensor event. 73For more information about the coordinate systems that are used by sensors, see <a 74href="{@docRoot}guide/topics/sensors/sensors_overview.html#sensors-coords">Sensor Coordinate 75Systems</a>. The proximity sensor provides a single value for each sensor event. Table 1 summarizes 76the position sensors that are supported on the Android platform.</p> 77 78<p class="table-caption" id="table1"> 79 <strong>Table 1.</strong> Position sensors that are supported on the Android platform.</p> 80<table> 81 <tr> 82 <th scope="col" style="white-space:nowrap">Sensor</th> 83 <th scope="col" style="white-space:nowrap">Sensor event data</th> 84 <th scope="col" style="white-space:nowrap">Description</th> 85 <th scope="col" style="white-space:nowrap">Units of measure</th> 86 </tr> 87 <tr> 88 <td rowspan="3">{@link android.hardware.Sensor#TYPE_GAME_ROTATION_VECTOR}</td> 89 <td><code>SensorEvent.values[0]</code></td> 90 <td>Rotation vector component along the x axis (x * sin(θ/2)).</td> 91 <td rowspan="3">Unitless</td> 92 </tr> 93 <tr> 94 <td><code>SensorEvent.values[1]</code></td> 95 <td>Rotation vector component along the y axis (y * sin(θ/2)).</td> 96 </tr> 97 <tr> 98 <td><code>SensorEvent.values[2]</code></td> 99 <td>Rotation vector component along the z axis (z * sin(θ/2)).</td> 100 </tr> 101 <tr> 102 <td rowspan="3">{@link android.hardware.Sensor#TYPE_GEOMAGNETIC_ROTATION_VECTOR}</td> 103 <td><code>SensorEvent.values[0]</code></td> 104 <td>Rotation vector component along the x axis (x * sin(θ/2)).</td> 105 <td rowspan="3">Unitless</td> 106 </tr> 107 <tr> 108 <td><code>SensorEvent.values[1]</code></td> 109 <td>Rotation vector component along the y axis (y * sin(θ/2)).</td> 110 </tr> 111 <tr> 112 <td><code>SensorEvent.values[2]</code></td> 113 <td>Rotation vector component along the z axis (z * sin(θ/2)).</td> 114 </tr> 115 <tr> 116 <td rowspan="3">{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}</td> 117 <td><code>SensorEvent.values[0]</code></td> 118 <td>Geomagnetic field strength along the x axis.</td> 119 <td rowspan="3">μT</td> 120 </tr> 121 <tr> 122 <td><code>SensorEvent.values[1]</code></td> 123 <td>Geomagnetic field strength along the y axis.</td> 124 </tr> 125 <tr> 126 <td><code>SensorEvent.values[2]</code></td> 127 <td>Geomagnetic field strength along the z axis.</td> 128 </tr> 129 <tr> 130 <td rowspan="6">{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD_UNCALIBRATED}</td> 131 <td><code>SensorEvent.values[0]</code></td> 132 <td>Geomagnetic field strength (without hard iron calibration) along the x axis.</td> 133 <td rowspan="6">μT</td> 134 </tr> 135 <tr> 136 <td><code>SensorEvent.values[1]</code></td> 137 <td>Geomagnetic field strength (without hard iron calibration) along the y axis.</td> 138 </tr> 139 <tr> 140 <td><code>SensorEvent.values[2]</code></td> 141 <td>Geomagnetic field strength (without hard iron calibration) along the z axis.</td> 142 </tr> 143 <tr> 144 <td><code>SensorEvent.values[3]</code></td> 145 <td>Iron bias estimation along the x axis.</td> 146 </tr> 147 <tr> 148 <td><code>SensorEvent.values[4]</code></td> 149 <td>Iron bias estimation along the y axis.</td> 150 </tr> 151 <tr> 152 <td><code>SensorEvent.values[5]</code></td> 153 <td>Iron bias estimation along the z axis.</td> 154 </tr> 155 <tr> 156 <td rowspan="3">{@link android.hardware.Sensor#TYPE_ORIENTATION}<sup>1</sup></td> 157 <td><code>SensorEvent.values[0]</code></td> 158 <td>Azimuth (angle around the z-axis).</td> 159 <td rowspan="3">Degrees</td> 160 </tr> 161 <tr> 162 <td><code>SensorEvent.values[1]</code></td> 163 <td>Pitch (angle around the x-axis).</td> 164 </tr> 165 <tr> 166 <td><code>SensorEvent.values[2]</code></td> 167 <td>Roll (angle around the y-axis).</td> 168 </tr> 169 <tr> 170 <td>{@link android.hardware.Sensor#TYPE_PROXIMITY}</td> 171 <td><code>SensorEvent.values[0]</code></td> 172 <td>Distance from object.<sup>2</sup></td> 173 <td>cm</td> 174 </tr> 175</table> 176 177<p class="note"><sup><strong>1</strong></sup> This sensor was deprecated in Android 2.2 (API Level 178 8). The sensor framework provides alternate methods for acquiring device orientation, which are 179discussed in <a href="#sensors-pos-orient">Using the Orientation Sensor</a>.</p> 180 181<p class="note"><sup><strong>2</strong></sup> Some proximity sensors provide only binary values 182representing near and far.</p> 183 184 185<h2 id="sensors-pos-gamerot">Using the Game Rotation Vector Sensor</h2> 186 187<p>The game rotation vector sensor is identical to the 188<a href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-rotate">Rotation 189Vector Sensor</a>, except it does not use the geomagnetic field. Therefore the Y axis does not 190point north but instead to some other reference. That reference is allowed to drift by the 191same order of magnitude as the gyroscope drifts around the Z axis.</p> 192 193<p>Because the game rotation vector sensor does not use the magnetic field, relative rotations 194are more accurate, and not impacted by magnetic field changes. Use this sensor in a game if 195you do not care about where north is, and the normal rotation vector does not fit your needs 196because of its reliance on the magnetic field.</p> 197 198<p>The following code shows you how to get an instance of the default game rotation vector 199sensor:</p> 200 201<pre> 202private SensorManager mSensorManager; 203private Sensor mSensor; 204... 205mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 206mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR); 207</pre> 208 209 210<h2 id="sensors-pos-geomrot">Using the Geomagnetic Rotation Vector Sensor</h2> 211 212<p>The geomagnetic rotation vector sensor is similar to the 213<a href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-rotate">Rotation 214Vector Sensor</a>, but it uses a magnetometer instead of a gyroscope. The accuracy of this 215sensor is lower than the normal rotation vector sensor, but the power consumption is reduced. 216Only use this sensor if you want to collect some rotation information in the background without 217draining too much battery. This sensor is most useful when used in conjunction with batching.</p> 218 219<p>The following code shows you how to get an instance of the default geomagnetic rotation 220vector sensor:</p> 221 222<pre> 223private SensorManager mSensorManager; 224private Sensor mSensor; 225... 226mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 227mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR); 228</pre> 229 230 231<h2 id="sensors-pos-orient">Using the Orientation Sensor</h2> 232 233<p>The orientation sensor lets you monitor the position of a device relative to the earth's frame of 234reference (specifically, magnetic north). The following code shows you how to get an instance of the 235default orientation sensor:</p> 236 237<pre> 238private SensorManager mSensorManager; 239private Sensor mSensor; 240... 241mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 242mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); 243</pre> 244 245<p>The orientation sensor derives its data by using a device's geomagnetic field sensor in 246combination with a device's accelerometer. Using these two hardware sensors, an orientation sensor 247provides data for the following three dimensions:</p> 248 249<ul> 250 <li>Azimuth (degrees of rotation around the z axis). This is the angle between magnetic north 251and the device's y axis. For example, if the device's y axis is aligned with magnetic north 252this value is 0, and if the device's y axis is pointing south this value is 180. Likewise, when 253the y axis is pointing east this value is 90 and when it is pointing west this value is 270.</li> 254 <li>Pitch (degrees of rotation around the x axis). This value is positive when the positive z axis 255rotates toward the positive y axis, and it is negative when the positive z axis 256rotates toward the negative y axis. The range of values is 180 degrees to -180 257degrees.</li> 258 <li>Roll (degrees of rotation around the y axis). This value is positive when the positive z axis 259rotates toward the positive x axis, and it is negative when the positive z axis 260rotates toward the negative x axis. The range of values is 90 degrees to -90 261degrees.</li> 262</ul> 263 264<p>This definition is different from yaw, pitch, and roll used in aviation, where the X axis is 265along the long side of the plane (tail to nose). Also, for historical reasons the roll angle is 266positive in the clockwise direction (mathematically speaking, it should be positive in the 267counter-clockwise direction).</p> 268 269<p>The orientation sensor derives its data by processing the raw sensor data from the accelerometer 270and the geomagnetic field sensor. Because of the heavy processing that is involved, the accuracy and 271precision of the orientation sensor is diminished (specifically, this sensor is only reliable when 272the roll component is 0). As a result, the orientation sensor was deprecated in Android 2.2 (API 273level 8). Instead of using raw data from the orientation sensor, we recommend that you use the 274{@link android.hardware.SensorManager#getRotationMatrix getRotationMatrix()} method in conjunction 275with the {@link android.hardware#getOrientation getOrientation()} method to compute orientation 276values. You can also use the {@link android.hardware.SensorManager#remapCoordinateSystem 277remapCoordinateSystem()} method to translate the orientation values to your application's frame of 278reference.</p> 279 280<p>The following code sample shows how to acquire orientation data directly from the orientation 281sensor. We recommend that you do this only if a device has negligible roll.</p> 282 283<pre> 284public class SensorActivity extends Activity implements SensorEventListener { 285 286 private SensorManager mSensorManager; 287 private Sensor mOrientation; 288 289 @Override 290 public void onCreate(Bundle savedInstanceState) { 291 super.onCreate(savedInstanceState); 292 setContentView(R.layout.main); 293 294 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 295 mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); 296 } 297 298 @Override 299 public void onAccuracyChanged(Sensor sensor, int accuracy) { 300 // Do something here if sensor accuracy changes. 301 // You must implement this callback in your code. 302 } 303 304 @Override 305 protected void onResume() { 306 super.onResume(); 307 mSensorManager.registerListener(this, mOrientation, SensorManager.SENSOR_DELAY_NORMAL); 308 } 309 310 @Override 311 protected void onPause() { 312 super.onPause(); 313 mSensorManager.unregisterListener(this); 314 } 315 316 @Override 317 public void onSensorChanged(SensorEvent event) { 318 float azimuth_angle = event.values[0]; 319 float pitch_angle = event.values[1]; 320 float roll_angle = event.values[2]; 321 // Do something with these orientation angles. 322 } 323} 324</pre> 325 326<p>You do not usually need to perform any data processing or filtering of the raw data that you 327obtain from an orientation sensor, other than translating the sensor's coordinate system to your 328application's frame of reference. The <a 329href="{@docRoot}resources/samples/AccelerometerPlay/index.html">Accelerometer Play</a> sample shows 330you how to translate acceleration sensor data into another frame of reference; the technique is 331similar to the one you might use with the orientation sensor.</p> 332 333<h2 id="sensors-pos-mag">Using the Geomagnetic Field Sensor</h2> 334 335<p>The geomagnetic field sensor lets you monitor changes in the earth's magnetic field. The 336following code shows you how to get an instance of the default geomagnetic field sensor:</p> 337 338<pre> 339private SensorManager mSensorManager; 340private Sensor mSensor; 341... 342mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 343mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); 344</pre> 345 346<p>This sensor provides raw field strength data (in μT) for each of the three coordinate axes. 347Usually, you do not need to use this sensor directly. Instead, you can use the rotation vector 348sensor to determine raw rotational movement or you can use the accelerometer and geomagnetic field 349sensor in conjunction with the {@link android.hardware.SensorManager#getRotationMatrix 350getRotationMatrix()} method to obtain the rotation matrix and the inclination matrix. You can then 351use these matrices with the {@link android.hardware.SensorManager#getOrientation getOrientation()} 352and {@link android.hardware.SensorManager#getInclination getInclination()} methods to obtain azimuth 353and geomagnetic inclination data.</p> 354 355<h2 id="sensors-pos-magunc">Using the Uncalibrated Magnetometer</h2> 356 357<p>The uncalibrated magnetometer is similar to the <a href="#sensors-pos-mag">geomagnetic field 358sensor</a>, except that no hard iron calibration is applied to the magnetic field. Factory calibration 359and temperature compensation are still applied to the magnetic field. The uncalibrated magnetometer 360is useful to handle bad hard iron estimations. In general, <code>geomagneticsensor_event.values[0]</code> 361will be close to <code>uncalibrated_magnetometer_event.values[0] - 362uncalibrated_magnetometer_event.values[3]</code>. That is,</p> 363 364<p><code>calibrated_x ~= uncalibrated_x - bias_estimate_x</code></p></p> 365 366<p class="note"><strong>Note:</strong> Uncalibrated sensors provide more raw results and may 367include some bias, but their measurements contain fewer jumps from corrections applied through 368calibration. Some applications may prefer these uncalibrated results as smoother and more 369reliable. For instance, if an application is attempting to conduct its own sensor fusion, 370introducing calibrations can actually distort results.</p> 371 372<p>In addition to the magnetic field, the uncalibrated magnetometer also provides the 373estimated hard iron bias in each axis. The following code shows you how to get an instance of the 374default uncalibrated magnetometer:</p> 375 376<pre> 377private SensorManager mSensorManager; 378private Sensor mSensor; 379... 380mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 381mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED); 382</pre> 383 384<h2 id="sensors-pos-prox">Using the Proximity Sensor</h2> 385<p>The proximity sensor lets you determine how far away an object is from a device. The following 386code shows you how to get an instance of the default proximity sensor:</p> 387 388<pre> 389private SensorManager mSensorManager; 390private Sensor mSensor; 391... 392mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 393mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 394</pre> 395 396<p>The proximity sensor is usually used to determine how far away a person's head is from the face 397of a handset device (for example, when a user is making or receiving a phone call). Most 398proximity sensors return the absolute distance, in cm, but some return only near and 399far values. The following code shows you how to use the proximity sensor:</p> 400 401<pre> 402public class SensorActivity extends Activity implements SensorEventListener { 403 private SensorManager mSensorManager; 404 private Sensor mProximity; 405 406 @Override 407 public final void onCreate(Bundle savedInstanceState) { 408 super.onCreate(savedInstanceState); 409 setContentView(R.layout.main); 410 411 // Get an instance of the sensor service, and use that to get an instance of 412 // a particular sensor. 413 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 414 mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 415 } 416 417 @Override 418 public final void onAccuracyChanged(Sensor sensor, int accuracy) { 419 // Do something here if sensor accuracy changes. 420 } 421 422 @Override 423 public final void onSensorChanged(SensorEvent event) { 424 float distance = event.values[0]; 425 // Do something with this sensor data. 426 } 427 428 @Override 429 protected void onResume() { 430 // Register a listener for the sensor. 431 super.onResume(); 432 mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); 433 } 434 435 @Override 436 protected void onPause() { 437 // Be sure to unregister the sensor when the activity pauses. 438 super.onPause(); 439 mSensorManager.unregisterListener(this); 440 } 441} 442</pre> 443 444<p class="note"><strong>Note:</strong> Some proximity sensors return binary values that represent 445"near" or "far." In this case, the sensor usually reports its maximum range value in the far state 446and a lesser value in the near state. Typically, the far value is a value > 5 cm, but this can vary 447from sensor to sensor. You can determine a sensor's maximum range by using the {@link 448android.hardware.Sensor#getMaximumRange} method.</p> 449