1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.hardware; 18 19 import android.annotation.NonNull; 20 import android.compat.annotation.UnsupportedAppUsage; 21 22 /** 23 * This class represents a {@link android.hardware.Sensor Sensor} event and 24 * holds information such as the sensor's type, the time-stamp, accuracy and of 25 * course the sensor's {@link SensorEvent#values data}. 26 * 27 * <p> 28 * <u>Definition of the coordinate system used by the SensorEvent API.</u> 29 * </p> 30 * 31 * <p> 32 * The coordinate-system is defined relative to the screen of the phone in its 33 * default orientation. The axes are not swapped when the device's screen 34 * orientation changes. 35 * </p> 36 * 37 * <p> 38 * The X axis is horizontal and points to the right, the Y axis is vertical and 39 * points up and the Z axis points towards the outside of the front face of the 40 * screen. In this system, coordinates behind the screen have negative Z values. 41 * </p> 42 * 43 * <p> 44 * <center><img src="../../../images/axis_device.png" 45 * alt="Sensors coordinate-system diagram." border="0" /></center> 46 * </p> 47 * 48 * <p> 49 * <b>Note:</b> This coordinate system is different from the one used in the 50 * Android 2D APIs where the origin is in the top-left corner. 51 * </p> 52 * 53 * @see SensorManager 54 * @see SensorEvent 55 * @see Sensor 56 * 57 */ 58 59 public class SensorEvent { 60 /** 61 * <p> 62 * The length and contents of the {@link #values values} array depends on 63 * which {@link android.hardware.Sensor sensor} type is being monitored (see 64 * also {@link SensorEvent} for a definition of the coordinate system used). 65 * </p> 66 * 67 * <h4>{@link android.hardware.Sensor#TYPE_ACCELEROMETER 68 * Sensor.TYPE_ACCELEROMETER}:</h4> All values are in SI units (m/s^2) 69 * 70 * <ul> 71 * <li> values[0]: Acceleration minus Gx on the x-axis </li> 72 * <li> values[1]: Acceleration minus Gy on the y-axis </li> 73 * <li> values[2]: Acceleration minus Gz on the z-axis </li> 74 * </ul> 75 * 76 * <p> 77 * A sensor of this type measures the acceleration applied to the device 78 * (<b>Ad</b>). Conceptually, it does so by measuring forces applied to the 79 * sensor itself (<b>Fs</b>) using the relation: 80 * </p> 81 * 82 * <b><center>Ad = - ∑Fs / mass</center></b> 83 * 84 * <p> 85 * In particular, the force of gravity is always influencing the measured 86 * acceleration: 87 * </p> 88 * 89 * <b><center>Ad = -g - ∑F / mass</center></b> 90 * 91 * <p> 92 * For this reason, when the device is sitting on a table (and obviously not 93 * accelerating), the accelerometer reads a magnitude of <b>g</b> = 9.81 94 * m/s^2 95 * </p> 96 * 97 * <p> 98 * Similarly, when the device is in free-fall and therefore dangerously 99 * accelerating towards to ground at 9.81 m/s^2, its accelerometer reads a 100 * magnitude of 0 m/s^2. 101 * </p> 102 * 103 * <p> 104 * It should be apparent that in order to measure the real acceleration of 105 * the device, the contribution of the force of gravity must be eliminated. 106 * This can be achieved by applying a <i>high-pass</i> filter. Conversely, a 107 * <i>low-pass</i> filter can be used to isolate the force of gravity. 108 * </p> 109 * 110 * <pre class="prettyprint"> 111 * 112 * public void onSensorChanged(SensorEvent event) 113 * { 114 * // alpha is calculated as t / (t + dT) 115 * // with t, the low-pass filter's time-constant 116 * // and dT, the event delivery rate 117 * 118 * final float alpha = 0.8; 119 * 120 * gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0]; 121 * gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1]; 122 * gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2]; 123 * 124 * linear_acceleration[0] = event.values[0] - gravity[0]; 125 * linear_acceleration[1] = event.values[1] - gravity[1]; 126 * linear_acceleration[2] = event.values[2] - gravity[2]; 127 * } 128 * </pre> 129 * 130 * <p> 131 * <u>Examples</u>: 132 * <ul> 133 * <li>When the device lies flat on a table and is pushed on its left side 134 * toward the right, the x acceleration value is positive.</li> 135 * 136 * <li>When the device lies flat on a table, the acceleration value is 137 * +9.81, which correspond to the acceleration of the device (0 m/s^2) minus 138 * the force of gravity (-9.81 m/s^2).</li> 139 * 140 * <li>When the device lies flat on a table and is pushed toward the sky 141 * with an acceleration of A m/s^2, the acceleration value is equal to 142 * A+9.81 which correspond to the acceleration of the device (+A m/s^2) 143 * minus the force of gravity (-9.81 m/s^2).</li> 144 * </ul> 145 * 146 * 147 * <h4>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD 148 * Sensor.TYPE_MAGNETIC_FIELD}:</h4> 149 * All values are in micro-Tesla (uT) and measure the ambient magnetic field 150 * in the X, Y and Z axis. 151 * 152 * <h4>{@link android.hardware.Sensor#TYPE_GYROSCOPE Sensor.TYPE_GYROSCOPE}: 153 * </h4> All values are in radians/second and measure the rate of rotation 154 * around the device's local X, Y and Z axis. The coordinate system is the 155 * same as is used for the acceleration sensor. Rotation is positive in the 156 * counter-clockwise direction. That is, an observer looking from some 157 * positive location on the x, y or z axis at a device positioned on the 158 * origin would report positive rotation if the device appeared to be 159 * rotating counter clockwise. Note that this is the standard mathematical 160 * definition of positive rotation and does not agree with the definition of 161 * roll given earlier. 162 * <ul> 163 * <li> values[0]: Angular speed around the x-axis </li> 164 * <li> values[1]: Angular speed around the y-axis </li> 165 * <li> values[2]: Angular speed around the z-axis </li> 166 * </ul> 167 * <p> 168 * Typically the output of the gyroscope is integrated over time to 169 * calculate a rotation describing the change of angles over the time step, 170 * for example: 171 * </p> 172 * 173 * <pre class="prettyprint"> 174 * private static final float NS2S = 1.0f / 1000000000.0f; 175 * private final float[] deltaRotationVector = new float[4](); 176 * private float timestamp; 177 * 178 * public void onSensorChanged(SensorEvent event) { 179 * // This time step's delta rotation to be multiplied by the current rotation 180 * // after computing it from the gyro sample data. 181 * if (timestamp != 0) { 182 * final float dT = (event.timestamp - timestamp) * NS2S; 183 * // Axis of the rotation sample, not normalized yet. 184 * float axisX = event.values[0]; 185 * float axisY = event.values[1]; 186 * float axisZ = event.values[2]; 187 * 188 * // Calculate the angular speed of the sample 189 * float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ); 190 * 191 * // Normalize the rotation vector if it's big enough to get the axis 192 * if (omegaMagnitude > EPSILON) { 193 * axisX /= omegaMagnitude; 194 * axisY /= omegaMagnitude; 195 * axisZ /= omegaMagnitude; 196 * } 197 * 198 * // Integrate around this axis with the angular speed by the time step 199 * // in order to get a delta rotation from this sample over the time step 200 * // We will convert this axis-angle representation of the delta rotation 201 * // into a quaternion before turning it into the rotation matrix. 202 * float thetaOverTwo = omegaMagnitude * dT / 2.0f; 203 * float sinThetaOverTwo = sin(thetaOverTwo); 204 * float cosThetaOverTwo = cos(thetaOverTwo); 205 * deltaRotationVector[0] = sinThetaOverTwo * axisX; 206 * deltaRotationVector[1] = sinThetaOverTwo * axisY; 207 * deltaRotationVector[2] = sinThetaOverTwo * axisZ; 208 * deltaRotationVector[3] = cosThetaOverTwo; 209 * } 210 * timestamp = event.timestamp; 211 * float[] deltaRotationMatrix = new float[9]; 212 * SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector); 213 * // User code should concatenate the delta rotation we computed with the current 214 * // rotation in order to get the updated rotation. 215 * // rotationCurrent = rotationCurrent * deltaRotationMatrix; 216 * } 217 * </pre> 218 * <p> 219 * In practice, the gyroscope noise and offset will introduce some errors 220 * which need to be compensated for. This is usually done using the 221 * information from other sensors, but is beyond the scope of this document. 222 * </p> 223 * <h4>{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:</h4> 224 * <ul> 225 * <li>values[0]: Ambient light level in SI lux units </li> 226 * </ul> 227 * 228 * <h4>{@link android.hardware.Sensor#TYPE_PRESSURE Sensor.TYPE_PRESSURE}:</h4> 229 * <ul> 230 * <li>values[0]: Atmospheric pressure in hPa (millibar) </li> 231 * </ul> 232 * 233 * <h4>{@link android.hardware.Sensor#TYPE_PROXIMITY Sensor.TYPE_PROXIMITY}: 234 * </h4> 235 * 236 * <ul> 237 * <li>values[0]: Proximity sensor distance measured in centimeters </li> 238 * </ul> 239 * 240 * <p> 241 * <b>Note:</b> Some proximity sensors only support a binary <i>near</i> or 242 * <i>far</i> measurement. In this case, the sensor should report its 243 * {@link android.hardware.Sensor#getMaximumRange() maximum range} value in 244 * the <i>far</i> state and a lesser value in the <i>near</i> state. 245 * </p> 246 * 247 * <h4>{@link android.hardware.Sensor#TYPE_GRAVITY Sensor.TYPE_GRAVITY}:</h4> 248 * <p>A three dimensional vector indicating the direction and magnitude of gravity. Units 249 * are m/s^2. The coordinate system is the same as is used by the acceleration sensor.</p> 250 * <p><b>Note:</b> When the device is at rest, the output of the gravity sensor should be 251 * identical to that of the accelerometer.</p> 252 * 253 * <h4> 254 * {@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION Sensor.TYPE_LINEAR_ACCELERATION}: 255 * </h4> A three dimensional vector indicating acceleration along each device axis, not 256 * including gravity. All values have units of m/s^2. The coordinate system is the same as is 257 * used by the acceleration sensor. 258 * <p>The output of the accelerometer, gravity and linear-acceleration sensors must obey the 259 * following relation:</p> 260 * <p><ul>acceleration = gravity + linear-acceleration</ul></p> 261 * 262 * <h4>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR Sensor.TYPE_ROTATION_VECTOR}:</h4> 263 * <p>The rotation vector represents the orientation of the device as a combination of an 264 * <i>angle</i> and an <i>axis</i>, in which the device has rotated through an angle θ 265 * around an axis <x, y, z>.</p> 266 * <p>The three elements of the rotation vector are 267 * <x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)>, such that the magnitude of the rotation 268 * vector is equal to sin(θ/2), and the direction of the rotation vector is equal to the 269 * direction of the axis of rotation.</p> 270 * </p>The three elements of the rotation vector are equal to 271 * the last three components of a <b>unit</b> quaternion 272 * <cos(θ/2), x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)>.</p> 273 * <p>Elements of the rotation vector are unitless. 274 * The x,y, and z axis are defined in the same way as the acceleration 275 * sensor.</p> 276 * The reference coordinate system is defined as a direct orthonormal basis, 277 * where: 278 * </p> 279 * 280 * <ul> 281 * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to 282 * the ground at the device's current location and roughly points East).</li> 283 * <li>Y is tangential to the ground at the device's current location and 284 * points towards magnetic north.</li> 285 * <li>Z points towards the sky and is perpendicular to the ground.</li> 286 * </ul> 287 * 288 * <p> 289 * <center><img src="../../../images/axis_globe.png" 290 * alt="World coordinate-system diagram." border="0" /></center> 291 * </p> 292 * 293 * <ul> 294 * <li> values[0]: x*sin(θ/2) </li> 295 * <li> values[1]: y*sin(θ/2) </li> 296 * <li> values[2]: z*sin(θ/2) </li> 297 * <li> values[3]: cos(θ/2) </li> 298 * <li> values[4]: estimated heading Accuracy (in radians) (-1 if unavailable)</li> 299 * </ul> 300 * <p> values[3], originally optional, will always be present from SDK Level 18 onwards. 301 * values[4] is a new value that has been added in SDK Level 18. 302 * </p> 303 * 304 * <h4>{@link android.hardware.Sensor#TYPE_ORIENTATION 305 * Sensor.TYPE_ORIENTATION}:</h4> All values are angles in degrees. 306 * 307 * <ul> 308 * <li> values[0]: Azimuth, angle between the magnetic north direction and the 309 * y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South, 310 * 270=West 311 * </p> 312 * 313 * <p> 314 * values[1]: Pitch, rotation around x-axis (-180 to 180), with positive 315 * values when the z-axis moves <b>toward</b> the y-axis. 316 * </p> 317 * 318 * <p> 319 * values[2]: Roll, rotation around the y-axis (-90 to 90) 320 * increasing as the device moves clockwise. 321 * </p> 322 * </ul> 323 * 324 * <p> 325 * <b>Note:</b> This definition is different from <b>yaw, pitch and roll</b> 326 * used in aviation where the X axis is along the long side of the plane 327 * (tail to nose). 328 * </p> 329 * 330 * <p> 331 * <b>Note:</b> This sensor type exists for legacy reasons, please use 332 * {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR 333 * rotation vector sensor type} and 334 * {@link android.hardware.SensorManager#getRotationMatrix 335 * getRotationMatrix()} in conjunction with 336 * {@link android.hardware.SensorManager#remapCoordinateSystem 337 * remapCoordinateSystem()} and 338 * {@link android.hardware.SensorManager#getOrientation getOrientation()} to 339 * compute these values instead. 340 * </p> 341 * 342 * <p> 343 * <b>Important note:</b> For historical reasons the roll angle is positive 344 * in the clockwise direction (mathematically speaking, it should be 345 * positive in the counter-clockwise direction). 346 * </p> 347 * 348 * <h4>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY 349 * Sensor.TYPE_RELATIVE_HUMIDITY}:</h4> 350 * <ul> 351 * <li> values[0]: Relative ambient air humidity in percent </li> 352 * </ul> 353 * <p> 354 * When relative ambient air humidity and ambient temperature are 355 * measured, the dew point and absolute humidity can be calculated. 356 * </p> 357 * <u>Dew Point</u> 358 * <p> 359 * The dew point is the temperature to which a given parcel of air must be 360 * cooled, at constant barometric pressure, for water vapor to condense 361 * into water. 362 * </p> 363 * <center><pre> 364 * ln(RH/100%) + m·t/(T<sub>n</sub>+t) 365 * t<sub>d</sub>(t,RH) = T<sub>n</sub> · ------------------------------ 366 * m - [ln(RH/100%) + m·t/(T<sub>n</sub>+t)] 367 * </pre></center> 368 * <dl> 369 * <dt>t<sub>d</sub></dt> <dd>dew point temperature in °C</dd> 370 * <dt>t</dt> <dd>actual temperature in °C</dd> 371 * <dt>RH</dt> <dd>actual relative humidity in %</dd> 372 * <dt>m</dt> <dd>17.62</dd> 373 * <dt>T<sub>n</sub></dt> <dd>243.12 °C</dd> 374 * </dl> 375 * <p>for example:</p> 376 * <pre class="prettyprint"> 377 * h = Math.log(rh / 100.0) + (17.62 * t) / (243.12 + t); 378 * td = 243.12 * h / (17.62 - h); 379 * </pre> 380 * <u>Absolute Humidity</u> 381 * <p> 382 * The absolute humidity is the mass of water vapor in a particular volume 383 * of dry air. The unit is g/m<sup>3</sup>. 384 * </p> 385 * <center><pre> 386 * RH/100%·A·exp(m·t/(T<sub>n</sub>+t)) 387 * d<sub>v</sub>(t,RH) = 216.7 · ------------------------- 388 * 273.15 + t 389 * </pre></center> 390 * <dl> 391 * <dt>d<sub>v</sub></dt> <dd>absolute humidity in g/m<sup>3</sup></dd> 392 * <dt>t</dt> <dd>actual temperature in °C</dd> 393 * <dt>RH</dt> <dd>actual relative humidity in %</dd> 394 * <dt>m</dt> <dd>17.62</dd> 395 * <dt>T<sub>n</sub></dt> <dd>243.12 °C</dd> 396 * <dt>A</dt> <dd>6.112 hPa</dd> 397 * </dl> 398 * <p>for example:</p> 399 * <pre class="prettyprint"> 400 * dv = 216.7 * 401 * (rh / 100.0 * 6.112 * Math.exp(17.62 * t / (243.12 + t)) / (273.15 + t)); 402 * </pre> 403 * 404 * <h4>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE Sensor.TYPE_AMBIENT_TEMPERATURE}: 405 * </h4> 406 * 407 * <ul> 408 * <li> values[0]: ambient (room) temperature in degree Celsius.</li> 409 * </ul> 410 * 411 * 412 * <h4>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD_UNCALIBRATED 413 * Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED}:</h4> 414 * Similar to {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}, 415 * but the hard iron calibration is reported separately instead of being included 416 * in the measurement. Factory calibration and temperature compensation will still 417 * be applied to the "uncalibrated" measurement. Assumptions that the magnetic field 418 * is due to the Earth's poles is avoided. 419 * <p> 420 * The values array is shown below: 421 * <ul> 422 * <li> values[0] = x_uncalib </li> 423 * <li> values[1] = y_uncalib </li> 424 * <li> values[2] = z_uncalib </li> 425 * <li> values[3] = x_bias </li> 426 * <li> values[4] = y_bias </li> 427 * <li> values[5] = z_bias </li> 428 * </ul> 429 * </p> 430 * <p> 431 * x_uncalib, y_uncalib, z_uncalib are the measured magnetic field in X, Y, Z axes. 432 * Soft iron and temperature calibrations are applied. But the hard iron 433 * calibration is not applied. The values are in micro-Tesla (uT). 434 * </p> 435 * <p> 436 * x_bias, y_bias, z_bias give the iron bias estimated in X, Y, Z axes. 437 * Each field is a component of the estimated hard iron calibration. 438 * The values are in micro-Tesla (uT). 439 * </p> 440 * <p> Hard iron - These distortions arise due to the magnetized iron, steel or permanent 441 * magnets on the device. 442 * Soft iron - These distortions arise due to the interaction with the earth's magnetic 443 * field. 444 * </p> 445 * <h4> {@link android.hardware.Sensor#TYPE_GAME_ROTATION_VECTOR 446 * Sensor.TYPE_GAME_ROTATION_VECTOR}:</h4> 447 * Identical to {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR} except that it 448 * doesn't use the geomagnetic field. Therefore the Y axis doesn't 449 * point north, but instead to some other reference, that reference is 450 * allowed to drift by the same order of magnitude as the gyroscope 451 * drift around the Z axis. 452 * <p> 453 * In the ideal case, a phone rotated and returning to the same real-world 454 * orientation will report the same game rotation vector 455 * (without using the earth's geomagnetic field). However, the orientation 456 * may drift somewhat over time. See {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR} 457 * for a detailed description of the values. This sensor will not have 458 * the estimated heading accuracy value. 459 * </p> 460 * 461 * <h4> {@link android.hardware.Sensor#TYPE_GYROSCOPE_UNCALIBRATED 462 * Sensor.TYPE_GYROSCOPE_UNCALIBRATED}:</h4> 463 * All values are in radians/second and measure the rate of rotation 464 * around the X, Y and Z axis. An estimation of the drift on each axis is 465 * reported as well. 466 * <p> 467 * No gyro-drift compensation is performed. Factory calibration and temperature 468 * compensation is still applied to the rate of rotation (angular speeds). 469 * </p> 470 * <p> 471 * The coordinate system is the same as is used for the 472 * {@link android.hardware.Sensor#TYPE_ACCELEROMETER} 473 * Rotation is positive in the counter-clockwise direction (right-hand rule). 474 * That is, an observer looking from some positive location on the x, y or z axis 475 * at a device positioned on the origin would report positive rotation if the device 476 * appeared to be rotating counter clockwise. 477 * The range would at least be 17.45 rad/s (ie: ~1000 deg/s). 478 * <ul> 479 * <li> values[0] : angular speed (w/o drift compensation) around the X axis in rad/s </li> 480 * <li> values[1] : angular speed (w/o drift compensation) around the Y axis in rad/s </li> 481 * <li> values[2] : angular speed (w/o drift compensation) around the Z axis in rad/s </li> 482 * <li> values[3] : estimated drift around X axis in rad/s </li> 483 * <li> values[4] : estimated drift around Y axis in rad/s </li> 484 * <li> values[5] : estimated drift around Z axis in rad/s </li> 485 * </ul> 486 * </p> 487 * <p><b>Pro Tip:</b> Always use the length of the values array while performing operations 488 * on it. In earlier versions, this used to be always 3 which has changed now. </p> 489 * 490 * <h4>{@link android.hardware.Sensor#TYPE_POSE_6DOF 491 * Sensor.TYPE_POSE_6DOF}:</h4> 492 * 493 * A TYPE_POSE_6DOF event consists of a rotation expressed as a quaternion and a translation 494 * expressed in SI units. The event also contains a delta rotation and translation that show 495 * how the device?s pose has changed since the previous sequence numbered pose. 496 * The event uses the cannonical Android Sensor axes. 497 * 498 * 499 * <ul> 500 * <li> values[0]: x*sin(θ/2) </li> 501 * <li> values[1]: y*sin(θ/2) </li> 502 * <li> values[2]: z*sin(θ/2) </li> 503 * <li> values[3]: cos(θ/2) </li> 504 * 505 * 506 * <li> values[4]: Translation along x axis from an arbitrary origin. </li> 507 * <li> values[5]: Translation along y axis from an arbitrary origin. </li> 508 * <li> values[6]: Translation along z axis from an arbitrary origin. </li> 509 * 510 * <li> values[7]: Delta quaternion rotation x*sin(θ/2) </li> 511 * <li> values[8]: Delta quaternion rotation y*sin(θ/2) </li> 512 * <li> values[9]: Delta quaternion rotation z*sin(θ/2) </li> 513 * <li> values[10]: Delta quaternion rotation cos(θ/2) </li> 514 * 515 * <li> values[11]: Delta translation along x axis. </li> 516 * <li> values[12]: Delta translation along y axis. </li> 517 * <li> values[13]: Delta translation along z axis. </li> 518 * 519 * <li> values[14]: Sequence number </li> 520 * 521 * </ul> 522 * 523 * <h4>{@link android.hardware.Sensor#TYPE_STATIONARY_DETECT 524 * Sensor.TYPE_STATIONARY_DETECT}:</h4> 525 * 526 * A TYPE_STATIONARY_DETECT event is produced if the device has been 527 * stationary for at least 5 seconds with a maximal latency of 5 528 * additional seconds. ie: it may take up anywhere from 5 to 10 seconds 529 * afte the device has been at rest to trigger this event. 530 * 531 * The only allowed value is 1.0. 532 * 533 * <ul> 534 * <li> values[0]: 1.0 </li> 535 * </ul> 536 * 537 * <h4>{@link android.hardware.Sensor#TYPE_MOTION_DETECT 538 * Sensor.TYPE_MOTION_DETECT}:</h4> 539 * 540 * A TYPE_MOTION_DETECT event is produced if the device has been in 541 * motion for at least 5 seconds with a maximal latency of 5 542 * additional seconds. ie: it may take up anywhere from 5 to 10 seconds 543 * afte the device has been at rest to trigger this event. 544 * 545 * The only allowed value is 1.0. 546 * 547 * <ul> 548 * <li> values[0]: 1.0 </li> 549 * </ul> 550 * 551 * <h4>{@link android.hardware.Sensor#TYPE_HEART_BEAT 552 * Sensor.TYPE_HEART_BEAT}:</h4> 553 * 554 * A sensor of this type returns an event everytime a heart beat peak is 555 * detected. 556 * 557 * Peak here ideally corresponds to the positive peak in the QRS complex of 558 * an ECG signal. 559 * 560 * <ul> 561 * <li> values[0]: confidence</li> 562 * </ul> 563 * 564 * <p> 565 * A confidence value of 0.0 indicates complete uncertainty - that a peak 566 * is as likely to be at the indicated timestamp as anywhere else. 567 * A confidence value of 1.0 indicates complete certainly - that a peak is 568 * completely unlikely to be anywhere else on the QRS complex. 569 * </p> 570 * 571 * <h4>{@link android.hardware.Sensor#TYPE_LOW_LATENCY_OFFBODY_DETECT 572 * Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT}:</h4> 573 * 574 * <p> 575 * A sensor of this type returns an event every time the device transitions 576 * from off-body to on-body and from on-body to off-body (e.g. a wearable 577 * device being removed from the wrist would trigger an event indicating an 578 * off-body transition). The event returned will contain a single value to 579 * indicate off-body state: 580 * </p> 581 * 582 * <ul> 583 * <li> values[0]: off-body state</li> 584 * </ul> 585 * 586 * <p> 587 * Valid values for off-body state: 588 * <ul> 589 * <li> 1.0 (device is on-body)</li> 590 * <li> 0.0 (device is off-body)</li> 591 * </ul> 592 * </p> 593 * 594 * <p> 595 * When a sensor of this type is activated, it must deliver the initial 596 * on-body or off-body event representing the current device state within 597 * 5 seconds of activating the sensor. 598 * </p> 599 * 600 * <p> 601 * This sensor must be able to detect and report an on-body to off-body 602 * transition within 1 second of the device being removed from the body, 603 * and must be able to detect and report an off-body to on-body transition 604 * within 5 seconds of the device being put back onto the body. 605 * </p> 606 * 607 * <h4>{@link android.hardware.Sensor#TYPE_ACCELEROMETER_UNCALIBRATED 608 * Sensor.TYPE_ACCELEROMETER_UNCALIBRATED}:</h4> All values are in SI 609 * units (m/s^2) 610 * 611 * Similar to {@link android.hardware.Sensor#TYPE_ACCELEROMETER}, 612 * Factory calibration and temperature compensation will still be applied 613 * to the "uncalibrated" measurement. 614 * 615 * <p> 616 * The values array is shown below: 617 * <ul> 618 * <li> values[0] = x_uncalib without bias compensation </li> 619 * <li> values[1] = y_uncalib without bias compensation </li> 620 * <li> values[2] = z_uncalib without bias compensation </li> 621 * <li> values[3] = estimated x_bias </li> 622 * <li> values[4] = estimated y_bias </li> 623 * <li> values[5] = estimated z_bias </li> 624 * </ul> 625 * </p> 626 * <p> 627 * x_uncalib, y_uncalib, z_uncalib are the measured acceleration in X, Y, Z 628 * axes similar to the {@link android.hardware.Sensor#TYPE_ACCELEROMETER}, 629 * without any bias correction (factory bias compensation and any 630 * temperature compensation is allowed). 631 * x_bias, y_bias, z_bias are the estimated biases. 632 * </p> 633 * 634 * <h4>{@link android.hardware.Sensor#TYPE_HINGE_ANGLE Sensor.TYPE_HINGE_ANGLE}:</h4> 635 * 636 * A sensor of this type measures the angle, in degrees, between two integral parts of the 637 * device. Movement of a hinge measured by this sensor type is expected to alter the ways in 638 * which the user may interact with the device, for example by unfolding or revealing a display. 639 * 640 * <ul> 641 * <li> values[0]: Measured hinge angle between 0 and 360 degrees inclusive</li> 642 * </ul> 643 * 644 * @see GeomagneticField 645 */ 646 public final float[] values; 647 648 /** 649 * The sensor that generated this event. See 650 * {@link android.hardware.SensorManager SensorManager} for details. 651 */ 652 public Sensor sensor; 653 654 /** 655 * The accuracy of this event. See {@link android.hardware.SensorManager 656 * SensorManager} for details. 657 */ 658 public int accuracy; 659 660 /** 661 * The time in nanoseconds at which the event happened. For a given sensor, 662 * each new sensor event should be monotonically increasing using the same 663 * time base as {@link android.os.SystemClock#elapsedRealtimeNanos()}. 664 */ 665 public long timestamp; 666 667 @UnsupportedAppUsage SensorEvent(int valueSize)668 SensorEvent(int valueSize) { 669 values = new float[valueSize]; 670 } 671 672 /** 673 * Construct a sensor event object by sensor object, accuracy, timestamp and values. 674 * This is only used for constructing an input device sensor event object. 675 * @hide 676 */ SensorEvent(@onNull Sensor sensor, int accuracy, long timestamp, float[] values)677 public SensorEvent(@NonNull Sensor sensor, int accuracy, long timestamp, float[] values) { 678 this.sensor = sensor; 679 this.accuracy = accuracy; 680 this.timestamp = timestamp; 681 this.values = values; 682 } 683 } 684