Android 如何获取传感器的数据方法详解

目录
  • 1 传感器简介
  • 2 传感器的使用
    • 2.1 获取传感器服务
    • 2.2 获取待监听的传感器
    • 2.3 注册传感器的监听器
    • 2.4 注销传感器的监听器
  • 3 示例代码

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 对象,它就是传感器的监听器,其中包含两个方法,需要开发人员去实现它:

  • void onSensorChanged(SensorEvent event):当传感器感应的值发生变化时回调。
  • void onAccuracyChanged(Sensor sensor,int accuracy):当传感器精度发生变化时回调。 对于上面两个方法,传感器的精度一般是不会发生改变的,所以我们一般主要的代码量在 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轴上的加速度。

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);
        }

    }
}

运行效果如下:

到此这篇关于Android 如何获取传感器的数据的文章就介绍到这了,更多相关Android 获取传感器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android传感器数据获取的方法

    本文实例为大家分享了Android传感器数据获取的具体代码,供大家参考,具体内容如下 接着上篇wifi列表获取,我们这篇接着说传感器.还是看代码 我们先自己定义一个传感器的工具类(因为我这边只是获取了部分的传感器,需要获取额外的传感器自己配置一下就行了,工具类通过重载提供了不同的构造方法): public class SensorUtils implements SensorEventListener { private SensorManager manager; /** * @param c

  • Android编程实现获取所有传感器数据的方法

    本文实例讲述了Android编程实现获取所有传感器数据的方法.分享给大家供大家参考,具体如下: main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" androi

  • Android开发获取传感器数据的方法示例【加速度传感器,磁场传感器,光线传感器,方向传感器】

    本文实例讲述了Android开发获取传感器数据的方法.分享给大家供大家参考,具体如下: package mobile.android.sensor; import java.util.List; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import an

  • Android 如何获取传感器的数据方法详解

    目录 1 传感器简介 2 传感器的使用 2.1 获取传感器服务 2.2 获取待监听的传感器 2.3 注册传感器的监听器 2.4 注销传感器的监听器 3 示例代码 1 传感器简介 传感器 Sensor 是一种检测装置,能感受到被测量的信息,并能将感受到的信息,按一定规律变换成为电信号或其他所需形式的信息输出,以满足信息的传输.处理.存储.显示.记录和控制等要求. Android 提供了对设备传感器的支持,只要 Android 设备的硬件提供了这些传感器,Android 应用可以通过传感器来获取设备

  • Android 通过代码安装 APK的方法详解

    在 APK 开发中,通过 Java 代码来打开系统的安装程序以安装 APK 并不是什么难事,一般的 Android 系统都有开放这一功能. 但随着 Android系统版本的迭代,其对于权限的把控越来越严格,或者说是变得越来越注重安全性.这就导致了以前可以通过很简单的几行代码就能实现的功能,现在要复杂很多. 对于通过代码打开系统安装程序这一功能的限制,其分水岭在 Android7.0,即 Android N 上.通常在 Android N以上的系统使用一种做法,以下则使用另一种做法. 传统的通过代

  • 对python3 Serial 串口助手的接收读取数据方法详解

    其实网上已经有许多python语言书写的串口,但大部分都是python2写的,没有找到一个合适的python编写的串口助手,只能自己来写一个串口助手,由于我只需要串口能够接收读取数据就可以了,故而这个串口助手只实现了数据的接收读取. 创建串口助手首先需要创建一个类,重构类的实现过程如下: #coding=gb18030 import threading import time import serial class ComThread: def __init__(self, Port='COM3

  • Android适配底部虚拟按键的方法详解

    最近项目进行适配的时候发现部分(如华为手机)存在底部虚拟按键的手机会因为虚拟按键的存在导致挡住部分界面,因为需要全屏显示,故调用虚拟按键隐藏方法使之隐藏,然而发现出现如下问题: 手动操作隐藏虚拟按键后出现长白条区域 不自动隐藏 滑出状态栏后虚拟按键也出来,状态栏隐藏后虚拟却不跟着隐藏 在没有虚拟按键的设备上影响了SurfaceView全屏显示图传(原本全屏显示的图传在切出去再进来时变成了小屏显示) 通过google了很多方法并尝试终于解决了这个问题,达到如下效果: 每次进入界面时虚拟按键自动隐藏

  • 利用Pytorch实现获取特征图的方法详解

    目录 简单加载官方预训练模型 图片预处理 提取单个特征图 提取多个特征图 简单加载官方预训练模型 torchvision.models预定义了很多公开的模型结构 如果pretrained参数设置为False,那么仅仅设定模型结构:如果设置为True,那么会启动一个下载流程,下载预训练参数 如果只想调用模型,不想训练,那么设置model.eval()和model.requires_grad_(False) 想查看模型参数可以使用modules和named_modules,其中named_modul

  • Android 实现获取手机里面的所有图片详解及实例

    Android 实现获取手机里面的所有图片详解及实例 实现代码: public class MainActivity extends Activity { //查看图片按钮 private Button look; private Button add; //显示图片名称的list ListView show_list; ArrayList names = null; ArrayList descs= null; ArrayList fileNames = null; @Override pro

  • Android程序打包为APK的方法详解

    Andriod安装包文件(Android Package),简称APK,后缀名为.apk. 1.生成未签名的安装包 Build -> Build Bundle(s)/APK(s) -> Build APK(s)    会生成一个未签名的apk文件,默认为debug版,可以正常安装使用. 可以 Build -> Select Build Variant -> 选择生成的apk版本(debug.release),再 Build -> Build Bundle(s)/APK(s)

  • python更新数据库中某个字段的数据(方法详解)

    连接数据库基本操作,我把每一步的操作是为什么给大家注释一下,老手自行快进. 请注意这是连接数据库操作,还不是更新. import pymysql #导包 #连接数据库 db = pymysql.connect(host='localhost', user='用户名', password='数据库密码', port=3306, db='你的数据库名字') #定义游标 cursor = db.cursor() #sql语句 sql = 'select * from students;' cursor

  • javascript解析json格式的数据方法详解

    JSON (JavaScript Object Notation)是一种简单的数据格式,比xml更轻巧. 它是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON 数据不需要任何特殊的 API 或工具包.那么如何用JavaScript来解析json呢? 首先,科普一下json.在json中,有两种结构:对象和数组. 一个对象以"{"(左括号)开始,"}"(右括号)结束.每个"名称"后跟一个":"

  • js 数组当前行添加数据方法详解

    需求:1.点击新增一栏商品信息,表单验证区分 2.输入SKU编码,带出当前行的产品名称,品牌及单位 解决: 到此这篇关于js 数组当前行添加数据方法详解的文章就介绍到这了,更多相关js 数组当前行添加数据方法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

随机推荐