Android系统编程入门系列之硬件交互——传感器
到目前为止,关于应用程序与用户之间的相关内容便比较肤浅的大致介绍完毕。而在整个系统架构中,应用程序与用户之间的交互,犹如参天大树上的枝干和树叶,交互起来五彩缤纷,但使整个生态系统保持生命力的核心,在于树根,也就是应用程序通过Android系统与设备上硬件的交互。
设备硬件
设备的硬件目前主要分为三大类,包括传感器系列硬件(重力传感器、加速度传感器、陀螺仪、位置传感器、光亮传感器等),互联通信系列硬件(SIM卡,无线WLAN,蓝牙、NFC、USB等),多媒体系列硬件(麦克风、播放器、相机等)。
虽然设备硬件五花八门,但是在系统层都遵循各自的硬件协议封装了一层,而在应用程序内部只需要使用系统层提供的相关接口即可。不管是对哪种硬件的访问,首要步骤都是在应用程序的清单文件中,使用<uses-permission>
标签声明要使用的相关权限。
而对于某些设备非必需硬件,应用程序中可使用<uses-feature>
标签声明对某些硬件的需求,以兼容应用程序在没有该硬件的设备上运行。
注意,使用
<uses-feature>
标签声明的硬件需求,在应用程序安装到设备时,并不会检查该设备是否支持相关需求硬件,而只是在其他服务如官方Google Play中、或应用程序内部运行到相关硬件支持代码时,检测相关声明。
传感器系列硬件
权限声明
对于传感器系列硬件,需要声明权限名称为Manifest.permission.BODY_SENSORS,另外,在Android10.0即API 31及以上的版本中,还可以使用Manifest.permission.HIGH_SAMPLING_RATE_SENSORS权限以更快速的刷新获取传感器的数据。
使用流程
与传感器系列硬件的交互,主要借助android.hardware.SensorManager传感器管理类,该类的对象,可以在能获取上下文环境Context
对象的地方,调用其getSystemService(Context.SENSOR_SERVICE)
获取系统服务对象,将返回的结果类型强制转换为SensorManager
类型即可。
在得到SensorManager
传感器管理类的对象后,可以调用其getSensorList(int type)
方法,参数 type 可以指定为代表所有传感器类型的Sensor.TYPE_ALL=-1
,也可以指定某一类具体的传感器,这些类型及数值都是在android.hardware.Sensor传感器类中定义的静态常量。而该方法的返回结果,也是List<Sensor>
传感器集合,里边包含了当前系统所在设备的所有可使用的传感器信息。
而如果设备中有多个同一类型的传感器,可以调用getDefaultSensor(int type)
方法,参数 type 同样是指定的某一种传感器类型,返回该类型传感器所使用的默认一个Sensor
传感器对象,如果系统硬件中没有正常使用该类型的传感器,则会返回null
。
对于通过传感器管理类对象找到的Sensor
传感器对象,可以调用其getX()
系列方法,获取传感器的一些基本信息,方法名中的X
包括Id
、Name
、Version
等。
在找到匹配的Sensor
传感器对象后,就可以在合适的时机,开启实时监测该传感器获得的数据,以及在合适的时机,关闭对该传感器数据的监测活动。通常为了节省资源,在界面Activity
的onResume()
方法中开启监测,并在对应的onPause()
方法中关闭监测。
开启监测是调用SensorManager
对象的registerListener(SensorEventListener listener, Sensor sensor, int samplingPeriodUs, int maxReportLatencyUs, Handler handler)
方法。参数 listener 是android.hardware.SensorEventListener传感器事件监听器接口所实现的对象,在传感器发出数据时会回调该对象所实现的方法;参数 sensor 则是上文所匹配的要检测的Sensor
传感器对象;参数 samplingPeriodUs 是用int
类型标记的监测频率,其值是SensorManager
中定义的静态常量,包括正常频率SENSOR_DELAY_NORMAL=3
, 稍微快一点以在界面更新时的频率SENSOR_DELAY_UI=2
, 再快一点以在游戏更新时的频率SENSOR_DELAY_GAME=1
, 和最快的频率SENSOR_DELAY_FASTEST=0
;参数 maxReportLatencyUs 为可选参数,是int
类型表示传感器更新数据后回调上文监听接口对象的方法时的最大延时,单位是毫秒,且默认值为0;参数 handler 同样为可选参数,传感器发出的数据在回调上文的监听器接口对象后,也会交付到该Handler
类型的对象中处理,默认值为null。
关闭监测是调用SensorManager
对象的unregisterListener(SensorEventListener listener, Sensor sensor)
方法。参数 listener 即在开启监测方法中传入的SensorEventListener
监听器接口对象;参数 sensor 是可选参数,为开启监测方法中传入的Sensor
传感器对象,当该参数默认值为null时,则会对所有开启参数 listener 监听的传感器对象的监测活动都关闭。
在该SensorEventListener
传感器事件监听接口的实例化对象中,需要实现两个方法,包括onAccuracyChanged(Sensor sensor, int accuracy)
,和onSensorChanged(SensorEvent event)
方法。
其中,onAccuracyChanged(Sensor sensor, int accuracy)
方法会在传感器的精确度发生变化时回调,其参数 sensor 为发生变化的Sensor
传感器对象;参数 accuracy 是int
类型的标记,由SensorManager
定义的静态常量,其值包括传感器数据不允许应用程序访问的SENSOR_STATUS_NO_CONTACT=-1
,传感器需要校准或无法正常访问的SENSOR_STATUS_UNRELIABLE=0
,低精确度需要校准的SENSOR_STATUS_ACCURACY_LOW=1
。普通精确度可以检测平均值的SENSOR_STATUS_ACCURACY_MEDIUM=2
,高精确度非常精准的SENSOR_STATUS_ACCURACY_HIGH=3
。
onSensorChanged(SensorEvent event)
方法会在传感器更新数据时回调,其参数 event 是android.hardware.SensorEvent传感器事件类,该类型中包含了Sensor
传感器以及更新的float[]
数据等信息,其中的数据数组长度及内容,则是根据传感器的不同类型所确定的。
应用场景
类似指南针类应用,计步器类应用,自动调节屏幕亮度等功能,都是依靠传感器系列硬件实现的。应用程序借助传感器系列硬件,感知外界环境的动态变化,从而实时展示给用户查看,而这个数据流向是单向的。