2014-12-19 150 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