最近做一个程序要实现一个Shake手机的特性。

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

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

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

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

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

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

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

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

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

所以就有了这行代码

[java]  view plain copy
  1. float delta = FloatMath.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / diffTime * 10000;

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

[java]  view plain copy
  1. package zhengzhiren.android.hardware;
  2. import java.util.ArrayList;
  3. import android.content.Context;
  4. import android.hardware.Sensor;
  5. import android.hardware.SensorEvent;
  6. import android.hardware.SensorEventListener;
  7. import android.hardware.SensorManager;
  8. import android.util.FloatMath;
  9. /**
  10. * 用于检测手机摇晃
  11. *
  12. * @author 郑智仁
  13. * @see <a href="http://blog.csdn.net/zhengzhiren" mce_href="http://blog.csdn.net/zhengzhiren">Blog</a>
  14. */
  15. public class ShakeDetector implements SensorEventListener {
  16. /**
  17. * 检测的时间间隔
  18. */
  19. static final int UPDATE_INTERVAL = 100;
  20. /**
  21. * 上一次检测的时间
  22. */
  23. long mLastUpdateTime;
  24. /**
  25. * 上一次检测时,加速度在x、y、z方向上的分量,用于和当前加速度比较求差。
  26. */
  27. float mLastX, mLastY, mLastZ;
  28. Context mContext;
  29. SensorManager mSensorManager;
  30. ArrayList<OnShakeListener> mListeners;
  31. /**
  32. * 摇晃检测阈值,决定了对摇晃的敏感程度,越小越敏感。
  33. */
  34. public int shakeThreshold = 5000;
  35. public ShakeDetector(Context context) {
  36. mContext = context;
  37. mSensorManager = (SensorManager) context
  38. .getSystemService(Context.SENSOR_SERVICE);
  39. mListeners = new ArrayList<OnShakeListener>();
  40. }
  41. /**
  42. * 当摇晃事件发生时,接收通知
  43. */
  44. public interface OnShakeListener {
  45. /**
  46. * 当手机摇晃时被调用
  47. */
  48. void onShake();
  49. }
  50. /**
  51. * 注册OnShakeListener,当摇晃时接收通知
  52. *
  53. * @param listener
  54. */
  55. public void registerOnShakeListener(OnShakeListener listener) {
  56. if (mListeners.contains(listener))
  57. return;
  58. mListeners.add(listener);
  59. }
  60. /**
  61. * 移除已经注册的OnShakeListener
  62. *
  63. * @param listener
  64. */
  65. public void unregisterOnShakeListener(OnShakeListener listener) {
  66. mListeners.remove(listener);
  67. }
  68. /**
  69. * 启动摇晃检测
  70. */
  71. public void start() {
  72. if (mSensorManager == null) {
  73. throw new UnsupportedOperationException();
  74. }
  75. Sensor sensor = mSensorManager
  76. .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
  77. if (sensor == null) {
  78. throw new UnsupportedOperationException();
  79. }
  80. boolean success = mSensorManager.registerListener(this, sensor,
  81. SensorManager.SENSOR_DELAY_GAME);
  82. if (!success) {
  83. throw new UnsupportedOperationException();
  84. }
  85. }
  86. /**
  87. * 停止摇晃检测
  88. */
  89. public void stop() {
  90. if (mSensorManager != null)
  91. mSensorManager.unregisterListener(this);
  92. }
  93. @Override
  94. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  95. // TODO Auto-generated method stub
  96. }
  97. @Override
  98. public void onSensorChanged(SensorEvent event) {
  99. long currentTime = System.currentTimeMillis();
  100. long diffTime = currentTime - mLastUpdateTime;
  101. if (diffTime < UPDATE_INTERVAL)
  102. return;
  103. mLastUpdateTime = currentTime;
  104. float x = event.values[0];
  105. float y = event.values[1];
  106. float z = event.values[2];
  107. float deltaX = x - mLastX;
  108. float deltaY = y - mLastY;
  109. float deltaZ = z - mLastZ;
  110. mLastX = x;
  111. mLastY = y;
  112. mLastZ = z;
  113. float delta = FloatMath.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ
  114. * deltaZ)
  115. / diffTime * 10000;
  116. if (delta > shakeThreshold) { // 当加速度的差值大于指定的阈值,认为这是一个摇晃
  117. this.notifyListeners();
  118. }
  119. }
  120. /**
  121. * 当摇晃事件发生时,通知所有的listener
  122. */
  123. private void notifyListeners() {
  124. for (OnShakeListener listener : mListeners) {
  125. listener.onShake();
  126. }
  127. }
  128. }

如何使用ShakeDetector

  1. new一个ShakeDetector
  2. 调用mShakeDetector.registerOnShakeListener()注册一个OnShakeListener
  3. 在OnShakeListener的onShake函数中,处理摇晃事件
  4. 调用mShakeDetector.start()启动摇晃检测
  5. mShakeDetector.stop()用于停止摇晃检测

