diff options
author | Bill Gruber <billg@google.com> | 2011-11-01 09:31:57 -0700 |
---|---|---|
committer | Bill Gruber <billg@google.com> | 2011-12-13 10:25:41 -0800 |
commit | f8c029ee3d9e5ad88e1f1f2969e666d9e8a70969 (patch) | |
tree | 46418b71996c363cb4d45ab1d7f31fdc57320a01 /docs | |
parent | 69e24843fc89dcdd35802dbb6a2b693650ec8a41 (diff) | |
download | frameworks_base-f8c029ee3d9e5ad88e1f1f2969e666d9e8a70969.zip frameworks_base-f8c029ee3d9e5ad88e1f1f2969e666d9e8a70969.tar.gz frameworks_base-f8c029ee3d9e5ad88e1f1f2969e666d9e8a70969.tar.bz2 |
Dev guide for sensors
Change-Id: Ie8d64974a2b946cfa0fe7297a6ebd6cfe496bc7a
Diffstat (limited to 'docs')
-rw-r--r-- | docs/html/guide/guide_toc.cs | 27 | ||||
-rw-r--r-- | docs/html/guide/topics/sensors/accelerometer.jd | 18 | ||||
-rw-r--r-- | docs/html/guide/topics/sensors/camera.jd | 18 | ||||
-rw-r--r-- | docs/html/guide/topics/sensors/compass.jd | 18 | ||||
-rw-r--r-- | docs/html/guide/topics/sensors/index.jd | 85 | ||||
-rw-r--r-- | docs/html/guide/topics/sensors/sensors_environment.jd | 208 | ||||
-rw-r--r-- | docs/html/guide/topics/sensors/sensors_motion.jd | 454 | ||||
-rw-r--r-- | docs/html/guide/topics/sensors/sensors_overview.jd | 791 | ||||
-rw-r--r-- | docs/html/guide/topics/sensors/sensors_position.jd | 317 |
9 files changed, 1869 insertions, 67 deletions
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index af379de..5ad000c 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -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> diff --git a/docs/html/guide/topics/sensors/accelerometer.jd b/docs/html/guide/topics/sensors/accelerometer.jd deleted file mode 100644 index da760bc..0000000 --- a/docs/html/guide/topics/sensors/accelerometer.jd +++ /dev/null @@ -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
\ No newline at end of file diff --git a/docs/html/guide/topics/sensors/camera.jd b/docs/html/guide/topics/sensors/camera.jd deleted file mode 100644 index 821333e..0000000 --- a/docs/html/guide/topics/sensors/camera.jd +++ /dev/null @@ -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>
\ No newline at end of file diff --git a/docs/html/guide/topics/sensors/compass.jd b/docs/html/guide/topics/sensors/compass.jd deleted file mode 100644 index 1e45d2d..0000000 --- a/docs/html/guide/topics/sensors/compass.jd +++ /dev/null @@ -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
\ No newline at end of file diff --git a/docs/html/guide/topics/sensors/index.jd b/docs/html/guide/topics/sensors/index.jd index 54a0814..e00a5b1 100644 --- a/docs/html/guide/topics/sensors/index.jd +++ b/docs/html/guide/topics/sensors/index.jd @@ -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>
\ No newline at end of file +<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> diff --git a/docs/html/guide/topics/sensors/sensors_environment.jd b/docs/html/guide/topics/sensors/sensors_environment.jd new file mode 100644 index 0000000..93ea4bc --- /dev/null +++ b/docs/html/guide/topics/sensors/sensors_environment.jd @@ -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 °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>°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>°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; + + @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); + } + + @Override + public final void onAccuracyChanged(Sensor sensor, int accuracy) { + // Do something here if sensor accuracy changes. + } + + @Override + public final void onSensorChanged(SensorEvent event) { + float millibars_of_pressure = event.values[0]; + // Do something with this sensor data. + } + + @Override + protected void onResume() { + // Register a listener for the sensor. + super.onResume(); + mSensorManager.registerListener(this, mPressure, SensorManager.SENSOR_DELAY_NORMAL); + } + + @Override + protected void onPause() { + // Be sure to unregister the sensor when the activity pauses. + super.onPause(); + mSensorManager.unregisterListener(this); + } +} +</pre> + +<p>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> + diff --git a/docs/html/guide/topics/sensors/sensors_motion.jd b/docs/html/guide/topics/sensors/sensors_motion.jd new file mode 100644 index 0000000..3f712b2 --- /dev/null +++ b/docs/html/guide/topics/sensors/sensors_motion.jd @@ -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>
\ No newline at end of file diff --git a/docs/html/guide/topics/sensors/sensors_overview.jd b/docs/html/guide/topics/sensors/sensors_overview.jd new file mode 100644 index 0000000..3c5e94c --- /dev/null +++ b/docs/html/guide/topics/sensors/sensors_overview.jd @@ -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 (°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 +μ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 (°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<Sensor> 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<Sensor> gravSensors = mSensorManager.getSensorList(Sensor.TYPE_GRAVITY); + for(int i=0; i<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; + + @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); + } + + @Override + public final void onAccuracyChanged(Sensor sensor, int accuracy) { + // Do something here if sensor accuracy changes. + } + + @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. + } + + @Override + protected void onResume() { + super.onResume(); + mSensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL); + } + + @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><uses-feature> + </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><uses-feature></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> +<uses-feature android:name="android.hardware.sensor.accelerometer" + android:required="true" /> +</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><uses-feature></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—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; + ... +@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>
\ No newline at end of file diff --git a/docs/html/guide/topics/sensors/sensors_position.jd b/docs/html/guide/topics/sensors/sensors_position.jd new file mode 100644 index 0000000..869109b --- /dev/null +++ b/docs/html/guide/topics/sensors/sensors_position.jd @@ -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">μ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; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); + mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) { + // Do something here if sensor accuracy changes. + // You must implement this callback in your code. + } + + @Override + protected void onResume() { + super.onResume(); + mSensorManager.registerListener(this, mOrientation, SensorManager.SENSOR_DELAY_NORMAL); + } + + @Override + protected void onPause() { + super.onPause(); + mSensorManager.unregisterListener(this); + } + + @Override + public void onSensorChanged(SensorEvent event) { + float azimuth_angle = event.values[0]; + float pitch_angle = event.values[1]; + float roll_angle = event.values[2]; + // Do something with these orientation angles. + } +} +</pre> + +<p>You do not usually need to perform any data processing or filtering of the raw data that you +obtain from an orientation sensor, other than translating the sensor's coordinate system to your +application's frame of reference. The <a +href="{@docRoot}resources/samples/AccelerometerPlay/index.html">Accelerometer Play</a> sample shows +you how to translate acceleration sensor data into another frame of reference; the technique is +similar to the one you might use with the orientation sensor.</p> + +<h2 id="sensors-pos-mag">Using the Geomagnetic Field Sensor</h2> + +<p>The geomagnetic field sensor lets you monitor changes in the earth's magnetic field. The +following code shows you how to get an instance of the default geomagnetic field sensor:</p> + +<pre> +private SensorManager mSensorManager; +private Sensor mSensor; +... +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); +mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); +</pre> + +<p>This sensor provides raw field strength data (in μT) for each of the three coordinate axes. +Usually, you do not need to use this sensor directly. Instead, you can use the rotation vector +sensor to determine raw rotational movement or you can use the accelerometer and geomagnetic field +sensor in conjunction with the {@link android.hardware.SensorManager#getRotationMatrix +getRotationMatrix()} method to obtain the rotation matrix and the inclination matrix. You can then +use these matrices with the {@link android.hardware.SensorManager#getOrientation getOrientation()} +and {@link android.hardware.SensorManager#getInclination getInclination()} methods to obtain azimuth +and geomagnetic inclination data.</p> + +<h2 id="sensors-pos-prox">Using the Proximity Sensor</h2> +<p>The proximity sensor lets you determine how far away an object is from a device. The following +code shows you how to get an instance of the default proximity sensor:</p> + +<pre> +private SensorManager mSensorManager; +private Sensor mSensor; +... +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); +mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); +</pre> + +<p>The proximity sensor is usually used to determine how far away a person's head is from the face +of a handset device (for example, when a user is making or receiving a phone call). Most +proximity sensors return the absolute distance, in cm, but some return only near and +far values. The following code shows you how to use the proximity sensor:</p> + +<pre> +public class SensorActivity extends Activity implements SensorEventListener { + private SensorManager mSensorManager; + private Sensor mProximity; + + @Override + public final void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + // Get an instance of the sensor service, and use that to get an instance of + // a particular sensor. + mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); + mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); + } + + @Override + public final void onAccuracyChanged(Sensor sensor, int accuracy) { + // Do something here if sensor accuracy changes. + } + + @Override + public final void onSensorChanged(SensorEvent event) { + float distance = event.values[0]; + // Do something with this sensor data. + } + + @Override + protected void onResume() { + // Register a listener for the sensor. + super.onResume(); + mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); + } + + @Override + protected void onPause() { + // Be sure to unregister the sensor when the activity pauses. + super.onPause(); + mSensorManager.unregisterListener(this); + } +} +</pre> + +<p class="note"><strong>Note:</strong> Some proximity sensors return binary values that represent +"near" or "far." In this case, the sensor usually reports its maximum range value in the far state +and a lesser value in the near state. Typically, the far value is a value > 5 cm, but this can vary +from sensor to sensor. You can determine a sensor's maximum range by using the {@link +android.hardware.Sensor#getMaximumRange} method.</p>
\ No newline at end of file |