使用Android传感器框架访问传感器并获取原始传感器数据。传感器框架可以做什么?
- 确定设备上可用的传感器;
- 确定单个传感器的功能,例如:量程,制造商,功率要求和分辨率等;
- 获取原始数据并定义获取数据的最小速率;
- 注册和取消传感器事件监听。
传感器框架是android.hardware包的一部分,包括以下类和接口:
1、SensorManager:此类创建传感器服务的实例,提供了各种方法来访问和列出传感器,注册和取消注册传感器事件侦听器以及获取方向信息。该类还提供了几个传感器常数,用于报告传感器精度,设置数据采集速率和校准传感器。
2、Sensor:此类创建特定传感器的实例。此类提供了各种方法,可用于确定传感器的功能。
3、SensorEvent:此类创建传感器事件对象,该对象提供有关传感器事件的信息。传感器事件对象包括以下信息:原始数据,生成事件的传感器类型,数据的准确性以及事件的时间戳。
4、SensorEventListener:可以使用此界面创建两个回调方法,以便在传感器值更改或传感器精度更改时接收通知(传感器事件)。
框架实现两个基本任务:
5.1、识别传感器和传感器功能
要识别设备上的传感器,通过调用getSystemService()方法并传入SENSOR_SERVICE参数来创建SensorManager类的实例。 例如:
private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
接下来,通过调用getSensorList()方法并使用TYPE_ALL常量来获取设备上每个传感器的列表。例如:
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
如果要列出一类型的所有传感器,可以使用另一个常量,例如TYPE_GYROSCOPE、TYPE_LINEAR_ACCELERATION或TYPE_GRAVITY。
如果设备具有多个给定类型的传感器,必须将其中一个传感器指定为默认传感器。 如果给定类型的传感器不存在默认传感器,则方法调用返回null,意味着设备没有该类型的传感器。例如,以下代码检查设备上是否有Mag:
private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){
// Success!
} else {
// Failure!
}
我们还可以使用Sensor类的公共方法来确定各个传感器的功能和属性。例如,可以使用getResolution()和getMaximumRange()方法来获取传感器的分辨率和最大测量范围。
如果想针对不同制造商的传感器或不同版本的传感器进行优化。例如,应用程序监控用户手势(倾斜和晃动),可以为特定供应商的重力传感器创建一组数据过滤规则和优化,并为没有重力传感器,只有加速度计的设备创建另一组数据过滤规则和优化。
以下代码展示了如何使用getVendor()和getVersion()方法来执行此操作。示例中,我们正在寻找一种重力传感器,将Google LLC列为供应商,版本号为3.如果设备上没有该特定传感器,我们会尝试使用加速度计。
private SensorManager sensorManager;
private Sensor mSensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = null;
if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){
List<Sensor> gravSensors = sensorManager.getSensorList(Sensor.TYPE_GRAVITY);
for(int i=0; i<gravSensors.size(); i++) {
if ((gravSensors.get(i).getVendor().contains("Google LLC")) &&
(gravSensors.get(i).getVersion() == 3)){
// Use the version 3 gravity sensor.
mSensor = gravSensors.get(i);
}
}
}
if (mSensor == null){
// 使用加速度
if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
} else{
// 你的设备中没有加速度传感器
}
}
getMinDelay()方法返回传感器数据的最小时间间隔(以微秒为单位)。 任何为getMinDelay()返回非零值的传感器都是流传感器。
流传感器定期检测数据。如果在调用getMinDelay()方法时传感器返回零,则表示传感器不工作在轮询而是中断或其他,这时仅在感测到的参数发生变化时才报告数据。
如果应用程序中的某些功能需要高数据采集速率或流式传感器,则可以使用此方法确定传感器是否满足这些要求,然后相应地启用或禁用应用程序中的相关功能。
5.2、监控传感器事件
获取原始数据的方式。
每当传感器检测到其正在测量的参数发生变化时,就会发生传感器事件。
传感器事件提供四条信息:触发事件的传感器名称,事件的时间戳,事件的准确性以及触发传感器事件的原始数据。
要监视原始数据,需要实现两个SensorEventListener接口:onAccuracyChanged()和onSensorChanged()。每当发生以下情况时,Android系统都会调用这些方法:
- 传感器的精度发生变化:系统调用onAccuracyChanged()方法,提供已更改的Sensor对象的引用和传感器的新精度。精度有四种:SENSOR_STATUS_ACCURACY_LOW,SENSOR_STATUS_ACCURACY_MEDIUM,SENSOR_STATUS_ACCURACY_HIGH或SENSOR_STATUS_UNRELIABLE。
- 传感器报告新值:系统调用onSensorChanged()方法提供SensorEvent对象。SensorEvent对象包含有关新传感器数据的信息,包括:数据的准确性,生成数据的传感器,生成数据的时间戳以及传感器记录的新数据。
以下代码显示如何使用onSensorChanged()方法监视光感的数据。此示例在text.xml中显示原始数据,该文件在main.xml文件中定义为sensor_data.
public class SensorActivity extends Activity implements SensorEventListener {
private SensorManager sensorManager;
private Sensor mLight;
@Override
public final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
}
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// 传感器灵敏度变化后进行的动作
}
@Override
public final void onSensorChanged(SensorEvent event) {
// 光感返回单个数值
// 许多其他传感器会返回3个值, 每个轴各一个
float lux = event.values[0];
}
@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
}
在此示例中,调用registerListener()方法时指定默认数据延迟(SENSOR_DELAY_NORMAL)。数据延迟(或采样率)控制传感器事件通过onSensorChanged()回调方法发送到应用程序的时间间隔。例如SENSOR_DELAY_GAME(20,000微秒延迟),SENSOR_DELAY_UI(60,000微秒延迟)或SENSOR_DELAY_FASTEST(0微秒延迟)。指定的延迟仅是建议的延迟。
Android系统和其他应用程序可以改变这种延迟。使用较大的延迟会降低处理器的负载,从而降低功耗。
同样重要的是要注意,此示例使用onResume()和onPause()回调方法来注册和取消注册传感器事件侦听器。应始终禁用不需要的传感器,尤其是在活动暂停时。如果不这样做,可能会在几个小时内耗尽电池,因为某些传感器具有相当大的功率要求并且可能会快速耗尽电池电量。屏幕关闭时,系统不会自动禁用传感器。