展会信息港展会大全

Android ShakeDetector 摇晃检测基于加速传感器
来源:互联网   发布日期:2016-01-14 11:22:29   浏览:1572次  

导读:最近要实现一个手机摇晃的功能。想到这个功能可能应用广泛,比如摇晃手机换图片、截图、洗牌、结束当前程序等,所以找了些资料,并加以改进,将此功能封装成类(ShakeDetector),方便今后使用。摇晃检测基于加速传......

最近要实现一个手机摇晃的功能。

想到这个功能可能应用广泛,比如摇晃手机换图片、截图、洗牌、结束当前程序等,所以找了些资料,并加以改进,将此功能封装成类(ShakeDetector),方便今后使用。

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

由于重力的存在,当手机静止放于桌面时,加速传感器也是有加速度的。所以,仅通过是否有加速度来判断摇晃是不行的。

那么,判断加速度的变化吧。在一个较短的时间间隔求出加速度的差值,跟一个指定的阈值比较,如果差值大于阈值,则认为是摇晃发生了。ClingMarks的方法将x、y、z方向的加速度差值简单的加起来,我认为不是很准确。

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

所以就有了这行代码:

float delta = FloatMath.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / diffTime * 10000;

功能封装成类ShakeDetector,实现了SensorEventListener接口,用于向系统注册传感器事件的Listener。

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 郑智仁

*/

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);

}

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

// TODO Auto-generated method stub

}

@Override

public 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

1、new一个ShakeDetector

2、调用mShakeDetector.registerOnShakeListener()注册一个OnShakeListener

3、在OnShakeListener的onShake函数中,处理摇晃事件

4、调用mShakeDetector.start()启动摇晃检测

5、mShakeDetector.stop()用于停止摇晃检测

赞助本站

人工智能实验室

相关热词: 摇晃 加速传感器

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港