am e2a95b59: am 97aafdf4: Merge "Dev guide for sensors" into ics-mr0

* commit 'e2a95b59f554d1d60b7e6c27d870158ec7051e31':
  Dev guide for sensors
This commit is contained in:
Bill Gruber
2011-12-16 11:15:46 -08:00
committed by Android Git Automerger
9 changed files with 1869 additions and 67 deletions

View File

@@ -309,14 +309,25 @@
<a href="<?cs var:toroot ?>guide/topics/clipboard/copy-paste.html">
<span class="en">Copy and Paste</span>
</a></li>
<!--<li class="toggle-list">
<div><a style="color:gray;">Sensors</a></div>
<ul>
<li><a style="color:gray;">Camera</a></li>
<li><a style="color:gray;">Compass</a></li>
<li><a style="color:gray;">Accelerometer</a></li>
</ul>
</li> -->
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/sensors/index.html">
<span class="en">Sensors</span>
</a><span class="new">new!</span></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/sensors/sensors_overview.html">
<span class="en">Sensors Overview</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/sensors/sensors_motion.html">
<span class="en">Motion Sensors</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/sensors/sensors_position.html">
<span class="en">Position Sensors</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/sensors/sensors_environment.html">
<span class="en">Environment Sensors</span>
</a></li>
</ul>
</li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/location/index.html">
<span class="en">Location and Maps</span>

View File

@@ -1,18 +0,0 @@
page.title=Accelerometer
parent.title=Sensors
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
</ol>
</div>
</div>
TODO

View File

@@ -1,18 +0,0 @@
page.title=Camera
parent.title=Sensors
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>Key class</h2>
<ol>
<li>{@link android.hardware.Camera android.hardware.Camera}</li>
</ol>
<h2>In this document</h2>
<ol>
<li>TODO</li>
</ol>
</div>
</div>

View File

@@ -1,18 +0,0 @@
page.title=Compass
parent.title=Sensors
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
</ol>
</div>
</div>
TODO

View File

@@ -2,12 +2,87 @@ page.title=Sensors
@jd:body
<div id="qv-wrapper">
<div id="qv">
<div id="qv">
<h2>Topics</h2>
<ol>
<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_position.html">Position
Sensors</a></li>
<li><a href="{@docRoot}guide/topics/sensors/sensors_environment.html">Environment
Sensors</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>
</div>
</div>
<p>Most Android-powered devices have built-in sensors that measure motion, orientation,
and various environmental conditions. These sensors are capable of providing raw data with high
precision and accuracy, and are useful if you want to monitor three-dimensional device movement or
positioning, or you want to monitor changes in the ambient environment near a device. For example, a
game might track readings from a device's gravity sensor to infer complex user gestures
and motions, such as tilt, shake, rotation, or swing. Likewise, a weather application might use a
device's temperature sensor and humidity sensor to calculate and report the dewpoint, or a travel
application might use the geomagnetic field sensor and accelerometer to report a compass
bearing.</p>
<p>The Android platform supports four broad categories of sensors:</p>
<h2>Accelerometer</h2>
<p>The accelerometer sensors allow you to detect the various movements of the device.</p>
<ul>
<li>Motion sensors
<p>These sensors measure acceleration forces and rotational forces along three axes. This
category includes accelerometers, gravity sensors, gyroscopes, and rotational vector
sensors.</p>
</li>
<li>Environmental sensors
<p>These sensors measure various environmental parameters, such as ambient air temperature
and pressure, illumination, and humidity. This category includes barometers, photometers, and
thermometers.</p>
</li>
<li>Position sensors
<p>These sensors measure the physical position of a device. This category includes
orientation sensors and magnetometers.</p>
</li>
</ul>
<h2>Compass</h2>
<p>The compass provides data on the devices current polar orientation.</p>
<p>To access these sensors, you can use the Android sensor framework. The sensor framework provides
several classes and interfaces that help you perform a wide variety of sensor-related tasks. To
learn more about the framework and the sensors that are supported on the Android system, read the
following documents:</p>
<dl>
<dt><strong><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors
Overview</a></strong></dt>
<dd>Learn how to list the sensors that are on a device, set up sensor event listeners, and
acquire sensor data. Also learn best practices for accessing and using sensors.</dd>
<dt><strong><a href="{@docRoot}guide/topics/sensors/sensors_motion.html">Motion
Sensors</a></strong></dt>
<dd>Learn how to use the sensors that provide acceleration data, such as the accelerometer,
gravity sensor, and linear acceleration sensor. Also learn how to use the sensors that
provide rotational data, such as gyroscopes and rotational vector sensors.</dd>
<dt><strong><a href="{@docRoot}guide/topics/sensors/sensors_position.html">Position
Sensors</a></strong></dt>
<dd>Learn how to use the sensors that provide orientation and compass data, such as the
orientation sensor and the geomagnetic field sensor.</dd>
<dt><strong><a href="{@docRoot}guide/topics/sensors/environment.html">Environment
Sensors</a></strong></dt>
<dd>Learn how to use the sensors that provide environmental data, such as the light,
humidity, pressure, temperature, and proximity sensors.</dd>
</dl>

View File

