Вот то, что у меня пока получилось, это несколько работает для меня, возвращаемые значения находятся в диапазоне от 0 до 360, но я не думаю, что север правильно откалиброван? Я использую это на LG G Pad под управлением Android 5.0.1
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float outR[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Y, outR);
SensorManager.getOrientation(outR, orientation);
azimut = orientation[0];
float degree = (float)(Math.toDegrees(azimut)+360)%360;
System.out.println("degree " + degree);
Я уверен, что есть вещи, которые я пропустил, но, надеюсь, это хорошая отправная точка для других. Я рассмотрел множество других вопросов, комментариев и т. Д., Чтобы добраться до этой точки.