zoukankan      html  css  js  c++  java
  • Android方向传感器

    在Android中传感器的使用场景比其他传感器更为广泛,因为它能够准确地判断出手机在各个方向的旋转角度,利用这些角度可以编写出指南针、地平仪等有用的工具。
    方向传感器的使用相较于其他的传感器有所不同。虽然在API中有TYPE_ORIENTATION常量,可以像得到加速度传感器那样得到方向传感器Sensor.TYPE_ORIENTATION,但是这样做的话,在新版的SDK中就会提示"这种方式已经过期,不建议使用!"官方推荐我们在应用程序中使用磁场域和加速度传感器结合SensorManager.setOrientation()来获得原始数据。下面通过实例来说明如何使用方向传感器。
    **MainActivity.java**
    
    package com.sdutacm.sensor;
    
    import android.content.Context;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity implements SensorEventListener{
    
        private SensorManager sensorManager;
    
        private Sensor accelerometerSensor;
    
        private Sensor magneticFieldSensor;
    
        private float[] accelerometerValues = new float[3];
    
        private float[] magneticValues = new float[3];
    
        //旋转矩阵,用来保存磁场和加速度的数据
        private float[] r = new float[9];
    
        //模拟方向传感器的数据(原始数据为弧度)
        private float[] values = new float[3];
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            getSensorManager();
        }
    
    
        @Override
        public void onSensorChanged(SensorEvent event) {
            if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
                //这里是对象,需要克隆一份,否则共用一份数据
                accelerometerValues = event.values.clone();
            }else if(event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD){
                //这里是对象,需要克隆一份,否则共用一份数据
                magneticValues = event.values.clone();
            }
            /**
             * 填充旋转数组r
             * r:要填充的旋转数组
             * I:将磁场数据转换成实际的重力坐标中,一般可以设置为null
             * gravity:加速度传感器数据
             * geomagnetic:地磁传感器数据
             */
            SensorManager.getRotationMatrix(r,null,accelerometerValues,magneticValues);
            /**
             * R:旋转数组
             * values :模拟方向传感器的数据
             */
            sensorManager.getOrientation(r,values);
    
            float degree = (float) Math.toDegrees(values[0]);
            Log.d("指南针","当前手机角度为:"+degree);
            Toast.makeText(this,"当前手机角度为:"+degree,Toast.LENGTH_SHORT).show();
    
    
            //Sensor 发生变化时,在次通过event.values获取数据
    //        float x = event.values[0];
    //        float y = event.values[0];
    //        float z = event.values[0];
    //        float light = event.values[0];
    //        Log.d("Light","当前的光线强度为:"+light+"勒克斯");
    //        Toast.makeText(this,"当前的光线强度为:"+light+"勒克斯",Toast.LENGTH_SHORT).show();
    
    //        if(x>20 || y>20 || z>20){
    //            Toast.makeText(this,"欢迎使用摇一摇",Toast.LENGTH_SHORT).show();
    //        }
        }
    
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            //注册的Sensor精度发生变化时,在此处处理
        }
    
        public void getSensorManager() {
            sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
            /**
             * 传入的参数决定传感器的类型
             * Senor.TYPE_ACCELEROMETER: 加速度传感器
             * Senor.TYPE_LIGHT:光照传感器
             * Senor.TYPE_GRAVITY:重力传感器
             * SenorManager.getOrientation(); //方向传感器
             */
            accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            magneticFieldSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            if(sensorManager != null){
                //一般在Resume方法中注册
                /**
                 * 第三个参数决定传感器信息更新速度
                 * SensorManager.SENSOR_DELAY_NORMAL:一般
                 * SENSOR_DELAY_FASTEST:最快
                 * SENSOR_DELAY_GAME:比较快,适合游戏
                 * SENSOR_DELAY_UI:慢
                 */
                sensorManager.registerListener(this,accelerometerSensor,SensorManager.SENSOR_DELAY_NORMAL);
                sensorManager.registerListener(this,magneticFieldSensor,SensorManager.SENSOR_DELAY_NORMAL);
            }
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            if(sensorManager != null){
                //解除注册
                sensorManager.unregisterListener(this,accelerometerSensor);
                sensorManager.unregisterListener(this,magneticFieldSensor);
            }
        }
    
    }
    

    简单的说,想要获取方向信息,需要使用加速度传感器和磁场域,然后分别获取他们的结果,然后使用SensorManager.getRotationMatrix(r,null,accelerometerValues,magneticValues)结合给r赋值再使用SensorManager.getOrientation(r,values)从r数组中解析出方向信息,并赋值给values数组。values数组中的第一个值就代表手机当前的角度。
    需要注意的是,加速度传感器和磁场域赋值的时候一定要调用values数组的clone()方法,不然,accelerometerValues和magneticValues会指向同一个引用.另外,accelerometerValues和magneticValues两个数组必须以成员变量的形式进行声明,而不能是局部变量。

  • 相关阅读:
    219. Contains Duplicate II
    189. Rotate Array
    169. Majority Element
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    119. Pascal's Triangle II
    118. Pascal's Triangle
    88. Merge Sorted Array
    53. Maximum Subarray
    CodeForces 359D Pair of Numbers (暴力)
  • 原文地址:https://www.cnblogs.com/CCCrunner/p/11781869.html
Copyright © 2011-2022 走看看