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
原创粉丝点击