Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/197.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android无法获取指南针方向_Android_Android Sensors - Fatal编程技术网

Android无法获取指南针方向

Android无法获取指南针方向,android,android-sensors,Android,Android Sensors,我正在尝试使用SensorEventListener获取用户的磁头。不幸的是,在Android上,这可能会有点麻烦 在我的HTC上,我的读数应该相当准确。在我的三星Galaxy S3上,读数完全是随机的。我知道我的课肯定出了问题,因为Play store seam的compass应用程序可以正常工作 我的代码是: public class HeadingSensor implements SensorEventListener { private static final String LOG_

我正在尝试使用
SensorEventListener
获取用户的磁头。不幸的是,在Android上,这可能会有点麻烦

在我的HTC上,我的读数应该相当准确。在我的三星Galaxy S3上,读数完全是随机的。我知道我的课肯定出了问题,因为Play store seam的compass应用程序可以正常工作

我的代码是:

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) { }
}

我已经阅读了尽可能多的教程,参考资料等,但我找不到一个好方法来获得指南针的方向。有人能告诉我这个类有什么问题吗?

你应该使用重力型而不是加速计型,否则你应该使用低通滤波器型加速计。你的问题主要在于

mGravity = sensorEvent.values;

由于
sensorEvent
是一个局部变量,并且
mGravity
mGeomagnetic
指向该值,因此在下次调用
onSensorChanged
时,这两个变量都可以是任何值。应该是

mGravity = sensorEvent.values.clone();


你可以在

上查看我的答案。你把S3带出去了吗?我的Moto G上的指南针极易受到干扰。是的,同时,如果我把手机放在办公桌上的同一位置,指南针应用程序会正确地报告所有内容,而我的代码会给出非常随机的读数。
mGravity = sensorEvent.values.clone();
mGeomagnetic = sensorEvent.values.clone();