参考资料:

http://www.clingmarks.com/?p=25

http://android.hlidskialf.com/blog/code/android-shake-detection-listener

Android摇晃检测ShakeDetector相关推荐

  1. Android下检测网络连接 3G WIFI

    Android下检测网络状态 3G WIFI 实现 代码如下 package Android.HelloAndroid; import android.app.Activity; import and ...

  2. android frida 检测_Android 逆向 | Frida 是万能的吗? 检测 Frida 的几种办法

    Frida 在逆向工程狮中很受欢迎,你基本可以在运行时访问到你能想到的任何东西,内存地址.native 函数.Java 实例对象等. 在 OWASP 的移动测试指南里就提到了 Frida.但是啊,每出 ...

  3. Android 手势检测实战 打造支持缩放平移的图片预览效果(下)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39480503,本文出自:[张鸿洋的博客] 上一篇已经带大家实现了自由的放大缩小图 ...

  4. android 人脸检测_Android人脸检测

    android 人脸检测 With the release of Google Play services 7.8, Google has brought in the Mobile Vision A ...

  5. 深度学习自学(六):Android人脸检测环境配置等相关问题

    Android人脸检测环境配置等相关问题 1.android studio 包查找不到 2.android studio 快捷键 搜索类的快捷键是Ctrl+N,搜索以后点击结果,可以跳到相应类的文件. ...

  6. Android中检测应用是否安装

    Android中检测应用是否安装有多种方法,其中比较常用的有如下2种: 1.通过获取系统上已安装的所有app列表来查找[不推荐.因为要获取已安装的所有app信息,可能会有隐私泄露风险] public ...

  7. Android模拟器检测体系梳理

    转自:https://www.wireghost.cn/2018/05/10/Android模拟器检测体系梳理/ 模拟器作为一种虚拟机,配合改机工具,能够以较低成本实现设备多开,因此而备受黑灰产的青睐 ...

  8. android安全检测工具,梆梆安全 - 防止反编译|APP安全加固|应用加固|盗版监测

    android安全检测工具,梆梆安全 - 防止反编译|APP安全加固|应用加固|盗版监测 https://dev.bangcle.com/ 业内专业的应用加固服务供应商 帮助数十万APP抵御破解风险, ...

  9. android 人脸检测 对焦,Android API教程:人脸检测(上)

    通过两个主要的API,Android提供了一个直接在位图上进行脸部检测的方法,这两个API分别是    android.media.FaceDetector和android.media.FaceDet ...

  10. Android内存检测工具系列工具集

    Android内存检测工具系列工具集 Android关于内存的工具不少,灵活地选择工具就显得特别重要.在此特别推荐分享涵盖一定初步和定位能力的工具,可以让我们一步到位地分析问题,提升效率. 在此列举几 ...

最新文章

  1. WEB+windows集群
  2. java 运算符_java 运算符
  3. 产品需求文档的10步
  4. iPhone客户端开发笔记(八)
  5. .NET 3.5 - DLINQ(LINQ to SQL)之面向对象的添加、查询、更新和删除
  6. 容器编排技术 -- Kubernetes StatefulSet基本使用
  7. 【SpringCloud】Spring cloud Alibaba Sentinel 服务熔断
  8. mysql 行转列 显示_mysql 行转列 (结果集以坐标显示)
  9. SharpMap在web上的应用
  10. matlab积分超过最大值,MATLAB 定积分上限是变量a,如何求解目标函数关于变量a的最大值?谢谢...
  11. 微信获取当前位置-vue中
  12. 很多网友问那个磁力搜索站好用,就由本君说说吧!
  13. LabView---信号发生器
  14. 查看手机 ip 地址的方法
  15. 2023年全国最新交安安全员精选真题及答案4
  16. rpm方式安装redis4.0
  17. Pikachu靶场之文件包含漏洞详解
  18. 谷歌气球 simplekml 入门《四》
  19. 【面向对象】小游戏“终结者”程序的设计与实现
  20. 苹果刷机未知错误75_被抢先体验的苹果iOS14 系统坑惨的用户,到底遇到了多少bug ,怎么降级系统...

热门文章

  1. 初识CTF Day3 CTFHUBRCE
  2. 编译原理课设:DO-WHILE循环语句的翻译程序设计
  3. 美国科学家开发模拟人类大脑视觉系统计算机
  4. 你没有迟到,只是活在自己的时区里
  5. YOLOv5进行半自动标注
  6. C语言:位运算符----与(),或(|),非(~),异或(^),左移(<<)和右移(>>)
  7. ubuntukylin(64bit)安装推荐
  8. [AAAI2019] DRr-Net:Dynamic Re-read Netwok for Sentence Semantic Matching
  9. 文章:Integration of omic networks in a developmental atlas of maize
  10. 网站建设时选公司要注意什么