Android Sensor Development
本文我们说一下Android中的传感器,这对于我们有时候做一些特殊的应用的时候还是需要的,这里我用小米手机下载了一个安兔兔,我们来看下大致的传感器
安兔兔上面,有很多的传感器对吧,但是他们大致的其实是分三类,在我们的官方文档上,是这样说的
一.传感器概述
大多数Android设备都具有测量运动,方向和各种环境条件的内置传感器。这些传感器能够以高精度和精确度提供原始数据,如果要监视三维设备移动或定位,或者想要监视设备附近的环境环境中的变化,这些传感器很有用。例如,游戏可以跟踪来自设备的重力传感器的读数,以推断复杂的用户手势和运动,例如倾斜,摇动,旋转或摆动。同样,天气应用可能会使用设备的温度传感器和湿度传感器来计算和报告露点,或旅行应用程序可能会使用地磁场传感器和加速度计来报告罗盘方位。
Android平台支持三大类传感器:
- 运动传感器
这些传感器测量沿着三个轴的加速力和旋转力。该类别包括加速度计,重力传感器,陀螺仪和旋转矢量传感器。
- 环境传感器
这些传感器测量各种环境参数,例如环境空气温度和压力,照明和湿度。此类别包括气压计,光度计和温度计。
- 位置传感器
这些传感器测量设备的物理位置。该类别包括定向传感器和磁力计
上面说的天花乱坠,其实我们可以这样去总结
- 方向 TYPE_ORIENTATION
- 加速 TYPE_ACCELEROMETER
- 光纤 TYPE_LIGHT
- 磁场 TYPE_MAGNETIC_FIELD
- 距离 TYPE_PROXIMITY
- 温度 TYPE_TEMPERATURE
二.传感器框架
您可以使用Android传感器框架访问这些传感器并获取原始传感器数据。传感器框架是android.hardware包的一部分,包括以下类和接口:
- SensorManager
您可以使用此类创建传感器服务的实例。该类提供了访问和列出传感器,注册和注销传感器事件监听器以及获取方向信息的各种方法。该类还提供了几个传感器常数,用于报告传感器精度,设置数据采集率和校准传感器。
- Sensor
您可以使用此类创建特定传感器的实例。该类提供了各种可以确定传感器功能的方法。
- SensorEvent
系统使用此类创建传感器事件对象,该对象提供有关传感器事件的信息。传感器事件对象包括以下信息:原始传感器数据,生成事件的传感器类型,数据的准确性以及事件的时间戳。
- SensorEventListener
您可以使用此接口创建两个回传方法,当传感器值更改或传感器精度更改时接收通知(传感器事件)。
在典型的应用程序中,您可以使用这些与传感器相关的API执行两个基本任务:
- 识别传感器和传感器功能
如果您的应用程序具有依赖于特定传感器类型或功能的功能,则在运行时识别传感器和传感器功能非常有用。例如,您可能想要识别设备上存在的所有传感器,并禁用依赖于不存在的传感器的任何应用程序功能。同样,您可能想要识别给定类型的所有传感器,因此您可以选择具有最佳性能的传感器实现。
- 监控传感器事件
监控传感器事件是如何获取原始传感器数据。每当传感器检测到其测量参数的变化时,就会发生传感器事件。传感器事件为您提供四条信息:触发事件的传感器的名称,事件的时间戳,事件的准确性以及触发事件的原始传感器数据。
三.传感器的可用性
虽然传感器可用性因设备而异,但Android版本也可能有所不同。这是因为在几个平台发布的过程中引入了Android传感器。例如,Android 1.5(API 3级)中引入了许多传感器,但有些没有实现,直到Android 2.3(API Level 9)才能使用。同样,Android 2.3(API 9级)和Android 4.0(API等级14)中引入了几种传感器。两个传感器已被弃用,并由更新更好的传感器代替。
表2总结了逐个平台的每个传感器的可用性。只列出了四个平台,因为这些是涉及传感器变化的平台。被列为不推荐使用的传感器仍然可以在随后的平台上使用(传感器位于设备上),这符合Android的前向兼容性策略。
四.识别传感器和传感器能力
我们尝试通过代码来获取设备上的传感器,其实代码是比较简单的,我们来看一下
//获取所有的传感器
private List<Sensor> getAllSensor() {
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
//这里的Type就是我们需要获取的传感器类型,这里我获取全部的
List<Sensor> mList = sensorManager.getSensorList(Sensor.TYPE_ALL);
return mList;
}
我们打印下
其实这个类型是一个实体类,也就是说我们依旧可以get单个元素,我这里就全部打印出来了
除了列出设备上的传感器之外,还可以使用Sensor该类的公共方法 来确定各个传感器的功能和属性。如果您希望应用程序根据设备上可用的传感器或传感器功能的不同而有所不同。例如,您可以使用getResolution()和getMaximumRange() 方法来获取传感器的分辨率和最大测量范围。您还可以使用该 getPower()方法来获取传感器的电源要求。
五.光线传感器
我们这里,就列举几个代表性的传感器来说一下就好了,通过代码个官方文档来实践
,我们来获取光线传感器的速率
//光线传感器
private void LightSensor() {
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
/**
* 注册事件
* 回调
* 传感器
* 采样率
*/
sensorManager.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
//光线强度
float values = event.values[0];
tvResult.append(values + "\n");
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, sensor, sensorManager.SENSOR_DELAY_UI);
}
可以看到我这里获取到光线传感器之后我就注册了一个监听,而速率就是在里面拿的
一般我们的自动调节亮度这种功能会需要到
使用传感器的时候一定要注意的就是资源的回收
@Override
protected void onDestroy() {
super.onDestroy();
if (sensorManager != null) {
sensorManager.unregisterListener(listener);
}
}
这里我们在销毁的时候就取消了监听
六.加速度传感器
加速度其实和光线传感器的代码差不多,我们可以看一下
//加速度传感器
private void AccelerometerSensor() {
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
listener = new LightSensorListener();
sensorManager.registerListener(listener, sensor, sensorManager.SENSOR_DELAY_UI);
}
我们的监听器
class LightSensorListener implements SensorEventListener {
@Override
public void onSensorChanged(SensorEvent event) {
//0: x轴 1:y轴 2:z轴
float values0 = event.values[0];
float values1 = event.values[1];
float values2 = event.values[2];
//计算加速度
tvResult.append("x轴:"+values0 + "y轴:" + values1 + "z轴:" + values2 + "\n");
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
这样就可以检测了
从源码中可以看到
我们可以根据这三个值去通过牛顿的第二定律去计算我们想要的值,或者套用自己专用的公式去操作等
七.方向传感器
写三个传感器,其实都类似,我们把不同的写法写上,如果你不知道values的具体用法,可以直接点开values的源码看他的注释,找到对应的传感器就好了,我们来再看下方向,等下尝试着自己实现一个指南针
同样的,我们先实现代码
//方向传感器
private void OrientationSensor() {
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
listener = new LightSensorListener();
sensorManager.registerListener(listener, sensor, sensorManager.SENSOR_DELAY_FASTEST);
}
而我们的指南针的功能,也是通过这个监听了
class LightSensorListener implements SensorEventListener {
@Override
public void onSensorChanged(SensorEvent event) {
//夹角度数
float values = event.values[0];
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
八.指南针
指南针的话,我们可以先吧UI实现
<RelativeLayout
android:layout_width="200dp"
android:layout_height="200dp">
<ImageView
android:id="@+id/iv_point"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/iv_pointer"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="北"
android:textColor="@android:color/background_dark"
android:textSize="18sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="南"
android:textColor="@android:color/background_dark"
android:textSize="18sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="西"
android:textColor="@android:color/background_dark"
android:textSize="18sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="东"
android:textColor="@android:color/background_dark"
android:textSize="18sp"/>
</RelativeLayout>
实现的效果
我们主要是怎么来实现这个指针的动画,这里直接用了一个旋转动画
class LightSensorListener implements SensorEventListener {
float lastValues = 0;
@Override
public void onSensorChanged(SensorEvent event) {
//夹角度数
float values = event.values[0];
//tvResult.setText("夹角:" + values);
/**
* 0:东
* 90:南
* 180:西
* 270:北
*/
RotateAnimation anim = new RotateAnimation(
-lastValues, values, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
iv_point.startAnimation(anim);
lastValues = values;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
这样我们就实现了
好的,到这里,我们的传感器就BB完了,有兴趣的同学可以加群
Android旅行的路途:484167109
当然,你也可以关注我的微信公众号