鸿蒙新特性:@ohos.vibrator 触感反馈引擎实战
前言触感反馈Haptic Feedback是现代移动设备交互体验的重要组成部分。从键盘按键的轻微振动到闹钟的持续提醒从游戏中的碰撞反馈到通知到达时的短震线性马达驱动的高品质振动已经成为区分设备档次的关键指标。HarmonyOS 通过ohos.vibrator模块为开发者提供了完整的振动马达控制能力。该模块封装了从简单的时长振动到复杂的预设效果、从振动用途分类到模式停止控制的全套 API。与 Android 的Vibrator服务相比HarmonyOS 的 API 设计更加现代化——使用类型化的VibrateEffect替代原始数字参数使用Usage分类让系统智能调度振动资源。本文通过一个可交互的触感反馈实验室Demo深入讲解ohos.vibrator的全部核心 API涵盖预设效果、自定义时长、序列组合和振动控制四大功能模块。读者可将 Demo 安装到真机上亲身体验不同振动效果的差异。环境与权限模块导入importvibratorfromohos.vibrator;vibrator模块属于kit.SensorServiceKit使用 default export 方式导出。权限声明振动功能需要ohos.permission.VIBRATE权限该权限属于 normal 级别无需用户手动授权声明即可使用。在module.json5中配置requestPermissions: [ { name: ohos.permission.VIBRATE, reason: $string:vibrate_permission_reason, usedScene: { abilities: [EntryAbility], when: inuse } } ]如果未声明该权限调用任何startVibration()方法都会抛出 BusinessError 201权限拒绝异常。在封装振动调用时务必包裹 try-catch 以提供用户友好的降级体验。核心 API 模型ohos.vibrator的 API 设计围绕三个核心概念展开VibrateEffect— 描述怎么振时长time、预设preset、来自文件file、自定义模式patternVibrateAttribute— 描述为什么振用途分类usage、马达 IDid、设备 IDdeviceIdVibratorStopMode— 描述怎么停按时间停止time或按预设停止preset这种设计将振动描述与振动意图解耦让系统可以根据 usage 参数智能分配振动资源——例如来电铃声alarm的振动优先级高于 UI 触感touch。startVibration — 启动振动functionstartVibration(effect:VibrateEffect,attribute:VibrateAttribute):Promisevoid这是 API 9 引入的核心方法替代了早期已废弃的vibrate()函数。它接受两个参数振动效果和振动属性返回 Promise。stopVibration — 停止振动functionstopVibration(stopMode:VibratorStopMode):PromisevoidfunctionstopVibration():PromisevoidfunctionstopVibrationSync():void三种停止模式按模式停止、停止所有异步、停止所有同步。stopVibrationSync()是 API 12 新增的无参数方法可立即停止所有类型的振动无需传入 stopMode。isSupportEffect / isSupportEffectSync — 检测支持functionisSupportEffect(effectId:string):PromisebooleanfunctionisSupportEffectSync(effectId:string):boolean检测设备是否支持某个预设振动效果。不同设备的线性马达硬件能力不同部分效果可能不可用。建议在触发预设效果前先检测。VibrateEffect 详解VibrateEffect是一个联合类型包含四种振动效果描述方式。1. VibrateTime — 时长振动最简单的振动形式按指定时长持续振动。适合简单的触感反馈场景。interfaceVibrateTime{type:time;duration:number;// 振动时长毫秒}// 示例振动 500msvibrator.startVibration({type:time,duration:500},{usage:touch});duration的有效范围建议在 10ms 到 5000ms 之间。太短10ms人无法感知太长5s可能被系统截断或触发过热保护。2. VibratePreset — 预设效果HarmonyOS 内置了一系列预设振动效果这些效果由系统根据设备马达硬件特性自动优化通常比手动设置时长能获得更好的触感体验。interfaceVibratePreset{type:preset;effectId:string;// 预设效果 IDcount:number;// 重复次数intensity?:number;// 强度系数1-5默认 5}// 示例触发成功通知效果vibrator.startVibration({type:preset,effectId:haptic.notice.success,count:1},{usage:notification});HapticFeedback 枚举值API 12 引入了HapticFeedback枚举定义了一套简单通用的振动效果枚举成员effectId 字符串描述EFFECT_SOFThaptic.effect.soft轻柔振动适合轻微交互反馈EFFECT_HARDhaptic.effect.hard强烈振动适合物理按键模拟EFFECT_SHARPhaptic.effect.sharp尖锐振动适合短触感提示EFFECT_NOTICE_SUCCESShaptic.notice.success成功通知短振上升感EFFECT_NOTICE_FAILUREhaptic.notice.fail失败通知双振下沉感EFFECT_NOTICE_WARNINGhaptic.notice.warning警告通知长振间隔重复此外还有EFFECT_CLOCK_TIMEREffectId枚举值为haptic.clock.timer专门用于计时器调节场景的振动反馈。effectId 字符串 vs 枚举注意 SDK 中的effectId是string类型而非枚举值。HapticFeedback.EFFECT_SOFT只是一个值为haptic.effect.soft的字符串常量。在代码中直接使用字符串haptic.effect.soft或vibrator.HapticFeedback.EFFECT_SOFT均可效果相同。3. VibrateFromFile — 自定义效果文件对于需要高度定制振动曲线的应用如游戏可以通过 JSON 或特定格式文件定义振动效果interfaceVibrateFromFile{type:file;hapticFd:HapticFileDescriptor;// 效果文件的文件描述符}这种方式需要先读取自定义效果文件将文件的HapticFileDescriptor传入。实际开发中较少使用一般预设效果已能满足大部分需求。4. VibrateFromPattern — Builder 模式API 18API 18 引入了VibratorPatternBuilder用于编程式构建复杂的振动事件序列letbuildernewvibrator.VibratorPatternBuilder();builder.addTransientEvent(200,{});// 在 200ms 处触发瞬时振动builder.addContinuousEvent(500,300,{});// 在 500ms 处开始 300ms 的持续振动letpattern:vibrator.VibratorPatternbuilder.build();vibrator.startVibration({type:pattern,pattern:pattern},{usage:physicalFeedback});VibratorPatternBuilder支持addTransientEvent(time, options)和addContinuousEvent(time, duration, options)两种事件类型分别对应瞬时振动和持续振动。通过组合不同的事件类型和时间点可以精确编排振动节奏。VibrateAttribute 详解Usage — 振动用途分类Usage是VibrateAttribute中最关键的属性它告诉系统这次振动的目的让系统可以做出智能调度决策typeUsageunknown|alarm|ring|notification|communication|touch|media|physicalFeedback|simulateReality;值含义典型场景优先级alarm闹钟起床闹钟、计时器到期高ring来电铃声电话、视频通话来电高notification通知消息推送、邮件提醒中communication通讯短信、即时消息中touch触控反馈按钮点击、滑动反馈低media媒体音乐、视频播放中的振动低physicalFeedback物理反馈游戏、模拟实体的触感中simulateReality虚拟现实AR/VR 场景中的触感模拟中unknown未知未分类的振动用途低实际影响当系统检测到多个振动请求并发时会按优先级决定哪个振动执行。例如闹钟响铃期间触控反馈的振动会被降级或忽略。完整示例letattribute:vibrator.VibrateAttribute{usage:alarm,// 必须声明振动用途id:0,// 可选马达 ID默认 0deviceId:undefined// 可选设备 ID默认本地设备};通常只需要设置usage其余参数使用默认值即可。VibratorStopMode 详解enumVibratorStopMode{VIBRATOR_STOP_MODE_TIMEtime,VIBRATOR_STOP_MODE_PRESETpreset}VIBRATOR_STOP_MODE_TIME‘time’停止由时长触发的一次性振动VIBRATOR_STOP_MODE_PRESET‘preset’停止由预设效果触发的振动如果使用stopVibration()无参数版本API 10则无需关心停止模式直接停止所有类型的振动。API 12 新增的stopVibrationSync()更是提供了同步停止的能力适合在页面销毁aboutToDisappear等同步上下文中使用。Demo触感反馈实验室我们构建了一个功能完整的触感反馈体验工具用户可在真机上亲身感受不同振动效果的差异。功能模块预设效果网格— 7 种预设振动轻柔/强烈/尖锐/成功/失败/警告/计时器以 4 列网格布局展示点击即可触发。配合重复次数调节器1-10 次可测试多次重复振动自定义时长振动— 通过滑块选择振动时长50ms-3000ms切换八种振动用途分类一键触发。底部提示文字解释 Usage 参数的调度意义组合振动序列— 两个预设序列按钮轻→强→尖质感序列和成功→警告→失败通知序列通过setTimeout串联多个startVibration调用实现振动组合实时状态面板— 显示最近触发的效果名称、马达支持状态、权限要求、停止模式等运行信息紧急停止按钮— 常驻顶部状态栏红色醒目样式调用stopVibrationSync()立即终止所有振动核心实现检测马达支持checkSupport():void{try{this.isSupportedvibrator.isSupportEffectSync(haptic.effect.soft)?支持:不支持;}catch(e){this.isSupported检测失败;}}使用同步 APIisSupportEffectSync()在页面初始化时检测马达硬件状态。检测失败通常意味着设备不具备线性马达如部分平板设备。核心实现触发预设效果triggerPresetEffect(item:PresetEffect):void{try{vibrator.startVibration({type:preset,effectId:item.effectId,count:this.vibrateCount},{usage:item.usage});this.statusMsg已触发: item.name xthis.vibrateCount.toString();}catch(e){this.statusMsg触发失败: 请确认已授予振动权限;}}VibratePreset的三个参数type: preset— 指定为预设效果模式effectId— 预设效果的字符串 IDcount— 重复次数帮助用户体验连续振动模式如紧急通知连续震 3 次核心实现自定义时长振动triggerTimeVibration():void{try{vibrator.startVibration({type:time,duration:this.duration},{usage:this.usageValues[this.usageIndex]});this.statusMsg时长振动: this.duration.toString()ms (this.usageLabels[this.usageIndex]);}catch(e){this.statusMsg触发失败: 请确认已授予振动权限;}}VibrateTime只需要两个参数type: time和duration毫秒。配合usage属性让系统了解振动目的。核心实现振动序列playSequence():void{try{// 第一步轻柔振动vibrator.startVibration({type:preset,effectId:haptic.effect.soft,count:1},{usage:physicalFeedback});// 250ms 后第二步强烈振动setTimeout((){vibrator.startVibration({type:preset,effectId:haptic.effect.hard,count:1},{usage:physicalFeedback});// 300ms 后第三步尖锐振动setTimeout((){vibrator.startVibration({type:preset,effectId:haptic.effect.sharp,count:1},{usage:physicalFeedback});},300);},250);this.statusMsg播放序列: 轻柔 → 强烈 → 尖锐;}catch(e){this.statusMsg播放失败: 请授予振动权限;}}通过setTimeout串联多个振动调用实现自定义的振动序列组合。间隔时间需要根据实际效果调试——太短会产生重叠太长则有明显停顿感。核心实现同步停止stopAllVibration():void{try{vibrator.stopVibrationSync();this.statusMsg振动已停止;}catch(e){this.statusMsg停止失败;}}使用stopVibrationSync()代替stopVibration()的原因同步版本无需 callback/Promise代码更简洁适合在页面即将销毁等需要在同步上下文中立即停止的场景。枚举值与 SDK 版本对应关系本 Demo 使用的 API 版本跨度较大API 9-12整理如下API内容EffectIdAPI 8已废弃仅保留 EFFECT_CLOCK_TIMERstartVibrationAPI 9替代 vibrate()VibrateEffect VibrateTime | VibratePresetAPI 9VibrateAttributeAPI 9vibrate() — 废弃API 8API 9 起弃用VibrateFromFileAPI 10stopVibration() 无参数版API 10isSupportEffectSync / stopVibrationSyncAPI 12HapticFeedback 枚举API 12VibratorPatternBuilderAPI 18在 API 24 环境下建议使用startVibration()VibrateEffectVibrateAttribute的标准组合废弃的vibrate()函数不再推荐使用。最佳实践1. 始终包裹 try-catch振动权限可能被用户拒绝某些 ROM 可关闭马达硬件可能异常。对每个振动调用包裹 try-catch 确保不影响主流程try{vibrator.startVibration({type:time,duration:200},{usage:touch});}catch(e){// 静默降级无振动不影响功能}2. 选择合适的 Usage不恰当的 Usage 会导致振动被系统抑制。关键规则UI 交互反馈→touch按钮点击、开关切换等消息通知→notification紧急提醒→alarm或ring游戏/模拟→physicalFeedback或simulateReality错误示例用alarm做按钮点击反馈——闹钟的振动强度通常很大会让用户感到不适。3. 控制振动时长和频率单次不超过 3 秒连续振动超过 3 秒在用户体验上通常是负面的间隔不小于 100ms过于密集的振动会糊成一团失去层次感重复次数合理预设效果的count参数不要超过 5特别是报警类效果4. 页面销毁时停止振动在aboutToDisappear生命周期中停止振动避免页面退出后振动仍在进行aboutToDisappear():void{try{vibrator.stopVibrationSync();}catch(e){// 静默处理}}5. 检测马达能力在应用启动时检测马达能力根据设备差异提供降级体验lethasHaptic:booleanvibrator.isSupportEffectSync(haptic.effect.soft);if(!hasHaptic){// 使用视觉反馈替代触感反馈如闪烁、颜色变化}6. 避免在主线程大量调用虽然startVibration()返回 Promise但底层 IPC 调用是异步的频繁调用如滚动列表中每个 item 触发振动会导致性能问题。建议设置最小触发间隔如 300ms debounce。与 Android Vibrator API 对比特性HarmonyOSAndroid基础 APIstartVibration(effect, attr)vibrator.vibrate(VibrationEffect)时长振动{ type: time, duration }VibrationEffect.createOneShot(millis, amplitude)预设效果{ type: preset, effectId, count }VibrationEffect.createPredefined(id)用途分类usage: alarm | ring | ...AudioAttributes.USAGE_*停止方式stopVibrationSync()同步 /stopVibration()异步vibrator.cancel()权限ohos.permission.VIBRATE(normal)android.permission.VIBRATE(normal)自定义模式VibratorPatternBuilder(API 18)VibrationEffect.createWaveform(timings, amplitudes, repeat)HarmonyOS 的优势在于Usage分类更加细粒度8 种场景且使用类型化对象替代 Android 的原始数组参数代码可读性更好。Android 的自定义波形支持更早API 26HarmonyOS 的VibratorPatternBuilder直到 API 18 才引入。线性马达硬件基础理解 API 后了解硬件特性有助于撰写更精细的振动体验X 轴线性马达振动方向沿设备短轴振感紧凑响应快通常 10ms 起振多用于旗舰手机Z 轴线性马达振动方向沿设备厚度振感偏弹跳响应较慢ERM偏心转子马达传统方案通过旋转偏心轮产生振动起振慢50ms振感模糊HarmonyOS 的预设效果如EFFECT_SOFT/EFFECT_HARD/EFFECT_SHARP在 X 轴线性马达上表现最佳各项差异明显。在 ERM 马达上这几个效果的差别会缩小。总结本文详细讲解了 HarmonyOS 振动马达控制的核心 APIstartVibration(effect, attribute)— 启动振动支持四种效果类型stopVibration / stopVibrationSync— 按模式或全部停止振动isSupportEffect / isSupportEffectSync— 检测马达硬件能力VibrateEffect— 联合类型VibrateTime|VibratePreset|VibrateFromFile|VibrateFromPatternVibrateAttribute— 振动属性核心是usage8 种场景分类HapticFeedback— 预设效果枚举SOFT/HARD/SHARP NOTICE_SUCCESS/FAIL/WARNINGVibratorPatternBuilder— Builder 模式构建复杂振动序列API 18触感反馈实验室 Demo 是一个实用的开发工具展示了从简单到复杂的各类振动控制场景。读者可在真机上安装体验直观感受不同振动效果和 Usage 参数的实际差异。对于需要构建高品质交互体验的应用精心设计的触感反馈是不可忽视的细节竞争力。