Refine sensor integration strategy

This commit is contained in:
2026-03-25 17:42:16 +08:00
parent a19342d61f
commit f7d4499e36
11 changed files with 1509 additions and 8 deletions

View File

@@ -0,0 +1,124 @@
export interface AccelerometerControllerCallbacks {
onSample: (x: number, y: number, z: number) => void
onError: (message: string) => void
}
const ACCELEROMETER_START_RETRY_DELAY_MS = 120
export class AccelerometerController {
callbacks: AccelerometerControllerCallbacks
listening: boolean
starting: boolean
accelerometerCallback: ((result: WechatMiniprogram.OnAccelerometerChangeCallbackResult) => void) | null
retryTimer: number
constructor(callbacks: AccelerometerControllerCallbacks) {
this.callbacks = callbacks
this.listening = false
this.starting = false
this.accelerometerCallback = null
this.retryTimer = 0
}
start(): void {
if (this.listening || this.starting) {
return
}
if (typeof wx.startAccelerometer !== 'function' || typeof wx.onAccelerometerChange !== 'function') {
this.callbacks.onError('当前环境不支持加速度计监听')
return
}
this.clearRetryTimer()
this.starting = true
this.detachCallback()
wx.stopAccelerometer({
complete: () => {
this.startAfterStop(false)
},
})
}
private startAfterStop(retried: boolean): void {
const callback = (result: WechatMiniprogram.OnAccelerometerChangeCallbackResult) => {
if (
typeof result.x !== 'number'
|| typeof result.y !== 'number'
|| typeof result.z !== 'number'
|| Number.isNaN(result.x)
|| Number.isNaN(result.y)
|| Number.isNaN(result.z)
) {
return
}
this.callbacks.onSample(result.x, result.y, result.z)
}
this.accelerometerCallback = callback
wx.onAccelerometerChange(callback)
wx.startAccelerometer({
interval: 'ui',
success: () => {
this.starting = false
this.listening = true
},
fail: (res) => {
const errorMessage = res && res.errMsg ? res.errMsg : 'startAccelerometer failed'
if (!retried && errorMessage.indexOf('has enable') >= 0) {
this.detachCallback()
this.clearRetryTimer()
this.retryTimer = setTimeout(() => {
this.retryTimer = 0
wx.stopAccelerometer({
complete: () => {
this.startAfterStop(true)
},
})
}, ACCELEROMETER_START_RETRY_DELAY_MS) as unknown as number
return
}
this.starting = false
this.detachCallback()
this.callbacks.onError(errorMessage)
},
})
}
stop(): void {
this.clearRetryTimer()
this.detachCallback()
wx.stopAccelerometer({
complete: () => {},
})
this.starting = false
this.listening = false
}
destroy(): void {
this.stop()
}
private clearRetryTimer(): void {
if (!this.retryTimer) {
return
}
clearTimeout(this.retryTimer)
this.retryTimer = 0
}
private detachCallback(): void {
if (!this.accelerometerCallback) {
return
}
if (typeof wx.offAccelerometerChange === 'function') {
wx.offAccelerometerChange(this.accelerometerCallback)
}
this.accelerometerCallback = null
}
}