/** * 震动能力(契约 §8.4,T-M3-04)。@kit.SensorServiceKit vibrator。 * - vibrator:data=毫秒裸串,单次震动。 * - repeatvibrator:data="1" 重复 / 其他停止重复。 * - canclevibrator(拼写原样):取消全部震动。 * 需 module.json5 声明 ohos.permission.VIBRATE。 */ import { vibrator } from '@kit.SensorServiceKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { BridgeController } from 'feature_bridge'; import { InboundHandlers } from 'contracts'; import { Logger } from 'common'; import { CapabilityContext, CapabilityProvider } from '../core/CapabilityProvider'; const DEFAULT_DURATION: number = 1000; export class VibrateProvider implements CapabilityProvider { readonly name: string = 'vibrate'; private readonly log: Logger = Logger.tag('VibrateProvider'); private lastDuration: number = DEFAULT_DURATION; private repeating: boolean = false; private repeatTimer: number = -1; register(bridge: BridgeController, _ctx: CapabilityContext): void { bridge.registerHandler(InboundHandlers.Vibrator, (data: string, _cb: (resp: string) => void) => { this.vibrateOnce(this.parseMs(data)); }); bridge.registerHandler(InboundHandlers.RepeatVibrator, (data: string, _cb: (resp: string) => void) => { if (data === '1') { this.startRepeat(); } else { this.stopRepeat(); } }); bridge.registerHandler(InboundHandlers.CancleVibrator, (_d: string, _cb: (resp: string) => void) => { this.cancel(); }); } onDestroy(): void { this.cancel(); } private parseMs(data: string): number { const n: number = parseInt(data, 10); return isNaN(n) || n <= 0 ? DEFAULT_DURATION : n; } private vibrateOnce(ms: number): void { this.lastDuration = ms; vibrator.startVibration({ type: 'time', duration: ms }, { usage: 'notification' }) .catch((e: BusinessError) => this.log.w(`startVibration failed: ${e.code} ${e.message}`)); } private startRepeat(): void { this.repeating = true; this.loop(); } private loop(): void { if (!this.repeating) { return; } this.vibrateOnce(this.lastDuration); // 当次震动结束后再触发下一次(间隔取等长),形成重复,直到取消 this.repeatTimer = setTimeout(() => this.loop(), this.lastDuration * 2); } private stopRepeat(): void { this.repeating = false; if (this.repeatTimer !== -1) { clearTimeout(this.repeatTimer); this.repeatTimer = -1; } } private cancel(): void { this.stopRepeat(); vibrator.stopVibration().catch((e: BusinessError) => this.log.w(`stopVibration failed: ${e.code} ${e.message}`)); } }