天天看点

Android Api Demos登顶之路(七十三)Graphics-->Compass

/*
 * 这个demon需要重点关注的是传感器的使用
 * 传感器的使用步骤为:
 * 感应检测功能:
 1、取得SensorManager
 Context.getSysteService(SENSER_SERVICE)方法来取得感应检测的服务
 2、实现取得感应检测Sensor状态的监听功能
 实现以下两个SensorEventListener方法来监听,并取得感应检测Sensor状态:
 //在感应检测到Sensor的精密度有变化时被调用到。  
 public void onAccuracyChanged(Senso sensor,int accuracy);  
 //在感应检测到Sensor的值有变化时会被调用到。  
 public void onSensorChanged(SensorEvent event);  
 3、实现取得感应检测Sensor目标各类的值
 实现下列getSensorList()方法来取得感应检测Sensor的值;
 List<Sensor> sensors = sm.getSensorList(Sensor.TYPE_TEMPERATURE);  
 4、注册SensorListener
 sm.regesterListener(SensorEventListener listener, Sensor sensor, int rate);  
 第一个参数:监听Sensor事件,第二个参数是Sensor目标种类的值,第三个参数是延迟时间的精度密度。延迟时间的精密度参数如下:
 参数5、取消注册
 sm.unregisterListener(SensorEventListener listener) 
 */
public class MainActivity extends Activity {
    private SensorManager mSensorManager;
    private Sensor mSensor;
    // 定义一个数组,用于存储传感器中的各种信息的值
    private float[] mValues=new float[];
    private SampleView mView;

    // 定义加速传感器和磁场传感器
    private Sensor mAccelerometer;
    private Sensor mMagnetic;

    // 定义两个数组,用于存放加速传感器和磁场传感器中的数据
    private float[] accelers = new float[];
    private float[] magnetics = new float[];

    private int mMethodId=;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 演示第一种方法使用Sensor.TYPE_ORIENTATION,但我们看到这个常量已经过时了
        // 下面演示第二种方法,用官方推荐的方法
        // mehtod1();
        mehtod2();
    }

    /*
     * 方向传感器是基于软件的并且它的数据是通过加速度传感器和磁场传感器共同获得
     * 官方推荐我们使用SensorManager.getOrientation()方法
     */
    private void mehtod2() {
        mMethodId=;
        // 1.获取传感器的管理者
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager
                .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mMagnetic = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

        mView = new SampleView(this);
        setContentView(mView);
    }

    private void mehtod1() {
        // 1.获取传感器的管理者
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        // 2.获取方位传感器
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        mView = new SampleView(this);
        setContentView(mView);
    }

    private SensorEventListener mListener = new SensorEventListener() {
        // sensor的值发生变化时被调用.SensorEvent对象包含了有关新的传感器数据的信息,
        // 包括:数据的精度、产生数据的传感器、产生数据时的时间戳、以及传感器记录的新的数据。
        @Override
        public void onSensorChanged(SensorEvent event) {
            // 获取到sensor信息的值
            mValues = event.values;
            if (mView != null) {
                mView.invalidate();
            }
        }

        // sensor的精密度发生变化时被调用
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    };
    private class MyListener implements SensorEventListener {
        @Override
        public void onSensorChanged(SensorEvent event) {
            //获取加速传感器的磁场传感器中的数据
            if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
                accelers=event.values;
            }
            if(event.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){
                magnetics=event.values;
            }
            //System.out.println("accelers:"+accelers.length);
            //System.out.println("magnetics:"+magnetics.length);

            float[] R = new float[];
            // 填R矩阵.第一个参数表示要填充的基准矩阵。第二个参数将磁场数据转换进实际的重力坐标系当中
            // 通常可以设置为null,第三个参数为加速传感器中的数据(重力传感器与加速传感器使用同一套坐标系)
            // 第四个参数为磁场传感器中的数据,所以我们需要获取这两个传感器中的数据,在对传感器的监听接口中获取
            SensorManager.getRotationMatrix(R, null, accelers, magnetics);
            /*
             * 该方法的作用就是基于旋转矩阵计算设备的方向,R就是用于计算设备方向的基准矩阵。 它是一个4*4或者3*3的矩阵,用一维数组来表示。
             * 其实R是用来保存磁场和加速度的数据的。那么它的值是如何获取的呢?
             * 官方推荐我们使用SensorManage.getRotationMatrix来填充
             */
            SensorManager.getOrientation(R, mValues);
            mValues[] = (float) Math.toDegrees(mValues[]);
            System.out.println("mValues:"+mValues[]);
            if(mView!=null){
                mView.invalidate();
            }
        }

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

    @Override
    protected void onResume() {
        super.onResume();
        if(mMethodId==){
            //System.out.println("In Method2");
            mSensorManager.registerListener(new MyListener(), mAccelerometer,
                    SensorManager.SENSOR_DELAY_GAME);
            mSensorManager.registerListener(new MyListener(), mMagnetic,
                    SensorManager.SENSOR_DELAY_GAME);
        }else{
        // 注册传感器的监听,第二个参数为传感器,第三个参数表示延迟时间的精密度
        mSensorManager.registerListener(mListener, mSensor,
                SensorManager.SENSOR_DELAY_GAME);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if(mMethodId==){
            mSensorManager.unregisterListener(new MyListener());
        }
        // 取消对传感器的监听
        mSensorManager.unregisterListener(mListener);

    }

    private class SampleView extends View {
        private Paint mPaint;
        private Path mPath;

        public SampleView(Context context) {
            super(context);
            mPath = new Path();
            // 定义路径,绘制批南针的指针轮廓
            mPath.moveTo(, -);
            mPath.lineTo(-, );
            mPath.lineTo(, );
            mPath.lineTo(, );
            mPath.close();
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawColor(Color.WHITE);
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.BLACK);
            mPaint.setStyle(Paint.Style.FILL);

            // 获取画布的宽和高
            int w = canvas.getWidth();
            int h = canvas.getHeight();
            int cx = w / ;
            int cy = h / ;
            // 将画布移到屏幕的中心点
            canvas.translate(cx, cy);
            if (mValues != null) {
                // mValues[0]表示y轴与磁北之间的夹角,现在我们需要使指针旋转一定的角度
                // 让指针的头部指向磁北方向
                canvas.rotate(-mValues[]);
            }
            // 绘制指针
            canvas.drawPath(mPath, mPaint);
        }
    }
}
           

继续阅读