如何在android上制作精确的指南针

如何在android上制作精确的指南针,android,orientation,compass-geolocation,android-sensors,Android,Orientation,Compass Geolocation,Android Sensors,我的android应用程序显示了世界上某个特定地方的方向,因此需要获得指南针度数。 这是我用来计算度数的代码: public void getDirection() { mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); List<Sensor> mySensors = mySensorManager.getSensorList(Sensor.TYPE_

我的android应用程序显示了世界上某个特定地方的方向,因此需要获得指南针度数。
这是我用来计算度数的代码:

public void getDirection() {        
    mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
    List<Sensor> mySensors = mySensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
    if(mySensors.size() > 0){
        mySensorManager.registerListener(mySensorEventListener, mySensors.get(0), SensorManager.SENSOR_DELAY_UI);           
    }
    else{
        TextView alert = (TextView)findViewById(R.id.instruct);
        alert.setText(getString(R.string.direction_not_found));
        myCompassView.setVisibility(myCompassView.INVISIBLE);

    }
}
private SensorEventListener mySensorEventListener = new SensorEventListener(){

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        // TODO Auto-generated method stub
        compassBearing = (float)event.values[0];
        float bearing;
        bearing = compassBearing - templeBearing;
        if (bearing < 0)
            bearing = 360 + bearing;
        myCompassView.updateDirection(bearing);
        }
};
public void getDirection(){
mySensorManager=(SensorManager)getSystemService(Context.SENSOR\u SERVICE);
List mySensors=mySensorManager.getSensorList(Sensor.TYPE_方向);
如果(mySensors.size()>0){
mySensorManager.registerListener(mysensorreventListener、mySensors.get(0)、SensorManager.SENSOR\u DELAY\u UI);
}
否则{
TextView警报=(TextView)findViewById(R.id.direction);
alert.setText(getString(R.string.direction_未找到));
设置可见性(myCompassView.INVISIBLE);
}
}
私有SensorEventListener mySensorEventListener=新的SensorEventListener(){
@凌驾
精度更改时的公共无效(传感器,int精度){
//TODO自动生成的方法存根
}
@凌驾
传感器更改时的公共无效(传感器事件){
//TODO自动生成的方法存根
compassBearing=(浮点)事件值[0];
浮动轴承;
轴承=罗盘轴承-模板轴承;
如果(轴承<0)
轴承=360+轴承;
myCompassView.updateDirection(轴承);
}
};

这种方法通常是有效的,但有时它只是到达了错误的北方,我该怎么做才能获得更准确的位置?

我有一些建议供您参考:

1)您的设备可能未校准。要执行此操作,请以8()的形式移动它。如果您不知道您的设备是否已校准,请将设备指向某个已知的基点方向进行一些测试,并比较这些值。通常,如果设备未校准,您将看到小旋转时方位角值的巨大变化。这就是我所担心的

现在,别忘了传感器为您提供指向磁北的方位,而不是正北的方向!这种差异被称为磁场的磁偏角,由于地球磁场的变化,它的值在不同的地方和时间发生变化。可以相对准确地为您计算一些值。我不会太担心这一点,因为赤纬通常很小,但您可能会寻求良好的精度(我居住的地方,目前赤纬为3º)

2)远离产生强磁场的金属物体或物体。例如,如果您的手机靠近电脑或任何物理键盘,请不要进行测试!这是测试罗盘地理位置的纯毒药。有些可以测量磁场强度(如果设备支持)。当你接近金属材料时,你会体验到更高的价值和方向上的强烈变化。有趣的是,还有一些“:当你靠近“金属物体”或磁性干扰设备的东西时,这个应用程序可以识别磁场的变化并振动

3)当您将设备倾斜到横向模式时,请记住更新方位。()这是因为方位角值基于垂直轴相对于手机平面的旋转。当您将设备旋转到横向时,该值会改变+/-90º禁用应用程序横向模式无法解决此问题您必须通过分析围绕其他两个轴(俯仰和滚动)的旋转,以编程方式确定它。这不是一件小事,但是在网络的某个地方有一些例子

编辑:如果您对某些代码感兴趣,请查看,它是一个开源的增强现实框架,位于Android的GPL3下。看看他们关于方位、罗盘地理位置和方位的代码


PS:我与上述应用程序的创建者没有任何联系。

1)有没有办法告诉用户设备未校准?2)有没有办法知道何时存在磁干扰?3) 我禁用了横向模式,所以我不必担心,对吗?@MobileCushion回答得很好,非常感谢。磁偏角通常是一个很小的值,但可以高达180度(沿着磁北和北极之间的一条线)所以可能不应该被忽略。这将是一个很好的问题,可以添加到新的StackExchange提案中。此链接应该会有所帮助。