android 类似微信的摇晃触发事件(确认可行,已封装,可直接调用)
来源:互联网 发布:寻仙3100端口怎么回事 编辑:程序博客网 时间:2024/05/17 07:05
看了网上很多关于此类方法的介绍,最多的是使用加速传感器,根据三个分量(x,y,z)的差值相加来判断移动距离,可是我觉得不太靠谱,三个分量差值平方和开平方才是正确距离,至少从数学角度来着,这样比较精确,以下是代码(注释已经比较详细了)。不好意思代码做了点修改,现在已经没问题了,控制时间间隔和阀值都是可以自己设定的,因机器原因而导致的问题可通过调节这两个参数来匹配。
[代码]java代码:
package com.zero.lessions.recorder;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;public class ShakeInterface implements SensorEventListener { //检测摇动相关变量 private long initTime = 0; private long lastTime = 0; private long curTime = 0; private long duration = 0; /** * 上次检测时,各分量 * */ private float last_x = 0.0f,last_y = 0.0f,last_z = 0.0f; /** * 本次晃动值 * */ private float shake = 0.0f; /** * 控制时间间隔 * */ private int TimeInterval = 100; /** * 晃动阀值 * */ private int shakeThreshold = 3000; private boolean isRecoding = false; private SensorManager mSensorManager; private ArrayList<OnShakeListener> mListeners; public ShakeInterface(Context context){ mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); mListeners = new ArrayList<OnShakeListener>(); } /** * 定义摇晃发生时的事件处理接口,需实现onShake方法 */ 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(); }else{ System.out.println("注册成功"); } } /** * 停止摇晃检测 */ public void stop() { if (mSensorManager != null) mSensorManager.unregisterListener(this); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { //什么也不干 System.out.println("精度发生变化"); } //传感器数据变动事件 @Override public void onSensorChanged(SensorEvent event) { //如果没有开始录音的话可以监听是否有摇动事件,如果有摇动事件可以开始录音 //获取加速度传感器的三个参数 float x = event.values[SensorManager.DATA_X]; float y = event.values[SensorManager.DATA_Y]; float z = event.values[SensorManager.DATA_Z]; //获取当前时刻的毫秒数 curTime = System.currentTimeMillis(); if(!isRecoding){ //100毫秒检测一次 //System.out.println("开始变化,curtime:" + curTime +"lasttime:" + lastTime); if ((curTime - lastTime) > TimeInterval) { duration = (curTime - lastTime); // 看是不是刚开始晃动 if (last_x == 0.0f && last_y == 0.0f && last_z == 0.0f) { //last_x、last_y、last_z同时为0时,表示刚刚开始记录 initTime = System.currentTimeMillis(); } else { //精确算法,各方向差值平方和开平方,单次晃动幅度 shake = FloatMath.sqrt((x - last_x)*(x - last_x)+(y - last_y)*(y - last_y)+(z - last_z)*(z - last_z))/duration*10000; } System.out.println(shake); if(shake >= shakeThreshold){ //此处开始执行 this.notifyListeners(); } last_x = x; last_y = y; last_z = z; lastTime = curTime; } } } /** * 当摇晃事件发生时,通知所有的listener */ private void notifyListeners() { for (OnShakeListener listener : mListeners) { System.out.println("你执行了?"); isRecoding = true; listener.onShake(); } }public int getTimeInterval() {return TimeInterval;}public void setTimeInterval(int timeInterval) {TimeInterval = timeInterval;}public int getShakeThreshold() {return shakeThreshold;}public void setShakeThreshold(int shakeThreshold) {this.shakeThreshold = shakeThreshold;}public boolean isRecoding() {return isRecoding;}public void setRecoding(boolean isRecoding) {this.isRecoding = isRecoding;} }
使用时需要在Activity中创建ShakeInterface的对象,调用registerOnShakeListener方法,当然调用此方法时还需要实现OnShakeListener的接口,也就是具体摇晃事件发生时需要处理的动作。最后再调用start方法开启监听。别忘了在关闭Activity时注销下(即调用stop方法,我是拦截了返回按钮,退出Activity时注销滴),此外,值得注意的是,如果响应完一次摇晃动作后是不会立即响应第二次的,除非调用setRecoding(false)方法,将判断位置为false才会继续响应摇晃事件。希望我的代码对大家有帮助,谢谢。
0 0
- android 类似微信的摇晃触发事件(确认可行,已封装,可直接调用)
- Android网络请求--动态加载的效果(已封装、可直接使用)
- android利用Chronometer实现倒计时(已封装,可直接使用)
- Android摇晃监听事件
- Java 封装的邮件发送类,可直接调用(基于Maven)
- Android封装类似微信的顶部TitleBar弹出的PopupWindow代码
- android 类似微信的摇一摇实现
- 封装好的Android对话框Dialog,包含了丰富的dialog样式、点击事件数据回传接口。直接调用封装好的方法即可操作dialog
- js 直接触发事件
- Android调用系统分享直接抵达微信
- 使用最原始的http-post方式上传图片 ,上传工具类已封装 可直接使用
- Android 制作可独立运行的Android模拟器(2.2,2.3亲测可行)
- Android端可用的AES加密/解密,已直接封装为文件加密
- 封装好的Android 微信支付
- appdelegate中事件的触发调用
- 微信公众号支付(已封装和未封装)
- android学习笔记----类似微信的TabHost
- android实现类似微信的开门效果
- Linux中fork()函数详解
- View 绘制流程
- opencv中读取图像像素数据的问题
- error while loading shared libraries
- u-boot中SPL源代码分析
- android 类似微信的摇晃触发事件(确认可行,已封装,可直接调用)
- IOS经常用到的控件尺寸集合
- 用两个栈实现一个队列——我作为面试官的小结
- linux下动态链接库(.so)的显式调用和隐式调用
- What is The Rule of Three?
- java反射机制+方法体
- Annotation注解
- 使用HttpClient下载图片常用代码,以及下载失败原因
- 如何修改避免闪烁(Anti-Flicker)默认值