• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 振动开发指导
2
3
4## 场景介绍
5
6当设备需要设置不同的振动效果时,可以调用Vibrator模块,例如:设备的按键可以设置不同强度和不同时长的振动,闹钟和来电可以设置不同强度和时长的单次或周期振动。
7
8详细的接口介绍请参考[Vibrator接口](../../reference/apis-sensor-service-kit/js-apis-vibrator.md)。
9
10
11## 接口说明
12
13| 模块          | 接口名                                                       | 描述                                                         |
14| ------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
15| ohos.vibrator | startVibration(effect: VibrateEffect, attribute: VibrateAttribute): Promise<void> | 根据指定振动效果和振动属性触发马达振动,使用Promise异步回调。 |
16| ohos.vibrator | startVibration(effect: VibrateEffect, attribute: VibrateAttribute, callback: AsyncCallback<void>): void | 根据指定振动效果和振动属性触发马达振动,使用Callback异步回调。 |
17| ohos.vibrator | stopVibration(stopMode: VibratorStopMode): Promise<void> | 按照指定模式停止马达的振动,使用Promise异步回调。                               |
18| ohos.vibrator | stopVibration(stopMode: VibratorStopMode, callback: AsyncCallback<void>): void | 按照指定模式停止马达的振动,使用Callback异步回调。                                 |
19| ohos.vibrator | stopVibration(): Promise<void>                         | 停止所有模式的马达振动,使用Promise异步回调。                                     |
20| ohos.vibrator | stopVibration(callback: AsyncCallback<void>): void     | 停止所有模式的马达振动,使用Callback异步回调。                                     |
21| ohos.vibrator | isSupportEffect(effectId: string): Promise<boolean>    | 查询是否支持传入的参数effectId。返回true则表示支持,否则不支持,使用Promise异步回调。 |
22| ohos.vibrator | isSupportEffect(effectId: string, callback: AsyncCallback<boolean>): void | 查询是否支持传入的参数effectId。返回true则表示支持,否则不支持,使用Callback异步回调。 |
23
24
25## 振动效果说明
26
27目前支持3类振动效果,如下所示。
28
29### 固定时长振动
30
31传入一个固定时长,马达按照默认强度和频率触发振动,振动效果描述请参考[VibrateTime](../../reference/apis-sensor-service-kit/js-apis-vibrator.md#vibratetime9)。
32
33### 预置振动
34
35系统中的[预置振动效果](../../reference/apis-sensor-service-kit/js-apis-vibrator.md#effectid),这些效果适用于某些固定场景,比如效果"haptic.clock.timer"通常用于用户调整计时器时的振感反馈,振动效果描述请参考[VibratePreset](../../reference/apis-sensor-service-kit/js-apis-vibrator.md#vibratepreset9)。
36
37### 自定义振动
38
39自定义振动提供给用户设计自己所需振动效果的能力,用户可通过自定义振动配置文件,并遵循相应规则编排所需振动形式,使能更加开放的振感交互体验,效果描述请参考[VibrateFromFile](../../reference/apis-sensor-service-kit/js-apis-vibrator.md#vibratefromfile10)。
40
41自定义振动配置文件为Json格式,在形式上如下所示:
42
43```json
44{
45    "MetaData": {
46        "Create": "2023-01-09",
47        "Description": "a haptic case",
48        "Version": 1.0,
49        "ChannelNumber": 1
50    },
51    "Channels": [
52        {
53            "Parameters": {
54                "Index": 0
55            },
56            "Pattern": [
57                {
58                    "Event": {
59                        "Type": "transient",
60                        "StartTime": 0,
61                        "Parameters": {
62                            "Frequency": 31,
63                            "Intensity": 100
64                        }
65                    }
66                },
67                {
68                    "Event": {
69                        "Type": "continuous",
70                        "StartTime": 40,
71                        "Duration": 54,
72                        "Parameters": {
73                            "Frequency": 30,
74                            "Intensity": 38,
75                            "Curve": [
76                                {
77                                    "Time": 0,
78                                    "Frequency": 0,
79                                    "Intensity": 0
80                                },
81                                {
82                                    "Time": 1,
83                                    "Frequency": 15,
84                                    "Intensity": 0.5
85                                },
86                                {
87                                    "Time": 40,
88                                    "Frequency": -8,
89                                    "Intensity": 1.0
90                                },
91                                {
92                                    "Time": 54,
93                                    "Frequency": 0,
94                                    "Intensity": 0
95                                }
96                            ]
97                        }
98                    }
99                }
100            ]
101        }
102    ]
103}
104```
105
106Json文件共包含2个属性。
1071. "MetaData"属性中为文件头信息,可在如下属性中添加描述:
108
109     | 名称          | 必填项 | 说明                                          |
110     | ------------- | ------ | --------------------------------------------- |
111     | Version       | 是     | 文件格式的版本号,向前兼容,目前支持版本1.0。 |
112     | ChannelNumber | 是     | 表示马达振动的通道数,最大支持双马达通道。    |
113     | Create        | 否     | 可记录文件创作时间。                          |
114     | Description   | 否     | 可指明振动效果、创建信息等附加说明。          |
115
1162. "Channels"属性中为马达振动通道的相关信息。
117
118     "Channels"是Json数组,表示各个通道的信息,包含2个属性。
119
120     | 名称       | 必填项 | 说明                                                         |
121     | ---------- | ------ | ------------------------------------------------------------ |
122     | Parameters | 是     | 为通道参数。其中"Index"表示通道编号,0表示全通道发送,1、2分别对应左右马达。 |
123     | Pattern    | 否     | 马达振动序列。                                               |
124
125     "Pattern"是Json数组,包含振动事件序列,每个"Event"属性代表1个振动事件,支持添加2种振动类型。
126
127     | 振动类型   | 说明                                           |
128     | ---------- | ---------------------------------------------- |
129     | transient  | 瞬态短振动,干脆有力。                         |
130     | continuous | 稳态长振动,具备长时间输出强劲有力振动的能力。 |
131
132     "Event"表示一个振动事件,包含如下属性:
133
134     | 名称      | 必填项 | 说明                                                         |
135     | --------- | ------ | ------------------------------------------------------------ |
136     | Type      | 是     | 振动事件类型,为"transient" 或"continuous"。                 |
137     | StartTime | 是     | 振动的起始时间,单位ms,有效范围为[0, 1800,000]。            |
138     | Duration  | 是     | 振动持续时间,仅当类型为"continuous"时有效,单位ms,有效范围为[0, 5000]。 |
139
1403. "Parameters"表示振动事件参数设置,必填项,可设置以下属性参数:
141
142     | 名称      | 必填项 | 说明                                                         |
143     | --------- | ------ | ------------------------------------------------------------ |
144     | Intensity | 是     | 振动事件强度,有效范围为[0, 100]。                           |
145     | Frequency | 是     | 振动事件频率,有效范围为[0, 100]。                           |
146     | Curve     | 否     | 振动曲线,当振动事件类型为"continuous"时有效,为Json数组,支持设置一组调节点,调节点数量最大支持16个,最小为4个,每个调节点需包含如下属性:<br/>"Time":相对事件起始时间的偏移,最小为0,最大不能超过事件振动时长;<br/>"Intensity":相对事件振动强度的增益,范围为[0, 1],此值乘上振动事件强度为对应时间点调节后的强度;<br/>"Frequency":相对事件振动频率的变化,范围为[-100, 100],此值加上振动事件频率为对应时间点调节后的频率。 |
147
148其他要求:
149
150| 参数 | 要求                 |
151| -------- | ------------------------ |
152| 振动事件(event)的数量 | 不得超过128个。 |
153| 振动配置文件长度 | 不得超过64KB。 |
154
155
156## 开发步骤
157
1581. 控制设备上的振动器,需要申请权限ohos.permission.VIBRATE。具体配置方式请参考[声明权限](../../security/AccessToken/declare-permissions.md)。
159
1602. 根据指定振动效果和振动属性触发马达振动。
161
162   情形一,按照指定持续时间触发马达振动:
163
164   ```ts
165   import vibrator from '@ohos.vibrator';
166   import { BusinessError } from '@ohos.base';
167
168   try {
169     // 触发马达振动
170     vibrator.startVibration({
171       type: 'time',
172       duration: 1000,
173     }, {
174       id: 0,
175       usage: 'alarm'
176     }, (error: BusinessError) => {
177       if (error) {
178         console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);
179         return;
180       }
181       console.info('Succeed in starting vibration');
182     });
183   } catch (err) {
184     let e: BusinessError = err as BusinessError;
185     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
186   }
187   ```
188
189   情形二,按照预置振动效果触发马达振动,可先查询振动效果是否被支持,再调用振动接口:
190
191   ```ts
192   import vibrator from '@ohos.vibrator';
193   import { BusinessError } from '@ohos.base';
194
195   try {
196     // 查询是否支持'haptic.clock.timer'
197     vibrator.isSupportEffect('haptic.clock.timer', (err: BusinessError, state: boolean) => {
198       if (err) {
199         console.error(`Failed to query effect. Code: ${err.code}, message: ${err.message}`);
200         return;
201       }
202       console.info('Succeed in querying effect');
203       if (state) {
204         try {
205           // 触发马达振动
206           vibrator.startVibration({
207             type: 'preset',
208             effectId: 'haptic.clock.timer',
209             count: 1,
210           }, {
211             usage: 'unknown'
212           }, (error: BusinessError) => {
213             if (error) {
214               console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);
215             } else {
216               console.info('Succeed in starting vibration');
217             }
218           });
219         } catch (error) {
220           let e: BusinessError = error as BusinessError;
221           console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
222         }
223       }
224     })
225   } catch (error) {
226     let e: BusinessError = error as BusinessError;
227     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
228   }
229   ```
230
231   情形三,按照自定义振动配置文件触发马达振动:
232
233   ```ts
234   import vibrator from '@ohos.vibrator';
235   import resourceManager from '@ohos.resourceManager';
236   import { BusinessError } from '@ohos.base';
237
238   const fileName: string = 'xxx.json';
239
240   // 获取文件资源描述符
241   let rawFd: resourceManager.RawFileDescriptor = getContext().resourceManager.getRawFdSync(fileName);
242
243   // 触发马达振动
244   try {
245     vibrator.startVibration({
246       type: "file",
247       hapticFd: { fd: rawFd.fd, offset: rawFd.offset, length: rawFd.length }
248     }, {
249       id: 0,
250       usage: 'alarm'
251     }, (error: BusinessError) => {
252       if (error) {
253         console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);
254         return;
255       }
256       console.info('Succeed in starting vibration');
257     });
258   } catch (err) {
259     let e: BusinessError = err as BusinessError;
260     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
261   }
262
263   // 关闭文件资源描述符
264   getContext().resourceManager.closeRawFdSync(fileName);
265   ```
266
2673. 停止马达的振动。
268
269   方式一,按照指定模式停止对应的马达振动,自定义振动不支持此类停止方式:
270
271   ​	停止固定时长振动:
272
273   ```ts
274   import vibrator from '@ohos.vibrator';
275   import { BusinessError } from '@ohos.base';
276
277   try {
278     // 按照VIBRATOR_STOP_MODE_TIME模式停止振动
279     vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_TIME, (error: BusinessError) => {
280       if (error) {
281         console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`);
282         return;
283       }
284       console.info('Succeed in stopping vibration');
285     })
286   } catch (err) {
287     let e: BusinessError = err as BusinessError;
288     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
289   }
290   ```
291
292   ​	停止预置振动:
293
294   ```ts
295   import vibrator from '@ohos.vibrator';
296   import { BusinessError } from '@ohos.base';
297
298   try {
299     // 按照VIBRATOR_STOP_MODE_PRESET模式停止振动
300     vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_PRESET, (error: BusinessError) => {
301       if (error) {
302         console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`);
303         return;
304       }
305       console.info('Succeed in stopping vibration');
306     })
307   } catch (err) {
308     let e: BusinessError = err as BusinessError;
309     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
310   }
311   ```
312
313   方式二,停止所有模式的马达振动,包括自定义振动:
314
315   ```ts
316   import vibrator from '@ohos.vibrator';
317   import { BusinessError } from '@ohos.base';
318
319   try {
320     // 停止所有模式的马达振动
321     vibrator.stopVibration((error: BusinessError) => {
322       if (error) {
323         console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`);
324         return;
325       }
326       console.info('Succeed in stopping vibration');
327     })
328   } catch (error) {
329     let e: BusinessError = error as BusinessError;
330     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
331   }
332   ```
333
334
335## 相关实例
336
337针对振动开发,有以下相关实例可供参考:
338
339- [振动(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/BasicVibration)
340
341- [自定义振动(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/CustomHaptic)
342