首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

【Android】检测手机摇摆

2012-09-06 
【Android】检测手机摇晃做游戏的时候,一般都要使用到多种多样的传感器,以实现比较丰富的UI 互动,比如检测手

【Android】检测手机摇晃


做游戏的时候,一般都要使用到多种多样的传感器,以实现比较丰富的UI 互动,比如检测手机的晃动。

如何检测手机的摇晃和摇晃程度呢?

找了些资料,并加以改进,将此功能封装成类(ShakeDetector),方便今后使用。

?

http://blog.csdn.net/ZhengZhiRen/archive/2010/10/09/5930451.aspx

摇晃检测基于加速传感器(Sensor.TYPE_ACCELEROMETER)。

由于重力的存在,当手机静止放于桌面时,加速传感器也是有加速度的。

所以,仅通过是否有加速度来判断摇晃是不行的。

那么,判断加速度的变化吧。。。

在一个较短的时间间隔求出加速度的差值,跟一个指定的阈值比较,如果差值大于阈值,则认为是摇晃发生了。

ClingMarks的方法将x、y、z方向的加速度差值简单的加起来,我认为不是很准确。

加速度是向量,求差应该是各方向的差值平方后相加,再开方。(数学忘光了,没记错吧。。。)

?

代码

?

package zhengzhiren.android.hardware;import java.util.ArrayList;import android.content.Context;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.util.FloatMath;/** * 用于检测手机摇晃 *  * @author 郑智仁 * @see <a href="http://blog.csdn.net/zhengzhiren" mce_href="http://blog.csdn.net/zhengzhiren">Blog</a> */public class ShakeDetector implements SensorEventListener {/** * 检测的时间间隔 */static final int UPDATE_INTERVAL = 100;/** * 上一次检测的时间 */long mLastUpdateTime;/** * 上一次检测时,加速度在x、y、z方向上的分量,用于和当前加速度比较求差。 */float mLastX, mLastY, mLastZ;Context mContext;SensorManager mSensorManager;ArrayList<OnShakeListener> mListeners;/** * 摇晃检测阈值,决定了对摇晃的敏感程度,越小越敏感。 */public int shakeThreshold = 5000;public ShakeDetector(Context context) {mContext = context;mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);mListeners = new ArrayList<OnShakeListener>();}/** * 当摇晃事件发生时,接收通知 */public interface OnShakeListener {/** * 当手机摇晃时被调用 */void onShake();}/** * 注册OnShakeListener,当摇晃时接收通知 *  * @param listener */public void registerOnShakeListener(OnShakeListener listener) {if (mListeners.contains(listener))return;mListeners.add(listener);}/** * 移除已经注册的OnShakeListener *  * @param listener */public void unregisterOnShakeListener(OnShakeListener listener) {mListeners.remove(listener);}/** * 启动摇晃检测 */public void start() {if (mSensorManager == null) {throw new UnsupportedOperationException();}Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);if (sensor == null) {throw new UnsupportedOperationException();}boolean success = mSensorManager.registerListener(this, sensor,SensorManager.SENSOR_DELAY_GAME);if (!success) {throw new UnsupportedOperationException();}}/** * 停止摇晃检测 */public void stop() {if (mSensorManager != null)mSensorManager.unregisterListener(this);}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {// TODO Auto-generated method stub}@Overridepublic void onSensorChanged(SensorEvent event) {long currentTime = System.currentTimeMillis();long diffTime = currentTime - mLastUpdateTime;if (diffTime < UPDATE_INTERVAL)return;mLastUpdateTime = currentTime;float x = event.values[0];float y = event.values[1];float z = event.values[2];float deltaX = x - mLastX;float deltaY = y - mLastY;float deltaZ = z - mLastZ;mLastX = x;mLastY = y;mLastZ = z;float delta = FloatMath.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ* deltaZ)/ diffTime * 10000;if (delta > shakeThreshold) { // 当加速度的差值大于指定的阈值,认为这是一个摇晃this.notifyListeners();}}/** * 当摇晃事件发生时,通知所有的listener */private void notifyListeners() {for (OnShakeListener listener : mListeners) {listener.onShake();}}}
??如何使用ShakeDetector
    new一个ShakeDetector调用mShakeDetector.registerOnShakeListener()注册一个OnShakeListener在OnShakeListener的onShake函数中,处理摇晃事件调用mShakeDetector.start()启动摇晃检测mShakeDetector.stop()用于停止摇晃检测

?

热点排行