做鸿蒙元服务开发时,振动反馈是提升交互体验的实用能力。用户操作成功可以给一个短振动,收到重要消息可以给一个长振动提醒。ASCF 提供了 vibrateShort 和 vibrateLong 两个 API,用法不复杂,但权限、强度和真机适配有几个容易踩的坑。
两个 API 的区别
vibrateShort 是短振动,持续约 15ms,适合按钮点击反馈、操作确认等轻量级提示。它的 type 参数是必填项,只能传 'heavy'、'medium'、'light',分别对应强、中、弱三种强度。不传 type 会直接报错。
vibrateLong 是长振动,固定 400ms,适合消息提醒、闹钟、紧急通知等需要用户注意的场景。两个 API 都需要 ohos.permission.VIBRATE 权限。
权限配置
在 module.json5 中声明振动权限:- {
- "requestPermissions": [
- {
- "name": "ohos.permission.VIBRATE",
- "reason": "用于操作反馈和消息提醒",
- "usedScene": {
- "abilities": ["EntryAbility"],
- "when": "inuse"
- }
- }
- ]
- }
复制代码
短振动调用
短振动通过 type 选择强度,调用成功后可以在 success 回调中记录日志或更新状态:- has.vibrateShort({
- type: 'heavy',
- success: () => console.info('强振动成功'),
- fail: (err) => console.error('振动失败:', err)
- });
- has.vibrateShort({
- type: 'medium',
- success: () => console.info('中振动成功')
- });
- has.vibrateShort({
- type: 'light',
- success: () => console.info('弱振动成功')
- });
复制代码
长振动调用
长振动不需要 type 参数,固定 400ms,可同时使用 success、fail 和 complete 回调:- has.vibrateLong({
- success: () => {
- console.info('长振动成功');
- },
- fail: (err) => {
- console.error('长振动失败:', err);
- },
- complete: () => {
- console.info('长振动完成');
- }
- });
复制代码
常见使用场景
按钮点击反馈:在用户点击重要按钮时,先调用 medium 短振动,再执行提交订单等业务逻辑。
操作成功/失败提示:成功时用 light 短振动配合 showToast;失败时用 vibrateLong 引起注意,并配合错误提示。
消息提醒:收到新消息时调用 vibrateLong,再通过 setData 展示消息内容。
游戏触觉反馈:轻击用 light,重击用 heavy,游戏结束用 vibrateLong,不同强度对应不同事件。
完整示例片段
把短振动、长振动和连续振动测试整合在一起时,可以用 data 中的 lastAction 和 vibrateCount 记录状态。短振动调用成功后累加计数;长振动成功后记录为 400ms;连续振动测试则通过 setTimeout 间隔 200ms 依次调用三次 medium 短振动。- Page({
- data: {
- lastAction: '',
- vibrateCount: 0,
- },
- doVibrateShort(e) {
- const type = e.currentTarget.dataset.type;
- let that = this;
- has.vibrateShort({
- type: type,
- success: () => {
- that.setData({
- lastAction: '短振动 (' + type + ')',
- vibrateCount: that.data.vibrateCount + 1,
- });
- console.info('短振动成功:', type);
- },
- fail: (err) => {
- that.setData({ lastAction: '振动失败: ' + JSON.stringify(err) });
- console.error('短振动失败:', err);
- },
- complete: () => {
- console.info('短振动接口调用完成');
- }
- });
- },
- doVibrateLong() {
- let that = this;
- has.vibrateLong({
- success: () => {
- that.setData({
- lastAction: '长振动 (400ms)',
- vibrateCount: that.data.vibrateCount + 1,
- });
- console.info('长振动成功');
- },
- fail: (err) => {
- that.setData({ lastAction: '振动失败: ' + JSON.stringify(err) });
- console.error('长振动失败:', err);
- },
- complete: () => {
- console.info('长振动接口调用完成');
- }
- });
- },
- doVibratePattern() {
- let that = this;
- let count = 0;
- function doOne() {
- if (count >= 3) {
- that.setData({ lastAction: '连续振动完成' });
- return;
- }
- has.vibrateShort({
- type: 'medium',
- success: () => {
- count++;
- setTimeout(doOne, 200);
- }
- });
- }
- doOne();
- },
- resetCount() {
- this.setData({ vibrateCount: 0, lastAction: '已重置' });
- }
- });
复制代码
踩过的坑
1. type 参数必填:vibrateShort 的 type 不传会直接报错,不会使用默认值。
2. 振动效果跟设备有关:不同设备的振动马达不一样,同样的 heavy 在不同手机上感受可能差别很大,有些手机振动很强,有些很弱,这个无法控制。
3. 连续振动要注意间隔:连续快速调用振动 API,有些设备可能会合并振动或丢失振动。原文测试发现,间隔 100ms 以上比较稳定。
4. 模拟器不振动:模拟器没有振动马达,必须用真机测试。
5. 振动权限:必须在 module.json5 中声明 ohos.permission.VIBRATE,否则调用会失败。
复杂振动模式
ASCF 的 vibrateShort 和 vibrateLong 适合大多数业务场景。如果需要自定义振动时长、循环振动等更复杂的振动模式,这两个 API 不够用,需要使用系统的 @ohos.vibrator 模块。
振动 API 本身不复杂,但用好了能明显提升操作反馈、消息提醒和游戏触感。关键是选对强度和时机,并注意真机差异与连续调用间隔,别让用户觉得烦。 |