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