六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 757|回复: 0

[原创] 如何在android中实现shake的动作检测

[复制链接]

升级  60%

38

主题

38

主题

38

主题

秀才

Rank: 2

积分
140
 楼主| 发表于 2013-1-29 13:56:45 | 显示全部楼层 |阅读模式
新型的手机现在都加入了三维规则加速器(accelerometer), 所以手势/动作的检测也逐渐成为移动应用开发的一部分.  比如想擦掉一副画好的画, 可以轻微摇一摇你的手机, 就可以擦掉canvas里的graphics了.  第一次看见这个是07年在越狱了的iPhone上面一个叫SketchUp的软件.  还有就是todo list, 完成了的项目, 轻轻摇摇就自动删除了.

如何检测shake动作其实有好多种approach, 一个是ClingMarks写的一个博客提到过.  基本上就是把x,y,z三个
轴上的距离变化统统加起来, 然后除以间隔的时间, 得出一个速度, 然后如果这个速度是大于某一个值的话, 就是shake动作了.  我个人认为这个公式有偏差, 在某些情况下一些非shake的动作也会被检测成shake.  而且你并不知道是在哪个方向产生了这个shake动作.  所以我叫这种模式coarse-grain, 很粗糙.  但如果你并不关心shake的一些具体细节, 只是想知道是不是shake动作而已, 这个应该已经足够了.

在你的Activity里, 你要implement这个SensorListener:

public class ShakeActivity extends Activity implements SensorListener

然后你需要获取一个SensorManager:
sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);

然后注册自己这个感应器需要所获得的数据的flags:
ensorMgr.registerListener(this,SensorManager.SENSOR_ACCELEROMETER,SensorManager.SENSOR_DELAY_GAME);

在你的onSensorChange()方法中, 你有这个粗糙公式来确定shake动作:

public void onSensorChanged(int sensor, float[] values) {if (sensor == SensorManager.SENSOR_ACCELEROMETER) {long curTime = System.currentTimeMillis();// 每100毫秒检测一次if ((curTime - lastUpdate) > 100) {long diffTime = (curTime - lastUpdate);lastUpdate = curTime;x = values[SensorManager.DATA_X];y = values[SensorManager.DATA_Y];z = values[SensorManager.DATA_Z];float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;if (speed > SHAKE_THRESHOLD) {Log.d(”sensor”, “shake detected w/ speed: ” + speed);Toast.makeText(this, “shake detected w/ speed: ” + speed, Toast.LENGTH_SHORT).show();}last_x = x;last_y = y;last_z = z;}}}

这个shake的速度临界点值定义为:
private static final int SHAKE_THRESHOLD = 800;

这个实现其实是很简单的.  在我的下篇帖子中我会介绍比较细腻的检测方法, 也是我在iPhone开发中学到的一些心得.

本帖例子源码在附件里.
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表