学习笔记:
一、摇一摇
实现的效果:在1.5秒内,出现两次,摇晃手机幅度(加速度)达到15,则算成功。
实现原理:
1、利用加速度传感器,并注册监听器
2、通过传感器回调中的x、y、z的值,做摇一摇动作的判定
3、根据条件,设置摇一摇监听回调的触发频率,以及震动提示
二、可配置项:
参数 | 作用描述 | 默认值 | 类型 |
---|---|---|---|
intervlTimeMillis | 间隔时间毫秒 | 1500L | Long |
thresholdCount | 到达阀值的次数 | 2 | Int |
shakeThreshold | 阀值 | 15 | Int |
isOpenVibrator | 摇一摇成功后,是否开启震动 | false | Boolean |
三、注意项
- 在规定的间隔时间内,有可能会出现多次摇一摇成功的情况;需要业务层作处理。
- 每次摇成功,都会有一次结果回调;未成功是没有结果回调的。
四、代码示例
class ShakeManager: SensorEventListener {
private var context: Context
private var intervlTimeMillis: Long // 时间范围;例如:1.5秒内,有2次加速度达到阀值,才算摇成功
private var thresholdCount: Int // 达到阀值的次数;例如:1.5秒内,有2次加速度达到阀值,才算摇成功
private var shakeThreshold: Int // 摇一摇加速度阀值
private var isOpenVibrator: Boolean // 是否打开震动器;摇一摇成功后,震动提示
private var mSensorMgr: SensorManager? = null // 声明一个传感管理器对象
private var sensor:Sensor? = null
private var mVibrator: Vibrator? = null // 声明一个震动器对象
private var onShakeListener:OnShakeListener? = null
private var lastShakeTime: Long = 0 // 上一次摇晃的时间
private var shakeCount: Int = 0 // 摇晃次数
/**
* @param intervlTime 时间范围;例如:1.5秒内,有2次加速度达到阀值,才算摇成功
* @param count 在规定时间内,达到阀值的次数;例如:1.5秒内,有2次加速度达到阀值,才算摇成功
* @param shakeRange 摇一摇加速度阀值
* @param isOpenVibrator 是否打开震动器;摇一摇成功后,震动提示
*/
constructor(context: Context, intervlTimeMillis: Long = 1500,
thresholdCount: Int = 2, shakeThreshold: Int = 15,
isOpenVibrator: Boolean = false, ) {
this.context = context
this.intervlTimeMillis = intervlTimeMillis
this.thresholdCount = thresholdCount
this.shakeThreshold = shakeThreshold
this.isOpenVibrator = isOpenVibrator
initShake()
}
/**
* 初始化,加速度传感器,震动传感器
*/
private fun initShake() {
mSensorMgr = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
if (isOpenVibrator){
mVibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
}
// 给加速度传感器注册传感监听器
mSensorMgr!!.registerListener(
this,
mSensorMgr!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL
)
}
/**
* 释放,加速度传感器,震动传感器
*/
fun releaseShake(){
mSensorMgr?.unregisterListener(this)
if (isOpenVibrator){
mVibrator?.cancel()
}
}
interface OnShakeListener{
fun onShake(isSuccess:Boolean)
}
fun setOnShakeListener(listener:OnShakeListener){
onShakeListener = listener
}
override fun onSensorChanged(event: SensorEvent) {
if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) { // 加速度变更事件
val currentTime = System.currentTimeMillis()
if (currentTime - lastShakeTime > intervlTimeMillis) { // 两次摇晃间隔大于1.5秒则重置摇晃次数
shakeCount = 0
}
val values = event.values
if ((abs(values[0]) > shakeThreshold || abs(values[1]) > shakeThreshold || abs(values[2]) > shakeThreshold)) {
lastShakeTime = currentTime // 更新上一次摇晃时间
shakeCount++
if (shakeCount >= thresholdCount) { // 达到两次摇晃且加速度达到要求
if (isOpenVibrator){
mVibrator?.vibrate(500) // 系统检测到摇一摇事件后,震动手机提示用户
}
shakeCount = 0 // 重置摇晃次数
lastShakeTime = 0 // 更新时间,重新计时2s
onShakeListener?.onShake(true) // 通知摇一摇成功
}
}
}
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
}