振动开发指导(C/C++)
场景介绍
当设备需要设置不同的振动效果时,可以调用Vibrator模块,例如:设备的按键可以设置不同强度和不同时长的振动,闹钟和来电可以设置不同强度和时长的单次或周期振动。
详细的接口介绍请参考Vibrator。
函数说明
| 名称 | 描述 |
|---|---|
| OHOS::Sensors::OH_Vibrator_PlayVibration(int32_t duration, Vibrator_Attribute attribute) | 控制马达在指定时间内持续振动。 |
| OHOS::Sensors::OH_Vibrator_PlayVibrationCustom(Vibrator_FileDescription fileDescription, Vibrator_Attribute vibrateAttribute) | 播放自定义振动序列。 |
| OHOS::Sensors::OH_Vibrator_Cancel() | 停止马达振动。 |
振动效果说明
目前支持两类振动效果,如下所示。
固定时长振动
传入一个固定时长,马达按照默认强度和频率触发振动。
自定义振动
自定义振动提供给用户设计自己所需振动效果的能力,用户可通过自定义振动配置文件,并遵循相应规则编排所需振动形式,使能更加开放的振感交互体验。
开发步骤
-
新建一个Native C++工程。

-
控制设备上的振动器,需要申请权限ohos.permission.VIBRATE。具体配置方式请参考声明权限。
"requestPermissions": [{"name": "ohos.permission.VIBRATE"}] -
CMakeLists.txt文件中引入动态依赖库。
target_link_libraries(entry PUBLIC libace_napi.z.so)target_link_libraries(entry PUBLIC libhilog_ndk.z.so)target_link_libraries(entry PUBLIC libohvibrator.z.so)target_link_libraries(entry PUBLIC librawfile.z.so) -
导入模块。
#include <sensors/vibrator.h>#include "napi/native_api.h"#include "hilog/log.h"#include <thread>#include <fcntl.h>#include <unistd.h>#include <sys/stat.h>#include <rawfile/raw_file_manager.h> -
定义常量。
const int VIBRATOR_LOG_DOMAIN = 0xD002701;const char *TAG = "[NativeVibratorTest]";constexpr int32_t TIME_WAIT_FOR_OP = 2; -
控制马达在指定时间内持续振动和停止马达振动。
static napi_value PlayVibrationInDuration(napi_env env, napi_callback_info info){Vibrator_Attribute vibrateAttribute;vibrateAttribute.usage = VIBRATOR_USAGE_ALARM;// 控制马达在指定时间内持续振动。int32_t ret = OH_Vibrator_PlayVibration(2000, vibrateAttribute);if (ret != 0) {OH_LOG_Print(LOG_APP, LOG_ERROR, VIBRATOR_LOG_DOMAIN, TAG, "vibration fail");return nullptr;}OH_LOG_Print(LOG_APP, LOG_INFO, VIBRATOR_LOG_DOMAIN, TAG, "vibration successful");std::this_thread::sleep_for(std::chrono::milliseconds(TIME_WAIT_FOR_OP));// 停止马达振动。ret = OH_Vibrator_Cancel();if (ret != 0) {OH_LOG_Print(LOG_APP, LOG_ERROR, VIBRATOR_LOG_DOMAIN, TAG, "cancel vibration fail");return nullptr;}return nullptr;} -
播放自定义振动序列。
static napi_value PlayVibrationCustom(napi_env env, napi_callback_info info){size_t argc = 1;napi_value argv[1] = { nullptr };// 获取参数信息napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);// argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]);if (mNativeResMgr == nullptr) {OH_LOG_Print(LOG_APP, LOG_ERROR, VIBRATOR_LOG_DOMAIN, TAG, "Get native resource manager failed");return nullptr;}// 获取rawfile指针对象std::string fileName = "coin_drop.json";RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, fileName.c_str());if (rawFile == nullptr) {OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);OH_LOG_Print(LOG_APP, LOG_ERROR, VIBRATOR_LOG_DOMAIN, TAG, "Get native rawFile failed");return nullptr;}// 获取rawfile的描述符RawFileDescriptor {fd, offset, length}RawFileDescriptor descriptor;OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor);Vibrator_FileDescription fileDescription = {.fd = descriptor.fd,.offset = descriptor.start,.length = descriptor.length};Vibrator_Attribute vibrateAttribute = {.usage = VIBRATOR_USAGE_RING};// 播放自定义振动序列。int32_t ret = OH_Vibrator_PlayVibrationCustom(fileDescription, vibrateAttribute);bool isSuccess = ((ret == 0) || (ret == UNSUPPORTED));if (!isSuccess) {OH_LOG_Print(LOG_APP, LOG_INFO, VIBRATOR_LOG_DOMAIN, TAG, "Vibratecustom fail");} else {OH_LOG_Print(LOG_APP, LOG_INFO, VIBRATOR_LOG_DOMAIN, TAG, "Vibratecustom successful");}std::this_thread::sleep_for(std::chrono::milliseconds(TIME_WAIT_FOR_OP));// 停止马达振动。OH_Vibrator_Cancel();// 关闭打开的指针对象OH_ResourceManager_CloseRawFile(rawFile);OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);return nullptr;} -
在Init函数中补充接口。
EXTERN_C_STARTstatic napi_value Init(napi_env env, napi_value exports){napi_property_descriptor desc[] = {{"playVibrationInDuration", nullptr, PlayVibrationInDuration, nullptr, nullptr, nullptr, napi_default, nullptr},{"playVibrationCustom", nullptr, PlayVibrationCustom, nullptr, nullptr, nullptr, napi_default, nullptr}};napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);return exports;}EXTERN_C_END -
在types/libentry路径下index.d.ts文件中引入Napi接口。
export const playVibrationInDuration: () => object;export const playVibrationCustom: (resmgr: object) => object; -
编写程序入口调用代码。
import { BusinessError } from '@kit.BasicServicesKit';import { hilog } from '@kit.PerformanceAnalysisKit';import { resourceManager } from '@kit.LocalizationKit';import vibratorCapi from 'libentry.so';const DOMAIN = 0xD002701;// ...try {vibratorCapi.playVibrationInDuration();// ...} catch (error) {let e: BusinessError = error as BusinessError;hilog.error(DOMAIN, 'testTag', `Failed to invoke playVibrationInDuration. Code: ${e.code}, message: ${e.message}`);}// ...try {vibratorCapi.playVibrationCustom(this.getUIContext().getHostContext()?.resourceManager);// ...} catch (error) {let e: BusinessError = error as BusinessError;hilog.error(DOMAIN, 'testTag', `Failed to invoke playVibrationCustom. Code: ${e.code}, message: ${e.message}`);}