From f8c029ee3d9e5ad88e1f1f2969e666d9e8a70969 Mon Sep 17 00:00:00 2001 From: Bill Gruber Date: Tue, 1 Nov 2011 09:31:57 -0700 Subject: Dev guide for sensors Change-Id: Ie8d64974a2b946cfa0fe7297a6ebd6cfe496bc7a --- docs/html/guide/guide_toc.cs | 27 +- docs/html/guide/topics/sensors/accelerometer.jd | 18 - docs/html/guide/topics/sensors/camera.jd | 18 - docs/html/guide/topics/sensors/compass.jd | 18 - docs/html/guide/topics/sensors/index.jd | 85 ++- .../guide/topics/sensors/sensors_environment.jd | 208 ++++++ docs/html/guide/topics/sensors/sensors_motion.jd | 454 ++++++++++++ docs/html/guide/topics/sensors/sensors_overview.jd | 791 +++++++++++++++++++++ docs/html/guide/topics/sensors/sensors_position.jd | 317 +++++++++ 9 files changed, 1869 insertions(+), 67 deletions(-) delete mode 100644 docs/html/guide/topics/sensors/accelerometer.jd delete mode 100644 docs/html/guide/topics/sensors/camera.jd delete mode 100644 docs/html/guide/topics/sensors/compass.jd create mode 100644 docs/html/guide/topics/sensors/sensors_environment.jd create mode 100644 docs/html/guide/topics/sensors/sensors_motion.jd create mode 100644 docs/html/guide/topics/sensors/sensors_overview.jd create mode 100644 docs/html/guide/topics/sensors/sensors_position.jd (limited to 'docs') 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 @@ Copy and Paste - +
  • +
    + Sensors + new!
    + +
  • Location and Maps 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 - -
    -
    - -

    In this document

    -
      - -
    - -
    -
    - - -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 - -
    -
    - -

    Key class

    -
      -
    1. {@link android.hardware.Camera android.hardware.Camera}
    2. -
    -

    In this document

    -
      -
    1. TODO
    2. -
    -
    -
    \ 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 - -
    -
    - -

    In this document

    -
      - -
    - -
    -
    - - -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
    -
    +
    +

    Topics

    +
      +
    1. Sensors Overview
    2. +
    3. Motion Sensors
    4. +
    5. Position + Sensors
    6. +
    7. Environment + Sensors
    8. +
    +

    Key classes and interfaces

    +
      +
    1. {@link android.hardware.Sensor}
    2. +
    3. {@link android.hardware.SensorEvent}
    4. +
    5. {@link android.hardware.SensorManager}
    6. +
    7. {@link android.hardware.SensorEventListener}
    8. +
    +

    Related samples

    +
      +
    1. Accelerometer + Play
    2. +
    3. +API Demos (OS - RotationVectorDemo)
    4. +
    5. API Demos +(OS - Sensors)
    6. +
    +
    +
    +

    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.

    +

    The Android platform supports four broad categories of sensors:

    -

    Accelerometer

    -

    The accelerometer sensors allow you to detect the various movements of the device.

    +
      +
    • Motion sensors +

      These sensors measure acceleration forces and rotational forces along three axes. This + category includes accelerometers, gravity sensors, gyroscopes, and rotational vector + sensors.

      +
    • +
    • Environmental sensors +

      These sensors measure various environmental parameters, such as ambient air temperature + and pressure, illumination, and humidity. This category includes barometers, photometers, and + thermometers.

      +
    • +
    • Position sensors +

      These sensors measure the physical position of a device. This category includes + orientation sensors and magnetometers.

      +
    • +
    -

    Compass

    -

    The compass provides data on the devices current polar orientation.

    \ No newline at end of file +

    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:

    + +
    +
    Sensors + Overview
    +
    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.
    +
    Motion + Sensors
    +
    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.
    +
    Position + Sensors
    +
    Learn how to use the sensors that provide orientation and compass data, such as the + orientation sensor and the geomagnetic field sensor.
    +
    Environment + Sensors
    +
    Learn how to use the sensors that provide environmental data, such as the light, + humidity, pressure, temperature, and proximity sensors.
    +
    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 + + + +

    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.

    + +

    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.

    + +

    + Table 1. Environment sensors that are supported on the Android platform.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SensorSensor event dataUnits of measureData description
    {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}event.values[0]°CAmbient air temperature.
    {@link android.hardware.Sensor#TYPE_LIGHT}event.values[0]lxIlluminance.
    {@link android.hardware.Sensor#TYPE_PRESSURE}event.values[0]hPa or mbarAmbient air pressure.
    {@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}event.values[0]%Ambient relative humidity.
    {@link android.hardware.Sensor#TYPE_TEMPERATURE}event.values[0]°CDevice temperature.1
    + +

    1 Implementations vary from device to +device. This sensor was deprecated in Android 4.0 (API Level 14).

    + +

    Using the Light, Pressure, and Temperature Sensors

    + +

    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:

    + +
    +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);
    +  }
    +}
    +
    + +

    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.

    + +

    Using the Humidity Sensor

    + +

    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.

    + +

    Dew point

    + +

    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:

    + +
    +                       ln(RH/100%) + m·t/(Tn+t)
    +td(t,RH) = Tn · ------------------------------------
    +                    m - [ln(RH/100%) + m·t/(Tn+t)]
    +
    + +

    Where,

    + +
      +
    • td = dew point temperature in degrees C
    • +
    • t = actual temperature in degrees C
    • +
    • RH = actual relative humidity in percent (%)
    • +
    • m = 17.62
    • +
    • Tn = 243.12
    • +
    + +

    Absolute humidity

    + +

    The absolute humidity is the mass of water vapor in a given volume of dry air. Absolute + humidity is measured in grams/meter3. The following equation shows how you + can calculate the absolute humidity:

    + +
    +                          (RH/100%) · A · exp(m·t/(Tn+t)
    +dv(t,RH) = 216.7 · ------------------------------------
    +                                    273.15 + t
    +
    + +

    Where,

    + +
      +
    • dv = absolute humidity in grams/meter3
    • +
    • t = actual temperature in degrees C
    • +
    • RH = actual relative humidity in percent (%)
    • +
    • m = 17.62
    • +
    • Tn = 243.12 degrees C
    • +
    • A = 6.112 hPa
    • +
    + 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 + +
    +
    +

    In this document

    +
      +
    1. Using the Accelerometer
    2. +
    3. Using the Gravity Sensor
    4. +
    5. Using the Gyroscope
    6. +
    7. Using the Linear Accelerometer
    8. +
    9. Using the Rotation Vector Sensor
    10. +
    +

    Key classes and interfaces

    +
      +
    1. {@link android.hardware.Sensor}
    2. +
    3. {@link android.hardware.SensorEvent}
    4. +
    5. {@link android.hardware.SensorManager}
    6. +
    7. {@link android.hardware.SensorEventListener}
    8. +
    +

    Related samples

    +
      +
    1. Accelerometer + Play
    2. +
    3. +API Demos (OS - RotationVectorDemo)
    4. +
    5. API Demos (OS - Sensors)
    6. +
    +

    See also

    +
      +
    1. Sensors
    2. +
    3. Sensors Overview
    4. +
    5. Position Sensors
    6. +
    7. Environment +Sensors
    8. +
    +
    +
    + +

    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.

    + +

    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 Position Sensors for more +information).

    + +

    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 float 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.

    + +

    + Table 1. Motion sensors that are supported on the Android platform.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SensorSensor event dataDescriptionUnits of measure
    {@link android.hardware.Sensor#TYPE_ACCELEROMETER}SensorEvent.values[0]Acceleration force along the x axis (including gravity).m/s2
    SensorEvent.values[1]Acceleration force along the y axis (including gravity).
    SensorEvent.values[2]Acceleration force along the z axis (including gravity).
    {@link android.hardware.Sensor#TYPE_GRAVITY}SensorEvent.values[0]Force of gravity along the x axis.m/s2
    SensorEvent.values[1]Force of gravity along the y axis.
    SensorEvent.values[2]Force of gravity along the z axis.
    {@link android.hardware.Sensor#TYPE_GYROSCOPE}SensorEvent.values[0]Rate of rotation around the x axis.rad/s
    SensorEvent.values[1]Rate of rotation around the y axis.
    SensorEvent.values[2]Rate of rotation around the z axis.
    {@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}SensorEvent.values[0]Acceleration force along the x axis (excluding gravity).m/s2
    SensorEvent.values[1]Acceleration force along the y axis (excluding gravity).
    SensorEvent.values[2]Acceleration force along the z axis (excluding gravity).
    {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}SensorEvent.values[0]Rotation vector component along the x axis (x * sin(θ/2)).Unitless
    SensorEvent.values[1]Rotation vector component along the y axis (y * sin(θ/2)).
    SensorEvent.values[2]Rotation vector component along the z axis (z * sin(θ/2)).
    SensorEvent.values[3]Scalar component of the rotation vector ((cos(θ/2)).1
    + +

    1 The scalar component is an optional value.

    + +

    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.

    + +

    Android Open Source Project Sensors

    + +

    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.

    + +

    Using the Accelerometer

    + +

    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:

    + +
    +private SensorManager mSensorManager;
    +private Sensor mSensor;
    +  ...
    +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    +mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    +
    + +

    Conceptually, an acceleration sensor determines the acceleration that is applied +to a device (Ad) by measuring the forces that are applied to the sensor +itself (Fs) using the following relationship:

    + +
    +Ad = - ∑Fs / mass
    +
    + +

    However, the force of gravity is always influencing the measured acceleration according to +the following relationship:

    + +
    +Ad = -g - ∑F / mass
    +
    + +

    For this reason, when the device is sitting on a table (and not accelerating), the +accelerometer reads a magnitude of g = 9.81 m/s2. Similarly, when the device is in +free fall and therefore rapidly accelerating toward the ground at 9.81 m/s2, its +accelerometer reads a magnitude of g = 0 m/s2. 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:

    + +
    +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];
    +}
    +
    + +

    Note: 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.

    + +

    Accelerometers use the standard sensor coordinate +system. In practice, this means that the following conditions apply when a device is laying +flat on a table in its natural orientation:

    + +
      +
    • If you push the device on the left side (so it moves to the right), the x acceleration value +is positive.
    • +
    • If you push the device on the bottom (so it moves away from you), the y acceleration value is +positive.
    • +
    • If you push the device toward the sky with an acceleration of A m/s2, the +z acceleration value is equal to A + 9.81, which corresponds to the acceleration of the device (+A +m/s2) minus the force of gravity (-9.81 m/s2).
    • +
    • The stationary device will have an acceleration value of +9.81, which corresponds to the +acceleration of the device (0 m/s2 minus the force of gravity, which is -9.81 +m/s2).
    • +
    + +

    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.

    + +

    The Android SDK provides a sample application that shows how to use the acceleration sensor (Accelerometer Play).

    + +

    Using the Gravity Sensor

    + +

    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:

    + +
    +private SensorManager mSensorManager;
    +private Sensor mSensor;
    +...
    +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    +mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
    +
    + +

    The units are the same as those used by the acceleration +sensor (m/s2), and the coordinate system is the same as the one used by the +acceleration sensor.

    + +

    Note: When a device is at rest, the output of the gravity sensor +should be identical to that of the accelerometer.

    + +

    Using the Gyroscope

    +

    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:

    + +
    +private SensorManager mSensorManager;
    +private Sensor mSensor;
    +...
    +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    +mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
    +
    + +

    The sensor's coordinate system +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.

    + +

    Usually, the output of the gyroscope is integrated over time to calculate a rotation describing +the change of angles over the timestep. For example:

    + +
    +// 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;
    +   }
    +}
    + 
    + +

    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.

    + +

    Using the Linear Accelerometer

    + +

    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:

    + +
    +private SensorManager mSensorManager;
    +private Sensor mSensor;
    +...
    +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    +mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
    +
    + +

    Conceptually, this sensor provides you with acceleration data according to the following +relationship:

    + +
    +linear acceleration = acceleration - acceleration due to gravity
    +
    + +

    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.

    + +

    The sensor coordinate +system is the same as the one used by the acceleration sensor, as are the units of measure +(m/s2). + +

    Using the Rotation Vector Sensor

    + +

    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:

    + +
    +private SensorManager mSensorManager;
    +private Sensor mSensor;
    +...
    +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    +mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
    +
    + +

    The three elements of the rotation vector are expressed as follows:

    + +
    +x*sin(θ/2)
    +y*sin(θ/2)
    +z*sin(θ/2)
    +
    + +

    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.

    + +
    + +

    + Figure 1. Coordinate system used by the rotation vector sensor. +

    +
    + +

    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:

    + +
      +
    • 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.
    • +
    • Y is tangential to the ground at the device's current location and points toward the +geomagnetic +North Pole.
    • +
    • Z points toward the sky and is perpendicular to the ground plane.
    • +
    + +

    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 ( +OS - RotationVectorDemo).

    \ 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 + +
    +
    +

    Quickview

    +
      +
    • Learn about the sensors that Android supports and the Android sensor framework.
    • +
    • Find out how to list sensors, determine sensor capabilities, and monitor sensor data.
    • +
    • Learn about best practices for accessing and using sensors.
    • +
    +

    In this document

    +
      +
    1. Introduction to Sensors
    2. +
    3. Identifying Sensors and Sensor Capabilities
    4. +
    5. Monitoring Sensor Events
    6. +
    7. Handling Different Sensor Configurations
    8. +
    9. Sensor Coordinate System
    10. +
    11. Best Practices for Accessing and Using Sensors
    12. +
    +

    Key classes and interfaces

    +
      +
    1. {@link android.hardware.Sensor}
    2. +
    3. {@link android.hardware.SensorEvent}
    4. +
    5. {@link android.hardware.SensorManager}
    6. +
    7. {@link android.hardware.SensorEventListener}
    8. +
    +

    Related samples

    +
      +
    1. Accelerometer + Play
    2. +
    3. +API Demos (OS - RotationVectorDemo)
    4. +
    5. API Demos +(OS - Sensors)
    6. +
    +

    See also

    +
      +
    1. Sensors
    2. +
    3. Motion Sensors
    4. +
    5. Position + Sensors
    6. +
    7. Environment + Sensors
    8. +
    +
    +
    + +

    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.

    + +

    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:

    + +
      +
    • Determine which sensors are available on a device.
    • +
    • Determine an individual sensor's capabilities, such as its maximum range, manufacturer, power + requirements, and resolution.
    • +
    • Acquire raw sensor data and define the minimum rate at which you acquire sensor data.
    • +
    • Register and unregister sensor event listeners that monitor sensor changes.
    • +
    + +

    This topic provides an overview of the sensors that are available on the Android platform. +It also provides an introduction to the sensor framework.

    + +

    Introduction to Sensors

    + +

    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.

    + +

    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.

    + +

    + Table 1. Sensor types supported by the Android platform.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SensorTypeDescriptionCommon Uses
    {@link android.hardware.Sensor#TYPE_ACCELEROMETER}HardwareMeasures the acceleration force in m/s2 that is applied to a device on +all three physical axes (x, y, and z), including the force of gravity.Motion detection (shake, tilt, etc.).
    {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}HardwareMeasures the ambient room temperature in degrees Celsius (°C). See note below.Monitoring air temperatures.
    {@link android.hardware.Sensor#TYPE_GRAVITY}Software or HardwareMeasures the force of gravity in m/s2 that is applied to a device on all + three physical axes (x, y, z).Motion detection (shake, tilt, etc.).
    {@link android.hardware.Sensor#TYPE_GYROSCOPE}HardwareMeasures a device's rate of rotation in rad/s around each of the three +physical axes + (x, y, and z).Rotation detection (spin, turn, etc.).
    {@link android.hardware.Sensor#TYPE_LIGHT}HardwareMeasures the ambient light level (illumination) in lx.Controlling screen brightness.
    {@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}Software or HardwareMeasures the acceleration force in m/s2 that is +applied to a device on + all three physical axes (x, y, and z), excluding the force of gravity.Monitoring acceleration along a single axis.
    {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}HardwareMeasures the ambient geomagnetic field for all three physical axes (x, y, z) in +μT.Creating a compass.
    {@link android.hardware.Sensor#TYPE_ORIENTATION}SoftwareMeasures 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.Determining device position.
    {@link android.hardware.Sensor#TYPE_PRESSURE}HardwareMeasures the ambient air pressure in hPa or mbar.Monitoring air pressure changes.
    {@link android.hardware.Sensor#TYPE_PROXIMITY}HardwareMeasures 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.Phone position during a call.
    {@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}HardwareMeasures the relative ambient humidity in percent (%).Monitoring dewpoint, absolute, and relative humidity.
    {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}Software or HardwareMeasures the orientation of a device by providing the three elements of the device's + rotation vector.Motion detection and rotation detection.
    {@link android.hardware.Sensor#TYPE_TEMPERATURE}HardwareMeasures 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 14Monitoring temperatures.
    + +

    Sensor Framework

    + +

    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:

    + +
    +
    {@link android.hardware.SensorManager}
    +
    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.
    +
    {@link android.hardware.Sensor}
    +
    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.
    +
    {@link android.hardware.SensorEvent}
    +
    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.
    +
    {@link android.hardware.SensorEventListener}
    +
    You can use this interface to create two callback methods that receive notifications (sensor +events) when sensor values change or when sensor accuracy changes.
    +
    + +

    In a typical application you use these sensor-related APIs to perform two basic tasks:

    + +
      +
    • Identifying sensors and sensor capabilities +

      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.

      +
    • +
    • Monitor sensor events +

      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.

      +
    • +
    + +

    Sensor Availability

    + +

    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.

    + +

    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.

    + +

    + Table 2. Sensor availability by platform.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SensorAndroid 4.0
    (API Level 14)
    Android 2.3
    (API Level 9)
    Android 2.2
    (API Level 8)
    Android 1.5
    (API Level 3)
    {@link android.hardware.Sensor#TYPE_ACCELEROMETER}YesYesYesYes
    {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}Yesn/an/an/a
    {@link android.hardware.Sensor#TYPE_GRAVITY}YesYesn/an/a
    {@link android.hardware.Sensor#TYPE_GYROSCOPE}YesYesn/a1n/a1
    {@link android.hardware.Sensor#TYPE_LIGHT}YesYesYesYes
    {@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}YesYesn/an/a
    {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}YesYesYesYes
    {@link android.hardware.Sensor#TYPE_ORIENTATION}Yes2Yes2Yes2Yes
    {@link android.hardware.Sensor#TYPE_PRESSURE}YesYesn/a1n/a1
    {@link android.hardware.Sensor#TYPE_PROXIMITY}YesYesYesYes
    {@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}Yesn/an/an/a
    {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}YesYesn/an/a
    {@link android.hardware.Sensor#TYPE_TEMPERATURE}Yes2YesYesYes
    + +

    1 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).

    + +

    2 This sensor is available, but it has been +deprecated.

    + +

    Identifying Sensors and Sensor Capabilities

    + +

    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.

    + +

    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:

    + +
    +private SensorManager mSensorManager;
    +...
    +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    +
    + +

    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:

    +
    +List<Sensor> deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
    +
    + +

    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}. +

    + +

    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:

    +
    +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.
    +  }
    +
    + +

    Note: 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.

    + +

    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.

    + +

    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.

    + +
    +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.
    +  }
    +}
    +
    + +

    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.

    + +

    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.

    + +

    Caution: 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 Monitoring Sensor Events.

    + +

    Monitoring Sensor Events

    + +

    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:

    + +
      +
    • A sensor's accuracy changes. +

      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}.

      +
    • +
    • A sensor reports a new value. +

      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.

      +
    • +
    + +

    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 sensor_data.

    + +
    +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);
    +  }
    +}
    +
    + +

    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).

    + +

    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.

    + +

    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.

    + +

    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.

    + +

    Handling Different Sensor Configurations

    + +

    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:

    +
      +
    • Detect sensors at runtime and enable or disable application features as appropriate.
    • +
    • Use Android Market filters to target devices with specific sensor configurations.
    • +
    + +

    Each option is discussed in the following sections.

    + +

    Detecting sensors at runtime

    + +

    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:

    +
    +  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.
    +  }
    +
    + +

    Using Android Market filters to target specific sensor configurations

    + +

    If you are publishing your application on Android Market you can use the + <uses-feature> + element in your manifest file to filter your application from devices that do not +have the appropriate sensor configuration for your application. The +<uses-feature> 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:

    + +
    +<uses-feature android:name="android.hardware.sensor.accelerometer"
    +              android:required="true" />
    +
    + +

    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.

    + +

    You should set the descriptor to android:required="true" 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 <uses-feature> +element, but set the descriptor to android:required="false". 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.

    + +

    Sensor Coordinate System

    + +

    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:

    + +
    + +

    + Figure 1. Coordinate system (relative to a device) that's used by the Sensor + API. +

    +
    + + + +

    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.

    + +

    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.

    + +

    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.

    + +

    For more information about the sensor coordinate system, including information about how to +handle screen rotations, see One +Screen Turn Deserves Another.

    + +

    Note: 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, Orientation +Sensor, and Rotation Vector +Sensor.

    + +

    Best Practices for Accessing and Using Sensors

    + +

    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.

    + +

    Unregister sensor listeners

    + +

    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:

    + +
    +private SensorManager mSensorManager;
    +  ...
    +@Override
    +protected void onPause() {
    +  super.onPause();
    +  mSensorManager.unregisterListener(this);
    +}
    +
    + +

    For more information, see {@link android.hardware.SensorManager#unregisterListener}.

    + +

    Don't test your code on the emulator

    + +

    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.

    + +

    Don't block the onSensorChanged() method

    + +

    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.

    + +

    Avoid using deprecated methods or sensor types

    + +

    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.

    + +

    Verify sensors before you use them

    + +

    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.

    + +

    Choose sensor delays carefully

    + +

    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.

    \ 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 + +
    +
    +

    In this document

    +
      +
    1. Using the Orientation Sensor
    2. +
    3. Using the Geomagnetic Field Sensor
    4. +
    5. Using the Proximity Sensor
    6. +
    +

    Key classes and interfaces

    +
      +
    1. {@link android.hardware.Sensor}
    2. +
    3. {@link android.hardware.SensorEvent}
    4. +
    5. {@link android.hardware.SensorManager}
    6. +
    7. {@link android.hardware.SensorEventListener}
    8. +
    +

    Related samples

    +
      +
    1. Accelerometer + Play
    2. +
    3. +API Demos (OS - RotationVectorDemo)
    4. +
    5. API Demos +(OS - Sensors)
    6. +
    +

    See also

    +
      +
    1. Sensors
    2. +
    3. Sensors Overview
    4. +
    5. Motion + Sensors
    6. +
    7. Environment + Sensors
    8. +
    +
    +
    + +

    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.

    + +

    Note: The orientation sensor was deprecated in Android 2.2 (API +Level 8).

    + +

    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 Motion Sensors).

    + +

    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 Sensor Coordinate +Systems. The proximity sensor provides a single value for each sensor event. Table 1 summarizes +the position sensors that are supported on the Android platform.

    + +

    + Table 1. Position sensors that are supported on the Android platform.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SensorSensor event dataDescriptionUnits of measure
    {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}SensorEvent.values[0]Geomagnetic field strength along the x axis.μT
    SensorEvent.values[1]Geomagnetic field strength along the y axis.
    SensorEvent.values[2]Geomagnetic field strength along the z axis.
    {@link android.hardware.Sensor#TYPE_ORIENTATION}1SensorEvent.values[0]Azimuth (angle around the z-axis).Degrees
    SensorEvent.values[1]Pitch (angle around the x-axis).
    SensorEvent.values[2]Roll (angle around the y-axis).
    {@link android.hardware.Sensor#TYPE_PROXIMITY}SensorEvent.values[0]Distance from object.2cm
    + +

    1 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 Using the Orientation Sensor.

    + +

    2 Some proximity sensors provide only binary values +representing near and far.

    + +

    Using the Orientation Sensor

    + +

    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 :

    + +
    +private SensorManager mSensorManager;
    +private Sensor mSensor;
    +...
    +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    +mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
    +
    + +

    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:

    + +
      +
    • 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.
    • +
    • 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.
    • +
    • 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.
    • +
    + +

    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).

    + +

    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.

    + +

    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.

    + +
    +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.
    +  }
    +}
    +
    + +

    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 Accelerometer Play 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.

    + +

    Using the Geomagnetic Field Sensor

    + +

    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:

    + +
    +private SensorManager mSensorManager;
    +private Sensor mSensor;
    +...
    +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    +mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    +
    + +

    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.

    + +

    Using the Proximity Sensor

    +

    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:

    + +
    +private SensorManager mSensorManager;
    +private Sensor mSensor;
    +...
    +mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    +mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    +
    + +

    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:

    + +
    +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);
    +  }
    +}
    +
    + +

    Note: 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.

    \ No newline at end of file -- cgit v1.1