| page.title=Position Sensors |
| page.tags=sensorevent,orientation,proximity |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#sensors-pos-gamerot">Using the Game Rotation Vector Sensor</a></li> |
| <li><a href="#sensors-pos-geomrot">Using the Geomagnetic Rotation Vector Sensor</a></li> |
| <li><a href="#sensors-pos-orient">Using the Orientation Sensor</a></li> |
| <li><a href="#sensors-pos-mag">Using the Geomagnetic Field Sensor</a></li> |
| <li><a href="#sensors-pos-prox">Using the Proximity Sensor</a></li> |
| </ol> |
| <h2>Key classes and interfaces</h2> |
| <ol> |
| <li>{@link android.hardware.Sensor}</li> |
| <li>{@link android.hardware.SensorEvent}</li> |
| <li>{@link android.hardware.SensorManager}</li> |
| <li>{@link android.hardware.SensorEventListener}</li> |
| </ol> |
| <h2>Related samples</h2> |
| <ol> |
| <li><a href="{@docRoot}resources/samples/AccelerometerPlay/index.html">Accelerometer |
| Play</a></li> |
| <li><a |
| href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/RotationVectorDemo.html"> |
| API Demos (OS - RotationVectorDemo)</a></li> |
| <li><a |
| href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/Sensors.html">API Demos |
| (OS - Sensors)</a></li> |
| </ol> |
| <h2>See also</h2> |
| <ol> |
| <li><a href="{@docRoot}guide/topics/sensors/index.html">Sensors</a></li> |
| <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li> |
| <li><a href="{@docRoot}guide/topics/sensors/sensors_motion.html">Motion |
| Sensors</a></li> |
| <li><a href="{@docRoot}guide/topics/sensors/sensors_environment.html">Environment |
| Sensors</a></li> |
| </ol> |
| </div> |
| </div> |
| |
| <p>The Android platform provides two sensors that let you determine the position of a device: the |
| geomagnetic field sensor and the orientation sensor. The Android platform also |
| provides a sensor that lets you determine how close the face of a device is to an object (known as |
| the proximity sensor). The geomagnetic field sensor and the proximity sensor are hardware-based. |
| Most |
| handset and tablet manufacturers include a geomagnetic field sensor. Likewise, handset manufacturers |
| usually include a proximity sensor to determine when a handset is being held close to a user's face |
| (for example, during a phone call). The orientation sensor is software-based and derives its data |
| from the accelerometer and the geomagnetic field sensor.</p> |
| |
| <p class="note"><strong>Note:</strong> The orientation sensor was deprecated in Android 2.2 (API |
| Level 8).</p> |
| |
| <p>Position sensors are useful for determining a device's physical position in the |
| world's frame of reference. For example, you can use the geomagnetic field sensor in |
| combination with the accelerometer to determine a device's position relative to |
| the magnetic North Pole. You can also use the orientation sensor (or similar sensor-based |
| orientation methods) to determine a device's position in your application's frame of reference. |
| Position sensors are not typically used to monitor device movement or motion, such as shake, tilt, |
| or thrust (for more information, see <a |
| href="{@docRoot}guide/topics/sensors/sensors_motion.html">Motion Sensors</a>).</p> |
| |
| <p>The geomagnetic field sensor and orientation sensor return multi-dimensional arrays of sensor |
| values |
| for each {@link android.hardware.SensorEvent}. For example, the orientation sensor provides |
| geomagnetic |
| field strength values for each of the three coordinate axes during a single sensor event. Likewise, |
| the orientation sensor provides azimuth (yaw), pitch, and roll values during a single sensor event. |
| For more information about the coordinate systems that are used by sensors, see <a |
| href="{@docRoot}guide/topics/sensors/sensors_overview.html#sensors-coords">Sensor Coordinate |
| Systems</a>. The proximity sensor provides a single value for each sensor event. Table 1 summarizes |
| the position sensors that are supported on the Android platform.</p> |
| |
| <p class="table-caption" id="table1"> |
| <strong>Table 1.</strong> Position sensors that are supported on the Android platform.</p> |
| <table> |
| <tr> |
| <th scope="col" style="white-space:nowrap">Sensor</th> |
| <th scope="col" style="white-space:nowrap">Sensor event data</th> |
| <th scope="col" style="white-space:nowrap">Description</th> |
| <th scope="col" style="white-space:nowrap">Units of measure</th> |
| </tr> |
| <tr> |
| <td rowspan="3">{@link android.hardware.Sensor#TYPE_GAME_ROTATION_VECTOR}</td> |
| <td><code>SensorEvent.values[0]</code></td> |
| <td>Rotation vector component along the x axis (x * sin(θ/2)).</td> |
| <td rowspan="3">Unitless</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[1]</code></td> |
| <td>Rotation vector component along the y axis (y * sin(θ/2)).</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[2]</code></td> |
| <td>Rotation vector component along the z axis (z * sin(θ/2)).</td> |
| </tr> |
| <tr> |
| <td rowspan="3">{@link android.hardware.Sensor#TYPE_GEOMAGNETIC_ROTATION_VECTOR}</td> |
| <td><code>SensorEvent.values[0]</code></td> |
| <td>Rotation vector component along the x axis (x * sin(θ/2)).</td> |
| <td rowspan="3">Unitless</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[1]</code></td> |
| <td>Rotation vector component along the y axis (y * sin(θ/2)).</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[2]</code></td> |
| <td>Rotation vector component along the z axis (z * sin(θ/2)).</td> |
| </tr> |
| <tr> |
| <td rowspan="3">{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}</td> |
| <td><code>SensorEvent.values[0]</code></td> |
| <td>Geomagnetic field strength along the x axis.</td> |
| <td rowspan="3">μT</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[1]</code></td> |
| <td>Geomagnetic field strength along the y axis.</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[2]</code></td> |
| <td>Geomagnetic field strength along the z axis.</td> |
| </tr> |
| <tr> |
| <td rowspan="6">{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD_UNCALIBRATED}</td> |
| <td><code>SensorEvent.values[0]</code></td> |
| <td>Geomagnetic field strength (without hard iron calibration) along the x axis.</td> |
| <td rowspan="6">μT</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[1]</code></td> |
| <td>Geomagnetic field strength (without hard iron calibration) along the y axis.</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[2]</code></td> |
| <td>Geomagnetic field strength (without hard iron calibration) along the z axis.</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[3]</code></td> |
| <td>Iron bias estimation along the x axis.</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[4]</code></td> |
| <td>Iron bias estimation along the y axis.</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[5]</code></td> |
| <td>Iron bias estimation along the z axis.</td> |
| </tr> |
| <tr> |
| <td rowspan="3">{@link android.hardware.Sensor#TYPE_ORIENTATION}<sup>1</sup></td> |
| <td><code>SensorEvent.values[0]</code></td> |
| <td>Azimuth (angle around the z-axis).</td> |
| <td rowspan="3">Degrees</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[1]</code></td> |
| <td>Pitch (angle around the x-axis).</td> |
| </tr> |
| <tr> |
| <td><code>SensorEvent.values[2]</code></td> |
| <td>Roll (angle around the y-axis).</td> |
| </tr> |
| <tr> |
| <td>{@link android.hardware.Sensor#TYPE_PROXIMITY}</td> |
| <td><code>SensorEvent.values[0]</code></td> |
| <td>Distance from object.<sup>2</sup></td> |
| <td>cm</td> |
| </tr> |
| </table> |
| |
| <p class="note"><sup><strong>1</strong></sup> This sensor was deprecated in Android 2.2 (API Level |
| 8). The sensor framework provides alternate methods for acquiring device orientation, which are |
| discussed in <a href="#sensors-pos-orient">Using the Orientation Sensor</a>.</p> |
| |
| <p class="note"><sup><strong>2</strong></sup> Some proximity sensors provide only binary values |
| representing near and far.</p> |
| |
| |
| <h2 id="sensors-pos-gamerot">Using the Game Rotation Vector Sensor</h2> |
| |
| <p>The game rotation vector sensor is identical to the |
| <a href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-rotate">Rotation |
| Vector Sensor</a>, except it does not use the geomagnetic field. Therefore the Y axis does not |
| point north but instead to some other reference. That reference is allowed to drift by the |
| same order of magnitude as the gyroscope drifts around the Z axis.</p> |
| |
| <p>Because the game rotation vector sensor does not use the magnetic field, relative rotations |
| are more accurate, and not impacted by magnetic field changes. Use this sensor in a game if |
| you do not care about where north is, and the normal rotation vector does not fit your needs |
| because of its reliance on the magnetic field.</p> |
| |
| <p>The following code shows you how to get an instance of the default game rotation vector |
| sensor:</p> |
| |
| <pre> |
| private SensorManager mSensorManager; |
| private Sensor mSensor; |
| ... |
| mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); |
| mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR); |
| </pre> |
| |
| |
| <h2 id="sensors-pos-geomrot">Using the Geomagnetic Rotation Vector Sensor</h2> |
| |
| <p>The geomagnetic rotation vector sensor is similar to the |
| <a href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-rotate">Rotation |
| Vector Sensor</a>, but it uses a magnetometer instead of a gyroscope. The accuracy of this |
| sensor is lower than the normal rotation vector sensor, but the power consumption is reduced. |
| Only use this sensor if you want to collect some rotation information in the background without |
| draining too much battery. This sensor is most useful when used in conjunction with batching.</p> |
| |
| <p>The following code shows you how to get an instance of the default geomagnetic rotation |
| vector sensor:</p> |
| |
| <pre> |
| private SensorManager mSensorManager; |
| private Sensor mSensor; |
| ... |
| mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); |
| mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR); |
| </pre> |
| |
| |
| <h2 id="sensors-pos-orient">Using the Orientation Sensor</h2> |
| |
| <p>The orientation sensor lets you monitor the position of a device relative to the earth's frame of |
| reference (specifically, magnetic north). The following code shows you how to get an instance of the |
| default orientation sensor:</p> |
| |
| <pre> |
| private SensorManager mSensorManager; |
| private Sensor mSensor; |
| ... |
| mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); |
| mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); |
| </pre> |
| |
| <p>The orientation sensor derives its data by using a device's geomagnetic field sensor in |
| combination with a device's accelerometer. Using these two hardware sensors, an orientation sensor |
| provides data for the following three dimensions:</p> |
| |
| <ul> |
| <li>Azimuth (degrees of rotation around the z axis). This is the angle between magnetic north |
| and the device's y axis. For example, if the device's y axis is aligned with magnetic north |
| this value is 0, and if the device's y axis is pointing south this value is 180. Likewise, when |
| the y axis is pointing east this value is 90 and when it is pointing west this value is 270.</li> |
| <li>Pitch (degrees of rotation around the x axis). This value is positive when the positive z axis |
| rotates toward the positive y axis, and it is negative when the positive z axis |
| rotates toward the negative y axis. The range of values is 180 degrees to -180 |
| degrees.</li> |
| <li>Roll (degrees of rotation around the y axis). This value is positive when the positive z axis |
| rotates toward the positive x axis, and it is negative when the positive z axis |
| rotates toward the negative x axis. The range of values is 90 degrees to -90 |
| degrees.</li> |
| </ul> |
| |
| <p>This definition is different from yaw, pitch, and roll used in aviation, where the X axis is |
| along the long side of the plane (tail to nose). Also, for historical reasons the roll angle is |
| positive in the clockwise direction (mathematically speaking, it should be positive in the |
| counter-clockwise direction).</p> |
| |
| <p>The orientation sensor derives its data by processing the raw sensor data from the accelerometer |
| and the geomagnetic field sensor. Because of the heavy processing that is involved, the accuracy and |
| precision of the orientation sensor is diminished (specifically, this sensor is only reliable when |
| the roll component is 0). As a result, the orientation sensor was deprecated in Android 2.2 (API |
| level 8). Instead of using raw data from the orientation sensor, we recommend that you use the |
| {@link android.hardware.SensorManager#getRotationMatrix getRotationMatrix()} method in conjunction |
| with the {@link android.hardware#getOrientation getOrientation()} method to compute orientation |
| values. You can also use the {@link android.hardware.SensorManager#remapCoordinateSystem |
| remapCoordinateSystem()} method to translate the orientation values to your application's frame of |
| reference.</p> |
| |
| <p>The following code sample shows how to acquire orientation data directly from the orientation |
| sensor. We recommend that you do this only if a device has negligible roll.</p> |
| |
| <pre> |
| public class SensorActivity extends Activity implements SensorEventListener { |
| |
| private SensorManager mSensorManager; |
| private Sensor mOrientation; |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| setContentView(R.layout.main); |
| |
| mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); |
| mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); |
| } |
| |
| @Override |
| public void onAccuracyChanged(Sensor sensor, int accuracy) { |
| // Do something here if sensor accuracy changes. |
| // You must implement this callback in your code. |
| } |
| |
| @Override |
| protected void onResume() { |
| super.onResume(); |
| mSensorManager.registerListener(this, mOrientation, SensorManager.SENSOR_DELAY_NORMAL); |
| } |
| |
| @Override |
| protected void onPause() { |
| super.onPause(); |
| mSensorManager.unregisterListener(this); |
| } |
| |
| @Override |
| public void onSensorChanged(SensorEvent event) { |
| float azimuth_angle = event.values[0]; |
| float pitch_angle = event.values[1]; |
| float roll_angle = event.values[2]; |
| // Do something with these orientation angles. |
| } |
| } |
| </pre> |
| |
| <p>You do not usually need to perform any data processing or filtering of the raw data that you |
| obtain from an orientation sensor, other than translating the sensor's coordinate system to your |
| application's frame of reference. The <a |
| href="{@docRoot}resources/samples/AccelerometerPlay/index.html">Accelerometer Play</a> sample shows |
| you how to translate acceleration sensor data into another frame of reference; the technique is |
| similar to the one you might use with the orientation sensor.</p> |
| |
| <h2 id="sensors-pos-mag">Using the Geomagnetic Field Sensor</h2> |
| |
| <p>The geomagnetic field sensor lets you monitor changes in the earth's magnetic field. The |
| following code shows you how to get an instance of the default geomagnetic field sensor:</p> |
| |
| <pre> |
| private SensorManager mSensorManager; |
| private Sensor mSensor; |
| ... |
| mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); |
| mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); |
| </pre> |
| |
| <p>This sensor provides raw field strength data (in μT) for each of the three coordinate axes. |
| Usually, you do not need to use this sensor directly. Instead, you can use the rotation vector |
| sensor to determine raw rotational movement or you can use the accelerometer and geomagnetic field |
| sensor in conjunction with the {@link android.hardware.SensorManager#getRotationMatrix |
| getRotationMatrix()} method to obtain the rotation matrix and the inclination matrix. You can then |
| use these matrices with the {@link android.hardware.SensorManager#getOrientation getOrientation()} |
| and {@link android.hardware.SensorManager#getInclination getInclination()} methods to obtain azimuth |
| and geomagnetic inclination data.</p> |
| |
| <h2 id="sensors-pos-magunc">Using the Uncalibrated Magnetometer</h2> |
| |
| <p>The uncalibrated magnetometer is similar to the <a href="#sensors-pos-mag">geomagnetic field |
| sensor</a>, except that no hard iron calibration is applied to the magnetic field. Factory calibration |
| and temperature compensation are still applied to the magnetic field. The uncalibrated magnetometer |
| is useful to handle bad hard iron estimations. In general, <code>geomagneticsensor_event.values[0]</code> |
| will be close to <code>uncalibrated_magnetometer_event.values[0] - |
| uncalibrated_magnetometer_event.values[3]</code>. That is,</p> |
| |
| <p><code>calibrated_x ~= uncalibrated_x - bias_estimate_x</code></p></p> |
| |
| <p class="note"><strong>Note:</strong> Uncalibrated sensors provide more raw results and may |
| include some bias, but their measurements contain fewer jumps from corrections applied through |
| calibration. Some applications may prefer these uncalibrated results as smoother and more |
| reliable. For instance, if an application is attempting to conduct its own sensor fusion, |
| introducing calibrations can actually distort results.</p> |
| |
| <p>In addition to the magnetic field, the uncalibrated magnetometer also provides the |
| estimated hard iron bias in each axis. The following code shows you how to get an instance of the |
| default uncalibrated magnetometer:</p> |
| |
| <pre> |
| private SensorManager mSensorManager; |
| private Sensor mSensor; |
| ... |
| mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); |
| mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED); |
| </pre> |
| |
| <h2 id="sensors-pos-prox">Using the Proximity Sensor</h2> |
| <p>The proximity sensor lets you determine how far away an object is from a device. The following |
| code shows you how to get an instance of the default proximity sensor:</p> |
| |
| <pre> |
| private SensorManager mSensorManager; |
| private Sensor mSensor; |
| ... |
| mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); |
| mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); |
| </pre> |
| |
| <p>The proximity sensor is usually used to determine how far away a person's head is from the face |
| of a handset device (for example, when a user is making or receiving a phone call). Most |
| proximity sensors return the absolute distance, in cm, but some return only near and |
| far values. The following code shows you how to use the proximity sensor:</p> |
| |
| <pre> |
| public class SensorActivity extends Activity implements SensorEventListener { |
| private SensorManager mSensorManager; |
| private Sensor mProximity; |
| |
| @Override |
| public final void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| setContentView(R.layout.main); |
| |
| // Get an instance of the sensor service, and use that to get an instance of |
| // a particular sensor. |
| mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); |
| mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); |
| } |
| |
| @Override |
| public final void onAccuracyChanged(Sensor sensor, int accuracy) { |
| // Do something here if sensor accuracy changes. |
| } |
| |
| @Override |
| public final void onSensorChanged(SensorEvent event) { |
| float distance = event.values[0]; |
| // Do something with this sensor data. |
| } |
| |
| @Override |
| protected void onResume() { |
| // Register a listener for the sensor. |
| super.onResume(); |
| mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); |
| } |
| |
| @Override |
| protected void onPause() { |
| // Be sure to unregister the sensor when the activity pauses. |
| super.onPause(); |
| mSensorManager.unregisterListener(this); |
| } |
| } |
| </pre> |
| |
| <p class="note"><strong>Note:</strong> Some proximity sensors return binary values that represent |
| "near" or "far." In this case, the sensor usually reports its maximum range value in the far state |
| and a lesser value in the near state. Typically, the far value is a value > 5 cm, but this can vary |
| from sensor to sensor. You can determine a sensor's maximum range by using the {@link |
| android.hardware.Sensor#getMaximumRange} method.</p> |