Магнитометр Android, возвращающий случайные значения

Я создаю приложение для Android, которое записывает градусы компаса устройства в файл. Есть два способа получить эту степень:

Способ 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]
}

Метод 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;
        }
    }
}

Я опробовал оба метода, разместив свое устройство в северном направлении (около 360 градусов):

Метод 1 дает отличные результаты, но, к сожалению, этот метод устарел:

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

Метод 2 также дает хорошие результаты, но иногда (случайно) он возвращает неправильную степень:

  • 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

Как видите, второй метод случайным образом возвращает несколько неверных степеней. Устройство откалибровано, и я думаю, что проблема во втором методе, так как первый метод дает отличные результаты. Ребята, вы можете мне помочь?


person duncanportelli    schedule 25.03.2013    source источник
comment
в каком положении находится устройство, когда вы получаете этот результат. например, держать устройство вертикально   -  person Hoan Nguyen    schedule 25.03.2013
comment
Я держу его в руке. Почти плоский   -  person duncanportelli    schedule 25.03.2013
comment
Просто поменять? = event.values ​​на event.values.clone() и посмотрите, будет ли у вас такое же поведение.   -  person Hoan Nguyen    schedule 25.03.2013
comment
Вау, чувак, это сработало. Почему это так?   -  person duncanportelli    schedule 25.03.2013
comment
потому что если вы установите mGravity = event.values, вы установите mGravity в указатель, значение по адресу, на который указывает указатель, может измениться.   -  person Hoan Nguyen    schedule 25.03.2013
comment
Это происходит довольно часто, поэтому позвольте мне написать ответ, чтобы другие люди с похожей проблемой могли легко это заметить, вместо того, чтобы читать все эти комментарии.   -  person Hoan Nguyen    schedule 25.03.2013
comment
Хорошо, большое спасибо @HoanNguyen   -  person duncanportelli    schedule 25.03.2013


Ответы (1)


Проблема в назначении mGravity и mGeomagnetic должно быть event.values.clone(). mGravity имеет область класса, но, используя mGravity = event.values, вы присваиваете его значение значению в адресе, который имеет область действия метода. Итак, как только onSensorChanged вызывается снова, и это магнитный тип, mGravity теперь указывает на переменную, которой больше не существует и, следовательно, может иметь любое значение.

person Hoan Nguyen    schedule 25.03.2013