`
不夜的星辰
  • 浏览: 87845 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

android 实现甩屏

阅读更多

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

想到这个功能可能应用广泛,比如摇晃手机换图片、截图、洗牌、结束当前程序等,所以找了些资料,并加以改进,将此功能封装成类(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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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()用于停止摇晃检测

参考资料:
http://www.clingmarks.com/?p=25
http://android.hlidskialf.com/blog/code/android-shake-detection-listener

 

注:此文转载

分享到:
评论

相关推荐

    Google Android SDK开发范例大全(PDF高清完整版1)(4-1)

    3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast...

    Google Android SDK开发范例大全(PDF完整版4)(4-4)

    3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast...

    Google Android SDK开发范例大全(PDF高清完整版3)(4-3)

    3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast...

    Google Android SDK开发范例大全的目录

    3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast...

    android重力感应甩歌音乐播放器

    2. **重力感应器**:Android设备内置的重力感应器是实现甩歌功能的关键。它能检测设备在三维空间中的加速度变化,包括重力加速度和动态加速度。通过监听SensorManager的SensorEvent事件,可以获取到设备的实时姿态...

    Google Android SDK开发范例大全(完整版附部分源码).pdf

    3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——...

    Android表白秀恩爱源码

    8. **自定义视图**:为了实现独特的表白效果,开发者可能会创建自定义视图类,扩展Android的View或ViewGroup,以实现更复杂的交互和视觉效果。 9. **第三方库集成**:为了简化开发或增强功能,源码中可能会集成一些...

    android音乐播放器

    "甩歌"功能是一种手势识别的实现,通常依赖于SensorManager类,监听加速度传感器的变化。当检测到特定的甩动模式(比如设备的加速度在短时间内迅速改变)时,播放器会执行下一首或上一首歌曲的操作。 歌词同步功能...

    Google Android SDK 开发范例大全01

    3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast...

    Google Android SDK 开发范例大全02

    3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast...

    Google+Android+SDK开发范例大全

    ——具选择功能的对话框 3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给...

    Google Android sdk 开发范例大全 部分章节代码

    3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast...

    Google Android SDK开发范例大全(完整版)

    3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast...

    推箱子简单游戏apk源码

    源码中还提到了“甩你画布”(可能是指“刷新画布”或“重绘画布”),这指的是Android的Canvas对象和绘图操作。在每次角色或箱子移动后,需要更新界面显示,这就需要用到`Canvas`进行绘制。开发者可能使用`onDraw()...

    第六小组彩电行业分析.pptx

    例如,创维32E7BRD在娱乐功能上的表现突出,长虹Android UTV Plus则带来了全新的智能互动体验,康佳X6000DS注重外观设计和实用性,海尔LE55A700K的无线甩屏功能增加了便利性,海信LED55K610X3D的深度定制Android系统...

    Delphi FireMonkey百叶窗动画效果.rar

    FireMonkey是Embarcadero Technologies开发的一个跨平台UI框架,用于构建高性能的原生应用程序,支持Windows、macOS、iOS和Android等多个操作系统。 百叶窗动画是一种常见于用户界面设计中的过渡效果,它模拟了百叶...

    新增手势功能 唯美GO桌面HD版本评测.docx

    用户现在可以通过长按图标并将其向任意方向甩出,轻松实现图标的删除,这种直观的手势操作使得管理桌面更加灵活和直观。 总的来说,GO桌面HD通过其精美的设计、强大的小部件管理和创新的手势操作,为Android平板...

    华为发布首款云手机Vision 云储存空间达160GB.docx

    发布会还展示了华为7英寸的平板电脑MediaPad,运行Android 3.2系统,搭载1.2GHz双核处理器,配备分辨率为1280x800的IPS屏幕,支持1080P全高清视频播放。据透露,MediaPad预计在第三季度在国内上市,售价约3000元...

Global site tag (gtag.js) - Google Analytics