Sensors

Motion and Environmental Sensors

SensorManager exposes motion sensors (accelerometer, gyroscope), position sensors (magnetometer) and environmental ones (light, pressure, humidity) through one API: a SensorEventListener receives SensorEvents whose values depend on the type (three axes in m/s² for the accelerometer, lux for light). The same callbackFlow pattern makes a sensor a Flow that unregisters itself:

location/Branches.kt: any sensor as a FlowKotlin
fun Context.sensorReadings(type: Int): Flow<FloatArray> = callbackFlow {
  val manager = getSystemService(SensorManager::class.java)
  val sensor = manager.getDefaultSensor(type) ?: run { close(); return@callbackFlow }
  val listener = object : SensorEventListener {
    override fun onSensorChanged(event: SensorEvent) { trySend(event.values.clone()) }
    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) = Unit
  }
  manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_UI)
  awaitClose { manager.unregisterListener(listener) }
}

Clone values, because the system may reuse the event object. The emulator's getSensorList() shows its virtual "Goldfish" hardware and the software sensors Android fuses from it (excerpt):

Output of 183
D/BookNestSensor( 6805): accelerometer: Goldfish 3-axis Accelerometer
D/BookNestSensor( 6805): light: Goldfish Light sensor
...
D/BookNestSensor( 6805): gravity: Gravity Sensor
D/BookNestSensor( 6805): rotation_vector: Rotation Vector Sensor

adb -s emulator-5556 emu sensor set acceleration 2.5:9.4:1.2 tilted the virtual phone: the branch screen's accelerometer line went from x 0.0 y 9.8 z 0.0 (upright) to x 2.5 y 9.4 z 1.2 m/s² (figure in Nearest Branch). Sample no faster than needed (SENSOR_DELAY_UI is about 16 Hz).