Android摇一摇功能实现(摇一摇监听)

近期项目中要求增加摇一摇功能,搜了相关帖子,自己整理一套代码,发个博客保留一份。

解析:Android中摇一摇主要通过[SensorManager]实现,想了解可以查一下。

上期的不够完善 更新了一下,添加了防暴力摇动控制

public class ShakeService implements SensorEventListener {
  private Context mContext;
  private final MyHandler mHandler;
  private static final int START_SHAKE = 0x1;
  private static final int END_SHAKE = 0x2;
  //传感器管理器
  private SensorManager mSensorManager;
  //检测的时间间隔
  private static final int UPDATE_INTERVAL = 130;
  //上一次检测的时间
  private long mLastUpdateTime;
  //上一次检测时,加速度在x、y、z方向上的分量,用于和当前加速度比较求差。
  private float mLastX, mLastY, mLastZ;
  //摇晃检测阈值,决定了对摇晃的敏感程度,越小越敏感。
  private static final int shakeThreshold = 3800;
  //记录摇动状态
  private boolean isShake = false;
  //动画
  private Animation rotateAnimation, alphaAnimation, translateAnimation;
  private static final int DURATION = 1000;
  private static final int DURATION_STAR = 800;

  public ShakeService(Context mContext) {
    this.mContext = mContext;
    mHandler = new MyHandler();
  }

  @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 =
        (float) (Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / diffTime * 10000);
    // 当加速度的差值大于指定的阈值,认为这是一个摇晃
    if (delta > shakeThreshold && !isShake) {
      isShake = true;

      Thread thread = new Thread() {
        @Override
        public void run() {
          super.run();
          try {
            if (isValid()) {
              mHandler.obtainMessage(START_SHAKE).sendToTarget();
            }
            //开始 展示动画效果
            //Thread.sleep(100);
            //再来一次提示
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      };
      thread.start();

    } else {
      mHandler.obtainMessage(END_SHAKE).sendToTarget();
    }
  }

  @Override
  public void onAccuracyChanged(Sensor sensor, int accuracy) {

  }

  public void start() {
    mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
    if (mSensorManager != null) {
      //传感器
      Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
      if (mSensor != null) {
        mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
      }
    }
  }

  public void Stop() {
    if (mSensorManager != null) {
      mSensorManager.unregisterListener(this);
      //清空消息队列
      mHandler.removeCallbacks(null);
      //置位可摇一摇
      isShake = false;
      //关闭动画
    }
    if (rotateAnimation != null) {
      rotateAnimation.cancel();
    }
    if (alphaAnimation != null) {
      alphaAnimation.cancel();
    }
    if (translateAnimation != null) {
      translateAnimation.cancel();
    }
  }

  private static final long intervalAtMillis = 1000L;
  private static long sLastTime;

  public static boolean isValid() {
    //防止暴力摇动
    long currentTime = System.currentTimeMillis();

    if (currentTime - sLastTime < intervalAtMillis) {
      return false;
    }
    sLastTime = currentTime;
    return true;
  }

  class MyHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      switch (msg.what) {
        case START_SHAKE:
          //发出动画触发,执行动画
          break;
        case END_SHAKE:
          isShake = false;
          break;
      }
    }
  }


  //接口回调,摇一摇开始通知外部
  public interface onStartListener {
    void onStart();
  }

  public onStartListener startListener;

  public void setStartListener(onStartListener startListener) {
    this.startListener = startListener;
  }

}

动画部分 根据需求编写哦 

private void devilDialog() {
    final CustomDialog dialog = new CustomDialog(mContext);
    View view = LayoutInflater.from(mContext).inflate(R.layout.view_jackpot_shake, null);
    dialog.setCanceledOnTouchOutside(false);
    dialog.setContentView(view);
    dialog.show();

    ImageView devilFish = view.findViewById(R.id.iv_devilFish);
    ImageView background = view.findViewById(R.id.iv_background);
    ImageView soccer = view.findViewById(R.id.iv_soccer);
    ImageView star1 = view.findViewById(R.id.iv_star1);
    ImageView star2 = view.findViewById(R.id.iv_star2);
    ImageView star3 = view.findViewById(R.id.iv_star3);

    rotateAnimation =
        new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
            0.5f);
    rotateAnimation.setDuration(3000);
    //rotateAnimation.setRepeatCount(Animation.INFINITE);
    background.startAnimation(rotateAnimation);

    rotateAnimation.setAnimationListener(new Animation.AnimationListener() {
      @Override
      public void onAnimationStart(Animation animation) {
      }

      @Override
      public void onAnimationEnd(Animation animation) {
        //动画结束  关闭动画效果  通知外部摇一摇结束
        if (startListener != null) {
          startListener.onStart();
        }
        rotateAnimation.cancel();
        alphaAnimation.cancel();
        translateAnimation.cancel();
        dialog.dismiss();
      }

      @Override
      public void onAnimationRepeat(Animation animation) {

      }
    });

    //star闪烁  
    alphaAnimation = new AlphaAnimation(0.1f, 1.0f);
    alphaAnimation.setDuration(DURATION_STAR);
    alphaAnimation.setRepeatCount(Animation.INFINITE);
    alphaAnimation.setRepeatMode(Animation.REVERSE);
    star1.setAnimation(alphaAnimation);
    star2.setAnimation(alphaAnimation);
    star3.setAnimation(alphaAnimation);

    //soccer弹跳
    translateAnimation = new TranslateAnimation(0, 0, 0, 25);
    translateAnimation.setDuration(DURATION);
    translateAnimation.setInterpolator(new CycleInterpolator(Animation.INFINITE));
    translateAnimation.setRepeatCount(Animation.INFINITE);
    soccer.setAnimation(translateAnimation);

  }

猜你喜欢

转载自blog.csdn.net/weixin_43917449/article/details/101064587