资讯详情

Android 如何获取传感器的数据

1 传感器简介

传感器 Sensor 它是一种检测装置,可以感受到测量的信息,并将感觉到的信息按照一定的规则转换为电信号或其他形式的信息输出,以满足信息传输、处理、存储、显示、记录和控制的要求。 Android 只要为设备传感器提供支持, Android 该设备的硬件提供了这些传感器,Android 该应用程序可以通过传感器获得设备的外部条件,包括手机的运行状态、当前的方向等。Android 该系统还提供了一个驱动程序来管理这些传感器硬件,以监控传感器硬件所感知的外部环境的变化。Android 平台支持三类传感器:

类别 传感器 说明
运动传感器 TYPE_ACCELEROMETER 基于硬件的加速度传感器
TYPE_GRAVITY 基于硬件或软件的重力传感器
TYPE_GYROSCOPE 陀螺仪传感器以硬件为基础
TYPE_ROTATION_VECTOR 基于硬件或软件的旋转矢量传感器
TYPE_LINEAR_ACCELERATION 基于硬件或软件的线性加速度传感器
位置传感器 TYPE_MAGNETIC_FIELD 基于硬件的磁力传感器
TYPE_ORIENTATION 基于软件的方向传感器
TYPE_PROXIMITY 基于硬件的距离传感器
环境传感器 TYPE_LIGHT 基于硬件的光传感器
TYPE_PRESSURE 基于硬件的压力传感器
TYPE_TEMPERATURE 基于硬件的温度传感器
有的传感器基于硬件,有的基于软件。基于硬件的传感器是内置在手机或平板电脑上的物理组件。这种传感器通过直接测量特定的环境属性(如加速度、地磁场强度或角度变化)来收集数据。基于软件的传感器不是物理设备,它们只是模仿基于硬件的传感器。基于软件的传感器从一个或多个基于硬件的传感器中获取数据,有时被称为虚拟传感器或合成传感器。例如,基于软件的线性加速度传感器和重力传感器。

  • Android 2.2(API 级别 8)方向传感器已被废弃,Android 4.4W(API 级别 20)这种传感器类型已被弃用 TYPE_ORIENTATION。见后面的示例代码。
  • 温度传感器已经存在 Android 4.0(API 级别 14)放弃,不同的设备有不同的实现。

2 使用传感器

2.1 获取传感器服务

Android 为开发人员提供多种系统级服务,传感器也通过传感器服务 SensorManager 来管理的。而在 Android 在组件中获中获得系统服务 Context.getSystemService(String) 可以,它的参数都是 static final 定义的方在 Context 中,而获取 SensorManager 需要传入 Context.SENSOR_SERVICE。

SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 

2.2 获取待监控的传感器

所有器服务管理设备上的所有传感器,因此需要获得待监控的传感器。 可以通过在 getSensorList() 方法中传入 TYPE_ALL 获取设备上的所有传感器:

List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL); 

也可以指定 type 参数获得相应的传感器。如果设备上有多种特定类型的传感器,则必须将其中一种指定为默认传感器。如果没有指定的默认传感器,则该方法将返回 null,这意味着设备没有这种传感器。

Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 

  • 运行时检测。
