美文网首页
Android传感器

Android传感器

作者: 残非 | 来源:发表于2019-10-29 08:24 被阅读0次

    一.Android的三大类传感器

    Android传感器按大方向划分大致有这么三类传感器:动作(Motion)传感器(来回摇动,动一动)、环境(Environmental)传感器(温度,湿度,广感)、位置(Position)传感器(定位)。

    (1)动作传感器

    这类传感器在三个轴(x、y、z)上测量加速度和旋转角度。包括如下几个传感器:
    加速(accelerometer)传感器:(手机摇一摇)
    重力(gravity)传感器、(愤怒的小鸟)
    陀螺仪(gyroscope)传感器、(指南针,还有我们以前玩的小游戏,通过手机控制方向玩摩托车)
    旋转向量(rotational vector )传感器(比如我们做地图的那个小图标,你转一下,手机也转一下)

    下面来看一下传感器世界的坐标系:


    传感器.png

    (2)环境传感器

    这类传感器可以测量不同环境的参数,例如,周围环境的空气温度和压强、光照强度和湿度。包括如下几个传感器:

    湿度(barometer)传感器、光线(photometer)传感器、温度(thermometer)传感器
    (3)位置传感器

    这类传感器可以测量设备的物理位置。包括如下几个传感器:

    方向(orientation)传感器(指南针除了用陀螺仪还要用方向)
    磁力(magnetometer)传感器(指南针的南北极)

    二.Android传感器的框架

    了解后我们就开始进入传感器的编程工作了,接下来我们看一下Android为我们提供的传感器框架(Android sensor framework,简称ASF)。

    android传感器有很多种,不同的设备上可能有不同的传感器,android系统中有一个专门管理传感器的对象

    获取手机的传感器

    通过实例化的SensorManager可以获取到手机的传感器集合

                //获取传感器SensorManager对象
              SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
              List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
              for (Sensor sensor : sensors) {
                     tvSensors.append(sensor.getName() + "\n");
              }
    

    Android对每个设备的传感器都进行了抽象,其中SensorManger类用来控制传感器,Sensor用来描述具体的传感器,SensorEventListener用来监听传感器值的改变。
    (1)SensorManager类(就相当于领导)
    用于创建sensor service的实例。该类提供了很多用于访问和枚举传感器,注册和注销传感器监听器的方法。而且还提供了与传感器精度、扫描频率、校正有关的常量。

    (2)Sensor类
    Sensor类为我们提供了一些用于获取传感器技术参数的方法。如版本、类型、生产商等。例如所有传感器的TYPE类型如下:


    传感器1.png

    (3)SensorEvent类
    系统使用该类创建传感器事件对象。该对象可以提供与传感器事件有关的信息。传感器事件对象包括的信息有原始的传感器回传数据、传感器类型、数据的精度以及触发事件的时间。

    (4)SensorEventListener接口
    该接口包含两个回调方法,当传感器的回传值或精度发生变化时,系统会调用这两个回调方法。

               /**
     * 传感器精度变化时回调
     * */
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
        /*
     * 传感器数据变化时回调
     */
    @Override
    public void onSensorChanged(SensorEvent event) {
    }
    

    三.获取传感器技术参数

    下来我们编写代码来获取一下自己手机的传感器技术参数

               //获取传感器SensorManager对象
    SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
     List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
    for (Sensor sensor : sensors) {    tvSensors.append(sensor.getName() + "\n");
    }
    

    各种传感器的使用:
    1.加速度传感器

    //创建一个SensorManager来获取系统的传感器服务
    sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    /*
     * 最常用的一个方法 注册事件
     * 参数1 :SensorEventListener监听器
     * 参数2 :Sensor 一个服务可能有多个Sensor实现,此处调用getDefaultSensor获取默认的Sensor
     * 参数3 :模式 可选数据变化的刷新频率,多少微秒取一次。
     * */
    //加速度传感器
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
    

    接下来我们只要监听这个传感器值的变化,然后更新textView的值就好了

              @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
    if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        float X_lateral = sensorEvent.values[0];
        float Y_longitudinal = sensorEvent.values[1];
        float Z_vertical = sensorEvent.values[2];
        mtextViewx.setText(X_lateral + "");
        mtextViewy.setText(Y_longitudinal + "");
        mtextViewz.setText(Z_vertical + "");
    }
    }
    

    在activity变为不可见的时候,传感器依然在工作,这样很耗电,所以我们根据需求可以在onStop方法里面停掉传感器的工作

    @Override
    public void onStop() {
    sm.unregisterListener(this);
    super.onStop();
    }
    

    2.磁场传感器

    和加速度计一样,为sensormanager监听磁场变化即可,把手机放在电脑旁边时候可以清楚看到数值的变化

    // 为磁场传感器注册监听器
    sm.registerListener(this,  sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL);
    else if(sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD){
    float X_lateral = sensorEvent.values[0];
    float Y_longitudinal = sensorEvent.values[1];
    float Z_vertical = sensorEvent.values[2];
    mtextView1.setText("x轴的磁场强度\n"+ X_lateral );
    mtextView2.setText("y轴的磁场强度\n"+ Y_longitudinal );
    mtextView3.setText("z轴的磁场强度\n"+ Z_vertical );
    }
    

    3.方向传感器

    这个可以用来做指南针之类的,绕z轴转过的角度为0时大概指向正北。这个TYPE_ORIENTATION接口不够精确已经过时了,可以使用旋转矩阵来代替。这里绕z轴转过的角度是value[0],看源码可得

    // 为方向传感器注册监听器
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
    else if(sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION){
    float X_lateral = sensorEvent.values[0];
    float Y_longitudinal = sensorEvent.values[1];
    float Z_vertical = sensorEvent.values[2];
    mtextView4.setText("绕z轴转过的角度\n"+ X_lateral );
    mtextView5.setText("绕x轴转过的角度\n"+ Y_longitudinal );
    mtextView6.setText("绕y轴转过的角度\n"+ Z_vertical );
    }
    

    4.陀螺仪传感器

    // 为陀螺仪传感器注册监听器
    
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);
    
    else if(sensorEvent.sensor.getType() == Sensor.TYPE_GYROSCOPE){
    
    //需要将弧度转为角度
    
    float X = (float)Math.toDegrees(sensorEvent.values[0]);
    
    float Y = (float)Math.toDegrees(sensorEvent.values[1]);
    
    float Z = (float)Math.toDegrees(sensorEvent.values[2]);
    
    mtextView7.setText("绕x轴转过的角速度\n"+ X );
    
    mtextView8.setText("绕y轴转过的角速度\n"+ Y );
    
    mtextView9.setText("绕z轴转过的角速度\n"+ Z );
    
    }
    

    5.重力传感器

    就是把重力加速度分解到xyz三个方向上

    // 为重力传感器注册监听器
    
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_NORMAL);
    
    else if(sensorEvent.sensor.getType() == Sensor.TYPE_GRAVITY){
    
    float X = sensorEvent.values[0];
    
    float Y = sensorEvent.values[1];
    float Z = sensorEvent.values[2];
    
    mtextViewgx.setText("x方向的重力加速度\n"+ X );
    
    mtextViewgy.setText("Y方向的重力加速度\n"+ Y );
    
    mtextViewgz.setText("Z方向的重力加速度\n"+ Z );
    

    6.线性加速度传感器

    就是去掉重力加速度后各个方向的加速度

    // 为线性加速度传感器注册监听器
    
    sm.registerListener(this,     sm.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION), SensorManager.SENSOR_DELAY_NORMAL);
    
    else if(sensorEvent.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION){
    
    float X = sensorEvent.values[0];
    
    float Y = sensorEvent.values[1];
    
    float Z = sensorEvent.values[2];
    
    mtextViewlx.setText("x方向的线性加速度\n"+ X );
    
    mtextViewly.setText("Y方向的线性加速度\n"+ Y );
    
    mtextViewlz.setText("Z方向的线性加速度\n"+ Z );
    
    }
    

    7.温度传感器

    这里的TYPE_TEMPERATURE已经过时,测出来的是cpu的温度,所以测出来的数值有点大,如果测环境温度的话应该使用

    TYPE_AMBIENT_TEMPERATURE。不过大部分手机都没有这个传感器

    // 为温度传感器注册监听器
    
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_TEMPERATURE), SensorManager.SENSOR_DELAY_NORMAL);
    
    
    else if(sensorEvent.sensor.getType() == Sensor.TYPE_TEMPERATURE){
    
    float X = sensorEvent.values[0];
    
    mtextView10.setText("温度为"+ X );
    }
    

    8.光传感器

    // 为光传感器注册监听器
    
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_NORMAL);
    
    else if(sensorEvent.sensor.getType() == Sensor.TYPE_LIGHT){
    
    float X = sensorEvent.values[0];
    
    mtextView11.setText("光强度为为"+ X );
    
    }
    

    9.距离传感器

    可以控制手机打电话时候息屏,如果使用光线传感器的话在黑夜中打电话就自动息屏了

    // 为距离传感器注册监听器
    
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_PROXIMITY), SensorManager.SENSOR_DELAY_NORMAL);
    
    
    else if(sensorEvent.sensor.getType() == Sensor.TYPE_PROXIMITY){
    float X = sensorEvent.values[0];
    mtextView12.setText("距离为"+ X );
    }
    

    10.压力传感器

    // 为压力传感器注册监听器
    
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_PRESSURE), SensorManager.SENSOR_DELAY_NORMAL);
    
    else if(sensorEvent.sensor.getType() == Sensor.TYPE_PRESSURE){
    float X = sensorEvent.values[0];
    mtextView13.setText("压强为"+ X );
    }
    

    11.计步传感器

    有两个接口,一个Counter统计的是总步数,而DETECTOR为该计步是否有效,有效的话就置1

    // 计步统计
    
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER), SensorManager.SENSOR_DELAY_NORMAL);
    
    // 单次计步
    
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR), SensorManager.SENSOR_DELAY_NORMAL);
    
    else if(sensorEvent.sensor.getType() == Sensor.TYPE_STEP_COUNTER){
    float X = sensorEvent.values[0];
    mtextView14.setText("COUNTER:"+ X );
    } else if(sensorEvent.sensor.getType() == Sensor.TYPE_STEP_DETECTOR){
    //检测到走动时值为1
    float X = sensorEvent.values[0];
    mtextView15.setText("DECTOR:"+ X );
    }
    

    相关文章

      网友评论

          本文标题:Android传感器

          本文链接:https://www.haomeiwen.com/subject/mcwvvctx.html