Sensor
- Coordinate system used by
rotation vectorsensor (device front is at Z)

class ShakeDetector(private val onShake: () -> Unit) : SensorEventListener { private var lastUpdate: Long = 0L private val shakeThreshold = 5f private var lastShake: Long = 0L
override fun onAccuracyChanged(p0: Sensor?, p1: Int) {}
override fun onSensorChanged(event: SensorEvent) { if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) { val currentTime = System.currentTimeMillis() if ((currentTime - lastUpdate) > 100) { val x = event.values[0] val y = event.values[1] val z = event.values[2]
// Log.i("Accelerometer","X: $x, Y: $y, Z: $z")
val accelerometer = abs(sqrt(x * x + y * y + z * z) - SensorManager.GRAVITY_EARTH) // 3D畢氏定理計算總重力後去掉地心引力
if (accelerometer > shakeThreshold) { if (currentTime - lastShake > 500) { lastShake = currentTime onShake() } } lastUpdate = currentTime } } }}Composable:
val context = LocalContext.current
DisposableEffect(Unit) { val sensorManager = context.getSystemService(SensorManager::class.java) val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
val detector = ShakeDetector { // fun when shake }
sensorManager.registerListener(detector, accelerometer, SensorManager.SENSOR_DELAY_UI)
onDispose { sensorManager.unregisterListener(detector) }}Roll & Pitch
Section titled “Roll & Pitch”
Math.toDegrees()convert radius to degrees
val context = LocalContext.currentvar rollAngle by remember { mutableFloatStateOf(0f) }
DisposableEffect(Unit) { val manager = context.getSystemService(SensorManager::class.java) val sensor = manager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR) val rotationMatrix = FloatArray(9) val orientation = FloatArray(3) val listener = object : SensorEventListener { override fun onAccuracyChanged(p0: Sensor, p1: Int) {}
override fun onSensorChanged(sensor: SensorEvent) { SensorManager.getRotationMatrixFromVector(rotationMatrix, sensor.values) SensorManager.getOrientation(rotationMatrix, orientation) rollAngle = Math.toDegrees(orientation[2].toDouble()).toFloat() } }
manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_UI)
onDispose { manager.unregisterListener(listener) }}