摇一摇demo

1.需求:摇一摇伴随振动,能获取到 摇一摇 开始 结束的消息。
2.过程:网上好多摇一摇demo,到自己用的时候,还是找了半天,借鉴了几篇,记录下来,方便复用。
3.实现:
3.1 Mainifest里添加振动权限

<uses-permission android:name="android.permission.VIBRATE"/>

3.2
基本步骤:

  1. 获取SensorManager,注册加速计
  2. 内部类ShakeSensorListener实现SensorEventListener,重写onSensorChanged的方法,根据加速值判断 是否摇动,摇动时振动
  3. 添加boolean tag isShake,标记是否在摇动,开始摇的时候发送 SHAKE_START消息,结束时发送 SHAKE_END 消息
    代码如下:
package shake.jieqiong.com.shake;

import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;

public class MainActivity extends Activity {

    private static final String TAG = "###MainActivity";
    private static final int SHAKE_START = 1;
    private static final int SHAKE_END = 2;

    SensorManager sensorManager;
    ShakeSensorListener shakeListener;
    private boolean isShake;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SHAKE_START:
                    isShake = true;
                    Log.d(TAG, "handleMessage:: start shake SHAKE_START");

                    break;
                case SHAKE_END:
                    Log.d(TAG, "handleMessage:: end shake SHAKE_END");
                    mHandler.removeMessages(SHAKE_END);
                    isShake = false;
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //获取 sensorManager
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        shakeListener = new ShakeSensorListener();
    }


    @Override
    protected void onResume() {
        super.onResume();
        //register AccelerometerSensor
        if (null != sensorManager) {
            Log.v(TAG, "onResume:: register TYPE_ACCELEROMETER");
            sensorManager.registerListener(shakeListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                    SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (null != sensorManager) {
            sensorManager.unregisterListener(shakeListener);
        }
    }

    private class ShakeSensorListener implements SensorEventListener {
        //检测的时间间隔
        static final int UPDATE_INTERVAL = 100;
        //上一次检测的时间
        long mLastUpdateTime;
        //上一次检测时,加速度在x、y、z方向上的分量,用于和当前加速度比较求差。
        float mLastX, mLastY, mLastZ;

        //摇晃检测阈值,决定了对摇晃的敏感程度,越小越敏感。
        public int shakeThreshold = 500;
        private static final int ACCELERATE_VALUE = 20;

        @Override
        public void onSensorChanged(SensorEvent event) {

            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                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) {
                    Log.v(TAG, "onSensorChanged:: shake");
                    Vibrator vibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
                    vibrator.vibrate(100);

                    if (!isShake) {
                        mHandler.sendEmptyMessage(SHAKE_START);
                    }
                    mHandler.removeMessages(SHAKE_END);
                } else if (isShake &&
                           (Math.abs(x) < ACCELERATE_VALUE && Math.abs(y) < ACCELERATE_VALUE &&
                            Math.abs(z) < ACCELERATE_VALUE)) {
                    mHandler.sendEmptyMessageDelayed(SHAKE_END, 300);
                }
            }

        }

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

        }
    }
}

摇动手机会打如下log

12-07 11:19:01.916 15276-15276/? V/###MainActivity: onResume:: register TYPE_ACCELEROMETER
12-07 11:19:04.058 15276-15276/? V/###MainActivity: onSensorChanged:: shake
12-07 11:19:04.071 15276-15276/? D/###MainActivity: handleMessage:: start shake SHAKE_START
12-07 11:19:04.453 15276-15276/? V/###MainActivity: onSensorChanged:: shake
12-07 11:19:04.649 15276-15276/? V/###MainActivity: onSensorChanged:: shake
12-07 11:19:04.846 15276-15276/? V/###MainActivity: onSensorChanged:: shake
12-07 11:19:05.346 15276-15276/? D/###MainActivity: handleMessage:: end shake SHAKE_END

demo地址:
https://github.com/FloraJieQiong/shake
http://download.youkuaiyun.com/detail/jieqiong1/9704156

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值