For a recent project, I had to create a game-style controller Android app that senses the phone’s tilt and uses it as an input.
(image via SO)
To simplify the explanation, imagine a jet thruster game where the farther you tilt the phone back, the stronger the jet thrusters fire:
- When the phone sits upright, the thrusters don’t fire at all
- When the phone is tilted all the way back, the thrusters fire at full force
Going into it, I knew I would need to use Sensors, specifically something about the Accelerometer. Digging in a bit more, no amount of Googling/Stack searching provided me with exactly what I was looking for, so I figured I’d write it up here…
Initial search results:
- A few pretty quiet SO posts with no real solutions
- A pretty extensive SO overview of Android orientation
- A solution that remaps the actual returned coordinate system
- which led me down the path of SensorManager.remapCoordinateSystem() (not where I needed to be)
- and this solution for measuring the tilt of the XY plane which does a lot of the math, which I’m assuming was written prior to the Android SDK providing some of the convenience methods.
My fully open-sourced solution lives here: https://github.com/loisaidasam/tilt
Specifically, check out MainActivity.java:
- It sets up the sensor listeners
- listens for sensor updates
- uses SensorManager.getRotationMatrix()
- and then SensorManager.getOrientation() to get
- From there, we convert the radians returned in
- and then apply the results to a 0-100 scale
A few notes:
Another thing to keep in mind is the orientation of your device, which is subject to change despite settings you’ve applied in your app – check out this Android Developers Blog post “One Screen Turn Deserves Another”. It highlights always checking your device orientation using Display.getRotation(), comparing constants such as ROTATION_0, ROTATION_90, etc.