一、問題背景:
應用在強提醒場景下,一般會有馬達振動的效果,提示用戶注意力的關注。
比如消息提醒,掃碼提示,刪除鍵確認提示等。
針對高定制化或者固定的振動方式,我們需要有不同的方案實現,馬達振動效果。
二、解決方案:
鴻蒙針對振動效果的實現,有多種方案,目前分為振動和音振協同兩種方式。
單純的只是振動,又分為三種方式:
- 系統定制的振動方式,例如鬧鐘
- 非系統定制,自定義振動配置json文件的方式
- 線性馬達振動,只需要設置時間和強度(最簡單的調用方式)
音振協同一般用于,音效播放和振動同時的場景,例如掃碼。
1.首先需要配置振動權限,該權限是系統權限,只需要配置后,默認就會被授權。
ohos.permission.VIBRATE
2.之后根據需要實現不同的馬達振動效果,方案調用詳情參見下方代碼示例的注釋。
三、DEMO示例:
import vibrator from '@ohos.vibrator';
import { BusinessError } from '@ohos.base';
import { resourceManager } from '@kit.LocalizationKit';/*** 振動管理類* 需要權限: ohos.permission.VIBRATE*/
export class HapticMgr {private TAG: string = 'HapticMgr';private static mHapticMgr: HapticMgr | undefined = undefined;public static Ins(): HapticMgr{if(!HapticMgr.mHapticMgr){HapticMgr.mHapticMgr = new HapticMgr();}return HapticMgr.mHapticMgr;}/*** 按照指定持續時間觸發馬達振動*/public timeVibration(){try {// 觸發馬達振動vibrator.startVibration({type: 'time',duration: 1000,}, {id: 0,usage: 'alarm'}, (error: BusinessError) => {if (error) {console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);return;}console.info('Succeed in starting vibration');});} catch (err) {let e: BusinessError = err as BusinessError;console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);}}/*** 按照預置振動效果觸發馬達振動,可先查詢振動效果是否被支持,再調用振動接口*/public typeVibration(){try {// 查詢是否支持'haptic.clock.timer'vibrator.isSupportEffect('haptic.clock.timer', (err: BusinessError, state: boolean) => {if (err) {console.error(`Failed to query effect. Code: ${err.code}, message: ${err.message}`);return;}console.info('Succeed in querying effect');if (state) {try {// 觸發馬達振動vibrator.startVibration({type: 'preset',effectId: 'haptic.clock.timer',count: 1,}, {usage: 'unknown'}, (error: BusinessError) => {if (error) {console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);} else {console.info('Succeed in starting vibration');}});} catch (error) {let e: BusinessError = error as BusinessError;console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);}}})} catch (error) {let e: BusinessError = error as BusinessError;console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);}}public fileVibration(){const fileName: string = 'vibration.json';// 獲取文件資源描述符let rawFd: resourceManager.RawFileDescriptor = getContext().resourceManager.getRawFdSync(fileName);// 觸發馬達振動try {vibrator.startVibration({type: "file",hapticFd: { fd: rawFd.fd, offset: rawFd.offset, length: rawFd.length }}, {id: 0,usage: 'alarm'}, (error: BusinessError) => {if (error) {console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);return;}console.info('Succeed in starting vibration');});} catch (err) {let e: BusinessError = err as BusinessError;console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);}// 關閉文件資源描述符getContext().resourceManager.closeRawFdSync(fileName);}/*** 按照指定模式停止對應的馬達振動,自定義振動不支持此類停止方式*/public stopVibrationByType(){// 停止固定時長振動try {// 按照VIBRATOR_STOP_MODE_TIME模式停止振動vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_TIME, (error: BusinessError) => {if (error) {console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`);return;}console.info('Succeed in stopping vibration');})} catch (err) {let e: BusinessError = err as BusinessError;console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);}// 停止預置振動:try {// 按照VIBRATOR_STOP_MODE_PRESET模式停止振動vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_PRESET, (error: BusinessError) => {if (error) {console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`);return;}console.info('Succeed in stopping vibration');})} catch (err) {let e: BusinessError = err as BusinessError;console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);}}/*** 停止所有模式的馬達振動,包括自定義振動:*/public stopVibration(){try {// 停止所有模式的馬達振動vibrator.stopVibration((error: BusinessError) => {if (error) {console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`);return;}console.info('Succeed in stopping vibration');})} catch (error) {let e: BusinessError = error as BusinessError;console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);}}}
振動配置文件:
{"MetaData": {"Create": "2023-01-09","Description": "a haptic case","Version": 1.0,"ChannelNumber": 1},"Channels": [{"Parameters": {"Index": 0},"Pattern": [{"Event": {"Type": "transient","StartTime": 0,"Parameters": {"Frequency": 31,"Intensity": 100}}},{"Event": {"Type": "continuous","StartTime": 40,"Duration": 54,"Parameters": {"Frequency": 30,"Intensity": 38,"Curve": [{"Time": 0,"Frequency": 0,"Intensity": 0},{"Time": 1,"Frequency": 15,"Intensity": 0.5},{"Time": 40,"Frequency": -8,"Intensity": 1.0},{"Time": 54,"Frequency": 0,"Intensity": 0}]}}}]}]
}