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(callback: AsyncCallback<void>): void | Stops vibration in all modes. This API uses an asynchronous callback to return the result. | 21| isSupportEffect(effectId: string): Promise<boolean> | Checks whether an effect ID is supported. This API uses a promise to return the result. 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.| 22| isSupportEffect(effectId: string, callback: AsyncCallback<boolean>): void | Checks whether an effect ID is supported. This API uses an asynchronous callback to return the result. 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.| 23 24 25## Vibration Effect Description 26 27Currently, three types of vibration effects are supported. 28 29| Name | Description | 30| ------------ | ------------------------------------------------------------ | 31| 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).| 32| 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).| 33| 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).| 34 35The custom vibration configuration file is in JSON format. An example file is as follows: 36 37```json 38{ 39 "MetaData": { 40 "Create": "2023-01-09", 41 "Description": "a haptic case", 42 "Version": 1.0, 43 "ChannelNumber": 1 44 }, 45 "Channels": [ 46 { 47 "Parameters": { 48 "Index": 0 49 }, 50 "Pattern": [ 51 { 52 "Event": { 53 "Type": "transient", 54 "StartTime": 0, 55 "Parameters": { 56 "Frequency": 31, 57 "Intensity": 100 58 } 59 } 60 }, 61 { 62 "Event": { 63 "Type": "continuous", 64 "StartTime": 40, 65 "Duration": 54, 66 "Parameters": { 67 "Frequency": 30, 68 "Intensity": 38, 69 "Curve": [ 70 { 71 "Time": 0, 72 "Frequency": 0, 73 "Intensity": 0 74 }, 75 { 76 "Time": 1, 77 "Frequency": 15, 78 "Intensity": 0.5 79 }, 80 { 81 "Time": 40, 82 "Frequency": -8, 83 "Intensity": 1.0 84 }, 85 { 86 "Time": 54, 87 "Frequency": 0, 88 "Intensity": 0 89 } 90 ] 91 } 92 } 93 } 94 ] 95 } 96 ] 97} 98``` 99 100This JSON file contains two attributes: **MetaData** and **Channels**. 1011. **MetaData** contains information about the file header. You can add the following attributes under **MetaData**. 102 103 | Name | Mandatory| Description | 104 | ------------- | ------ | --------------------------------------------- | 105 | Version | Yes | Version number of the file format, which is forward compatible. Currently, only version 1.0 is supported.| 106 | ChannelNumber | Yes | Number of channels for vibration. A maximum of two channels are supported. | 107 | Create | No | Time when the file was created. | 108 | Description | No | Additional information such as the vibration effect and creation information. | 109 1102. **Channels** provides information about the vibration channel. 111 112 It is a JSON array that holds information about each channel. It contains two attributes: **Parameters** and **Pattern**. 113 114 | Name | Mandatory| Description | 115 | ---------- | ------ | ------------------------------------------------------------ | 116 | 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.| 117 | Pattern | No | Vibration sequence. | 118 119 **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: 120 121 | Vibration Type | Description | 122 | ---------- | ---------------------------------------------- | 123 | transient | Short vibration. | 124 | continuous | Long vibration.| 125 126 A vibration event contains the following attributes: 127 128 | Name | Mandatory| Description | 129 | --------- | ------ | ------------------------------------------------------------ | 130 | Type | Yes | Type of the vibration event, which can be **transient** or **continuous**. | 131 | StartTime | Yes | Vibration start time. The value range is [0, 1800000], in ms. | 132 | Duration | Yes | Vibration duration. This parameter is valid only when **Type** is set to **continuous**. The value range is [0, 5000], in ms.| 133 1343. **Parameters** provides the following parameters related to the vibration event and is mandatory. 135 136 | Name | Mandatory| Description | 137 | --------- | ------ | ------------------------------------------------------------ | 138 | Intensity | Yes | Vibration intensity. The value range is [0, 100]. | 139 | Frequency | Yes | Vibration frequency. The value range is [0, 100]. | 140 | 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.| 141 142The following requirements must be met: 143 144| Item| Description | 145| -------- | ------------------------ | 146| Number of vibration events| No more than 128| 147| Length of the vibration configuration file| Not greater than 64 KB| 148 149 150## How to Develop 151 1521. 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). 153 1542. Start vibration with the specified effect and attribute. 155 156 Scenario 1: Trigger vibration with the specified duration. 157 158 ```ts 159 import { vibrator } from '@kit.SensorServiceKit'; 160 import { BusinessError } from '@kit.BasicServicesKit'; 161 162 try { 163 // Start vibration. 164 vibrator.startVibration({ 165 type: 'time', 166 duration: 1000, 167 }, { 168 id: 0, 169 usage: 'alarm' 170 }, (error: BusinessError) => { 171 if (error) { 172 console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`); 173 return; 174 } 175 console.info('Succeed in starting vibration'); 176 }); 177 } catch (err) { 178 let e: BusinessError = err as BusinessError; 179 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 180 } 181 ``` 182 183 Scenario 2: Trigger vibration with a preset effect. You can check whether the preset effect is supported before calling **startVibration()**. 184 185 ```ts 186 import { vibrator } from '@kit.SensorServiceKit'; 187 import { BusinessError } from '@kit.BasicServicesKit'; 188 189 try { 190 // Check whether 'haptic.effect.soft' is supported. 191 vibrator.isSupportEffect('haptic.effect.soft', (err: BusinessError, state: boolean) => { 192 if (err) { 193 console.error(`Failed to query effect. Code: ${err.code}, message: ${err.message}`); 194 return; 195 } 196 console.info('Succeed in querying effect'); 197 if (state) { 198 try { 199 // Start vibration. 200 vibrator.startVibration({ 201 type: 'preset', 202 effectId: 'haptic.effect.soft', 203 count: 1, 204 intensity: 50, 205 }, { 206 usage: 'unknown' 207 }, (error: BusinessError) => { 208 if (error) { 209 console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`); 210 } else { 211 console.info('Succeed in starting vibration'); 212 } 213 }); 214 } catch (error) { 215 let e: BusinessError = error as BusinessError; 216 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 217 } 218 } 219 }) 220 } catch (error) { 221 let e: BusinessError = error as BusinessError; 222 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 223 } 224 ``` 225 226 Scenario 3: Trigger vibration according to a custom vibration configuration file. 227 228 ```ts 229 import { vibrator } from '@kit.SensorServiceKit'; 230 import { resourceManager } from '@kit.LocalizationKit'; 231 import { BusinessError } from '@kit.BasicServicesKit'; 232 233 const fileName: string = 'xxx.json'; 234 235 // Obtain the file descriptor of the vibration configuration file. 236 let rawFd: resourceManager.RawFileDescriptor = getContext().resourceManager.getRawFdSync(fileName); 237 238 // Start vibration. 239 try { 240 vibrator.startVibration({ 241 type: "file", 242 hapticFd: { fd: rawFd.fd, offset: rawFd.offset, length: rawFd.length } 243 }, { 244 id: 0, 245 usage: 'alarm' 246 }, (error: BusinessError) => { 247 if (error) { 248 console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`); 249 return; 250 } 251 console.info('Succeed in starting vibration'); 252 }); 253 } catch (err) { 254 let e: BusinessError = err as BusinessError; 255 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 256 } 257 258 // Close the file descriptor of the vibration configuration file. 259 getContext().resourceManager.closeRawFdSync(fileName); 260 ``` 261 2623. Stop vibration. 263 264 Method 1: Stop vibration in the specified mode. This method is invalid for custom vibration. 265 266 Stop fixed-duration vibration. 267 268 ```ts 269 import { vibrator } from '@kit.SensorServiceKit'; 270 import { BusinessError } from '@kit.BasicServicesKit'; 271 272 try { 273 // Stop vibration in VIBRATOR_STOP_MODE_TIME mode. 274 vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_TIME, (error: BusinessError) => { 275 if (error) { 276 console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`); 277 return; 278 } 279 console.info('Succeed in stopping vibration'); 280 }) 281 } catch (err) { 282 let e: BusinessError = err as BusinessError; 283 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 284 } 285 ``` 286 287 Stop preset vibration. 288 289 ```ts 290 import { vibrator } from '@kit.SensorServiceKit'; 291 import { BusinessError } from '@kit.BasicServicesKit'; 292 293 try { 294 // Stop vibration in VIBRATOR_STOP_MODE_PRESET mode. 295 vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_PRESET, (error: BusinessError) => { 296 if (error) { 297 console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`); 298 return; 299 } 300 console.info('Succeed in stopping vibration'); 301 }) 302 } catch (err) { 303 let e: BusinessError = err as BusinessError; 304 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 305 } 306 ``` 307 308 Method 2: Stop vibration in all modes, including custom vibration. 309 310 ```ts 311 import { vibrator } from '@kit.SensorServiceKit'; 312 import { BusinessError } from '@kit.BasicServicesKit'; 313 314 try { 315 // Stop vibration in all modes. 316 vibrator.stopVibration((error: BusinessError) => { 317 if (error) { 318 console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`); 319 return; 320 } 321 console.info('Succeed in stopping vibration'); 322 }) 323 } catch (error) { 324 let e: BusinessError = error as BusinessError; 325 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 326 } 327 ``` 328 329 330## Samples 331 332The following sample is provided to help you better understand how to develop vibrators: 333 334- [Vibrator (ArkTS, API version 9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/BasicVibration) 335 336- [CustomHaptic (ArkTS, Full SDK, API version 10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/CustomHaptic) 337