Question

I am building an Android application which logs the degrees of the compass of the device into a file. There are two methods the get this degrees:

Method 1:

SensorManager mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor orientationSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
mSensorManager.registerListener(this, orientationSensor, SensorManager.SENSOR_DELAY_NORMAL);


public void onSensorChanged(SensorEvent event) {
    float azimuthInDegrees = event.values[0]
}

Method 2:

SensorManager mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Sensor magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_NORMAL);

float[] mGravity;
float[] mGeomagnetic;

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 I[] = new float[9];
        boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
        if (success) {
            float orientation[] = new float[3];
            SensorManager.getOrientation(R, orientation);   

            float azimuthInDegress = ((float) Math.toDegrees(orientation[0]) + 360) % 360;
        }
    }
}

I tried out both methods by placing my device in the North direction (which is around 360 degrees):

Method 1 returns perfect results but unfortunately this method is deprecated:

  • 359.6567
  • 359.5034
  • 359.859
  • 359.76212
  • 359.8878
  • 359.87048
  • 359.8356
  • 359.80356
  • 359.81192
  • 359.7671
  • 359.84668
  • 359.88528

Method 2 also returns good results but sometimes (randomly) it returns an incorrect degree:

  • 359.91495
  • 359.83652
  • 263.67697
  • 359.67993
  • 359.70038
  • 359.688
  • 359.71155
  • 359.70276
  • 359.6984
  • 359.6429
  • 270.6323
  • 359.62302
  • 359.49954
  • 359.44757
  • 359.47803
  • 359.4947
  • 359.39572

As you can see, some incorrect degrees are randomly returned with the second method. The device is calibrated and I think that the problem is with the second method as the first method returns perfect results. Can you guys help me out?

Était-ce utile?

La solution

The problem is in the assigment of mGravity and mGeomagnetic it should be event.values.clone(). mGravity has class scope but, by using mGravity = event.values, you assign its value to a value in an address that has method scope. So as soon as onSensorChanged is called again and it is magnetic type, the mGravity is now pointing to a variable which no longer exists and thus can have any value.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top