• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Vibrator Development (ArkTS)
2
3
4## When to Use
5
6You can set different vibration effects as needed, for example, customizing the vibration intensity, frequency, and duration for button touches, alarm clocks, and incoming calls.
7
8For details about the APIs, see [Vibrator](../../reference/apis-sensor-service-kit/js-apis-vibrator.md).
9
10
11## Available APIs
12
13| Name                                                        | Description                                                                         |
14| ------------------------------------------------------------ |-----------------------------------------------------------------------------|
15| startVibration(effect: VibrateEffect, attribute: VibrateAttribute): Promise<void> | Starts vibration with the specified effect and attribute. This API uses a promise to return the result.                                         |
16| startVibration(effect: VibrateEffect, attribute: VibrateAttribute, callback: AsyncCallback<void>): void | Starts vibration with the specified effect and attribute. This API uses an asynchronous callback to return the result.                                        |
17| stopVibration(stopMode: VibratorStopMode): Promise<void> | Stops vibration in the specified mode. This API uses a promise to return the result.                                               |
18| stopVibration(stopMode: VibratorStopMode, callback: AsyncCallback<void>): void | Stops vibration in the specified mode. This API uses an asynchronous callback to return the result.                                              |
19| stopVibration(): Promise<void>                         | Stops vibration in all modes. This API uses a promise to return the result.                                                 |
20| stopVibration(param?: VibratorInfoParam): Promise<void> | Stops vibration based on the specified vibrator parameters. This API uses a promise to return the result.                                |
21| stopVibration(callback: AsyncCallback<void>): void     | Stops vibration in all modes. This API uses an asynchronous callback to return the result.                                                |
22| isSupportEffect(effectId: string): Promise<boolean>    | Checks whether an effect ID is supported. This API uses a promise to return the result. The return value **true** means that the effect ID is supported, and **false** means the opposite.                       |
23| isSupportEffect(effectId: string, callback: AsyncCallback<boolean>): void | Checks whether an effect ID is supported. This API uses an asynchronous callback to return the result. The return value **true** means that the effect ID is supported, and **false** means the opposite.                      |
24| getEffectInfoSync(effectId: string, param?: VibratorInfoParam): EffectInfo | Checks whether the effect specified by the input **effectId** is supported. The **param** parameter can be used to specify a specific vibrator. You can check the **isEffectSupported** field in the returned **EffectInfo** object to determine whether the effect is supported.|
25| getVibratorInfoSync(param?: VibratorInfoParam): Array<VibratorInfo> | Queries the vibrator list of one or all devices. The returned **VibratorInfo** object includes the following information: device ID, vibrator ID, device name, support for HD vibration, and local device flag.      |
26| on(type: 'vibratorStateChange', callback: Callback<VibratorStatusEvent>): void | Enables listening for vibrator status changes. The **VibratorStatusEvent** parameter includes the following information: event timestamp, device ID, number of vibrators, and online/offline status. |
27| off(type: 'vibratorStateChange', callback?: Callback<VibratorStatusEvent>): void | Disables listening for vibrator status changes.                                                          |
28
29
30## Vibration Effect Description
31
32Currently, three types of vibration effects are supported.
33
34| Name        | Description                                                        |
35| ------------ | ------------------------------------------------------------ |
36| Fixed-Duration Vibration| Only a fixed duration is passed in, and the device vibrates based on the default intensity and frequency. For details about the vibration effect, see [VibrateTime](../../reference/apis-sensor-service-kit/js-apis-vibrator.md#vibratetime9).|
37| Preset Vibration    | Certain [vibration effects are preset](../../reference/apis-sensor-service-kit/js-apis-vibrator.md#effectid) for fixed scenes. For example, the effect "haptic.clock.timer" is preset to provide feedback when a user adjusts the timer. For details about the vibration effect, see [VibratePreset](../../reference/apis-sensor-service-kit/js-apis-vibrator.md#vibratepreset9).|
38| Custom Vibration  | Custom vibration enables you to design vibration effects by customizing a vibration configuration file and orchestrating vibration forms based on the corresponding rules. For details about the vibration effect, see [VibrateFromFile](../../reference/apis-sensor-service-kit/js-apis-vibrator.md#vibratefromfile10).|
39
40The custom vibration configuration file is in JSON format. An example file is as follows:
41
42```json
43{
44    "MetaData": {
45        "Create": "2023-01-09",
46        "Description": "a haptic case",
47        "Version": 1.0,
48        "ChannelNumber": 1
49    },
50    "Channels": [
51        {
52            "Parameters": {
53                "Index": 0
54            },
55            "Pattern": [
56                {
57                    "Event": {
58                        "Type": "transient",
59                        "StartTime": 0,
60                        "Parameters": {
61                            "Frequency": 31,
62                            "Intensity": 100
63                        }
64                    }
65                },
66                {
67                    "Event": {
68                        "Type": "continuous",
69                        "StartTime": 40,
70                        "Duration": 54,
71                        "Parameters": {
72                            "Frequency": 30,
73                            "Intensity": 38,
74                            "Curve": [
75                                {
76                                    "Time": 0,
77                                    "Frequency": 0,
78                                    "Intensity": 0
79                                },
80                                {
81                                    "Time": 1,
82                                    "Frequency": 15,
83                                    "Intensity": 0.5
84                                },
85                                {
86                                    "Time": 40,
87                                    "Frequency": -8,
88                                    "Intensity": 1.0
89                                },
90                                {
91                                    "Time": 54,
92                                    "Frequency": 0,
93                                    "Intensity": 0
94                                }
95                            ]
96                        }
97                    }
98                }
99            ]
100        }
101    ]
102}
103```
104
105This JSON file contains three attributes: **MetaData**, **Channels**, and **Parameters**.
1061. **MetaData** contains information about the file header. You can add the following attributes under **MetaData**.
107
108     | Name         | Mandatory| Description                                         |
109     | ------------- | ------ | --------------------------------------------- |
110     | Version       | Yes    | Version number of the file format, which is forward compatible. Currently, only version 1.0 is supported.|
111     | ChannelNumber | Yes    | Number of channels for vibration. A maximum of two channels are supported.   |
112     | Create        | No    | Time when the file was created.                         |
113     | Description   | No    | Additional information such as the vibration effect and creation information.         |
114
1152. **Channels** provides information about the vibration channel.
116
117     It is a JSON array that holds information about each channel. It contains two attributes: **Parameters** and **Pattern**.
118
119     | Name      | Mandatory| Description                                                        |
120     | ---------- | ------ | ------------------------------------------------------------ |
121     | Parameters | Yes    | Channel parameters. Among them, **Index** indicates the channel ID. The value **0** indicates both channels, **1** indicates the left channel, and **2** indicates the right channel.|
122     | Pattern    | No    | Vibration sequence.                                              |
123
124     **Pattern** is a JSON array that holds the vibration events. Under it, **Event** indicates a vibration event, which can be either of the following types:
125
126     | Vibration Type  | Description                                          |
127     | ---------- | ---------------------------------------------- |
128     | transient  | Short vibration.                        |
129     | continuous | Long vibration.|
130
131     A vibration event contains the following attributes:
132
133     | Name     | Mandatory| Description                                                        |
134     | --------- | ------ | ------------------------------------------------------------ |
135     | Type      | Yes    | Type of the vibration event, which can be **transient** or **continuous**.                |
136     | StartTime | Yes    | Vibration start time. The value range is [0, 1800000], in ms.           |
137     | Duration  | Yes    | Vibration duration. This parameter is valid only when **Type** is set to **continuous**. The value range is [0, 5000], in ms.|
138
1393. **Parameters** provides the following parameters related to the vibration event and is mandatory.
140
141     | Name     | Mandatory| Description                                                        |
142     | --------- | ------ | ------------------------------------------------------------ |
143     | Intensity | Yes    | Vibration intensity. The value range is [0, 100].                          |
144     | Frequency | Yes    | Vibration frequency. The value range is [0, 100].                          |
145     | Curve     | No    | Vibration curve. This parameter is valid only when **Type** is set to **continuous**. It is a JSON array that holds 4 to 16 adjustment points. Each adjustment point must contain the following attributes:<br>**Time**: offset relative to the event start time. The value ranges from 0 to the vibration duration.<br>**Intensity**: gain relative to the vibration intensity. The value range is [0, 1]. This value multiplied by the vibration intensity is the adjusted intensity at the corresponding time point.<br>**Frequency**: change relative to the vibration frequency. The value range is [-100, 100]. This value plus the vibration frequency is the adjusted frequency at the corresponding time point.|
146
147The following requirements must be met:
148
149| Item| Description                |
150| -------- | ------------------------ |
151| Number of vibration events| No more than 128|
152| Length of the vibration configuration file| Not greater than 64 KB|
153
154
155## How to Develop
156
1571. Before using the vibrator on a device, you must declare the **ohos.permission.VIBRATE** permission. For details, see [Declaring Permissions](../../security/AccessToken/declare-permissions.md).
158
1592. Query vibrator information.
160
161  Scenario 1: Query information about all vibrators.
162
163  ```ts
164   import { vibrator } from '@kit.SensorServiceKit';
165   import { BusinessError } from '@kit.BasicServicesKit';
166
167  try {
168    const vibratorInfoList: vibrator.VibratorInfo[] = vibrator.getVibratorInfoSync();
169    console.log(`vibratorInfoList: ${JSON.stringify(vibratorInfoList)}`);
170  } catch (error) {
171    let e: BusinessError = error as BusinessError;
172    console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
173  }
174  ```
175
176  Scenario 2: Query information about one or more vibrators of the specified device.
177
178  ```ts
179   import { vibrator } from '@kit.SensorServiceKit';
180   import { BusinessError } from '@kit.BasicServicesKit';
181
182  try {
183    const vibratorParam: vibrator.VibratorInfoParam = {
184      deviceId: 1    // The device ID must be the one that actually exists.
185    }
186    const vibratorInfoList: vibrator.VibratorInfo[] = vibrator.getVibratorInfoSync(vibratorParam);
187    console.log(`vibratorInfoList: ${JSON.stringify(vibratorInfoList)}`);
188  } catch (error) {
189    let e: BusinessError = error as BusinessError;
190    console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
191  }
192  ```
193
1943. Start vibration with the specified effect and attribute.
195
196   Scenario 1: Trigger vibration with the specified duration.
197
198   ```ts
199   import { vibrator } from '@kit.SensorServiceKit';
200   import { BusinessError } from '@kit.BasicServicesKit';
201
202   try {
203     // Start vibration.
204     vibrator.startVibration({
205       type: 'time',
206       duration: 1000,
207     }, {
208       id: 0,
209       usage: 'alarm'
210     }, (error: BusinessError) => {
211       if (error) {
212         console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);
213         return;
214       }
215       console.info('Succeed in starting vibration');
216     });
217   } catch (err) {
218     let e: BusinessError = err as BusinessError;
219     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
220   }
221   ```
222
223   Scenario 2: Trigger vibration with a preset effect. You can check whether the preset effect is supported before calling **startVibration()**.
224
225   ```ts
226   import { vibrator } from '@kit.SensorServiceKit';
227   import { BusinessError } from '@kit.BasicServicesKit';
228
229   try {
230     // Check whether 'haptic.effect.soft' is supported.
231     vibrator.isSupportEffect('haptic.effect.soft', (err: BusinessError, state: boolean) => {
232       if (err) {
233         console.error(`Failed to query effect. Code: ${err.code}, message: ${err.message}`);
234         return;
235       }
236       console.info('Succeed in querying effect');
237       if (state) {
238         try {
239           // Start vibration.
240           vibrator.startVibration({
241             type: 'preset',
242             effectId: 'haptic.effect.soft',
243             count: 1,
244             intensity: 50,
245           }, {
246             usage: 'unknown'
247           }, (error: BusinessError) => {
248             if (error) {
249               console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);
250             } else {
251               console.info('Succeed in starting vibration');
252             }
253           });
254         } catch (error) {
255           let e: BusinessError = error as BusinessError;
256           console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
257         }
258       }
259     })
260   } catch (error) {
261     let e: BusinessError = error as BusinessError;
262     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
263   }
264   ```
265
266   Scenario 3: Trigger vibration according to a custom vibration configuration file.
267
268   ```ts
269   import { vibrator } from '@kit.SensorServiceKit';
270   import { resourceManager } from '@kit.LocalizationKit';
271   import { BusinessError } from '@kit.BasicServicesKit';
272
273   const fileName: string = 'xxx.json';
274
275   @Entry
276   @Component
277   struct Index {
278     uiContext = this.getUIContext();
279
280     build() {
281       Row() {
282         Column() {
283           Button('alarm-file')
284             .onClick(() => {
285               // Obtain the file descriptor of the vibration configuration file.
286               let rawFd: resourceManager.RawFileDescriptor | undefined = this.uiContext.getHostContext()?.resourceManager.getRawFdSync(fileName);
287               if (rawFd != undefined) {
288                 // Start vibration.
289                 try {
290                   vibrator.startVibration({
291                     type: "file",
292                     hapticFd: { fd: rawFd.fd, offset: rawFd.offset, length: rawFd.length }
293                   }, {
294                     id: 0,
295                     usage: 'alarm' // The switch control is subject to the selected type.
296                   }, (error: BusinessError) => {
297                     if (error) {
298                       console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);
299                       return;
300                     }
301                     console.info('Succeed in starting vibration');
302                   });
303                 } catch (err) {
304                   let e: BusinessError = err as BusinessError;
305                   console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
306                 }
307               }
308               // Close the file descriptor of the vibration configuration file.
309               this.uiContext.getHostContext()?.resourceManager.closeRawFdSync(fileName);
310             })
311         }
312         .width('100%')
313       }
314       .height('100%')
315     }
316   }
317   ```
318
3194. Stop vibration.
320
321   Method 1: Stop vibration in the specified mode. This method is invalid for custom vibration.
322
323   ​	Stop fixed-duration vibration.
324
325   ```ts
326   import { vibrator } from '@kit.SensorServiceKit';
327   import { BusinessError } from '@kit.BasicServicesKit';
328
329   try {
330     // Stop vibration in VIBRATOR_STOP_MODE_TIME mode.
331     vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_TIME, (error: BusinessError) => {
332       if (error) {
333         console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`);
334         return;
335       }
336       console.info('Succeed in stopping vibration');
337     })
338   } catch (err) {
339     let e: BusinessError = err as BusinessError;
340     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
341   }
342   ```
343
344   ​	Stop preset vibration.
345
346   ```ts
347   import { vibrator } from '@kit.SensorServiceKit';
348   import { BusinessError } from '@kit.BasicServicesKit';
349
350   try {
351     // Stop vibration in VIBRATOR_STOP_MODE_PRESET mode.
352     vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_PRESET, (error: BusinessError) => {
353       if (error) {
354         console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`);
355         return;
356       }
357       console.info('Succeed in stopping vibration');
358     })
359   } catch (err) {
360     let e: BusinessError = err as BusinessError;
361     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
362   }
363   ```
364
365   Method 2: Stop vibration in all modes, including custom vibration.
366
367   ```ts
368   import { vibrator } from '@kit.SensorServiceKit';
369   import { BusinessError } from '@kit.BasicServicesKit';
370
371   try {
372     // Stop vibration in all modes.
373     vibrator.stopVibration((error: BusinessError) => {
374       if (error) {
375         console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`);
376         return;
377       }
378       console.info('Succeed in stopping vibration');
379     })
380   } catch (error) {
381     let e: BusinessError = error as BusinessError;
382     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
383   }
384   ```
385
386   Method 3: Stop vibration of the specified device.
387
388   ```ts
389   import { vibrator } from '@kit.SensorServiceKit';
390   import { BusinessError } from '@kit.BasicServicesKit';
391
392   const vibratorInfoParam: vibrator.VibratorInfoParam = {
393     deviceId: 1   // The device ID must be the one that actually exists.
394   }
395   try {
396     vibrator.stopVibration(vibratorInfoParam).then(() => {
397       console.info('Succeed in stopping vibration');
398     }, (error: BusinessError) => {
399       console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`);
400     });
401   } catch (error) {
402     let e: BusinessError = error as BusinessError;
403     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
404   }
405   ```
406
407
4085. Enable listening for vibrator status changes.
409
410   Enable listening.
411   ```ts
412   import { vibrator } from '@kit.SensorServiceKit';
413   import { BusinessError } from '@kit.BasicServicesKit';
414
415   // Callback
416   const vibratorStateChangeCallback = (data: vibrator.VibratorStatusEvent) => {
417     console.log('vibrator state callback info:', JSON.stringify(data));
418   }
419
420   try {
421     // Subscribe to vibratorStateChange events.
422     vibrator.on('vibratorStateChange', vibratorStateChangeCallback);
423   } catch (error) {
424     let e: BusinessError = error as BusinessError;
425     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
426   }
427   ```
428
429   Disable listening. The specified callback must be the same as that passed to the **on** API.
430   ```ts
431   import { vibrator } from '@kit.SensorServiceKit';
432   import { BusinessError } from '@kit.BasicServicesKit';
433
434   // Callback
435   const vibratorStateChangeCallback = (data: vibrator.VibratorStatusEvent) => {
436     console.log('vibrator state callback info:', JSON.stringify(data));
437   }
438   try {
439     // Unsubscribe from specified vibratorStateChange events.
440     vibrator.off('vibratorStateChange', vibratorStateChangeCallback);
441     // Unsubscribe from all vibratorStateChange events.
442     // vibrator.off('vibratorStateChange');
443   } catch (error) {
444     let e: BusinessError = error as BusinessError;
445     console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
446   }
447   ```
448