學習筆記:
一、搖一搖
實現的效果:在1.5秒內,出現兩次,搖晃手機幅度(加速度)達到15,則算成功。
實現原理:
1、利用加速度傳感器,并注冊監(jiān)聽器
2、通過傳感器回調中的x、y、z的值,做搖一搖動作的判定
3、根據條件,設置搖一搖監(jiān)聽回調的觸發(fā)頻率,以及震動提示
二、可配置項:
| 參數 | 作用描述 | 默認值 | 類型 |
|---|---|---|---|
| intervlTimeMillis | 間隔時間毫秒 | 1500L | Long |
| thresholdCount | 到達閥值的次數 | 2 | Int |
| shakeThreshold | 閥值 | 15 | Int |
| isOpenVibrator | 搖一搖成功后,是否開啟震動 | false | Boolean |
三、注意項
- 在規(guī)定的間隔時間內,有可能會出現多次搖一搖成功的情況;需要業(yè)務層作處理。
- 每次搖成功,都會有一次結果回調;未成功是沒有結果回調的。
四、代碼示例
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 在規(guī)定時間內,達到閥值的次數;例如: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
}
// 給加速度傳感器注冊傳感監(jiān)聽器
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) // 系統(tǒng)檢測到搖一搖事件后,震動手機提示用戶
}
shakeCount = 0 // 重置搖晃次數
lastShakeTime = 0 // 更新時間,重新計時2s
onShakeListener?.onShake(true) // 通知搖一搖成功
}
}
}
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
}