sensors_position.jd revision ae5d7d5d61def1c7af9d69d3e72a0f5f4a8a6414
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">&mu;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">&mu;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  &#64;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  &#64;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  &#64;Override
305  protected void onResume() {
306    super.onResume();
307    mSensorManager.registerListener(this, mOrientation, SensorManager.SENSOR_DELAY_NORMAL);
308  }
309
310  &#64;Override
311  protected void onPause() {
312    super.onPause();
313    mSensorManager.unregisterListener(this);
314  }
315
316  &#64;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 &mu;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  &#64;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  &#64;Override
418  public final void onAccuracyChanged(Sensor sensor, int accuracy) {
419    // Do something here if sensor accuracy changes.
420  }
421
422  &#64;Override
423  public final void onSensorChanged(SensorEvent event) {
424    float distance = event.values[0];
425    // Do something with this sensor data.
426  }
427
428  &#64;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  &#64;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