作者:力华
最近在做关于游戏手柄的Android项目,开始研究各种传感器,比如以手柄当球拍操纵网球游戏,需要用到加速度传感器,方向传感器等。Android优于其他嵌入式平台的一个方面就是方便地支持多种传感器,从Android1.5开始,系统就内置了对多达八种传感器的支持,他们分别是:加速度传感器(accelerometer),陀螺仪(gyroscope),环境光照传感器(light),磁力传感器(magnetic field),方向传感器(orientation),压力传感器(pressure),距离传感器(proximity)和温度传感器(temperature)
这八种传感器的类型常量和内部整数值分别如下:
传感器类型常量 内部整数值 中文名称
Sensor.TYPE_ACCELEROMETER 1 加速度传感器
Sensor.TYPE_MAGNETIC_FIELD 2 磁力传感器
Sensor.TYPE_ORIENTATION 3 方向传感器
Sensor.TYPE_GYROSCOPE 4 陀螺仪传感器
Sensor.TYPE_LIGHT 5 环境光照传感器
Sensor.TYPE_PRESSURE 6 压力传感器
Sensor.TYPE_TEMPERATURE 7 温度传感器
Sensor.TYPE_PROXIMITY 8 距离传感器
利用这些传感器我们可以制作出各种有趣的应用程序和游戏。需要提醒的是模拟器中无法模拟传感器,因此你需要准备一款Android真机来运行与传感器相关的例子。
从传感器管理器中获取其中某个或者某些传感器的方法有如下三种:
第一种:获取某种传感器的默认传感器
Sensor defaultGyroscope=sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
第二种:获取某种传感器的列表
List<Sensor> pressureSensors = sensorManager.getSensorList(Sensor.TYPE_PRESSURE);
第三种:获取所有传感器的列表
List<Sensor> allSensors =sensorManager.getSensorList(Sensor.TYPE_ALL);
对于某一个传感器,它的一些具体信息的获取方法可以见下表:
getMaximumRange() 最大取值范围
getName() 设备名称
getPower() 功率
getResolution() 精度
getType() 传感器类型
getVentor() 设备供应商
getVersion() 设备版本号
下面的代码是对方向和加速表传感器的设计。当收到更改时,传感器值在 TextView 小部件的屏幕上显示。
package com.pku.lihua;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.widget.TextView;
importandroid.hardware.SensorManager;
import android.hardware.SensorListener;
public class SensorTestextends Activity implements SensorListener {
final String tag = "SensorTest";
SensorManager sm = null;
TextView xViewA = null;
TextView yViewA = null;
TextView zViewA = null;
TextView xViewO = null;
TextView yViewO = null;
TextView zViewO = null;
/** Called when the activity is firstcreated. */
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
// get reference to SensorManager
sm = (SensorManager)getSystemService(SENSOR_SERVICE);
setContentView(R.layout.main);
xViewA = (TextView)findViewById(R.id.xbox);
yViewA = (TextView)findViewById(R.id.ybox);
zViewA = (TextView)findViewById(R.id.zbox);
xViewO = (TextView)findViewById(R.id.xboxo);
yViewO = (TextView)findViewById(R.id.yboxo);
zViewO = (TextView)findViewById(R.id.zboxo);
}
public void onSensorChanged(int sensor,float[] values) {
synchronized (this) {
Log.d(tag, "onSensorChanged:" + sensor + ", x: " +
values[0] + ", y:" + values[1] + ", z: " + values[2]);
if (sensor ==SensorManager.SENSOR_ORIENTATION) {
xViewO.setText("OrientationX: " + values[0]);
yViewO.setText("Orientation Y: " + values[1]);
zViewO.setText("Orientation Z: " + values[2]);
}
if (sensor ==SensorManager.SENSOR_ACCELEROMETER) {
xViewA.setText("Accel X: "+ values[0]);
yViewA.setText("Accel Y:" + values[1]);
zViewA.setText("Accel Z:" + values[2]);
}
}
}
public void onAccuracyChanged(int sensor,int accuracy) {
Log.d(tag,"onAccuracyChanged:" + sensor + ", accuracy: " + accuracy);
}
@Override
protected void onResume() {
super.onResume();
// register this class as a listener forthe orientation and accelerometer sensors
sm.registerListener(this,
SensorManager.SENSOR_ORIENTATION |SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onStop() {
// unregister listener
sm.unregisterListener(this);
super.onStop();
}
}
编写代码需要基于常见的活动,因为它只是利用从传感器获取的数据更新屏幕。该活动的 onCreate 方法可以引用 SensorManager,其中包含所有与传感器有关的函数。onCreate 方法还建立了对 6 个 TextView 小部件的引用,您需要使用传感器数据值更新这些小部件。
onResume() 方法使用对 SensorManager 的引用通过 registerListener 方法注册传感器更新:
第一个参数是实现 SensorListener 接口的类的实例。
第二个参数是所需传感器的位掩码。在本例中,应用程序从 SENSOR_ORIENTATION 和 SENSOR_ACCELEROMETER 请求数据。
第三个参数是一个系统提示,指出应用程序更新传感器值所需的速度。
应用程序暂停后,需要注销监听器,这样以后就不会再收到传感器更新。这通过 SensorManager 的 unregisterListener 方法实现。惟一的参数是 SensorListener 的实例。
在 registerListener 和 unregisterListener 方法调用中,应用程序使用关键字 this。注意类定义中的 implements 关键字,其中声明了该类实现 SensorListener 接口。这就是要将它传递到 registerListener 和 unregisterListener 的原因。
SensorListener 必须实现两个方法 onSensorChange 和 onAccuracyChanged。上面的代码不关心传感器的准确度,但关注传感器当前的 X、Y 和 Z 值。onAccuracyChanged 方法实质上不执行任何操作;它只在每次调用时添加一个日志项。
经常需要调用 onSensorChanged 方法,因为加速表和方向传感器正在快速发送数据。查看第一个参数确定哪个传感器在发送数据。确认了发送数据的传感器之后,将使用方法第二个参数传递的浮点值数组中所包含的数据更新相应的 UI 元素。该示例只是显示这些值,但在更加高级的应用程序中,还可以分析这些值,比较原来的值,或者设置某种模式识别算法来确定用户的行为。
传感器的特性和Android平台的开放性结合在一起,使得在移动手机终端上开发各种新奇有趣的传感器应用成为可能,也为开发人员开辟了一个新的应用领域。