Android笔记

Android Orientation Sensor监听方向

2018-02-06  本文已影响239人  忘尘无憾

在使用方向传感器对手机方向进行监听的时候,如果使用到Sensor.TYPE_ORIENTATION,会发现已经过时了。不过好在官方提供了新的替代方法。即使用加速度传感器地磁场传感器联合使用从而保证获取到手机方向。

直接上代码:

public class OrientationListener implements SensorEventListener {

    private SensorManager mSensorManager;// 传感器管理者
    private Sensor mAccelerometer;// 加速度传感器
    private Sensor mMagnetic;// 地磁传感器
    private Context mContext;// 上下文
    private OnOrientationListener mOnOrientationListener;// 方向监听
    private float[] mAccelerometerValues = new float[3];// 用于保存加速度值
    private float[] mMagneticValues = new float[3];// 用于保存地磁值

    /**
     * 构造函数
     *
     * @param context
     */
    public OrientationListener(Context context) {
        this.mContext = context;
        start();
    }

    /**
     * 监听接口类
     */
    public interface OnOrientationListener {
        void onOrientationChanged(float azimuth, float pitch, float roll);
    }

    /**
     * 设置监听
     *
     * @param onOrientationListener
     */
    public void setOnOrientationListener(OnOrientationListener onOrientationListener) {
        this.mOnOrientationListener = onOrientationListener;
    }

    /**
     * 实例化方向监听所需的传感器
     */
    private void start() {
        // 实例化传感器管理工具
        mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
        // 初始化加速度传感器
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        // 初始化地磁场传感器
        mMagnetic = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

    }

    /**
     * <pre>
     *     注册加速度和地磁场传感器监听
     *     在onResume中调用
     * </pre>
     */
    public void registerListener() {
        if (mSensorManager != null && mAccelerometer != null && mMagnetic != null) {
            mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
            mSensorManager.registerListener(this, mMagnetic, SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    /**
     * <pre>
     *      解除监听
     *      onPause中进行调用
     * </pre>
     */
    public void unregisterListener() {
        mSensorManager.unregisterListener(this);
    }

    /**
     * <pre>
     *     计算方向
     *     根据传感器获取到的加速度值和地磁值先得出旋转矩阵
     *     再根据旋转矩阵得到最终结果,最终结果包含航向角、俯仰角、翻滚角
     * </pre>
     */
    private void calculateOrientation() {
        float[] values = new float[3];// 最终结果
        float[] R = new float[9];// 旋转矩阵
        SensorManager.getRotationMatrix(R, null, mAccelerometerValues, mMagneticValues);// 得到旋转矩阵
        SensorManager.getOrientation(R, values);// 得到最终结果
        float azimuth = (float) Math.toDegrees(values[0]);// 航向角
        if (azimuth < 0) {
            azimuth += 360;
        }
        azimuth = azimuth / 5 * 5;// 做了一个处理,表示以5°的为幅度
        float pitch = (float) Math.toDegrees(values[1]);// 俯仰角
        float roll = (float) Math.toDegrees(values[2]);// 翻滚角
        if (mOnOrientationListener != null) {
            Log.d("航向角:" + azimuth + "--俯仰角:" + pitch + "--翻滚角:" + roll);
            mOnOrientationListener.onOrientationChanged(azimuth, pitch, roll);
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            mAccelerometerValues = event.values;
        }
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            mMagneticValues = event.values;
        }
        calculateOrientation();
    }

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

    }
}

在调用过程中,先对OrientationListener进行实例化,并setOnOrientationListener拿到回调,在onResume中进行注册监听,在onPause解除监听。

上一篇下一篇

猜你喜欢

热点阅读