Bootstrap

传感器之方向:使用加速度传感器和地磁传感器共同实现

布局很简单:

activity:

/**
 * 方向加速度:使用加速度传感器和地磁传感器共同实现。
 * 此模拟简易指南针功能。
 */

public class ActOrientationSensor extends AppCompatActivity {

    @BindView(R.id.img_compass)
    ImageView imgCompass;
    @BindView(R.id.img_arrow)
    ImageView imgArrow;

    private SensorManager sensorManager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_act_orientationsensor);
        ButterKnife.bind(this);

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sensorManager.registerListener(sensorEventListener, magneticSensor, SensorManager.SENSOR_DELAY_GAME);
        sensorManager.registerListener(sensorEventListener, accelerometerSensor, SensorManager.SENSOR_DELAY_GAME);
    }

    private SensorEventListener sensorEventListener = new SensorEventListener() {
        float[] accelerometerValues = new float[3];
        float[] magneticValues = new float[3];
        private float lastRotateDegree;
        @Override
        public void onSensorChanged(SensorEvent event) {
            //判断当前是加速度传感器还是地磁传感器
            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                //注意赋值时要调用clone()方法,
                //不然accelerometerValues和magneticValues将会指向同一个引用
                accelerometerValues = event.values.clone();
            } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
                //注意赋值时要调用clone()方法,
                //不然accelerometerValues和magneticValues将会指向同一个引用
                magneticValues = event.values.clone();
            }
            float[] R = new float[9];
            float[] values = new float[3];
            //为R数组赋值
            SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticValues);
            //为values数组赋值,values中就已经包含手机在所有方向上旋转的弧度了
            SensorManager.getOrientation(R, values);
            //1.values[0]表示手机围绕Z轴旋转的弧度;
            //2.values[0]的取值范围为-180度到180度,
            //正负180度表示正南方向,0度表示正北方向,
            //-90度表示正西方向,90度表示正东方向;
            //3.Math.toDegrees()把弧度转换成角度;
            //将计算出的旋转角度取反,用于旋转指南针背景图
            float rotateDegree = -(float)Math.toDegrees(values[0]);
            if(Math.abs(rotateDegree - lastRotateDegree) > 1){
                RotateAnimation animation = new RotateAnimation(
                        lastRotateDegree, rotateDegree,
                        Animation.RELATIVE_TO_SELF, 0.5f,
                        Animation.RELATIVE_TO_SELF, 0.5f);
                animation.setFillAfter(true);
                imgCompass.startAnimation(animation);
                lastRotateDegree = rotateDegree;
            }
        }

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

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (sensorManager != null) {
            sensorManager.unregisterListener(sensorEventListener);
        }
    }
}

;