`
mmdev
  • 浏览: 13450541 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

[Android实例] Android ShakeDetector(摇晃检测)教程详解

 
阅读更多
最近要实现一个手机摇晃 的功能。

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

由于重力的存在,当手机静止放于桌面时,加速传感器也是有加速度的。所以,仅通过是否有加速度来判断摇晃是不行的。
那么,判断加速度的变化吧。在一个较短的时间间隔求出加速度的差值,跟一个指定的阈值比较,如果差值大于阈值,则认为是摇晃发生了。ClingMarks的方法将x、y、z方向的加速度差值简单的加起来,我认为不是很准确。

加速度是向量,求差应该是各方向的差值平方后相加,再开方。(数学忘光了,应该没记错吧。)
所以就有了这行代码:

  1. float delta = FloatMath.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / diffTime * 10000;
复制代码
功能封装成类 ShakeDetector,实现了SensorEventListener接口,用于向系统注册传感器事件的Listener。

  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. */
  14. public class ShakeDetector implements SensorEventListener {
  15. /**
  16. * 检测的时间间隔
  17. */
  18. static final int UPDATE_INTERVAL = 100;
  19. /**
  20. * 上一次检测的时间
  21. */
  22. long mLastUpdateTime;
  23. /**
  24. * 上一次检测时,加速度在x、y、z方向上的分量,用于和当前加速度比较求差。
  25. */
  26. float mLastX, mLastY, mLastZ;
  27. Context mContext;
  28. SensorManager mSensorManager;
  29. ArrayList<OnShakeListener> mListeners;
  30. /**
  31. * 摇晃检测阈值,决定了对摇晃的敏感程度,越小越敏感。
  32. */
  33. public int shakeThreshold = 5000;

  34. public ShakeDetector(Context context) {
  35. mContext = context;
  36. mSensorManager = (SensorManager) context
  37. .getSystemService(Context.SENSOR_SERVICE);
  38. mListeners = new ArrayList<OnShakeListener>();
  39. }

  40. /**
  41. * 当摇晃事件发生时,接收通知
  42. */
  43. public interface OnShakeListener {
  44. /**
  45. * 当手机晃动时被调用
  46. */
  47. void onShake();
  48. }

  49. /**
  50. * 注册OnShakeListener,当摇晃时接收通知
  51. *
  52. * @param listener
  53. */
  54. public void registerOnShakeListener(OnShakeListener listener) {
  55. if (mListeners.contains(listener))
  56. return;
  57. mListeners.add(listener);
  58. }

  59. /**
  60. * 移除已经注册的OnShakeListener
  61. *
  62. * @param listener
  63. */
  64. public void unregisterOnShakeListener(OnShakeListener listener) {
  65. mListeners.remove(listener);
  66. }

  67. /**
  68. * 启动摇晃检测
  69. */
  70. public void start() {
  71. if (mSensorManager == null) {
  72. throw new UnsupportedOperationException();
  73. }
  74. Sensor sensor = mSensorManager
  75. .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
  76. if (sensor == null) {
  77. throw new UnsupportedOperationException();
  78. }
  79. boolean success = mSensorManager.registerListener(this, sensor,
  80. SensorManager.SENSOR_DELAY_GAME);
  81. if (!success) {
  82. throw new UnsupportedOperationException();
  83. }
  84. }

  85. /**
  86. * 停止摇晃检测
  87. */
  88. public void stop() {
  89. if (mSensorManager != null)
  90. mSensorManager.unregisterListener(this);
  91. }

  92. @Override
  93. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  94. // TODO Auto-generated method stub
  95. }

  96. @Override
  97. public void onSensorChanged(SensorEvent event) {
  98. long currentTime = System.currentTimeMillis();
  99. long diffTime = currentTime - mLastUpdateTime;
  100. if (diffTime < UPDATE_INTERVAL)
  101. return;
  102. mLastUpdateTime = currentTime;
  103. float x = event.values[0];
  104. float y = event.values[1];
  105. float z = event.values[2];
  106. float deltaX = x - mLastX;
  107. float deltaY = y - mLastY;
  108. float deltaZ = z - mLastZ;
  109. mLastX = x;
  110. mLastY = y;
  111. mLastZ = z;
  112. float delta = FloatMath.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ
  113. * deltaZ)
  114. / diffTime * 10000;
  115. if (delta > shakeThreshold) { // 当加速度的差值大于指定的阈值,认为这是一个摇晃
  116. this.notifyListeners();
  117. }
  118. }

  119. /**
  120. * 当摇晃事件发生时,通知所有的listener
  121. */
  122. private void notifyListeners() {
  123. for (OnShakeListener listener : mListeners) {
  124. listener.onShake();
  125. }
  126. }
  127. }
复制代码
如何使用ShakeDetector

1、new一个ShakeDetector
2、调用mShakeDetector.registerOnShakeListener()注册一个OnShakeListener
3、在OnShakeListener的onShake函数中,处理摇晃事件
4、调用mShakeDetector.start()启动摇晃检测
分享到:
评论

相关推荐

    最详细的Android开发教程实例

    本教程"最详细的Android开发教程实例"旨在提供一个全面的学习路径,帮助新手和有经验的开发者深入理解Android开发的核心概念和技术。 【Android开发入门】: Android开发入门是学习Android编程的第一步。"101- ...

    Android核心技术与实例详解 第2版

    Android核心技术与实例详解 第2版

    android核心技术与实例详解光盘源代码3

    在本资源中,我们聚焦于Android开发的核心技术和实例解析,主要涵盖了光盘源代码的第13至第18章。这些章节深入探讨了Android应用开发的关键方面,为开发者提供了丰富的学习材料。以下是对各章节内容的详细解读: 第...

    Android Studio实例代码.zip_Android app实例_Android实例_android app源码_and

    本压缩包“Android Studio实例代码.zip”包含了多个Android app的实例源码,旨在帮助开发者深入理解并实践Android应用开发。 1. **Android Studio基础** Android Studio基于IntelliJ IDEA,提供了强大的代码编辑、...

    Android手机摇晃检测简单例子 (源码)

    这个"Android手机摇晃检测简单例子(源码)"就是这样一个实例,它提供了源代码,帮助开发者理解如何实现这一功能。下面我们将深入探讨相关的知识点。 首先,Android设备上的加速度传感器是检测手机摇晃的关键。当...

    ABAQUS_6.6基础教程与实例详解

    本教程名为《ABAQUS_6.6基础教程与实例详解》,由刘展主编,祖景平、钱英莉、周华樟等编著,并由著名出版社中国水利水电出版社出版。本教程将ABAQUS 6.6的使用方法全面而系统地介绍给读者。本书分为两大部分:第一...

    ANSYS Workbench基础教程与实例详解.pdf

    ANSYS Workbench基础教程与实例详解

    [Android实例] Android 竖着的SeekBar

    android[Android实例] Android 竖着的SeekBar[Android实例] Android 竖着的SeekBar[Android实例] Android 竖着的SeekBar[Android实例] Android 竖着的SeekBar[Android实例] Android 竖着的SeekBar[Android实例] ...

    Android开心消消乐代码实例详解

    Android开心消消乐代码实例详解 Android开心消消乐代码实例详解是Android开发领域中非常重要的一部分,对于Android开发者来说,掌握开心消消乐代码实例是非常必要的。下面我们将从开心消消乐代码实例的基本概念、...

    android实例教程

    【Android实例教程】是针对Android开发者的实践指南,旨在通过一系列具体的代码示例来提升编程技能。本教程覆盖了Android应用开发的关键方面,包括UI设计、数据存储、网络通信、多线程、传感器使用等核心知识点。...

    [Android实例] 面试题集

    android[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] ...

    Android 实例 源码 39个

    "Android 实例 源码 39个"这个资源包包含了39个不同的Android应用实例,旨在帮助开发者深入理解Android应用的工作原理,提高编程技巧。这些实例涵盖了Android开发的多个方面,包括用户界面设计、数据存储、网络通信...

    Android实例开发完全手册 pdf

    全书分为16个章,分别讲解了UI布局实例、控件实例、自动化服务实例、数据存储实例、电话和短信实例、图形图像实例和网络有关的实例,以及多媒体实例、Google地图实例。Google API实例、平板电脑应用开发、游戏应用、...

    Android核心技术与实例详解书后源码

    《Android核心技术与实例详解》是一本深入探讨Android开发的书籍,涵盖了从基础到高级的各种主题。书中提供的源码是学习Android编程的重要参考资料,它能让读者更直观地理解书中的概念和实践技巧。以下是对这些源码...

    Android核心技术与实例详解—Android游戏开发实践—快乐数独(附完整源码)

    《Android核心技术与实例详解—Android游戏开发实践—快乐数独》是针对Android平台游戏开发的一份深入学习资源,其中包含了完整的源代码,旨在帮助开发者掌握Android游戏开发的关键技术和实践经验。这篇博文通过...

    android 实例源码 集合

    在Android开发领域,掌握实例源码是提升技能和理解系统工作原理的重要途径。"android 实例源码 集合" 提供了多种Android应用程序的源代码,这为我们提供了宝贵的参考资源,帮助开发者深入理解Android应用开发的各种...

    《Android核心技术与实例详解》所有源码

    《Android核心技术与实例详解》是一本深入探讨Android开发技术的专著,涵盖了Android开发的各个方面。这本书通过详尽的实例,旨在帮助读者掌握Android开发的核心技术,并提升实战能力。源码是学习过程中不可或缺的一...

    android实例开发完全手册光盘

    在Android实例开发中,完全手册通常会涵盖一系列的实践教程,旨在帮助开发者深入理解平台的工作原理,提升开发技能。这个“android实例开发完全手册光盘”包含了一系列的源代码,覆盖了不同的主题和应用场景,这对于...

    Android创意实例详解

    Android创意实例详解

    android最新实例教程修改版

    详细介绍安卓开发的最新技术,和各个常用控件的使用说明,并附有代码段,让你轻松进行学习安卓开发。

Global site tag (gtag.js) - Google Analytics