Using accelerometer and gyroscope sensors in Android
Android applications can react to movement by reading the device’s inertial sensors through Android’s SensorManager. The accelerometer reports linear acceleration and gravity, while the gyroscope measures angular velocity around the X, Y and Z axes. Together, they reveal tilt, rotation, shakes and direction changes without touching the screen.
Most modern Android phones include both sensors, but their accuracy and availability vary between models. A robust implementation checks for missing sensors, registers listeners only while the screen is active, filters noisy readings and combines data when stable orientation is required. This matters in Australia, where Android apps published through Google Play range from Sydney commuter tools to bush-walking navigation. For location-aware companions, the GPS and geocoding guide provides the complementary positioning workflow.
| Property | Accelerometer | Gyroscope |
|---|---|---|
| Main measurement | Gravity and linear acceleration | Angular velocity |
| Typical units | Metres per second squared | Radians per second |
| Best response | Tilt and changes in movement | Rotation, turns and gestures |
| Main limitation | Movement can obscure gravity | Readings accumulate drift over time |
How Android motion sensors work
Android’s sensor framework supplies data through SensorEventListener. Each event includes the sensor type, a timestamp, an accuracy value and an array of readings. The first three accelerometer values represent the X, Y and Z axes in the device’s natural coordinate system.
The axes follow the phone rather than the screen orientation. When the device is held upright in portrait mode, X points right, Y points upwards and Z points out of the display. An app mounted in another position may require remapCoordinateSystem() to interpret rotations correctly.
Android also provides composite sensors such as TYPE_ROTATION_VECTOR. These combine information from several physical sensors to produce a more stable orientation estimate. They are useful when a simple accelerometer reading would be distorted by a quick hand movement or when gyroscope drift needs correction.
Setting up the Kotlin project
Create an ordinary Android Studio project and select Kotlin. Motion sensors require no third-party library or manifest permission. Obtain SensorManager from Context.SENSOR_SERVICE, then request the default accelerometer and gyroscope with getDefaultSensor().
private lateinit var sensorManager: SensorManager
private var accelerometer: Sensor? = null
private var gyroscope: Sensor? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
}
A null result means that sensor type is unavailable, so the interface should remain functional without it. For example, a step counter can fall back to manual entry if no gyroscope exists, while a tilt-based control can hide itself when no accelerometer is fitted.
Registering sensors with the activity
Register a listener in onResume() and remove it in onPause(). This prevents background sensor activity from wasting battery when the activity is not visible. SENSOR_DELAY_GAME offers frequent updates for responsive controls, while SENSOR_DELAY_UI is sufficient for ordinary interface feedback.
override fun onResume() {
super.onResume()
accelerometer?.let {
sensorManager.registerListener(this, it, SensorManager.SENSOR_DELAY_GAME)
}
gyroscope?.let {
sensorManager.registerListener(this, it, SensorManager.SENSOR_DELAY_GAME)
}
}
override fun onPause() {
sensorManager.unregisterListener(this)
super.onPause()
}
override fun onSensorChanged(event: SensorEvent) {
val x = event.values[0]
val y = event.values[1]
val z = event.values[2]
// Display or process the selected sensor values here.
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) = Unit
The requested delay is a hint rather than an exact interval. Measure timestamps between events when timing matters, and avoid doing expensive work inside onSensorChanged(), since sensor callbacks may arrive quickly.
Converting raw values into orientation
Raw acceleration values are rarely useful as angles. A stationary phone reading approximately 9.81 on one axis is responding to gravity. During movement, linear acceleration is added to that value, so the device can briefly appear tilted in a different direction.
A rotation-vector sensor offers a cleaner orientation result. Android converts its quaternion-like values into a rotation matrix and orientation angles containing pitch, roll and an azimuth-like heading.
private val rotationMatrix = FloatArray(9)
private val orientation = FloatArray(3)
if (event.sensor.type == Sensor.TYPE_ROTATION_VECTOR) {
SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)
SensorManager.getOrientation(rotationMatrix, orientation)
val pitch = Math.toDegrees(orientation[1].toDouble())
val roll = Math.toDegrees(orientation[2].toDouble())
}
For relative rotation, gyroscope values can be integrated over the interval between events. This approach still accumulates error because tiny manufacturing offsets become visible over time. A composite sensor is normally preferable when absolute orientation and repeatable movement matter.
Filtering noise and correcting drift
Vibrations, nearby traffic and imperfect sensor calibration introduce small fluctuations into the readings. A low-pass filter smooths those values by blending each new sample with the previous result.
private var filteredX = 0f
filteredX += 0.15f * (event.values[0] - filteredX)
A smaller factor produces heavier smoothing but increases lag, so game controls may need a quicker response than a level or measurement display. The appropriate value depends on the device sampling rate and the movement being detected.
Gyroscope drift can be reduced by estimating a bias while the phone remains stationary. Collect several samples, calculate the average X, Y and Z readings and subtract that offset from later events. Recalibrate after a substantial temperature change, because sensor bias can vary as a handset warms up in Australian summer conditions.
Designing useful motion features
Activity and wellness apps can recognise repeated movements, posture changes or falls without collecting location data. Motion events are also useful for camera controls, drawing tools and accessibility features that let users navigate with a tilt or shake gesture.
Public-transit applications around Sydney and Melbourne could combine motion signals with route information, although they must not treat a sudden movement as proof that a passenger boarded a bus. Sydney’s Opal system and Melbourne’s Myki network provide location-specific context for such features. Australian interfaces commonly use kilometres, kilometres per hour and Celsius, while “mobile” is the everyday word for a smartphone.
Bush-walking and fieldwork applications need tolerant thresholds because uneven ground produces stronger jolts than a desk-based test. A shake-to-action control should also say “shake for action” clearly, since some users may not discover a gesture that is demonstrated only with an animation.
Testing, battery use and production checks
Test on several physical Android devices because emulator movement data is limited and does not reproduce real sensor noise, axis orientation or calibration errors. A useful physical test includes placing the phone flat, tilting it along each axis, rotating it slowly and shaking it briefly while comparing the displayed values.
Sampling frequency affects battery consumption. Register sensors only for visible features, stop them when they are no longer needed and use less frequent updates for background analysis. If readings are recorded or transmitted, apply the same privacy and retention rules used for other personal information even though the sensor APIs themselves require no special runtime permission.
A production release should handle absent hardware, unexpected rotations, noisy readings and abrupt app backgrounding. It should also accommodate the range of Android devices sold through Google Play in Australia. These safeguards keep motion features responsive without making the app fragile, power-hungry or intrusive.