I want to get the current magnetic orientation regardless of the current screen orientation (landscape or portrait).
I found this example, but it's not orientation independant, right? And this didn't help me either. I did also read http://android-developers.blogspot.de/2010/09/one-screen-turn-deserves-another.html.
This is my current approach with the deprecated way I don't want to use (short):
mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
private SensorEventListener sensorEventListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent event) {
/* Get measured value */
float current_measured_bearing = (float) event.values[0];
/* Compensate device orientation */
switch (((WindowManager) getSystemService(WINDOW_SERVICE))
.getDefaultDisplay().getRotation()) {
case Surface.ROTATION_90:
current_measured_bearing = current_measured_bearing + 90f;
break;
case Surface.ROTATION_180:
current_measured_bearing = current_measured_bearing - 180f;
break;
case Surface.ROTATION_270:
current_measured_bearing = current_measured_bearing - 90f;
break;
}
But the last part is definitely wrong! How do I use the newer method getRotationMatrix()
correctly in this case? (Orientation independent) Or do I simply have to use other values of the event.values[]
array based on the Rotation Matrix? Or will I need to 'remap the coordinates'? So is that the correct way of achieving this?
I'm developing for devices with 360° screen rotation and on API Level 11+.
I know that those questions are asked very often but I could simply not transfer their answers to my question.
I think this code may help you:
OK I finally managed to get the code working!
First, I register a
Sensor.TYPE_MAGNETIC_FIELD
andSensor.TYPE_GRAVITY
: (like Hoan Nguyen said!)And I use that
SensorEventListner
for the computation:Sensor.TYPE_ORIENTATION
is depreciated and only good if the device is flat. When usingSensor.TYPE_ORIENTATION
, the bearing (azimuth) is the direction where the deviceY-axis
points. So if the device is held vertical, the direction where theY-axis
points using as the bearing does not make sense. It only make sense to calculate the direction where the back camera points. To find this direction you have to useSensor.TYPE_MAGNETIC_FIELD
andSensor.TYPE_GRAVITY
orSensor.TYPE_ACCELEROMETER
. If usingSensor.TYPE_ACCELEROMETER
, you have to filter the accelerometer values.Using these sensors, you call
getRotationMatrix
and thenremapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR)
before callinggetOrientation
. To get a stable direction you should keep a history of the direction and then calculate the average. For an implementation using TYPE_GRAVITY check Android getOrientation Azimuth gets polluted when phone is tilted