要监视原始的传感器数据,你需要实现两个通过SensorEventListener接口暴露的回调方法:onAccuracyChanged()和onSensorChanged()。
传感器数据的速度值,这些值如下:
1.SENSOR_DELAY_GAME : 如果利用传感器开发游戏,建议使用该值。 一般大多数实时行较高的游戏使用该级别。
2.SENSOR_DELAY_NORMAL : 默认的获取传感器数据的速度。标准延迟,对于一般的益智类游戏或者EASY界别的游戏可以使用,但过低的采样率可能对一些赛车类游戏有跳帧的现象。
3.SENSOR_DELAY_UI : 若使用传感器更新UI, 建议使用该值。
4.SENSOR_DELAY_FASTEST:最低延迟,一般不是特别灵敏的处理不推荐使用,该模式可能造成手机电力大量消耗,而且由于传递的为大量的原始数据,算法处理不好将会影响游戏逻辑和UI的性能。
ShakeListener:
用了SensorListener,在1.5上会有警告,于是改成SensorEventListener了。
引用的命名空间:
1 import android.hardware.Sensor; 2 import android.hardware.SensorEvent; 3 import android.hardware.SensorEventListener; 4 import android.hardware.SensorManager;
1 public class ShakeListener implements SensorEventListener { 2 // 速度阈值,当摇晃速度达到这值后产生作用 3 private static final int SPEED_SHRESHOLD = 3000; 4 // 两次检测的时间间隔 5 private static final int UPTATE_INTERVAL_TIME = 70; 6 // 传感器管理器 7 private SensorManager sensorManager; 8 // 传感器 9 private Sensor sensor; 10 // 重力感应监听器 11 private OnShakeListener onShakeListener; 12 // 上下文 13 private Context mContext; 14 // 手机上一个位置时重力感应坐标 15 private float lastX; 16 private float lastY; 17 private float lastZ; 18 // 上次检测时间 19 private long lastUpdateTime; 20 21 // 构造器 22 public ShakeListener(Context c) { 23 // 获得监听对象 24 mContext = c; 25 start(); 26 } 27 28 // 开始 29 public void start() { 30 // 获得传感器管理器 31 sensorManager = (SensorManager) mContext 32 .getSystemService(Context.SENSOR_SERVICE); 33 if (sensorManager != null) { 34 // 获得重力传感器 35 sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 36 } 37 // 注册 38 if (sensor != null) { 39 sensorManager.registerListener(this, sensor, 40 SensorManager.SENSOR_DELAY_GAME); 41 } 42 43 } 44 45 // 停止检测 46 public void stop() { 47 sensorManager.unregisterListener(this); 48 } 49 50 // 设置重力感应监听器 51 public void setOnShakeListener(OnShakeListener listener) { 52 onShakeListener = listener; 53 } 54 55 // 重力感应器感应获得变化数据 56 public void onSensorChanged(SensorEvent event) { 57 // 现在检测时间 58 long currentUpdateTime = System.currentTimeMillis(); 59 // 两次检测的时间间隔 60 long timeInterval = currentUpdateTime - lastUpdateTime; 61 // 判断是否达到了检测时间间隔 62 if (timeInterval < UPTATE_INTERVAL_TIME) 63 return; 64 // 现在的时间变成last时间 65 lastUpdateTime = currentUpdateTime; 66 67 // 获得x,y,z坐标 68 float x = event.values[0]; 69 float y = event.values[1]; 70 float z = event.values[2]; 71 72 // 获得x,y,z的变化值 73 float deltaX = x - lastX; 74 float deltaY = y - lastY; 75 float deltaZ = z - lastZ; 76 77 // 将现在的坐标变成last坐标 78 lastX = x; 79 lastY = y; 80 lastZ = z; 81 82 double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ 83 * deltaZ) / timeInterval * 10000; 85 Log.v("thelog", "===========log==================="); 86 // 达到速度阀值,发出提示 87 if (speed >= SPEED_SHRESHOLD) { 88 onShakeListener.onShake(); 89 } 90 } 91 92 public void onAccuracyChanged(Sensor sensor, int accuracy) { 93 94 } 95 96 // 摇晃监听接口 97 public interface OnShakeListener { 98 public void onShake(); 99 } 100 101 }
在Activity的onPause和onResume函数里需要调用ShakeListener实例的pause和resume过程,注册和注销事件监听:在这个类中添加取代start方法
1 public void resume() { 2 sensorManager = (SensorManager) mContext 3 .getSystemService(Context.SENSOR_SERVICE); 4 if (sensorManager == null) { 5 throw new UnsupportedOperationException("Sensors not supported"); 6 } 7 8 boolean supported = sensorManager.registerListener(this, mSensorMgr 9 .getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 10 SensorManager.SENSOR_DELAY_UI); 11 if (!supported) { 12 sensorMagager.unregisterListener(this); 13 throw new UnsupportedOperationException( 14 "Accelerometer not supported"); 15 } 16 } 17 18 public void pause() { 19 if (mSensorMgr != null) { 20 mSensorMgr.unregisterListener(this); 21 mSensorMgr = null; 22 } 23 }
运用ShakeListener:
1 mShakeListener = new ShakeListener(this); 2 mShakeListener.setOnShakeListener(new OnShakeListener() { 3 public void onShake() { 5 startAnim(); //开始 摇一摇手掌动画 6 mShakeListener.stop(); 7 startVibrato(); //开始 震动 8 new Handler().postDelayed(new Runnable(){ 9 @Override 10 public void run(){ 12 Toast mtoast; 13 mtoast = Toast.makeText(getApplicationContext(), 14 "抱歉,暂时没有找到 在同一时刻摇一摇的人。 再试一次吧!", 10); 16 mtoast.show(); 17 mVibrator.cancel(); 18 mShakeListener.start(); 19 } 20 }, 2000); 21 } 22 });
其他传感器:
1 int TYPE_ACCELEROMETER 加速度传感器 2 int TYPE_ALL 所有类型 3 int TYPE_GRAVITY A constant describing a gravity sensor type. 4 int TYPE_GYROSCOPE 回转仪传感器陀螺仪传感器 5 int TYPE_LIGHT 光线传感器 6 int TYPE_LINEAR_ACCELERATION //线性加速度传感器 7 int TYPE_MAGNETIC_FIELD 磁场传感器 8 int TYPE_ORIENTATION 磁场传感器 9 int TYPE_PRESSURE 压力计传感器 10 int TYPE_PROXIMITY 距离传感器近程传感器 11 int TYPE_ROTATION_VECTOR //旋转向量传感器 12 int TYPE_TEMPERATURE 温度传感器
注意:
虽然AndroidSDK定义了十多种传感器,但并不是每一部手机都完全支持这些传感器。例如,Google Nexus S支持其中的9种传感器(不支持压力和温度传感器),而HTC G7只支持其中的5种传感器。如果使用了手机不支持的传感器,一般不会抛出异常,但也无法获得传感器传回的数据。读者在使用传感器时最好先判断当前的手机是否支持所使用的传感器。