查看: 5164|回复: 3

鸿蒙元服务 vibrateShort 振动强度与权限适配踩坑

[复制链接]
发表于 2026-9-14 13:00:00 | 显示全部楼层 |阅读模式
做鸿蒙元服务开发时,振动反馈是提升交互体验的实用能力。用户操作成功可以给一个短振动,收到重要消息可以给一个长振动提醒。ASCF 提供了 vibrateShort 和 vibrateLong 两个 API,用法不复杂,但权限、强度和真机适配有几个容易踩的坑。

两个 API 的区别
vibrateShort 是短振动,持续约 15ms,适合按钮点击反馈、操作确认等轻量级提示。它的 type 参数是必填项,只能传 'heavy'、'medium'、'light',分别对应强、中、弱三种强度。不传 type 会直接报错。
vibrateLong 是长振动,固定 400ms,适合消息提醒、闹钟、紧急通知等需要用户注意的场景。两个 API 都需要 ohos.permission.VIBRATE 权限。

权限配置
在 module.json5 中声明振动权限:
  1. {
  2.   "requestPermissions": [
  3.     {
  4.       "name": "ohos.permission.VIBRATE",
  5.       "reason": "用于操作反馈和消息提醒",
  6.       "usedScene": {
  7.         "abilities": ["EntryAbility"],
  8.         "when": "inuse"
  9.       }
  10.     }
  11.   ]
  12. }
复制代码

短振动调用
短振动通过 type 选择强度,调用成功后可以在 success 回调中记录日志或更新状态:
  1. has.vibrateShort({
  2.   type: 'heavy',
  3.   success: () => console.info('强振动成功'),
  4.   fail: (err) => console.error('振动失败:', err)
  5. });
  6. has.vibrateShort({
  7.   type: 'medium',
  8.   success: () => console.info('中振动成功')
  9. });
  10. has.vibrateShort({
  11.   type: 'light',
  12.   success: () => console.info('弱振动成功')
  13. });
复制代码

长振动调用
长振动不需要 type 参数,固定 400ms,可同时使用 success、fail 和 complete 回调:
  1. has.vibrateLong({
  2.   success: () => {
  3.     console.info('长振动成功');
  4.   },
  5.   fail: (err) => {
  6.     console.error('长振动失败:', err);
  7.   },
  8.   complete: () => {
  9.     console.info('长振动完成');
  10.   }
  11. });
复制代码

常见使用场景
按钮点击反馈:在用户点击重要按钮时,先调用 medium 短振动,再执行提交订单等业务逻辑。
操作成功/失败提示:成功时用 light 短振动配合 showToast;失败时用 vibrateLong 引起注意,并配合错误提示。
消息提醒:收到新消息时调用 vibrateLong,再通过 setData 展示消息内容。
游戏触觉反馈:轻击用 light,重击用 heavy,游戏结束用 vibrateLong,不同强度对应不同事件。

完整示例片段
把短振动、长振动和连续振动测试整合在一起时,可以用 data 中的 lastAction 和 vibrateCount 记录状态。短振动调用成功后累加计数;长振动成功后记录为 400ms;连续振动测试则通过 setTimeout 间隔 200ms 依次调用三次 medium 短振动。
  1. Page({
  2.   data: {
  3.     lastAction: '',
  4.     vibrateCount: 0,
  5.   },
  6.   doVibrateShort(e) {
  7.     const type = e.currentTarget.dataset.type;
  8.     let that = this;
  9.     has.vibrateShort({
  10.       type: type,
  11.       success: () => {
  12.         that.setData({
  13.           lastAction: '短振动 (' + type + ')',
  14.           vibrateCount: that.data.vibrateCount + 1,
  15.         });
  16.         console.info('短振动成功:', type);
  17.       },
  18.       fail: (err) => {
  19.         that.setData({ lastAction: '振动失败: ' + JSON.stringify(err) });
  20.         console.error('短振动失败:', err);
  21.       },
  22.       complete: () => {
  23.         console.info('短振动接口调用完成');
  24.       }
  25.     });
  26.   },
  27.   doVibrateLong() {
  28.     let that = this;
  29.     has.vibrateLong({
  30.       success: () => {
  31.         that.setData({
  32.           lastAction: '长振动 (400ms)',
  33.           vibrateCount: that.data.vibrateCount + 1,
  34.         });
  35.         console.info('长振动成功');
  36.       },
  37.       fail: (err) => {
  38.         that.setData({ lastAction: '振动失败: ' + JSON.stringify(err) });
  39.         console.error('长振动失败:', err);
  40.       },
  41.       complete: () => {
  42.         console.info('长振动接口调用完成');
  43.       }
  44.     });
  45.   },
  46.   doVibratePattern() {
  47.     let that = this;
  48.     let count = 0;
  49.     function doOne() {
  50.       if (count >= 3) {
  51.         that.setData({ lastAction: '连续振动完成' });
  52.         return;
  53.       }
  54.       has.vibrateShort({
  55.         type: 'medium',
  56.         success: () => {
  57.           count++;
  58.           setTimeout(doOne, 200);
  59.         }
  60.       });
  61.     }
  62.     doOne();
  63.   },
  64.   resetCount() {
  65.     this.setData({ vibrateCount: 0, lastAction: '已重置' });
  66.   }
  67. });
