实现指南针的新方法SensorManager.getOrientation( )

本文详细介绍了开发指南针应用时,从使用弃用的Sensor.TYPE_ORIENTATION到推荐的SensorManager.getOrientation()方法的过渡过程。通过对比分析,展示了新方法在准确性上的优势,并提供了关键代码实现,帮助开发者提升应用的定位精度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

研究了下传感器,一时兴起做了个小的指南针APP,网上讲的比较多的方法:

1、注册一个针对方位传感器的事件监听器;

        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

Sensor compassSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);

mSensorManager.registerListener(this, compassSensor, SensorManager.SENSOR_DELAY_NORMAL);

2、得到传感器事件的values[0],作为手机头部朝向的方位角,从而得到相对正北的角度(顺时针)

@Override
    public void onSensorChanged(SensorEvent event) {
                // 获取绕Z轴转过的角度
                float degree = event.values[0];
                System.out.println("方位角=" + degree);

但是其实谷歌官方已经在API 8 开始就已经弃用了Sensor.TYPE_ORIENTATION这种方式,转而推荐使用SensorManager.getOrientation( )的方式来获取到方位、横滚、俯仰值。

我看了看API文档,试着用新方法实现了,肉眼对比了一下,大概和旧方法获取的方位值有不到1度的误差,也可以使用了。

不多说,关键代码如下,大家一看便知。

public class CompassActivity extends Activity implements SensorEventListener {

    private static final String TAG = "CompassActivity";
    //记录rotationMatrix矩阵值
    private float[] r = new float[9];
    //记录通过getOrientation()计算出来的方位横滚俯仰值
    private float[] values = new float[3];
    private float[] gravity = null;
    private float[] geomagnetic = null;
    // 定义真机的Sensor管理器
    private SensorManager mSensorManager;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if(gravity!=null && geomagnetic!=null) {
                if(SensorManager.getRotationMatrix(r, null, gravity, geomagnetic)) {
                    SensorManager.getOrientation(r, values);
                    float degree = (float) ((360f+values[0]*180f/Math.PI)%360);
                    Log.i(TAG, "计算出来的方位角=" + degree);
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_compass);
        // 获取真机的传感器管理服务
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //注册加速度传感器监听
        Sensor acceleSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mSensorManager.registerListener(this, acceleSensor, SensorManager.SENSOR_DELAY_NORMAL);
        //注册磁场传感器监听
        Sensor magSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        mSensorManager.registerListener(this, magSensor, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 取消所有注册
        mSensorManager.unregisterListener(this);
    }

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

    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        switch (event.sensor.getType()) {
            case Sensor.TYPE_ACCELEROMETER: //加速度传感器
                gravity = event.values;
                handler.sendEmptyMessage(0);
                break;
            case Sensor.TYPE_MAGNETIC_FIELD://磁场传感器
                geomagnetic = event.values;
                handler.sendEmptyMessage(0);
                break;
        }
    }
}



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值