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### Fixed-Duration Vibration 30 31Only 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 33### Preset Vibration 34 35Certain [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). 36 37### Custom Vibration 38 39Custom 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). 40 41The custom vibration configuration file is in JSON format. An example file is as follows: 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 106This JSON file contains two attributes: **MetaData** and **Channels**. 1071. **MetaData** contains information about the file header. You can add the following attributes under **MetaData**. 108 109 | Name | Mandatory| Description | 110 | ------------- | ------ | --------------------------------------------- | 111 | Version | Yes | Version number of the file format, which is forward compatible. Currently, only version 1.0 is supported.| 112 | ChannelNumber | Yes | Number of channels for vibration. A maximum of two channels are supported. | 113 | Create | No | Time when the file was created. | 114 | Description | No | Additional information such as the vibration effect and creation information. | 115 1162. **Channels** provides information about the vibration channel. 117 118 It is a JSON array that holds information about each channel. It contains two attributes: **Parameters** and **Pattern**. 119 120 | Name | Mandatory| Description | 121 | ---------- | ------ | ------------------------------------------------------------ | 122 | 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.| 123 | Pattern | No | Vibration sequence. | 124 125 **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: 126 127 | Vibration Type | Description | 128 | ---------- | ---------------------------------------------- | 129 | transient | Short vibration. | 130 | continuous | Long vibration.| 131 132 A vibration event contains the following attributes: 133 134 | Name | Mandatory| Description | 135 | --------- | ------ | ------------------------------------------------------------ | 136 | Type | Yes | Type of the vibration event, which can be **transient** or **continuous**. | 137 | StartTime | Yes | Vibration start time. The value range is [0, 1800000], in ms. | 138 | Duration | Yes | Vibration duration. This parameter is valid only when **Type** is set to **continuous**. The value range is [0, 5000], in ms.| 139 1403. **Parameters** provides the following parameters related to the vibration event and is mandatory. 141 142 | Name | Mandatory| Description | 143 | --------- | ------ | ------------------------------------------------------------ | 144 | Intensity | Yes | Vibration intensity. The value range is [0, 100]. | 145 | Frequency | Yes | Vibration frequency. The value range is [0, 100]. | 146 | 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.| 147 148The following requirements must be met: 149 150| Item| Description | 151| -------- | ------------------------ | 152| Number of vibration events| No more than 128| 153| Length of the vibration configuration file| Not greater than 64 KB| 154 155 156## How to Develop 157 1581. 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). 159 1602. Start vibration with the specified effect and attribute. 161 162 Scenario 1: Trigger vibration with the specified duration. 163 164 ```ts 165 import { vibrator } from '@kit.SensorServiceKit'; 166 import { BusinessError } from '@kit.BasicServicesKit'; 167 168 try { 169 // Start vibration. 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 Scenario 2: Trigger vibration with a preset effect. You can check whether the preset effect is supported before calling **startVibration()**. 190 191 ```ts 192 import { vibrator } from '@kit.SensorServiceKit'; 193 import { BusinessError } from '@kit.BasicServicesKit'; 194 195 try { 196 // Check whether 'haptic.effect.soft' is supported. 197 vibrator.isSupportEffect('haptic.effect.soft', (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 // Start vibration. 206 vibrator.startVibration({ 207 type: 'preset', 208 effectId: 'haptic.effect.soft', 209 count: 1, 210 intensity: 50, 211 }, { 212 usage: 'unknown' 213 }, (error: BusinessError) => { 214 if (error) { 215 console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`); 216 } else { 217 console.info('Succeed in starting vibration'); 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 } catch (error) { 227 let e: BusinessError = error as BusinessError; 228 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 229 } 230 ``` 231 232 Scenario 3: Trigger vibration according to a custom vibration configuration file. 233 234 ```ts 235 import { vibrator } from '@kit.SensorServiceKit'; 236 import { resourceManager } from '@kit.LocalizationKit'; 237 import { BusinessError } from '@kit.BasicServicesKit'; 238 239 const fileName: string = 'xxx.json'; 240 241 // Obtain the file descriptor of the vibration configuration file. 242 let rawFd: resourceManager.RawFileDescriptor = getContext().resourceManager.getRawFdSync(fileName); 243 244 // Start vibration. 245 try { 246 vibrator.startVibration({ 247 type: "file", 248 hapticFd: { fd: rawFd.fd, offset: rawFd.offset, length: rawFd.length } 249 }, { 250 id: 0, 251 usage: 'alarm' 252 }, (error: BusinessError) => { 253 if (error) { 254 console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`); 255 return; 256 } 257 console.info('Succeed in starting vibration'); 258 }); 259 } catch (err) { 260 let e: BusinessError = err as BusinessError; 261 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 262 } 263 264 // Close the file descriptor of the vibration configuration file. 265 getContext().resourceManager.closeRawFdSync(fileName); 266 ``` 267 2683. Stop vibration. 269 270 Method 1: Stop vibration in the specified mode. This method is invalid for custom vibration. 271 272 Stop fixed-duration vibration. 273 274 ```ts 275 import { vibrator } from '@kit.SensorServiceKit'; 276 import { BusinessError } from '@kit.BasicServicesKit'; 277 278 try { 279 // Stop vibration in VIBRATOR_STOP_MODE_TIME mode. 280 vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_TIME, (error: BusinessError) => { 281 if (error) { 282 console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`); 283 return; 284 } 285 console.info('Succeed in stopping vibration'); 286 }) 287 } catch (err) { 288 let e: BusinessError = err as BusinessError; 289 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 290 } 291 ``` 292 293 Stop preset vibration. 294 295 ```ts 296 import { vibrator } from '@kit.SensorServiceKit'; 297 import { BusinessError } from '@kit.BasicServicesKit'; 298 299 try { 300 // Stop vibration in VIBRATOR_STOP_MODE_PRESET mode. 301 vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_PRESET, (error: BusinessError) => { 302 if (error) { 303 console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`); 304 return; 305 } 306 console.info('Succeed in stopping vibration'); 307 }) 308 } catch (err) { 309 let e: BusinessError = err as BusinessError; 310 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 311 } 312 ``` 313 314 Method 2: Stop vibration in all modes, including custom vibration. 315 316 ```ts 317 import { vibrator } from '@kit.SensorServiceKit'; 318 import { BusinessError } from '@kit.BasicServicesKit'; 319 320 try { 321 // Stop vibration in all modes. 322 vibrator.stopVibration((error: BusinessError) => { 323 if (error) { 324 console.error(`Failed to stop vibration. Code: ${error.code}, message: ${error.message}`); 325 return; 326 } 327 console.info('Succeed in stopping vibration'); 328 }) 329 } catch (error) { 330 let e: BusinessError = error as BusinessError; 331 console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`); 332 } 333 ``` 334