复制代码

踩过的坑
1. type 参数必填:vibrateShort 的 type 不传会直接报错,不会使用默认值。
2. 振动效果跟设备有关:不同设备的振动马达不一样,同样的 heavy 在不同手机上感受可能差别很大,有些手机振动很强,有些很弱,这个无法控制。
3. 连续振动要注意间隔:连续快速调用振动 API,有些设备可能会合并振动或丢失振动。原文测试发现,间隔 100ms 以上比较稳定。
4. 模拟器不振动:模拟器没有振动马达,必须用真机测试。
5. 振动权限:必须在 module.json5 中声明 ohos.permission.VIBRATE,否则调用会失败。

复杂振动模式
ASCF 的 vibrateShort 和 vibrateLong 适合大多数业务场景。如果需要自定义振动时长、循环振动等更复杂的振动模式,这两个 API 不够用,需要使用系统的 @ohos.vibrator 模块。

振动 API 本身不复杂,但用好了能明显提升操作反馈、消息提醒和游戏触感。关键是选对强度和时机,并注意真机差异与连续调用间隔,别让用户觉得烦。
回复

使用道具 举报

发表于 2026-9-14 19:00:00 | 显示全部楼层

Re: 鸿蒙元服务 vibrateShort 振动强度与权限适配踩坑

感谢分享,这篇整理得很实用。vibrateShort 的 type 必填确实容易忽略,heavy、medium、light 三档在实际反馈里差别挺明显,按钮点击用 medium 或 light 会比较合适。权限那块也是关键,module.json5 里漏声明 ohos.permission.VIBRATE,调用就只能走 fail。长振动固定 400ms 对消息提醒很省心,不用自己控制时长。示例里用 lastAction 和 vibrateCount 记录状态,连续振动用 setTimeout 间隔 200ms 调三次 medium,调试时看起来挺直观。真机适配也得留意,有些设备可能没有振动马达,或者系统里关掉了触感反馈,最好在 fail 回调里做兜底提示,别把振动当成唯一反馈。
回复 支持 反对

使用道具 举报

发表于 2026-9-14 19:10:00 | 显示全部楼层

Re: 鸿蒙元服务 vibrateShort 振动强度与权限适配踩坑

感谢分享,这篇把 vibrateShort 和 vibrateLong 的区别、权限声明和调用示例讲得挺清楚,尤其是短振动 type 必填、只能传 heavy、medium、light,不传会直接报错这个点很容易踩。权限里 reason 和 usedScene 的写法也值得参考。 我比较关心真机适配:不同机型上 heavy、medium、light 的振动强度差异明显吗?还有用户如果关闭了系统触感反馈,接口是会走 success 但实际不振动,还是直接进 fail?另外连续振动那段示例好像最后没贴完,方便的话可以补上 setTimeout 间隔 200ms 调用三次 medium 的收尾逻辑。整体很有帮助。
回复 支持 反对

使用道具 举报

发表于 2026-9-14 19:20:00 | 显示全部楼层

Re: 鸿蒙元服务 vibrateShort 振动强度与权限适配踩坑

感谢分享,这篇把 vibrateShort 和 vibrateLong 的区别、权限声明和调用示例讲得挺清楚。之前我只知道短振动要传 type,没想到不传会直接报错,heavy、medium、light 三档在按钮反馈和游戏场景里确实更好区分。module.json5 里 VIBRATE 权限的 usedScene 写法也很有参考价值。长振动固定 400ms,配合失败提示和消息提醒比较实用。想再请教一下真机适配的坑,比如不同设备对 heavy 和 medium 的体感差异大不大,省电模式下会不会被拦截。连续振动那段用 setTimeout 间隔 200ms 调三次 medium,实际页面退出时记得清掉定时器,不然可能回调到已销毁页面。整体很有帮助,收藏了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-7 03:08 , Processed in 0.032077 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部