if (sensor != null) { 
             //传感器存在 } else { 
             //传感器不存在 } 
  • 目标设备必须配备指定的传感器来限制使用清单文件。
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />

对于某一个传感器,它的一些具体信息的获取方法如下:

  • getMaximumRange() 最大取值范围
  • getName() 设备名称
  • getPower() 功率
  • getResolution() 精度
  • getType() 传感器类型
  • getVentor() 设备供应商
  • getVersion() 设备版本号

2.3 注册传感器的监听器

获得 SensorManager 和 Sensor 对象之后,就可以为其 Sensor 注册监听器了。为传感器注册监听器,使用 SensorManager.registerListener() 方法即可,它存在多个重载方法,但是有些方法已经过时了,下面提供一个常用的方法:

boolean registerListener(SensorEventListener listener,Sensor sensor,int rateUs)

上面方法参数的意义:listener:传感器的监听器、sensor:待监听的传感器、rateUs:传感器的采样率。 从 registerListener() 方法可以看出,它需要传递一个 SensorEventListener 对象,它就是传感器的监听器,其中包含两个方法,需要开发人员去实现它:

  • :当传感器感应的值发生变化时回调。
  • :当传感器精度发生变化时回调。 对于上面两个方法,传感器的精度一般是不会发生改变的,所以我们一般主要的代码量在 onSensorChanged()中。

在 onSensorChanged(SensorEvent event) 方法中有一个参数 event,通过 event 可以获取传感器的类型以及传感器的数据。

  • 获取传感器的类型:event.sensor.getType()
  • 获取传感器的数据:event.values[i],i为0,1,2…,不同传感器,event.values[i] 对应的数据不同。以加速度传感器为例,values[0] 表示x轴上的加速度,values[1] 表示y轴上的加速度,values[2] 表示z轴上的加速度。 Sensor API 使用的坐标系

registerListener() 方法还有一个 rateUs 的参数,它表示监听传感器改变的采样率,就是从传感器获取值的频率。它被定义以 static final 的形式定义在 SensorManager 中,方便我们直接使用,它定义了如下几个参数:

参数 延时 说明
SensorManager.SENSOR_DELAY_FASTEST 0ms 一般不是特别敏感的处理不推荐使用,该种模式可能造成手机电力大量消耗,由于传递的为原始数据,算法不处理好将会影响游戏逻辑和 UI 的性能。
SensorManager.SENSOR_DELAY_GAME 20ms 一般绝大多数的实时性较高的游戏都使用该级别。
SensorManager.SENSOR_DELAY_UI 60ms 适合普通用户界面 UI 变化的频率,相对节省电能和逻辑处理,一般游戏开发中不使用。
SensorManager.SENSOR_DELAY_NORMAL 200ms 对于一般的益智类或 EASY 级别的游戏可以使用,但过低的采样率可能对一些赛车类游戏有跳帧现象。

Android 为我们提供了这几个采样率的参数,方便我们使用。但对于选择那种采样率而言,并不是越快越好,要参照实际开发的应用的情况来说,采样率越大,将越耗费资源,包括电量、CPU 等,所以要根据实际情况选择,毕竟再强大的应用,如果造成设备续航能力的降低,也是会被用户所不喜的。

2.4 注销传感器的监听器

当使用完传感器之后,需要为其注销监听器,因为传感器的监听器并不会因为应用的结束而自行释放资源,需要开发人员在适当的时候主动注销。注销传感器监听器使用 SensorManager.unregisterListener() 方法即可,和监听器的注册方法一样,它也具有多个重载的方法,但是有一些已经被弃用了,下面介绍一个常用的:

void unregisterListener(SensorEventListener listener)

3 示例代码

Java 代码如下:

public class MainActivity extends AppCompatActivity { 
        
    private final String TAG = "sensor-sample";
    private TextView mAccelerometerSensorTextView;
    private TextView mMagneticSensorTextView;
    private TextView mGyroscopeSensorTextView;
    private TextView mOrientationSensorTextView;
    private SensorManager mSensorManager;
    private MySensorEventListener mMySensorEventListener;
    private float[] mAccelerometerReading = new float[3];
    private float[] mMagneticFieldReading = new float[3];

    @Override
    protected void onCreate(Bundle savedInstanceState) { 
        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mAccelerometerSensorTextView = findViewById(R.id.accelerometer_sensor);
        mMagneticSensorTextView = findViewById(R.id.magnetic_sensor);
        mGyroscopeSensorTextView = findViewById(R.id.gyroscope_sensor);
        mOrientationSensorTextView = findViewById(R.id.orientation_sensor);

        this.mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        this.mMySensorEventListener = new MySensorEventListener();
    }

    @Override
    protected void onResume() { 
        
        super.onResume();
        if (mSensorManager == null) { 
        
            return;
        }

        Sensor accelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (accelerometerSensor != null) { 
        
            //register accelerometer sensor listener
            mSensorManager.registerListener(mMySensorEventListener, accelerometerSensor, SensorManager.SENSOR_DELAY_UI);
        } else { 
        
            Log.d(TAG, "Accelerometer sensors are not supported on current devices.");
        }

        Sensor magneticSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        if (magneticSensor != null) { 
        
            //register magnetic sensor listener
            mSensorManager.registerListener(mMySensorEventListener, magneticSensor, SensorManager.SENSOR_DELAY_UI);
        } else { 
        
            Log.d(TAG, "Magnetic sensors are not supported on current devices.");
        }

        Sensor gyroscopeSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
        if (gyroscopeSensor != null) { 
        
            //register gyroscope sensor listener
            mSensorManager.registerListener(mMySensorEventListener, gyroscopeSensor, SensorManager.SENSOR_DELAY_UI);
        } else { 
        
            Log.d(TAG, "Gyroscope sensors are not supported on current devices.");
        }
    }

    @Override
    protected void onPause() { 
        
        super.onPause();
        if (mSensorManager == null) { 
        
            return;
        }
        //unregister all listener
        mSensorManager.unregisterListener(mMySensorEventListener);
    }

    /* This orientation sensor was deprecated in Android 2.2 (API level 8), and this sensor type was deprecated in Android 4.4W (API level 20). The sensor framework provides alternate methods for acquiring device orientation. */
    private void calculateOrientation() { 
        
        final float[] rotationMatrix = new float[9];
        SensorManager.getRotationMatrix(rotationMatrix, null, mAccelerometerReading, mMagneticFieldReading);

        final float[] orientationAngles = new float[3];
        SensorManager.getOrientation(rotationMatrix, orientationAngles);
        Log.d(TAG, "orientation data[x:" + orientationAngles[0] + ", y:" + orientationAngles[1] + ", z:" + orientationAngles[2] + "]");
        mOrientationSensorTextView.setText("[x:" + orientationAngles[0] + ", y:" + orientationAngles[1] + ", z:" + orientationAngles[2] + "]");
    }

    private class MySensorEventListener implements SensorEventListener { 
        
        @Override
        public void onSensorChanged(SensorEvent event) { 
        
            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 
        
                mAccelerometerReading = event.values;
                Log.d(TAG, "accelerometer data[x:" + event.values[0] + ", y:" + event.values[1] + ", z:" + event.values[2] + "]");
                mAccelerometerSensorTextView.setText("[x:" + event.values[0] + ", y:" + event.values[1] + ", z:" + event.values[2] + "]");
            } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { 
        
                mMagneticFieldReading = event.values;
                Log.d(TAG, "magnetic data[x:" + event.values[0] + ", y:" + event.values[1] + ", z:" + event.values[2] + "]");
                mMagneticSensorTextView.setText("[x:" + event.values[0] + ", y:" + event.values[1] + ", z:" + event.values[2] + "]");
            } else if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) { 
        
                Log.d(TAG, "gyroscope data[x:" + event.values[0] + ", y:" + event.values[1] + ", z:" + event.values[2] + "]");
                mGyroscopeSensorTextView.setText("[x:" + event.values[0] + ", y:" + event.values[1] + ", z:" + event.values[2] + "]");
            }
            calculateOrientation();
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) { 
        
            Log.d(TAG, "onAccuracyChanged:" + sensor.getType() + "->" + accuracy);
        }

    }
}

运行效果如下:

示例代码下载:sensor-sample

详细参考 Android 开发者官方文档:传感器

标签: 磁传感器装置内置传感器类型3408556传感器android传感器类别android设备传感器相关传感器组件用于什么设备

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台