• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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">Computing the Device's Orientation</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>
46  The Android platform provides two sensors that let you determine the position
47  of a device: the geomagnetic field sensor and the accelerometer. The Android
48  platform also provides a sensor that lets you determine how close the face of
49  a device is to an object (known as the <em>proximity sensor</em>). The
50  geomagnetic field sensor and the proximity sensor are hardware-based. Most
51  handset and tablet manufacturers include a geomagnetic field sensor. Likewise,
52  handset manufacturers usually include a proximity sensor to determine when a
53  handset is being held close to a user's face (for example, during a phone
54  call). For determining a device's orientation, you can use the readings from
55  the device's accelerometer and the geomagnetic field sensor.
56</p>
57
58<p class="note">
59  <strong>Note:</strong> The orientation sensor was deprecated in Android 2.2
60  (API level 8), and the orientation sensor type was deprecated in Android 4.4W
61  (API level 20).
62</p>
63
64<p>
65  Position sensors are useful for determining a device's physical position in
66  the world's frame of reference. For example, you can use the geomagnetic field
67  sensor in combination with the accelerometer to determine a device's position
68  relative to the magnetic north pole. You can also use these sensors to
69  determine a device's orientation in your application's frame of reference.
70  Position sensors are not typically used to monitor device movement or motion,
71  such as shake, tilt, or thrust (for more information, see <a
72  href="{@docRoot}guide/topics/sensors/sensors_motion.html">Motion Sensors</a>).
73</p>
74
75<p>
76  The geomagnetic field sensor and accelerometer return multi-dimensional arrays
77  of sensor values for each {@link android.hardware.SensorEvent}. For example,
78  the geomagnetic field sensor provides geomagnetic field strength values for
79  each of the three coordinate axes during a single sensor event. Likewise, the
80  accelerometer sensor measures the acceleration applied to the device during a
81  sensor event. For more information about the coordinate systems that are used
82  by sensors, see <a
83  href="{@docRoot}guide/topics/sensors/sensors_overview.html#sensors-coords">
84  Sensor Coordinate Systems</a>. The proximity sensor provides a single value
85  for each sensor event. Table 1 summarizes the position sensors that are
86  supported on the Android platform.
87</p>
88
89<p class="table-caption" id="table1">
90  <strong>Table 1.</strong> Position sensors that are supported on the Android platform.</p>
91<table>
92  <tr>
93    <th scope="col" style="white-space:nowrap">Sensor</th>
94    <th scope="col" style="white-space:nowrap">Sensor event data</th>
95    <th scope="col" style="white-space:nowrap">Description</th>
96    <th scope="col" style="white-space:nowrap">Units of measure</th>
97  </tr>
98  <tr>
99    <td rowspan="3">{@link android.hardware.Sensor#TYPE_GAME_ROTATION_VECTOR}</td>
100    <td><code>SensorEvent.values[0]</code></td>
101    <td>Rotation vector component along the x axis (x * sin(θ/2)).</td>
102    <td rowspan="3">Unitless</td>
103  </tr>
104  <tr>
105    <td><code>SensorEvent.values[1]</code></td>
106    <td>Rotation vector component along the y axis (y * sin(θ/2)).</td>
107  </tr>
108  <tr>
109    <td><code>SensorEvent.values[2]</code></td>
110    <td>Rotation vector component along the z axis (z * sin(θ/2)).</td>
111  </tr>
112  <tr>
113    <td rowspan="3">{@link android.hardware.Sensor#TYPE_GEOMAGNETIC_ROTATION_VECTOR}</td>
114    <td><code>SensorEvent.values[0]</code></td>
115    <td>Rotation vector component along the x axis (x * sin(θ/2)).</td>
116    <td rowspan="3">Unitless</td>
117  </tr>
118  <tr>
119    <td><code>SensorEvent.values[1]</code></td>
120    <td>Rotation vector component along the y axis (y * sin(θ/2)).</td>
121  </tr>
122  <tr>
123    <td><code>SensorEvent.values[2]</code></td>
124    <td>Rotation vector component along the z axis (z * sin(θ/2)).</td>
125  </tr>
126  <tr>
127    <td rowspan="3">{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}</td>
128    <td><code>SensorEvent.values[0]</code></td>
129    <td>Geomagnetic field strength along the x axis.</td>
130    <td rowspan="3">&mu;T</td>
131  </tr>
132  <tr>
133    <td><code>SensorEvent.values[1]</code></td>
134    <td>Geomagnetic field strength along the y axis.</td>
135  </tr>
136  <tr>
137    <td><code>SensorEvent.values[2]</code></td>
138    <td>Geomagnetic field strength along the z axis.</td>
139  </tr>
140  <tr>
141    <td rowspan="6">{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD_UNCALIBRATED}</td>
142    <td><code>SensorEvent.values[0]</code></td>
143    <td>Geomagnetic field strength (without hard iron calibration) along the x axis.</td>
144    <td rowspan="6">&mu;T</td>
145  </tr>
146  <tr>
147    <td><code>SensorEvent.values[1]</code></td>
148    <td>Geomagnetic field strength (without hard iron calibration) along the y axis.</td>
149  </tr>
150  <tr>
151    <td><code>SensorEvent.values[2]</code></td>
152    <td>Geomagnetic field strength (without hard iron calibration) along the z axis.</td>
153  </tr>
154  <tr>
155    <td><code>SensorEvent.values[3]</code></td>
156    <td>Iron bias estimation along the x axis.</td>
157  </tr>
158  <tr>
159    <td><code>SensorEvent.values[4]</code></td>
160    <td>Iron bias estimation along the y axis.</td>
161  </tr>
162  <tr>
163    <td><code>SensorEvent.values[5]</code></td>
164    <td>Iron bias estimation along the z axis.</td>
165  </tr>
166  <tr>
167    <td rowspan="3">{@link android.hardware.Sensor#TYPE_ORIENTATION}<sup>1</sup></td>
168    <td><code>SensorEvent.values[0]</code></td>
169    <td>Azimuth (angle around the z-axis).</td>
170    <td rowspan="3">Degrees</td>
171  </tr>
172  <tr>
173    <td><code>SensorEvent.values[1]</code></td>
174    <td>Pitch (angle around the x-axis).</td>
175  </tr>
176  <tr>
177    <td><code>SensorEvent.values[2]</code></td>
178    <td>Roll (angle around the y-axis).</td>
179  </tr>
180  <tr>
181    <td>{@link android.hardware.Sensor#TYPE_PROXIMITY}</td>
182    <td><code>SensorEvent.values[0]</code></td>
183    <td>Distance from object.<sup>2</sup></td>
184    <td>cm</td>
185  </tr>
186</table>
187
188<p class="note">
189  <sup><strong>1</strong></sup>This sensor was deprecated in Android 2.2 (API
190  level 8), and this sensor type was deprecated in Android 4.4W (API level 20).
191  The sensor framework provides alternate methods for acquiring device
192  orientation, which are discussed in <a href="#sensors-pos-orient">Computing
193  the Device's Orientation</a>.
194</p>
195
196<p class="note"><sup><strong>2</strong></sup> Some proximity sensors provide only binary values
197representing near and far.</p>
198
199<h2 id="sensors-pos-gamerot">Using the Game Rotation Vector Sensor</h2>
200
201<p>The game rotation vector sensor is identical to the
202<a href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-rotate">Rotation
203Vector Sensor</a>, except it does not use the geomagnetic field. Therefore the Y axis does not
204point north but instead to some other reference. That reference is allowed to drift by the
205same order of magnitude as the gyroscope drifts around the Z axis.</p>
206
207<p>Because the game rotation vector sensor does not use the magnetic field, relative rotations
208are more accurate, and not impacted by magnetic field changes. Use this sensor in a game if
209you do not care about where north is, and the normal rotation vector does not fit your needs
210because of its reliance on the magnetic field.</p>
211
212<p>The following code shows you how to get an instance of the default game rotation vector
213sensor:</p>
214
215<pre>
216private SensorManager mSensorManager;
217private Sensor mSensor;
218...
219mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
220mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);
221</pre>
222
223
224<h2 id="sensors-pos-geomrot">Using the Geomagnetic Rotation Vector Sensor</h2>
225
226<p>The geomagnetic rotation vector sensor is similar to the
227<a href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-rotate">Rotation
228Vector Sensor</a>, but it uses a magnetometer instead of a gyroscope. The accuracy of this
229sensor is lower than the normal rotation vector sensor, but the power consumption is reduced.
230Only use this sensor if you want to collect some rotation information in the background without
231draining too much battery. This sensor is most useful when used in conjunction with batching.</p>
232
233<p>The following code shows you how to get an instance of the default geomagnetic rotation
234vector sensor:</p>
235
236<pre>
237private SensorManager mSensorManager;
238private Sensor mSensor;
239...
240mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
241mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR);
242</pre>
243
244
245<h2 id="sensors-pos-orient">Computing the Device's Orientation</h2>
246
247<p>By computing a device's orientation, you can monitor the position of the
248  device relative to the earth's frame of reference (specifically, the magnetic
249  north pole). The following code shows you how to compute a device's
250  orientation:
251</p>
252<pre>
253private SensorManager mSensorManager;
254...
255// Rotation matrix based on current readings from accelerometer and magnetometer.
256final float[] rotationMatrix = new float[9];
257mSensorManager.getRotationMatrix(rotationMatrix, null,
258  accelerometerReading, magnetometerReading);
259
260// Express the updated rotation matrix as three orientation angles.
261final float[] orientationAngles = new float[3];
262mSensorManager.getOrientation(rotationMatrix, orientationAngles);
263</pre>
264<p>The system computes the orientation angles by using a device's geomagnetic
265  field sensor in combination with the device's accelerometer. Using these two
266  hardware sensors, the system provides data for the following three
267  orientation angles:
268</p>
269<ul>
270  <li>
271    <strong>Azimuth (degrees of rotation about the -z axis).</strong> This is
272    the angle between the device's current compass direction and magnetic north.
273    If the top edge of the device faces magnetic north, the azimuth is 0
274    degrees; if the top edge faces south, the azimuth is 180 degrees. Similarly,
275    if the top edge faces east, the azimuth is 90 degrees, and if the top edge
276    faces west, the azimuth is 270 degrees.
277  </li>
278  <li>
279    <strong>Pitch (degrees of rotation about the x axis).</strong> This is the
280    angle between a plane parallel to the device's screen and a plane parallel
281    to the ground. If you hold the device parallel to the ground with the bottom
282    edge closest to you and tilt the top edge of the device toward the ground,
283    the pitch angle becomes positive. Tilting in the opposite direction&mdash;
284    moving the top edge of the device away from the ground&mdash;causes
285    the pitch angle to become negative. The range of values is -180 degrees to
286    180 degrees.
287  </li>
288  <li>
289    <strong>Roll (degrees of rotation about the y axis).</strong> This is the
290    angle between a plane perpendicular to the device's screen and a plane
291    perpendicular to the ground. If you hold the device parallel to the ground
292    with the bottom edge closest to you and tilt the left edge of the device
293    toward the ground, the roll angle becomes positive. Tilting in the opposite
294    direction&mdash;moving the right edge of the device toward the ground&mdash;
295    causes the roll angle to become negative. The range of values is -90 degrees
296    to 90 degrees.
297  </li>
298</ul>
299
300<p class="note">
301  <strong>Note:</strong>The sensor's roll definition has changed to reflect the
302  vast majority of implementations in the geosensor ecosystem.
303</p>
304
305<p>
306  Note that these angles work off of a different coordinate system than the
307  one used in aviation (for yaw, pitch, and roll). In the aviation system, the
308  x axis is along the long side of the plane, from tail to nose.
309</p>
310
311<p>
312  The orientation sensor derives its data by processing the raw sensor data
313  from the accelerometer and the geomagnetic field sensor. Because of the heavy
314  processing that is involved, the accuracy and precision of the orientation
315  sensor is diminished. Specifically, this sensor is reliable only when the roll
316  angle is 0. As a result, the orientation sensor was deprecated in Android
317  2.2 (API level 8), and the orientation sensor type was deprecated in Android
318  4.4W (API level 20).
319
320  Instead of using raw data from the orientation sensor, we recommend that you
321  use the {@link android.hardware.SensorManager#getRotationMatrix getRotationMatrix()}
322  method in conjunction with the
323  {@link android.hardware.SensorManager#getOrientation getOrientation()} method
324  to compute orientation values, as shown in the following code sample. As part
325  of this process, you can use the
326  {@link android.hardware.SensorManager#remapCoordinateSystem remapCoordinateSystem()}
327  method to translate the orientation values to your application's frame of
328  reference.
329</p>
330<pre>
331public class SensorActivity extends Activity implements SensorEventListener {
332
333  private SensorManager mSensorManager;
334  private final float[] mAccelerometerReading = new float[3];
335  private final float[] mMagnetometerReading = new float[3];
336
337  private final float[] mRotationMatrix = new float[9];
338  private final float[] mOrientationAngles = new float[3];
339
340  &#64;Override
341  public void onCreate(Bundle savedInstanceState) {
342    super.onCreate(savedInstanceState);
343    setContentView(R.layout.main);
344    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
345  }
346
347  &#64;Override
348  public void onAccuracyChanged(Sensor sensor, int accuracy) {
349    // Do something here if sensor accuracy changes.
350    // You must implement this callback in your code.
351  }
352
353  &#64;Override
354  protected void onResume() {
355    super.onResume();
356
357    // Get updates from the accelerometer and magnetometer at a constant rate.
358    // To make batch operations more efficient and reduce power consumption,
359    // provide support for delaying updates to the application.
360    //
361    // In this example, the sensor reporting delay is small enough such that
362    // the application receives an update before the system checks the sensor
363    // readings again.
364    mSensorManager.registerListener(this, Sensor.TYPE_ACCELEROMETER,
365      SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
366    mSensorManager.registerListener(this, Sensor.TYPE_MAGNETIC_FIELD,
367      SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
368  }
369
370  &#64;Override
371  protected void onPause() {
372    super.onPause();
373
374    // Don't receive any more updates from either sensor.
375    mSensorManager.unregisterListener(this);
376  }
377
378  // Get readings from accelerometer and magnetometer. To simplify calculations,
379  // consider storing these readings as unit vectors.
380  &#64;Override
381  public void onSensorChanged(SensorEvent event) {
382    if (event.sensor == Sensor.TYPE_ACCELEROMETER) {
383      System.arraycopy(event.values, 0, mAccelerometerReading,
384        0, mAccelerometerReading.length);
385    }
386    else if (event.sensor == Sensor.TYPE_MAGNETIC_FIELD) {
387      System.arraycopy(event.values, 0, mMagnetometerReading,
388        0, mMagnetometerReading.length);
389    }
390  }
391
392  // Compute the three orientation angles based on the most recent readings from
393  // the device's accelerometer and magnetometer.
394  public void updateOrientationAngles() {
395    // Update rotation matrix, which is needed to update orientation angles.
396    mSensorManager.getRotationMatrix(mRotationMatrix, null,
397      mAccelerometerReading, mMagnetometerReading);
398
399    // "mRotationMatrix" now has up-to-date information.
400
401    mSensorManager.getOrientation(mRotationMatrix, mOrientationAngles);
402
403    // "mOrientationAngles" now has up-to-date information.
404  }
405}
406</pre>
407
408<p>
409  You don't usually need to perform any data processing or filtering of the
410  device's raw orientation angles other than translating the sensor's
411  coordinate system to your application's frame of reference.
412</p>
413
414<h2 id="sensors-pos-mag">Using the Geomagnetic Field Sensor</h2>
415
416<p>The geomagnetic field sensor lets you monitor changes in the earth's magnetic field. The
417following code shows you how to get an instance of the default geomagnetic field sensor:</p>
418
419<pre>
420private SensorManager mSensorManager;
421private Sensor mSensor;
422...
423mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
424mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
425</pre>
426
427<p>This sensor provides raw field strength data (in &mu;T) for each of the three coordinate axes.
428Usually, you do not need to use this sensor directly. Instead, you can use the rotation vector
429sensor to determine raw rotational movement or you can use the accelerometer and geomagnetic field
430sensor in conjunction with the {@link android.hardware.SensorManager#getRotationMatrix
431getRotationMatrix()} method to obtain the rotation matrix and the inclination matrix. You can then
432use these matrices with the {@link android.hardware.SensorManager#getOrientation getOrientation()}
433and {@link android.hardware.SensorManager#getInclination getInclination()} methods to obtain azimuth
434and geomagnetic inclination data.</p>
435
436<h2 id="sensors-pos-magunc">Using the Uncalibrated Magnetometer</h2>
437
438<p>The uncalibrated magnetometer is similar to the <a href="#sensors-pos-mag">geomagnetic field
439sensor</a>, except that no hard iron calibration is applied to the magnetic field. Factory calibration
440and temperature compensation are still applied to the magnetic field. The uncalibrated magnetometer
441is useful to handle bad hard iron estimations. In general, <code>geomagneticsensor_event.values[0]</code>
442will be close to <code>uncalibrated_magnetometer_event.values[0] -
443uncalibrated_magnetometer_event.values[3]</code>. That is,</p>
444
445<p><code>calibrated_x ~= uncalibrated_x - bias_estimate_x</code></p></p>
446
447<p class="note"><strong>Note:</strong> Uncalibrated sensors provide more raw results and may
448include some bias, but their measurements contain fewer jumps from corrections applied through
449calibration. Some applications may prefer these uncalibrated results as smoother and more
450reliable. For instance, if an application is attempting to conduct its own sensor fusion,
451introducing calibrations can actually distort results.</p>
452
453<p>In addition to the magnetic field, the uncalibrated magnetometer also provides the
454estimated hard iron bias in each axis. The following code shows you how to get an instance of the
455default uncalibrated magnetometer:</p>
456
457<pre>
458private SensorManager mSensorManager;
459private Sensor mSensor;
460...
461mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
462mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED);
463</pre>
464
465<h2 id="sensors-pos-prox">Using the Proximity Sensor</h2>
466<p>The proximity sensor lets you determine how far away an object is from a device. The following
467code shows you how to get an instance of the default proximity sensor:</p>
468
469<pre>
470private SensorManager mSensorManager;
471private Sensor mSensor;
472...
473mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
474mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
475</pre>
476
477<p>The proximity sensor is usually used to determine how far away a person's head is from the face
478of a handset device (for example, when a user is making or receiving a phone call). Most
479proximity sensors return the absolute distance, in cm, but some return only near and
480far values. The following code shows you how to use the proximity sensor:</p>
481
482<pre>
483public class SensorActivity extends Activity implements SensorEventListener {
484  private SensorManager mSensorManager;
485  private Sensor mProximity;
486
487  &#64;Override
488  public final void onCreate(Bundle savedInstanceState) {
489    super.onCreate(savedInstanceState);
490    setContentView(R.layout.main);
491
492    // Get an instance of the sensor service, and use that to get an instance of
493    // a particular sensor.
494    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
495    mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
496  }
497
498  &#64;Override
499  public final void onAccuracyChanged(Sensor sensor, int accuracy) {
500    // Do something here if sensor accuracy changes.
501  }
502
503  &#64;Override
504  public final void onSensorChanged(SensorEvent event) {
505    float distance = event.values[0];
506    // Do something with this sensor data.
507  }
508
509  &#64;Override
510  protected void onResume() {
511    // Register a listener for the sensor.
512    super.onResume();
513    mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
514  }
515
516  &#64;Override
517  protected void onPause() {
518    // Be sure to unregister the sensor when the activity pauses.
519    super.onPause();
520    mSensorManager.unregisterListener(this);
521  }
522}
523</pre>
524
525<p class="note"><strong>Note:</strong> Some proximity sensors return binary values that represent
526"near" or "far." In this case, the sensor usually reports its maximum range value in the far state
527and a lesser value in the near state. Typically, the far value is a value > 5 cm, but this can vary
528from sensor to sensor. You can determine a sensor's maximum range by using the {@link
529android.hardware.Sensor#getMaximumRange} method.</p>
530