2014-12-19 123 views
0

我正在嘗試使用SensorEventListener來獲取用戶的磁性標題。令人遺憾的是,在Android上這個難題讓人感到有點麻煩。Android無法獲取指南針方向

在我的宏達電上,我的讀數接縫相當準確。在我的三星Galaxy S3上,讀數完全是隨機的。我知道我的班級一定有什麼問題,儘管從Play商店的指南針應用程序縫合起來工作得很好。

我的代碼是:

public class HeadingSensor implements SensorEventListener { 
private static final String LOG_TAG = "sw_HeadingSensor"; 

private SensorManager mSensorManager; 

private long mLastHeadingUpdate; 
private int mMinUpdateFrequency = 500;//milliseconds 
private HeadingListener mCallback; 

private float[] mGravity; 
private float[] mGeomagnetic; 

public interface HeadingListener { 
    public void headingChanged(int heading); 
} 

public HeadingSensor(Context context, HeadingListener headingListener) { 
    mCallback = headingListener; 
    mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); 
} 

public void registerListener() { 
    Log.d(LOG_TAG, "listener registered"); 

    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI); 
    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI); 
} 

public void unregisterListener() { 
    Log.d(LOG_TAG, "listener unregistered"); 

    mSensorManager.unregisterListener(this); 
} 

@Override 
public void onSensorChanged(SensorEvent sensorEvent) { 
    if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 
     mGravity = sensorEvent.values; 
    } 

    if (sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { 
     mGeomagnetic = sensorEvent.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) { 
      long currentTime = System.currentTimeMillis(); 

      if ((currentTime - mLastHeadingUpdate) > mMinUpdateFrequency) { 
       mLastHeadingUpdate = currentTime; 

       float orientation[] = new float[3]; 
       SensorManager.getOrientation(R, orientation); 
       float azimuthInRadians = orientation[0]; 
       int azimuthInDegress = (int)(Math.toDegrees(azimuthInRadians) + 360) % 360; 

       if (null != mCallback) { 
        mCallback.headingChanged(azimuthInDegress); 
       } 
      } 
     } 
    } 
} 

@Override 
public void onAccuracyChanged(Sensor sensor, int accuracy) { } 
} 

我讀過許多教程,參考資料等地,但我不能找到一個很好的辦法讓羅盤航向。有人能告訴我這個班有什麼問題嗎?

+0

回答您的戶外拍攝你的S3?我的Moto G上的指南針極易受到干擾。 – 2014-12-19 09:15:56

+0

是的,同時如果我把手機放在我辦公桌的同一位置,那麼指南針應用程序會正確報告所有內容,而我的代碼會給出非常隨機的讀數。 – shiznatix 2014-12-19 09:22:19

回答

0

您應該使用TYPE_GRAVITY而不是TYPE_ACCELEROMETER否則您應該低通濾波器TYPE_ACCELEROMETER。你的問題主要在於

mGravity = sensorEvent.values; 

mGeomagnetic = sensorEvent.values; 

由於sensorEvent是一個局部變量,要麼mGravitymGeomagnetic點這個值,無論這些可以通過下一次onSensorChanged叫什麼。它應該是

mGravity = sensorEvent.values.clone(); 

mGeomagnetic = sensorEvent.values.clone(); 

你可以看一下我在Android getOrientation Azimuth gets polluted when phone is tilted