Android摇一摇功能

2019-12-18  本文已影响0人  钦_79f7
  1. 利用加速度传感器,并注册监听器
  2. 通过回调中的x、y、z的值,做摇一摇动作的判定
  3. 结合自己的条件:如每2秒允许触发一次等,设置摇一摇监听回调的触发频率
  4. 触发监听回调的同时,调用震动传感器做震动提示,注意:震动的代码需要申请权限
/**
 * 注册摇一摇监听
 *
 * @return 将实际注册进入传感器中的监听对象返回,以便调用者寻找合适的时机解注册unregister
 */
@RequiresPermission(Manifest.permission.VIBRATE)
fun Context.registerShakeListener(onShakeListener: () -> Unit): SensorEventListener? {
    val manager = getSystemService(Context.SENSOR_SERVICE) as? SensorManager ?: return null
    val mSensorListener = object : SensorEventListener {
        private val SPEED_THRESHOLD = 2000
        // 两次检测的时间间隔
        private val UPDATE_INTERVAL_TIME = 100
        private var lastX: Float = 0f
        private var lastY: Float = 0f
        private var lastZ: Float = 0f
        private var lastUpdateTime: Long = 0
        private var lastInvokeTime: Long = 0

        override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}

        @SuppressLint("MissingPermission")
        override fun onSensorChanged(event: SensorEvent?) {
            event ?: return
            val currentUpdateTime = System.currentTimeMillis()// 两次检测的时间间隔
            val timeInterval = currentUpdateTime - lastUpdateTime// 判断是否达到了检测时间间隔
            if (timeInterval < UPDATE_INTERVAL_TIME) return

            // 现在的时间变成last时间
            lastUpdateTime = currentUpdateTime// 获得x,y,z坐标
            val x = event.values[0]
            val y = event.values[1]
            val z = event.values[2]// 获得x,y,z的变化值
            val deltaX = x - lastX
            val deltaY = y - lastY
            val deltaZ = z - lastZ// 将现在的坐标变成last坐标
            lastX = x
            lastY = y
            lastZ = z
//            Logs.d("onSensorChanged: $deltaX, $deltaY, $deltaZ")
            val speed = Math.sqrt((deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ).toDouble()) / timeInterval * 10000
//            Logs.i("onSensorChanged: $speed")
            // 达到速度阀值,发出提示
            if (speed >= SPEED_THRESHOLD && currentUpdateTime - lastInvokeTime > 2000) {//至少间隔两秒才允许下次触发
                lastInvokeTime = System.currentTimeMillis()
                (getSystemService(Context.VIBRATOR_SERVICE) as Vibrator).vibrate(200)
                onShakeListener()
            }
        }
    }
    manager.registerListener(mSensorListener, manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL)
    return mSensorListener
}

fun Context.unregisterShakeListener(listener: SensorEventListener?) {
    listener ?: return
    val manager = getSystemService(Context.SENSOR_SERVICE) as? SensorManager ?: return
    manager.unregisterListener(listener)
}

上一篇 下一篇

猜你喜欢

热点阅读