@@ -0,0 +1,208 @@
page.title=Environment Sensors
parent.title=Sensors
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#sensors-using-temp">Using the Light, Pressure, and Temperature
Sensors</a></li>
<li><a href="#sensors-using-humid">Using the Humidity Sensor</a></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_position.html">Position Sensors</a></li>
<li><a href="{@docRoot}guide/topics/sensors/sensors_motion.html">Motion
Sensors</a></li>
</ol>
</div>
</div>
<p>The Android platform provides four sensors that let you monitor various environmental properties.
You can use these sensors to monitor relative ambient humidity, illuminance, ambient pressure, and
ambient temperature near an Android-powered device. All four environment sensors are hardware-based
and are available only if a device manufacturer has built them into a device. With the exception of
the light sensor, which most device manufacturers use to control screen brightness, environment
sensors are not always available on devices. Because of this, it's particularly important that you
verify at runtime whether an environment sensor exists before you attempt to acquire data from
it.</p>
<p>Unlike most motion sensors and position sensors, which return a multi-dimensional array of sensor
values for each {@link android.hardware.SensorEvent}, environment sensors return a single sensor
value for each data event. For example, the temperature in &deg;C or the pressure in hPa.
Also, unlike motion sensors and position sensors, which often require high-pass or low-pass
filtering, environment sensors do not typically require any data filtering or data processing. Table
1 provides a summary of the environment sensors that are supported on the Android platform.</p>
<p class="table-caption" id="table1">
<strong>Table 1.</strong> Environment 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">Units of measure</th>
<th scope="col" style="white-space:nowrap">Data description</th>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}</td>
<td><code>event.values[0]</code></td>
<td>&deg;C</td>
<td>Ambient air temperature.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_LIGHT}</td>
<td><code>event.values[0]</code></td>
<td>lx</td>
<td>Illuminance.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_PRESSURE}</td>
<td><code>event.values[0]</code></td>
<td>hPa or mbar</td>
<td>Ambient air pressure.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}</td>
<td><code>event.values[0]</code></td>
<td>%</td>
<td>Ambient relative humidity.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_TEMPERATURE}</td>
<td><code>event.values[0]</code></td>
<td>&deg;C</td>
<td>Device temperature.<sup>1</sup></td>
</tr>
</table>
<p class="note"><sup><strong>1</strong></sup> Implementations vary from device to
device. This sensor was deprecated in Android 4.0 (API Level 14).</p>
<h2 id="sensors-using-temp">Using the Light, Pressure, and Temperature Sensors</h2>
<p>The raw data you acquire from the light, pressure, and temperature sensors usually requires no
calibration, filtering, or modification, which makes them some of the easiest sensors to use. To
acquire data from these sensors you first create an instance of the {@link
android.hardware.SensorManager} class, which you can use to get an instance of a physical sensor.
Then you register a sensor listener in the {@link android.app.Activity#onResume
onResume()} method, and start handling incoming sensor data in the {@link
android.hardware.SensorEventListener#onSensorChanged onSensorChanged()} callback method. The
following code shows you how to do this:</p>
<pre>
public class SensorActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mPressure;
&#64;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);
mPressure = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
}
&#64;Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
&#64;Override
public final void onSensorChanged(SensorEvent event) {
float millibars_of_pressure = event.values[0];
// Do something with this sensor data.
}
&#64;Override
protected void onResume() {
// Register a listener for the sensor.
super.onResume();
mSensorManager.registerListener(this, mPressure, SensorManager.SENSOR_DELAY_NORMAL);
}
&#64;Override
protected void onPause() {
// Be sure to unregister the sensor when the activity pauses.
super.onPause();
mSensorManager.unregisterListener(this);
}
}
</pre>
<p>You must always include implementations of both the {@link
android.hardware.SensorEventListener#onAccuracyChanged onAccuracyChanged()} and {@link
android.hardware.SensorEventListener#onSensorChanged onSensorChanged()} callback methods. Also, be
sure that you always unregister a sensor when an activity pauses. This prevents a sensor from
continually sensing data and draining the battery.</p>
<h2 id="sensors-using-humid">Using the Humidity Sensor</h2>
<p>You can acquire raw relative humidity data by using the humidity sensor the same way that you use
the light, pressure, and temperature sensors. However, if a device has both a humidity sensor
({@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}) and a temperature sensor ({@link
android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}) you can use these two data streams to calculate
the dew point and the absolute humidity.</p>
<h4>Dew point</h4>
<p>The dew point is the temperature at which a given volume of air must be cooled, at constant
barometric pressure, for water vapor to condense into water. The following equation shows how you
can calculate the dew point:</p>
<pre class="no-pretty-print classic">
ln(RH/100%) + m·t/(T<sub>n</sub>+t)
t<sub>d</sub>(t,RH) = T<sub>n</sub> · ------------------------------------
m - [ln(RH/100%) + m·t/(T<sub>n</sub>+t)]
</pre>
<p>Where,</p>
<ul type="none">
<li>t<sub>d</sub> = dew point temperature in degrees C</li>
<li>t = actual temperature in degrees C</li>
<li>RH = actual relative humidity in percent (%)</li>
<li>m = 17.62</li>
<li>T<sub>n</sub> = 243.12</li>
</ul>
<h4>Absolute humidity</h4>
<p>The absolute humidity is the mass of water vapor in a given volume of dry air. Absolute
humidity is measured in grams/meter<sup>3</sup>. The following equation shows how you
can calculate the absolute humidity:</p>
<pre class="no-pretty-print classic">
(RH/100%) · A · exp(m·t/(T<sub>n</sub>+t)
d<sub>v</sub>(t,RH) = 216.7 · ------------------------------------
273.15 + t
</pre>
<p>Where,</p>
<ul type="none">
<li>d<sub>v</sub> = absolute humidity in grams/meter<sup>3</sup></li>
<li>t = actual temperature in degrees C</li>
<li>RH = actual relative humidity in percent (%)</li>
<li>m = 17.62</li>
<li>T<sub>n</sub> = 243.12 degrees C</li>
<li>A = 6.112 hPa</li>
</ul>

View File

@@ -0,0 +1,454 @@
page.title=Motion Sensors
parent.title=Sensors
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#sensors-motion-accel">Using the Accelerometer</a></li>
<li><a href="#sensors-motion-grav">Using the Gravity Sensor</a></li>
<li><a href="#sensors-motion-gyro">Using the Gyroscope</a></li>
<li><a href="#sensors-motion-linear">Using the Linear Accelerometer</a></li>
<li><a href="#sensors-motion-rotate">Using the Rotation Vector 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/RotationVectorDemo.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_position.html">Position 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 several sensors that let you monitor the motion of a device. Two of
these sensors are always hardware-based (the accelerometer and gyroscope), and three of these
sensors can be either hardware-based or software-based (the gravity, linear acceleration, and
rotation vector sensors). For example, on some devices the software-based sensors derive their data
from the accelerometer and magnetometer, but on other devices they may also use the gyroscope to
derive their data. Most Android-powered devices have an accelerometer, and many now
include a gyroscope. The availability of the softare-based sensors is more variable because they
often rely on one or more hardware sensors to derive their data.</p>
<p>Motion sensors are useful for monitoring device movement, such as tilt, shake, rotation, or
swing. The movement is usually a reflection of direct user input (for example, a user steering a
car in a game or a user controlling a ball in a game), but it can also be a reflection of the
physical environment in which the device is sitting (for example, moving with you while you drive
your car). In the first case, you are monitoring motion relative to the device's frame of reference
or your application's frame of reference; in the second case you are monitoring motion relative to
the world's frame of reference. Motion sensors by themselves are not typically used to monitor
device position, but they can be used with other sensors, such as the geomagnetic field sensor, to
determine a device's position relative to the world's frame of reference (see <a
href="{@docRoot}guide/topics/sensors/sensors_position.html">Position Sensors</a> for more
information).</p>
<p>All of the motion sensors return multi-dimensional arrays of sensor values for each {@link
android.hardware.SensorEvent}. For example, during a single sensor event the accelerometer returns
acceleration force data for the three coordinate axes, and the gyroscope returns rate of rotation
data for the three coordinate axes. These data values are returned in a <code>float</code> array
({@link android.hardware.SensorEvent#values}) along with other {@link android.hardware.SensorEvent}
parameters. Table 1 summarizes the motion sensors that are available on the Android platform.</p>
<p class="table-caption" id="table1">
<strong>Table 1.</strong> Motion 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_ACCELEROMETER}</td>
<td><code>SensorEvent.values[0]</code></td>
<td>Acceleration force along the x axis (including gravity).</td>
<td rowspan="3">m/s<sup>2</sup></td>
</tr>
<tr>
<td><code>SensorEvent.values[1]</code></td>
<td>Acceleration force along the y axis (including gravity).</td>
</tr>
<tr>
<td><code>SensorEvent.values[2]</code></td>
<td>Acceleration force along the z axis (including gravity).</td>
</tr>
<tr>
<td rowspan="3">{@link android.hardware.Sensor#TYPE_GRAVITY}</td>
<td><code>SensorEvent.values[0]</code></td>
<td>Force of gravity along the x axis.</td>
<td rowspan="3">m/s<sup>2</sup></td>
</tr>
<tr>
<td><code>SensorEvent.values[1]</code></td>
<td>Force of gravity along the y axis.</td>
</tr>
<tr>
<td><code>SensorEvent.values[2]</code></td>
<td>Force of gravity along the z axis.</td>
</tr>
<tr>
<td rowspan="3">{@link android.hardware.Sensor#TYPE_GYROSCOPE}</td>
<td><code>SensorEvent.values[0]</code></td>
<td>Rate of rotation around the x axis.</td>
<td rowspan="3">rad/s</td>
</tr>
<tr>
<td><code>SensorEvent.values[1]</code></td>
<td>Rate of rotation around the y axis.</td>
</tr>
<tr>
<td><code>SensorEvent.values[2]</code></td>
<td>Rate of rotation around the z axis.</td>
</tr>
<tr>
<td rowspan="3">{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}</td>
<td><code>SensorEvent.values[0]</code></td>
<td>Acceleration force along the x axis (excluding gravity).</td>
<td rowspan="3">m/s<sup>2</sup></td>
</tr>
<tr>
<td><code>SensorEvent.values[1]</code></td>
<td>Acceleration force along the y axis (excluding gravity).</td>
</tr>
<tr>
<td><code>SensorEvent.values[2]</code></td>
<td>Acceleration force along the z axis (excluding gravity).</td>
</tr>
<tr>
<td rowspan="4">{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}</td>
<td><code>SensorEvent.values[0]</code></td>
<td>Rotation vector component along the x axis (x * sin(θ/2)).</td>
<td rowspan="4">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><code>SensorEvent.values[3]</code></td>
<td>Scalar component of the rotation vector ((cos(θ/2)).<sup>1</sup></td>
</tr>
</table>
<p class="note"><strong><sup>1</sup></strong> The scalar component is an optional value.</p>
<p>The rotation vector sensor and the gravity sensor are the most frequently used sensors for motion
detection and monitoring. The rotational vector sensor is particularly versatile and can be used for
a wide range of motion-related tasks, such as detecting gestures, monitoring angular change, and
monitoring relative orientation changes. For example, the rotational vector sensor is ideal if you
are developing a game, an augmented reality application, a 2-dimensional or 3-dimensional compass,
or a camera stabilization app. In most cases, using these sensors is a better choice than using
the accelerometer and geomagnetic field sensor or the orientation sensor.</p>
<h3>Android Open Source Project Sensors</h3>
<p>The Android Open Source Project (AOSP) provides three software-based motion sensors: a gravity
sensor, a linear acceleration sensor, and a rotation vector sensor. These sensors were updated in
Android 4.0 and now use a device's gyroscope (in addition to other sensors) to improve stability and
performance. If you want to try these sensors, you can identify them by using the {@link
android.hardware.Sensor#getVendor} method and the {@link android.hardware.Sensor#getVersion} method
(the vendor is Google Inc.; the version number is 3). Identifying these sensors by vendor and
version number is necessary because the Android system considers these three sensors to be secondary
sensors. For example, if a device manufacturer provides their own gravity sensor, then the AOSP
gravity sensor shows up as a secondary gravity sensor. All three of these sensors rely on a
gyroscope: if a device does not have a gyroscope, these sensors do not show up and are not
available for use.</p>
<h2 id="sensors-motion-accel">Using the Accelerometer</h2>
<p>An acceleration sensor measures the acceleration applied to the device, including the force of
gravity. The following code shows you how to get an instance of the default acceleration sensor:</p>
<pre>
private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
</pre>
<p>Conceptually, an acceleration sensor determines the acceleration that is applied
to a device (A<sub>d</sub>) by measuring the forces that are applied to the sensor
itself (F<sub>s</sub>) using the following relationship:</p>
<pre class="no-pretty-print classic">
A<sub>d</sub> = - ∑F<sub>s</sub> / mass
</pre>
<p>However, the force of gravity is always influencing the measured acceleration according to
the following relationship:</p>
<pre class="no-pretty-print classic">
A<sub>d</sub> = -g - ∑F / mass
</pre>
<p>For this reason, when the device is sitting on a table (and not accelerating), the
accelerometer reads a magnitude of g = 9.81 m/s<sup>2</sup>. Similarly, when the device is in
free fall and therefore rapidly accelerating toward the ground at 9.81 m/s<sup>2</sup>, its
accelerometer reads a magnitude of g = 0 m/s<sup>2</sup>. Therefore, to measure
the real acceleration of the device, the contribution of the force of gravity must be removed from
the accelerometer data. This can be achieved by applying a high-pass filter. Conversely, a low-pass
filter can be used to isolate the force of gravity. The following example shows how you can do
this:</p>
<pre>
public void onSensorChanged(SensorEvent event){
// In this example, alpha is calculated as t / (t + dT),
// where t is the low-pass filter's time-constant and
// dT is the event delivery rate.
final float alpha = 0.8;
// Isolate the force of gravity with the low-pass filter.
gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
// Remove the gravity contribution with the high-pass filter.
linear_acceleration[0] = event.values[0] - gravity[0];
linear_acceleration[1] = event.values[1] - gravity[1];
linear_acceleration[2] = event.values[2] - gravity[2];
}
</pre>
<p class="note"><strong>Note:</strong> You can use many different techniques to filter sensor data.
The code sample above uses a simple filter constant (alpha) to create a low-pass filter. This filter
constant is derived from a time constant (t), which is a rough representation of the latency that
the filter adds to the sensor events, and the sensor's event delivery rate (dt). The code sample
uses an alpha value of 0.8 for demonstration purposes. If you use this filtering method you may need
to choose a different alpha value.</p>
<p>Accelerometers use the standard sensor <a
href="{@docRoot}guide/topics/sensors/sensors_overview.html#sensors-coords">coordinate
system</a>. In practice, this means that the following conditions apply when a device is laying
flat on a table in its natural orientation:</p>
<ul>
<li>If you push the device on the left side (so it moves to the right), the x acceleration value
is positive.</li>
<li>If you push the device on the bottom (so it moves away from you), the y acceleration value is
positive.</li>
<li>If you push the device toward the sky with an acceleration of A m/s<sup>2</sup>, the
z acceleration value is equal to A + 9.81, which corresponds to the acceleration of the device (+A
m/s<sup>2</sup>) minus the force of gravity (-9.81 m/s<sup>2</sup>).</li>
<li>The stationary device will have an acceleration value of +9.81, which corresponds to the
acceleration of the device (0 m/s<sup>2</sup> minus the force of gravity, which is -9.81
m/s<sup>2</sup>).</li>
</ul>
<p>In general, the accelerometer is a good sensor to use if you are monitoring device motion.
Almost every Android-powered handset and tablet has an accelerometer, and it uses about 10 times
less power than the other motion sensors. One drawback is that you might have to implement
low-pass and high-pass filters to eliminate gravitational forces and reduce noise.</p>
<p>The Android SDK provides a sample application that shows how to use the acceleration sensor (<a
href="{@docRoot}resources/samples/AccelerometerPlay/index.html">Accelerometer Play</a>).</p>
<h2 id="sensors-motion-grav">Using the Gravity Sensor</h2>
<p>The gravity sensor provides a three dimensional vector indicating the direction and magnitude of
gravity. The following code shows you how to get an instance of the default gravity sensor:</p>
<pre>
private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
</pre>
<p>The units are the same as those used by the acceleration
sensor (m/s<sup>2</sup>), and the coordinate system is the same as the one used by the
acceleration sensor.</p>
<p class="note"><strong>Note:</strong> When a device is at rest, the output of the gravity sensor
should be identical to that of the accelerometer.</p>
<h2 id="sensors-motion-gyro">Using the Gyroscope</h2>
<p>The gyroscope measures the rate or rotation in rad/s around a device's x, y,
and z axis. The following code shows you how to get an instance of the default gyroscope:</p>
<pre>
private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
</pre>
<p>The sensor's <a
href="{@docRoot}guide/topics/sensors/sensors_overview.html#sensors-coords">coordinate system</a>
is the same as the one used for the acceleration sensor. Rotation is positive in the
counter-clockwise direction; that is, an observer looking
from some positive location on the x, y or z axis at a device positioned on the origin would report
positive rotation if the device appeared to be rotating counter clockwise. This is the
standard mathematical definition of positive rotation and is not the same as the definition for
roll that is used by the orientation sensor.</p>
<p>Usually, the output of the gyroscope is integrated over time to calculate a rotation describing
the change of angles over the timestep. For example:</p>
<pre>
// Create a constant to convert nanoseconds to seconds.
private static final float NS2S = 1.0f / 1000000000.0f;
private final float[] deltaRotationVector = new float[4]();
private float timestamp;
public void onSensorChanged(SensorEvent event) {
// This timestep's delta rotation to be multiplied by the current rotation
// after computing it from the gyro sample data.
if (timestamp != 0) {
final float dT = (event.timestamp - timestamp) * NS2S;
// Axis of the rotation sample, not normalized yet.
float axisX = event.values[0];
float axisY = event.values[1];
float axisZ = event.values[2];
// Calculate the angular speed of the sample
float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
// Normalize the rotation vector if it's big enough to get the axis
// (that is, EPSILON should represent your maximum allowable margin of error)
if (omegaMagnitude > EPSILON) {
axisX /= omegaMagnitude;
axisY /= omegaMagnitude;
axisZ /= omegaMagnitude;
}
// Integrate around this axis with the angular speed by the timestep
// in order to get a delta rotation from this sample over the timestep
// We will convert this axis-angle representation of the delta rotation
// into a quaternion before turning it into the rotation matrix.
float thetaOverTwo = omegaMagnitude * dT / 2.0f;
float sinThetaOverTwo = sin(thetaOverTwo);
float cosThetaOverTwo = cos(thetaOverTwo);
deltaRotationVector[0] = sinThetaOverTwo * axisX;
deltaRotationVector[1] = sinThetaOverTwo * axisY;
deltaRotationVector[2] = sinThetaOverTwo * axisZ;
deltaRotationVector[3] = cosThetaOverTwo;
}
timestamp = event.timestamp;
float[] deltaRotationMatrix = new float[9];
SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
// User code should concatenate the delta rotation we computed with the current rotation
// in order to get the updated rotation.
// rotationCurrent = rotationCurrent * deltaRotationMatrix;
}
}
</pre>
<p>Standard gyroscopes provide raw rotational data without any filtering or correction for noise and
drift (bias). In practice, gyroscope noise and drift will introduce errors that need to be
compensated for. You usually determine the drift (bias) and noise by monitoring other sensors, such
as the gravity sensor or accelerometer.</p>
<h2 id="sensors-motion-linear">Using the Linear Accelerometer</h2>
<p>The linear acceleration sensor provides you with a three-dimensional vector representing
acceleration along each device axis, excluding gravity. The following code shows you how to get an
instance of the default linear acceleration sensor:</p>
<pre>
private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
</pre>
<p>Conceptually, this sensor provides you with acceleration data according to the following
relationship:</p>
<pre class="no-pretty-print classic">
linear acceleration = acceleration - acceleration due to gravity
</pre>
<p>You typically use this sensor when you want to obtain acceleration data without the influence of
gravity. For example, you could use this sensor to see how fast your car is going. The linear
acceleration sensor always has an offset, which you need to remove. The simplest way to do this is
to build a calibration step into your application. During calibration you can ask the user to set
the device on a table, and then read the offsets for all three axes. You can then subtract that
offset from the acceleration sensor's direct readings to get the actual linear
acceleration.</p>
<p>The sensor <a
href="{@docRoot}guide/topics/sensors/sensors_overview.html#sensors-coords">coordinate
system</a> is the same as the one used by the acceleration sensor, as are the units of measure
(m/s<sup>2</sup>).
<h2 id="sensors-motion-rotate">Using the Rotation Vector Sensor</h2>
<p>The rotation vector represents the orientation of the device as a combination of an angle and an
axis, in which the device has rotated through an angle θ around an axis (x, y, or z). The following
code shows you how to get an instance of the default rotation vector sensor:</p>
<pre>
private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
</pre>
<p>The three elements of the rotation vector are expressed as follows:</p>
<pre class="no-pretty-print classic">
x*sin(θ/2)
y*sin(θ/2)
z*sin(θ/2)
</pre>
<p>Where the magnitude of the rotation vector is equal to sin(θ/2), and the direction of the
rotation vector is equal to the direction of the axis of rotation.</p>
<div class="figure" style="width:246px">
<img src="{@docRoot}images/axis_globe.png" alt="" height="235" />
<p class="img-caption">
<strong>Figure 1.</strong> Coordinate system used by the rotation vector sensor.
</p>
</div>
<p>The three elements of the rotation vector are equal to the last three components of a unit
quaternion (cos(θ/2), x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)). Elements of the rotation vector are
unitless. The x, y, and z axes are defined in the same way as the acceleration sensor. The reference
coordinate system is defined as a direct orthonormal basis (see figure 1). This coordinate system
has the following characteristics:</p>
<ul>
<li>X is defined as the vector product Y x Z. It is tangential to the
ground at the device's current location and points approximately East.</li>
<li>Y is tangential to the ground at the device's current location and points toward the
geomagnetic
North Pole.</li>
<li>Z points toward the sky and is perpendicular to the ground plane.</li>
</ul>
<p>The Android SDK provides a sample application that shows how to use the rotation vector sensor.
The sample application is located in the API Demos code (<a
href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/RotationVectorDemo.html">
OS - RotationVectorDemo</a>).</p>

View File

@@ -0,0 +1,791 @@
page.title=Sensors Overview
parent.title=Sensors
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>Quickview</h2>
<ul>
<li>Learn about the sensors that Android supports and the Android sensor framework.</li>
<li>Find out how to list sensors, determine sensor capabilities, and monitor sensor data.</li>
<li>Learn about best practices for accessing and using sensors.</li>
</ul>
<h2>In this document</h2>
<ol>
<li><a href="#sensors-intro">Introduction to Sensors</a></li>
<li><a href="#sensors-identify">Identifying Sensors and Sensor Capabilities</a></li>
<li><a href="#sensors-monitor">Monitoring Sensor Events</a></li>
<li><a href="#sensors-configs">Handling Different Sensor Configurations</a></li>
<li><a href="#sensors-coords">Sensor Coordinate System</a></li>
<li><a href="#sensors-practices">Best Practices for Accessing and Using Sensors</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_motion.html">Motion Sensors</a></li>
<li><a href="{@docRoot}guide/topics/sensors/sensors_position.html">Position
Sensors</a></li>
<li><a href="{@docRoot}guide/topics/sensors/sensors_environment.html">Environment
Sensors</a></li>
</ol>
</div>
</div>
<p>Most Android-powered devices have sensors that let you monitor changes in device
position and motion. Many devices also have sensors that let you determine ambient environmental
conditions, such as temperature, pressure, humidity, and lighting. You can access these
sensors and acquire raw sensor data by using the Android sensor framework.</p>
<p>The sensor framework provides several classes and interfaces that help you perform a wide variety
of sensor-related tasks. For example, you can use the sensor framework to do the following:</p>
<ul>
<li>Determine which sensors are available on a device.</li>
<li>Determine an individual sensor's capabilities, such as its maximum range, manufacturer, power
requirements, and resolution.</li>
<li>Acquire raw sensor data and define the minimum rate at which you acquire sensor data.</li>
<li>Register and unregister sensor event listeners that monitor sensor changes.</li>
</ul>
<p>This topic provides an overview of the sensors that are available on the Android platform.
It also provides an introduction to the sensor framework.</p>
<h2 id="sensors-intro">Introduction to Sensors</h2>
<p>The Android sensor framework lets you access many types of sensors. Some of these sensors are
hardware-based and some are software-based. Hardware-based sensors are physical components built
into a handset or tablet device. They derive their data by directly measuring specific environmental
properties, such as acceleration, geomagnetic field strength, or angular change. Software-based
sensors are not physical devices, although they mimic hardware-based sensors. Software-based sensors
derive their data from one or more of the hardware-based sensors and are sometimes called virtual
sensors or synthetic sensors. The linear acceleration sensor and the gravity sensor are examples of
software-based sensors. Table 1 summarizes the sensors that are supported by the Android
platform.</p>
<p>Few Android-powered devices have every type of sensor. For example, most handset devices and
tablets have an accelerometer and a magnetometer, but fewer devices have
barometers or thermometers. Also, a device can have more than one sensor of a given type. For
example, a device can have two gravity sensors, each one having a different range.</p>
<p class="table-caption" id="table1">
<strong>Table 1.</strong> Sensor types supported by the Android platform.</p>
<table>
<tr>
<th scope="col" style="white-space:nowrap">Sensor</th>
<th scope="col" style="white-space:nowrap">Type</th>
<th scope="col" style="white-space:nowrap">Description</th>
<th scope="col" style="white-space:nowrap">Common Uses</th>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_ACCELEROMETER}</td>
<td>Hardware</td>
<td>Measures the acceleration force in m/s<sup>2</sup> that is applied to a device on
all three physical axes (x, y, and z), including the force of gravity.</td>
<td>Motion detection (shake, tilt, etc.).</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}</td>
<td>Hardware</td>
<td>Measures the ambient room temperature in degrees Celsius (&deg;C). See note below.</td>
<td>Monitoring air temperatures.</td>
<tr>
<td>{@link android.hardware.Sensor#TYPE_GRAVITY}</td>
<td>Software or Hardware</td>
<td>Measures the force of gravity in m/s<sup>2</sup> that is applied to a device on all
three physical axes (x, y, z).</td>
<td>Motion detection (shake, tilt, etc.).</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_GYROSCOPE}</td>
<td>Hardware</td>
<td>Measures a device's rate of rotation in rad/s around each of the three
physical axes
(x, y, and z).</td>
<td>Rotation detection (spin, turn, etc.).</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_LIGHT}</td>
<td>Hardware</td>
<td>Measures the ambient light level (illumination) in lx.</td>
<td>Controlling screen brightness.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}</td>
<td>Software or Hardware</td>
<td>Measures the acceleration force in m/s<sup>2</sup> that is
applied to a device on
all three physical axes (x, y, and z), excluding the force of gravity.</td>
<td>Monitoring acceleration along a single axis.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}</td>
<td>Hardware</td>
<td>Measures the ambient geomagnetic field for all three physical axes (x, y, z) in
&mu;T.</td>
<td>Creating a compass.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_ORIENTATION}</td>
<td>Software</td>
<td>Measures degrees of rotation that a device makes around all three physical axes (x, y, z).
As of API level 3 you can obtain the inclination matrix and rotation matrix for
a device by using the gravity sensor and the geomagnetic field sensor in conjunction with
the {@link android.hardware.SensorManager#getRotationMatrix getRotationMatrix()}
method.</td>
<td>Determining device position.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_PRESSURE}</td>
<td>Hardware</td>
<td>Measures the ambient air pressure in hPa or mbar.</td>
<td>Monitoring air pressure changes.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_PROXIMITY}</td>
<td>Hardware</td>
<td>Measures the proximity of an object in cm relative to the view screen of a
device. This sensor is typically used to determine whether a handset is being held up to
a person's ear.</td>
<td>Phone position during a call.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}</td>
<td>Hardware</td>
<td>Measures the relative ambient humidity in percent (%).</td>
<td>Monitoring dewpoint, absolute, and relative humidity.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}</td>
<td>Software or Hardware</td>
<td>Measures the orientation of a device by providing the three elements of the device's
rotation vector.</td>
<td>Motion detection and rotation detection.</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_TEMPERATURE}</td>
<td>Hardware</td>
<td>Measures the temperature of the device in degrees Celsius (&deg;C). This sensor
implementation varies across devices and
this sensor was replaced with the {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} sensor in
API Level 14</td>
<td>Monitoring temperatures.</td>
</tr>
</table>
<h3>Sensor Framework</h3>
<p>You can access these sensors and acquire raw sensor data by using the Android sensor framework.
The sensor framework is part of the {@link android.hardware} package and includes the following
classes and interfaces:</p>
<dl>
<dt>{@link android.hardware.SensorManager}</dt>
<dd>You can use this class to create an instance of the sensor service. This class provides
various methods for accessing and listing sensors, registering and unregistering sensor event
listeners, and acquiring orientation information. This class also provides several sensor constants
that are used to report sensor accuracy, set data acquisition rates, and calibrate sensors.</dd>
<dt>{@link android.hardware.Sensor}</dt>
<dd>You can use this class to create an instance of a specific sensor. This class provides various
methods that let you determine a sensor's capabilities.</dd>
<dt>{@link android.hardware.SensorEvent}</dt>
<dd>The system uses this class to create a sensor event object, which provides information about a
sensor event. A sensor event object includes the following information: the raw sensor data, the
type of sensor that generated the event, the accuracy of the data, and the timestamp for the
event.</dd>
<dt>{@link android.hardware.SensorEventListener}</dt>
<dd>You can use this interface to create two callback methods that receive notifications (sensor
events) when sensor values change or when sensor accuracy changes.</dd>
</dl>
<p>In a typical application you use these sensor-related APIs to perform two basic tasks:</p>
<ul>
<li><strong>Identifying sensors and sensor capabilities</strong>
<p>Identifying sensors and sensor capabilities at runtime is useful if your application has
features that rely on specific sensor types or capabilities. For example, you may want to
identify all of the sensors that are present on a device and disable any application features
that rely on sensors that are not present. Likewise, you may want to identify all of the sensors
of a given type so you can choose the sensor implementation that has the optimum performance
for your application.</p>
</li>
<li><strong>Monitor sensor events</strong>
<p>Monitoring sensor events is how you acquire raw sensor data. A sensor event occurs every time
a sensor detects a change in the parameters it is measuring. A sensor event provides you
with four pieces of information: the name of the sensor that triggered the event, the
timestamp for the event, the accuracy of the event, and the raw sensor data that triggered
the event.</p>
</li>
</ul>
<h3>Sensor Availability</h3>
<p>While sensor availability varies from device to device, it can also vary between Android
versions. This is because the Android sensors have been introduced over the course of several
platform releases. For example, many sensors were introduced in Android 1.5 (API Level 3), but some
were not implemented and were not available for use until Android 2.3 (API Level 9). Likewise,
several sensors were introduced in Android 2.3 (API Level 9) and Android 4.0 (API Level 14). Two
sensors have been deprecated and replaced by newer, better sensors.</p>
<p>Table 2 summarizes the availability of each sensor on a platform-by-platform basis. Only four
platforms are listed because those are the platforms that involved sensor changes. Sensors that are
listed as deprecated are still available on subsequent platforms (provided the
sensor is present on a device), which is in line with Android's forward compatibility policy.</p>
<p class="table-caption" id="table2">
<strong>Table 2.</strong> Sensor availability by platform.</p>
<table>
<tr>
<th scope="col">Sensor</th>
<th scope="col">Android 4.0 <br>(API Level 14)</th>
<th scope="col">Android 2.3 <br>(API Level 9)</th>
<th scope="col">Android 2.2 <br>(API Level 8)</th>
<th scope="col">Android 1.5 <br>(API Level 3)</th>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_ACCELEROMETER}</td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}</td>
<td><strong>Yes</strong></td>
<td>n/a</td>
<td>n/a</td>
<td>n/a</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_GRAVITY}</td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td>n/a</td>
<td>n/a</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_GYROSCOPE}</td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td>n/a<sup>1</sup></td>
<td>n/a<sup>1</sup></td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_LIGHT}</td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}</td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td>n/a</td>
<td>n/a</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}</td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_ORIENTATION}</td>
<td><strong>Yes</strong><sup>2</sup></td>
<td><strong>Yes</strong><sup>2</sup></td>
<td><strong>Yes</strong><sup>2</sup></td>
<td><strong>Yes</strong></td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_PRESSURE}</td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td>n/a<sup>1</sup></td>
<td>n/a<sup>1</sup></td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_PROXIMITY}</td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}</td>
<td><strong>Yes</strong></td>
<td>n/a</td>
<td>n/a</td>
<td>n/a</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}</td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td>n/a</td>
<td>n/a</td>
</tr>
<tr>
<td>{@link android.hardware.Sensor#TYPE_TEMPERATURE}</td>
<td><strong>Yes</strong><sup>2</sup></td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
<td><strong>Yes</strong></td>
</tr>
</table>
<p class="note"><strong><sup>1</sup></strong> This sensor type was added in Android 1.5 (API Level
3),
but it was not available for use until Android 2.3 (API Level 9).</p>
<p class="note"><strong><sup>2</sup></strong> This sensor is available, but it has been
deprecated.</p>
<h2 id="sensors-identify">Identifying Sensors and Sensor Capabilities</h2>
<p>The Android sensor framework provides several methods that make it easy for you to determine at
runtime which sensors are on a device. The API also provides methods that let you determine the
capabilities of each sensor, such as its maximum range, its resolution, and its power
requirements.</p>
<p>To identify the sensors that are on a device you first need to get a reference to the sensor
service. To do this, you create an instance of the {@link android.hardware.SensorManager} class by
calling the {@link android.content.Context#getSystemService getSystemService()} method and passing
in the {@link android.content.Context#SENSOR_SERVICE SENSOR_SERVICE} argument. For example:</p>
<pre>
private SensorManager mSensorManager;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
</pre>
<p>Next, you can get a listing of every sensor on a device by calling the
{@link android.hardware.SensorManager#getSensorList getSensorList()} method and using the {@link
android.hardware.Sensor#TYPE_ALL} constant. For example:</p>
<pre>
List&lt;Sensor&gt; deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
</pre>
<p>If you want to list all of the sensors of a given type, you could use another constant instead of
{@link android.hardware.Sensor#TYPE_ALL} such as {@link android.hardware.Sensor#TYPE_GYROSCOPE},
{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}, or
{@link android.hardware.Sensor#TYPE_GRAVITY}.
</p>
<p>You can also determine whether a specific type of sensor exists on a device by using the {@link
android.hardware.SensorManager#getDefaultSensor getDefaultSensor()} method and passing in the type
constant for a specific sensor. If a device has more than one sensor of a given type, one of the
sensors must be designated as the default sensor. If a default sensor does not exist for a given
type of sensor, the method call returns null, which means the device does not have that type of
sensor. For example, the following code checks whether there's a magnetometer on a device:</p>
<pre>
private SensorManager mSensorManager;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){
// Success! There's a magnetometer.
}
else {
// Failure! No magnetometer.
}
</pre>
<p class="note"><strong>Note:</strong> Android does not require device manufacturers to build any
particular types of sensors into their Android-powered devices, so devices can have a wide range of
sensor configurations.</p>
<p>In addition to listing the sensors that are on a device, you can use the public methods of the
{@link android.hardware.Sensor} class to determine the capabilities and attributes of individual
sensors. This is useful if you want your application to behave differently based on which sensors or
sensor capabilities are available on a device. For example, you can use the {@link
android.hardware.Sensor#getResolution} and {@link android.hardware.Sensor#getMaximumRange}
methods to obtain a sensor's resolution and maximum range of measurement. You can also use the
{@link android.hardware.Sensor#getPower} method to obtain a sensor's power requirements.</p>
<p>Two of the public methods are particularly useful if you want to optimize your application for
different manufacturer's sensors or different versions of a sensor. For example, if your application
needs to monitor user gestures such as tilt and shake, you could create one set of data filtering
rules and optimizations for newer devices that have a specific vendor's gravity sensor, and another
set of data filtering rules and optimizations for devices that do not have a gravity sensor and have
only an accelerometer. The following code sample shows you how you can use the {@link
android.hardware.Sensor#getVendor} and {@link android.hardware.Sensor#getVersion} methods to do
this. In this sample, we're looking for a gravity sensor that lists Google Inc. as the vendor and
has a version number of 3. If that particular sensor is not present on the device, we try to use the
accelerometer.</p>
<pre>
private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){
List&lt;Sensor&gt; gravSensors = mSensorManager.getSensorList(Sensor.TYPE_GRAVITY);
for(int i=0; i&lt;gravSensors.size(); i++) {
if ((gravSensors.get(i).getVendor().contains("Google Inc.")) &&
(gravSensors.get(i).getVersion() == 3)){
// Use the version 3 gravity sensor.
mSensor = gravSensors.get(i);
}
}
}
else{
// Use the accelerometer.
if (mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
else{
// Sorry, there are no accelerometers on your device.
// You can't play this game.
}
}
</pre>
<p>Another useful method is the {@link android.hardware.Sensor#getMinDelay getMinDelay()} method,
which returns the minimum time interval (in microseconds) a sensor can use to sense data. Any sensor
that returns a non-zero value for the {@link android.hardware.Sensor#getMinDelay getMinDelay()}
method is a streaming
sensor. Streaming sensors sense data at regular intervals and were introduced in Android 2.3 (API
Level 9). If a sensor returns zero when you call the {@link android.hardware.Sensor#getMinDelay
getMinDelay()} method, it means the
sensor is not a streaming sensor because it reports data only when there is a change in the
parameters it is sensing.</p>
<p>The {@link android.hardware.Sensor#getMinDelay getMinDelay()} method is useful because it lets
you determine the maximum rate
at which a sensor can acquire data. If certain features in your application require high data
acquisition rates or a streaming sensor, you can use this method to determine whether a sensor
meets those requirements and then enable or disable the relevant features in your application
accordingly.</p>
<p class="caution"><strong>Caution:</strong> A sensor's maximum data acquisition rate is not
necessarily the rate at which the sensor framework delivers sensor data to your application. The
sensor framework reports data through sensor events, and several factors influence the rate at which
your application receives sensor events. For more information, see <a
href="#sensors-monitor">Monitoring Sensor Events</a>.</p>
<h2 id="sensors-monitor">Monitoring Sensor Events</h2>
<p>To monitor raw sensor data you need to implement two callback methods that are exposed through
the {@link android.hardware.SensorEventListener} interface: {@link
android.hardware.SensorEventListener#onAccuracyChanged onAccuracyChanged()} and {@link
android.hardware.SensorEventListener#onSensorChanged onSensorChanged()}. The Android system calls
these methods whenever the following occurs:</p>
<ul>
<li><strong>A sensor's accuracy changes.</strong>
<p>In this case the system invokes the {@link
android.hardware.SensorEventListener#onAccuracyChanged onAccuracyChanged()} method, providing
you with a reference to the {@link android.hardware.Sensor Sensor} object that changed and the
new accuracy of the sensor. Accuracy is represented by one of four status constants:
{@link android.hardware.SensorManager#SENSOR_STATUS_ACCURACY_LOW},
{@link android.hardware.SensorManager#SENSOR_STATUS_ACCURACY_MEDIUM},
{@link android.hardware.SensorManager#SENSOR_STATUS_ACCURACY_HIGH},
or {@link android.hardware.SensorManager#SENSOR_STATUS_UNRELIABLE}.</p>
</li>
<li><strong>A sensor reports a new value.</strong>
<p>In this case the system invokes the {@link
android.hardware.SensorEventListener#onSensorChanged onSensorChanged()} method, providing you with
a {@link android.hardware.SensorEvent SensorEvent} object. A {@link android.hardware.SensorEvent
SensorEvent} object
contains information about the new sensor data, including: the accuracy of the data, the
sensor that generated the data, the timestamp at which the data was generated, and the new
data that the sensor recorded.</p>
</li>
</ul>
<p>The following code shows how to use the {@link
android.hardware.SensorEventListener#onSensorChanged onSensorChanged()} method to monitor data from
the light sensor. This example displays the raw sensor data in a {@link android.widget.TextView}
that is
defined in the main.xml file as <code>sensor_data</code>.</p>
<pre>
public class SensorActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mLight;
&#64;Override
public final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
}
&#64;Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
&#64;Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
float lux = event.values[0];
// Do something with this sensor value.
}
&#64;Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
}
&#64;Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
}
</pre>
<p>In this example, the default data delay ({@link
android.hardware.SensorManager#SENSOR_DELAY_NORMAL}) is specified when the {@link
android.hardware.SensorManager#registerListener registerListener()} method is invoked. The data
delay (or sampling rate) controls the interval at which sensor events are sent to your application
via the {@link
android.hardware.SensorEventListener#onSensorChanged onSensorChanged()} callback method. The default
data delay is suitable for monitoring
typical screen orientation changes and uses a delay of 200,000 microseconds. You can specify other
data delays, such as {@link android.hardware.SensorManager#SENSOR_DELAY_GAME} (20,000 microsecond
delay), {@link android.hardware.SensorManager#SENSOR_DELAY_UI} (60,000 microsecond delay), or {@link
android.hardware.SensorManager#SENSOR_DELAY_FASTEST} (0 microsecond delay). As of Android 3.0 (API
Level 11) you can also specify the delay as an absolute value (in microseconds).</p>
<p>The delay that you specify is only a suggested delay. The Android system and other applications
can alter this delay. As a best practice, you should specify the largest delay that you can because
the system typically uses a smaller delay than the one you specify (that is, you should choose the
slowest sampling rate that still meets the needs of your application). Using a larger delay imposes
a lower load on the processor and therefore uses less power.</p>
<p>There is no public method for determining the rate at which the sensor framework is sending
sensor events to your application; however, you can use the timestamps that are associated with each
sensor event to calculate the sampling rate over several events. You should not have to change the
sampling rate (delay) once you set it. If for some reason you do need to change the delay, you will
have to unregister and reregister the sensor listener.</p>
<p>It's also important to note that this example uses the {@link android.app.Activity#onResume} and
{@link android.app.Activity#onPause} callback methods to register and unregister the sensor event
listener. As a best practice you should always disable sensors you don't need, especially when your
activity is paused. Failing to do so can drain the battery in just a few hours because some sensors
have substantial power requirements and can use up battery power quickly. The system
will not disable sensors automatically when the screen turns off.</p>
<h2 id="sensors-configs">Handling Different Sensor Configurations</h2>
<p>Android does not specify a standard sensor configuration for devices,
which means device manufacturers can incorporate any sensor configuration that they want into their
Android-powered devices. As a result, devices can include a variety
of sensors in a wide range of configurations. For example, the Motorola Xoom has a pressure sensor,
but the Samsung Nexus S does not. Likewise, the Xoom and Nexus S have gyroscopes, but the HTC Nexus
One does not. If your application relies on a specific type of sensor, you have to ensure that the
sensor is present on a device so your app can run successfully. You have two options for ensuring
that a given sensor is present on a device:</p>
<ul>
<li>Detect sensors at runtime and enable or disable application features as appropriate.</li>
<li>Use Android Market filters to target devices with specific sensor configurations.</li>
</ul>
<p>Each option is discussed in the following sections.</p>
<h4><strong>Detecting sensors at runtime</strong></h4>
<p>If your application uses a specific type of sensor, but doesn't rely on it, you can use the
sensor framework to detect the sensor at runtime and then disable or enable application features
as appropriate. For example, a navigation application might use the temperature sensor,
pressure sensor, GPS sensor, and geomagnetic field sensor to display the temperature, barometric
pressure, location, and compass bearing. If a device doesn't have a pressure sensor, you can use the
sensor framework to detect the absence of the pressure sensor at runtime and then disable the
portion of your application's UI that displays pressure. For example, the following code checks
whether there's a pressure sensor on a device:</p>
<pre>
private SensorManager mSensorManager;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){
// Success! There's a pressure sensor.
}
else {
// Failure! No pressure sensor.
}
</pre>
<h4>Using Android Market filters to target specific sensor configurations</h4>
<p>If you are publishing your application on Android Market you can use the
<a href="{@docRoot}guide//topics/manifest/uses-feature-element.html"><code>&lt;uses-feature&gt;
</code></a> element in your manifest file to filter your application from devices that do not
have the appropriate sensor configuration for your application. The
<code>&lt;uses-feature&gt;</code> element has several hardware descriptors that let you filter
applications based on the presence of specific sensors. The sensors you can list include:
accelerometer, barometer, compass (geomagnetic field), gyroscope, light, and proximity. The
following is an example manifest entry that filters apps that do not have an accelerometer:</p>
<pre>
&lt;uses-feature android:name="android.hardware.sensor.accelerometer"
android:required="true" /&gt;
</pre>
<p>If you add this element and descriptor to your application's manifest, users will see your
application on Android Market only if their device has an accelerometer.</p>
<p>You should set the descriptor to <code>android:required="true"</code> only if your application
relies entirely on a specific sensor. If your application uses a sensor for some functionality, but
still runs without the sensor, you should list the sensor in the <code>&lt;uses-feature&gt;</code>
element, but set the descriptor to <code>android:required="false"</code>. This helps ensure that
devices can install your app even if they do not have that particular sensor. This is also a
project management best practice that helps you keep track of the features your application uses.
Keep in mind, if your application uses a particular sensor, but still runs without the sensor,
then you should detect the sensor at runtime and disable or enable application features as
appropriate.</p>
<h2 id="sensors-coords">Sensor Coordinate System</h2>
<p>In general, the sensor framework uses a standard 3-axis coordinate system to express data values.
For most sensors, the coordinate system is defined relative to the device's screen when the device
is held in its default orientation (see figure 1). When a device is held in its default orientation,
the X axis is horizontal and points to the right, the Y axis is vertical and points up, and the Z
axis points toward the outside of the screen face. In this system, coordinates behind the screen
have negative Z values. This coordinate system is used by the following sensors:</p>
<div class="figure" style="width:269px">
<img src="{@docRoot}images/axis_device.png" alt="" height="225" />
<p class="img-caption">
<strong>Figure 1.</strong> Coordinate system (relative to a device) that's used by the Sensor
API.
</p>
</div>
<ul>
<li><a
href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-accel">Acceleration
sensor</a></li>
<li><a
href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-gravity">Gravity
sensor</a></li>
<li><a
href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-gyro">Gyroscope</a></li>
<li><a
href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-linear">Linear acceleration
sensor</a></li>
<li><a
href="{@docRoot}guide/topics/sensors/sensors_position.html#sensors-pos-mag">Geomagnetic field
sensor</a></li>
</ul>
<p>The most important point to understand about this coordinate system is that the axes are not
swapped when the device's screen orientation changes&mdash;that is, the sensor's coordinate system
never changes as the device moves. This behavior is the same as the behavior of the OpenGL
coordinate system.</p>
<p>Another point to understand is that your application must not assume that a device's natural
(default) orientation is portrait. The natural orientation for many tablet devices is landscape. And
the sensor coordinate system is always based on the natural orientation of a device.</p>
<p>Finally, if your application matches sensor data to the on-screen display, you need to use the
{@link android.view.Display#getRotation} method to determine screen rotation, and then use the
{@link android.hardware.SensorManager#remapCoordinateSystem remapCoordinateSystem()} method to map
sensor coordinates to screen coordinates. You need to do this even if your manifest specifies
portrait-only display.</p>
<p>For more information about the sensor coordinate system, including information about how to
handle screen rotations, see <a
href="http://android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.html">One
Screen Turn Deserves Another</a>.</p>
<p class="note"><strong>Note:</strong> Some sensors and methods use a coordinate system that is
relative to the world's frame of reference (as opposed to the device's frame of reference). These
sensors and methods return data that represent device motion or device position relative to the
earth. For more information, see the {@link android.hardware.SensorManager#getOrientation
getOrientation()} method, the {@link android.hardware.SensorManager#getRotationMatrix
getRotationMatrix()} method, <a
href="{@docRoot}guide/topics/sensors/sensors_position.html#sensors-pos-orient">Orientation
Sensor</a>, and <a
href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-rotate">Rotation Vector
Sensor</a>.</p>
<h2 id="sensors-practices">Best Practices for Accessing and Using Sensors</h2>
<p>As you design your sensor implementation, be sure to follow the guidelines that are discussed in
this section. These guidelines are recommended best practices for anyone who is using the sensor
framework to access sensors and acquire sensor data.</p>
<h4>Unregister sensor listeners</h4>
<p>Be sure to unregister a sensor's listener when you are done using the sensor or when the sensor
activity pauses. If a sensor listener is registered and its activity is paused, the sensor will
continue to acquire data and use battery resources unless you unregister the sensor. The following
code shows how to use the {@link android.app.Activity#onPause} method to unregister a listener:</p>
<pre>
private SensorManager mSensorManager;
...
&#64;Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
</pre>
<p>For more information, see {@link android.hardware.SensorManager#unregisterListener}.</p>
<h4>Don't test your code on the emulator</h4>
<p>You currently can't test sensor code on the emulator because the emulator cannot emulate sensors.
You must test your sensor code on a physical device. There are, however, sensor simulators that you
can use to simulate sensor output.</p>
<h4>Don't block the onSensorChanged() method</h4>
<p>Sensor data can change at a high rate, which means the system may call the {@link
android.hardware.SensorEventListener#onSensorChanged} method quite often. As a best practice, you
should do as little as possible within the {@link
android.hardware.SensorEventListener#onSensorChanged} method so you don't block it. If your
application requires you to do any data filtering or reduction of sensor data, you should perform
that work outside of the {@link android.hardware.SensorEventListener#onSensorChanged} method.</p>
<h4>Avoid using deprecated methods or sensor types</h4>
<p>Several methods and constants have been deprecated.
In particular, the {@link android.hardware.Sensor#TYPE_ORIENTATION}
sensor type has been deprecated. To get orientation data you should use the {@link
android.hardware.SensorManager#getOrientation getOrientation()} method instead. Likewise, the
{@link android.hardware.Sensor#TYPE_TEMPERATURE} sensor type has been deprecated. You should use
the {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} sensor type instead on devices
that are running Android 4.0.</p>
<h4>Verify sensors before you use them</h4>
<p>Always verify that a sensor exists on a device before you attempt to acquire data from it. Don't
assume that a sensor exists simply because it's a frequently-used sensor. Device manufacturers are
not required to provide any particular sensors in their devices.</p>
<h4>Choose sensor delays carefully</h4>
<p>When you register a sensor with the {@link android.hardware.SensorManager#registerListener
registerListener()} method, be sure you choose a delivery rate that is suitable for your
application or use-case. Sensors can provide data at very high rates. Allowing the system to send
extra data that you don't need wastes system resources and uses battery power.</p>

View File

@@ -0,0 +1,317 @@
page.title=Position Sensors
parent.title=Sensors
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<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_MAGNETIC_FIELD}</td>
<td><code>SensorEvent.values[0]</code></td>
<td>Geomagnetic field strength along the x axis.</td>
<td rowspan="3">&mu;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="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-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;
&#64;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);
}
&#64;Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
// You must implement this callback in your code.
}
&#64;Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mOrientation, SensorManager.SENSOR_DELAY_NORMAL);
}
&#64;Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
&#64;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 &mu;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-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;
&#64;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);
}
&#64;Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
&#64;Override
public final void onSensorChanged(SensorEvent event) {
float distance = event.values[0];
// Do something with this sensor data.
}
&#64;Override
protected void onResume() {
// Register a listener for the sensor.
super.onResume();
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
}
&#64;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>