diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/.gitignore b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/.gitignore
@@ -0,0 +1,12 @@
+/node_modules
+/oh_modules
+/local.properties
+/.idea
+**/build
+/.hvigor
+.cxx
+/.clangd
+/.clang-format
+/.clang-tidy
+**/.test
+/.appanalyzer
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/app.json5 b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..18914dcccadf4c0486155a7f8649a5bfd9e82454
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/app.json5
@@ -0,0 +1,10 @@
+{
+ "app": {
+ "bundleName": "com.samples.sensor",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:layered_image",
+ "label": "$string:app_name"
+ }
+}
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/element/string.json b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..81ecd132d91354a5686fb1327cace1aaae343549
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "SensorJsSamples"
+ }
+ ]
+}
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/media/background.png b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/media/background.png differ
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/media/foreground.png b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/media/foreground.png differ
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/media/layered_image.json b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/AppScope/resources/base/media/layered_image.json
@@ -0,0 +1,7 @@
+{
+ "layered-image":
+ {
+ "background" : "$media:background",
+ "foreground" : "$media:foreground"
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/README_zh.md b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..48336868a5ea49145a689d17a8e7a04b2d2c2150
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/README_zh.md
@@ -0,0 +1,85 @@
+# sensor js接口hap
+
+### 介绍
+
+本样例展示了sensor模块js接口的使用样例,包含订阅,去订阅传感器,订阅、去订阅外设热插拔事件、获取设备及扩展设备的上传感器信息等接口功能
+
+
+
+本示例用到了权限获取相关的的操作[@ohos.abilityAccessCtrl](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#abilityaccessctrlcreateatmanager)
+错误信息相关[@ohos.base](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-base.md)
+
+传感器相关接口操作[@kit.SensorServiceKit](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-sensor-service-kit/js-apis-sensor.md)
+
+
+### 效果预览
+| 主页 |
+|----------------------------------------------|
+|
|
+
+依次介绍sample具有什么功能,怎样使用这些功能,以及使用后会达到什么效果;示例如下:
+
+1. 在主界面,可以点击Please select sensor type文本框选择此设备上的传感器;
+2. 在主界面,可以点击deviceId选择想要使用的设备,目前手机上暂时不支持设置;
+4. 在主界面,点击subscribe按钮可以订阅Please select sensor type文本框中选择的传感器,后界面下方会显示回调数据;
+5. 在主界面,点击unsubscribe按钮可以去订阅选中的传感器,去订阅后不会再收到回调数据;
+6. 在主界面,点击getSensorListByDeviceSync按钮获取本设备及扩展设备上的传感器列表,并在下发显示(手机上只能获取本机上的传感器信息);
+7. 在主界面,点击getSingleSensorByDeviceSync按钮可以获取对应设备上对应的传感器信息,(手机只能获取本机上的传感器信息);
+8. 在主界面,点击on SensorStatusChange按钮订阅本设备上扩展设备的热插拔事件,(目前手机上暂时不支持此功能)
+8. 在主界面,点击off SensorStatusChange按钮去订阅本设备上扩展设备的热插拔事件,(目前手机上暂时不支持此功能)
+
+
+
+工程目录
+
+```
+entry
+| |--- src/main/
+| |--- module.json5 // sensor模块配置hap类型:"type": "feature"
+| |---ets/pages
+| |---index.ets // sensor组件接口实现页面
+```
+
+
+
+### 具体实现
+
+本样例展示了sensor模块js接口的使用样例,包含订阅,去订阅传感器,订阅、去订阅外设热插拔事件、获取设备及扩展设备的上传感器信息等接口的功能接口封装在index,源码参考:[index.ets](./entry/src/main/ets/pages/index.ets)
+
+* Please select sensor type文本框:使用sensor.getSensorList接口获取本设备上的所有传感器信息列表;
+* subscribe订阅传感器:先使用窗口框选择想要订阅的传感器,接着使用sensor.on接口对已经选择的传感器进行订阅;
+* unsubscribe去订阅传感器:先使用窗口框选择想要去订阅的传感器,接着使用sensor.off接口对已经选择的传感器进行去订阅,未订阅的传感器会去订阅失败
+* getSensorListByDeviceSync获取本设备及扩展设备上传感器列表,使用sensor.getSensorListByDeviceSync接口即可获取本设备及扩展设备上传感器列表。手机暂时只能获取本机传感器信息列表
+* getSingleSensorByDeviceSync获取指定设备上传感器信息,使用sensor.getSingleSensorByDeviceSync接口获取指定设备上指定传感器信息,目前手机上只能获取本机上传感器信息。
+* 订阅去订阅外设热插拔事件,通过sensor.on和sensor.off来实现对扩设备热插拔事件订阅。目前手机不支持此功能。
+
+### 相关权限
+
+附上使用到权限和链接,示例如下:
+
+[ohos.permission.ACCELEROMETER](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all.md#ohospermissionaccelerometer)
+
+### 依赖
+
+不涉及。
+
+### 约束与限制
+
+1.本示例仅支持标准系统上运行,支持设备:RK3568;
+
+2.本示例为Stage模型,仅支持API20版本SDK,SDK版本号(API Version 20 Beta),镜像版本号(4.1Beta)
+
+3.本示例需要使用DevEco Studio 5.0.4 Release (Build Version: 5.0.11.100, built on March 28, 2025)及以上版本才可编译运行。
+
+### 下载
+
+如需单独下载本工程,执行如下命令:
+```
+
+git init
+git config core.sparsecheckout true
+echo code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/ > .git/info/sparse-checkout
+git remote add origin https://gitee.com/openharmony/applications_app_samples.git
+git pull origin master
+
+```
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/build-profile.json5 b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..df1f453e84e588fa429b82dabf89e63fbefc722f
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/build-profile.json5
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "app": {
+ "signingConfigs": [],
+ "products": [
+ {
+ "name": "default",
+ "signingConfig": "default",
+ "compatibleSdkVersion": 20,
+ "compileSdkVersion": 20,
+ "runtimeOS": "OpenHarmony",
+ "buildOption": {
+ "strictMode": {
+ "caseSensitiveCheck": true,
+ "useNormalizedOHMUrl": true
+ }
+ }
+ }
+ ],
+ "buildModeSet": [
+ {
+ "name": "debug",
+ },
+ {
+ "name": "release"
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/code-linter.json5 b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/code-linter.json5
new file mode 100644
index 0000000000000000000000000000000000000000..5c4682f8164874ec7e9cb8f99ff8b3228ffbc126
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/code-linter.json5
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "files": [
+ "**/*.ets"
+ ],
+ "ignore": [
+ "**/src/ohosTest/**/*",
+ "**/src/test/**/*",
+ "**/src/mock/**/*",
+ "**/node_modules/**/*",
+ "**/oh_modules/**/*",
+ "**/build/**/*",
+ "**/.preview/**/*"
+ ],
+ "ruleSet": [
+ "plugin:@performance/recommended",
+ "plugin:@typescript-eslint/recommended"
+ ],
+ "rules": {
+ "@security/no-unsafe-aes": "error",
+ "@security/no-unsafe-hash": "error",
+ "@security/no-unsafe-mac": "warn",
+ "@security/no-unsafe-dh": "error",
+ "@security/no-unsafe-dsa": "error",
+ "@security/no-unsafe-ecdsa": "error",
+ "@security/no-unsafe-rsa-encrypt": "error",
+ "@security/no-unsafe-rsa-sign": "error",
+ "@security/no-unsafe-rsa-key": "error",
+ "@security/no-unsafe-dsa-key": "error",
+ "@security/no-unsafe-dh-key": "error",
+ "@security/no-unsafe-3des": "error"
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/.gitignore b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/build-profile.json5 b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..982dbb524bd63408e05cfbed7204dd87a31dd681
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/build-profile.json5
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ "files": [
+ "./obfuscation-rules.txt"
+ ]
+ }
+ }
+ }
+ },
+ ],
+ "targets": [
+ {
+ "name": "default"
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/hvigorfile.ts b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8774588471ede4c1563f09d9a1d22f764bb1fd9e
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/hvigorfile.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { hapTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
+}
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/obfuscation-rules.txt b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/obfuscation-rules.txt
@@ -0,0 +1,23 @@
+# Define project specific obfuscation rules here.
+# You can include the obfuscation configuration files in the current module's build-profile.json5.
+#
+# For more details, see
+# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
+
+# Obfuscation options:
+# -disable-obfuscation: disable all obfuscations
+# -enable-property-obfuscation: obfuscate the property names
+# -enable-toplevel-obfuscation: obfuscate the names in the global scope
+# -compact: remove unnecessary blank spaces and all line feeds
+# -remove-log: remove all console.* statements
+# -print-namecache: print the name cache that contains the mapping from the old names to new names
+# -apply-namecache: reuse the given cache file
+
+# Keep options:
+# -keep-property-name: specifies property names that you want to keep
+# -keep-global-name: specifies names that you want to keep in the global scope
+
+-enable-property-obfuscation
+-enable-toplevel-obfuscation
+-enable-filename-obfuscation
+-enable-export-obfuscation
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/oh-package.json5 b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..10cda399b0aec3099b257299a57d284393e4e55a
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/oh-package.json5
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "name": "entry",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {}
+}
+
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/ets/entryability/EntryAbility.ets b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..843c7f0c1f7b9a460e3dbbd2689e5b34016027d1
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { window } from '@kit.ArkUI';
+
+const DOMAIN = 0x0000;
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
+ this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
+ }
+
+ onDestroy(): void {
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
+ }
+
+ onWindowStageCreate(windowStage: window.WindowStage): void {
+ // Main window is created, set main page for this ability
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
+
+ windowStage.loadContent('pages/Index', (err) => {
+ if (err.code) {
+ hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
+ return;
+ }
+ hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
+ });
+ }
+
+ onWindowStageDestroy(): void {
+ // Main window is destroyed, release UI related resources
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
+ }
+
+ onForeground(): void {
+ // Ability has brought to foreground
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
+ }
+
+ onBackground(): void {
+ // Ability has back to background
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..4ce6449f0e91914e73d4502c9f2e8e9a395ea4b1
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit';
+
+const DOMAIN = 0x0000;
+
+export default class EntryBackupAbility extends BackupExtensionAbility {
+ async onBackup() {
+ hilog.info(DOMAIN, 'testTag', 'onBackup ok');
+ await Promise.resolve();
+ }
+
+ async onRestore(bundleVersion: BundleVersion) {
+ hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
+ await Promise.resolve();
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/ets/pages/Index.ets b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..46a47e9afb3bc999f68f554a65fc11e00193398a
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import AbilityAccessCtrl from '@ohos.abilityAccessCtrl';
+import common from '@ohos.app.ability.common';
+import { sensor } from '@kit.SensorServiceKit';
+import { ComponentContent, promptAction, PromptAction, SelectDialog } from '@kit.ArkUI';
+import BusinessError from '@ohos.base';
+import hilog from '@ohos.hilog'
+
+
+let TAG = 'sensor: '
+
+interface CheckRet {
+ ok: boolean
+ ret: number
+ msg?: string
+};
+
+interface SensorInfoParamValString {
+ deviceId: string
+ sensorIndex: string
+};
+
+interface SensorOptionsValString {
+ interval: string
+ sensorInfoParam: SensorInfoParamValString
+};
+
+let options: SensorOptionsValString = {
+ interval: "800000000",
+ sensorInfoParam: {
+ deviceId: "7",
+ sensorIndex: "1"
+ }
+};
+
+class Logger {
+ private domain: number = 0xC02701;
+ private prefix: string = '[Sample_Vibrator]'
+ private format: string = '%{public}, %{public}'
+ debug(...args: string[]) {
+ hilog.debug(this.domain, this.prefix, this.format, args)
+ }
+ info(...args: string[]) {
+ hilog.info(this.domain, this.prefix, this.format, args)
+ }
+ error(...args: string[]) {
+ hilog.error(this.domain, this.prefix, this.format, args)
+ }
+}
+const logger = new Logger();
+
+@Entry
+@Component
+struct SensorList {
+ @State
+ private sensorItems: string[] = [];
+ private sampleRate: number = 200000000;
+ private uiContext: UIContext = this.getUIContext();
+ private promptAction: PromptAction = this.uiContext.getPromptAction();
+ dialogControllerList: CustomDialogController | null = null;
+ selectedSensorId: number = 0;
+ @State
+ private realSensorName: string = '';
+ @State
+ private deviceId: number = 0;
+ private strDeviceId: string = '';
+ private sensors = new Map();
+ @State
+ private callbackContent:string = '';
+ @State
+ private SensorListByDevice:string = '';
+ SensorListByDeviceList: sensor.Sensor[] = [];
+ private supportSensorIdList: (number|undefined)[] = [1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 256,
+ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 277, 278, 279, 280, 281, 282];
+ private checkDeviceId(): CheckRet {
+ if (!this.strDeviceId.length) {
+ return { ok: false, ret: -1 };
+ }
+ return { ok: true, ret: Number(this.deviceId) };
+ }
+
+ sensorStatusChangeCallback = (data: sensor.SensorStatusEvent) => {
+ logger.debug('Succeeded in getting data: ' + JSON.stringify(data));
+ };
+
+ private getUserOption(): sensor.Options {
+ let result: sensor.Options = {};
+ if (options.interval.length) {
+ result.interval = Number(options.interval);
+ }
+ if (options.sensorInfoParam.deviceId.length) {
+ if (!result.sensorInfoParam) {
+ result.sensorInfoParam = {};
+ }
+ result.sensorInfoParam.deviceId = Number(options.sensorInfoParam.deviceId);
+ }
+ if (options.sensorInfoParam.sensorIndex.length) {
+ if (!result.sensorInfoParam) {
+ result.sensorInfoParam = {};
+ }
+ result.sensorInfoParam.sensorIndex = Number(options.sensorInfoParam.sensorIndex);
+ }
+ return result;
+ }
+
+ onPageShow(): void {
+ let traceCount = 0;
+ logger.info(TAG + 'getSensorList in');
+ try {
+ sensor.getSensorList((error, data) => {
+ if (error) {
+ logger.info(TAG + 'getSensorList failed');
+ } else {
+ logger.info(TAG + 'getSensorList call back in');
+ for (let i = 0; i < data.length; i++) {
+ logger.info(TAG + 'getSensorList ' + JSON.stringify(data[i]));
+ this.sensorItems[i] = data[i].sensorName;
+ this.sensors.set(data[i].sensorName, data[i].sensorId);
+ }
+ };
+ });
+ } catch (e) {
+ logger.error(TAG + 'get list exception in2, code:' + e.code + 'msg:' + e.message);
+ logger.error(TAG + 'get list exception in1, msg:' + JSON.stringify(e));
+ }
+ logger.info(TAG + 'getSensorList left');
+ }
+ build() {
+ Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ TextInput({ placeholder: 'Please select sensor type', text: this.realSensorName })
+ .placeholderColor('rgb(0,0,225)')
+ .placeholderFont({ size: 20, weight: 100, family: 'cursive', style: FontStyle.Italic })
+ .caretColor(Color.Blue)
+ .height(50)
+ .type(InputType.Normal)
+ .fontSize(20)
+ .fontWeight(FontWeight.Normal)
+ .fontFamily('sans-serif')
+ .fontStyle(FontStyle.Normal)
+ .fontColor(Color.Black)
+ .enableKeyboardOnFocus(false)
+ .textAlign(TextAlign.Center)
+ .borderStyle(BorderStyle.Solid).borderWidth(1).borderColor('rgb(0,0,225)').borderRadius(10)
+ .focusable(false)
+ .onClick(() => {
+ TextPickerDialog.show({
+ range: this.sensorItems,
+ selected: 0,
+ onAccept: (result: TextPickerResult) => {
+ this.realSensorName = result.value.toString();
+ },
+ onCancel: () => {
+ logger.info(TAG, 'TextPickerDialog onCancel');
+ }
+ });
+ })
+ .width('80%')
+ .margin({top: 10})
+
+ TextInput({ placeholder: 'deviceId' })
+ .placeholderColor('rgb(0,0,225)')
+ .placeholderFont({ size: 20, weight: 100, family: 'cursive', style: FontStyle.Italic })
+ .caretColor(Color.Blue)
+ .height(50)
+ .type(InputType.Number)
+ .fontSize(20)
+ .fontWeight(FontWeight.Bold)
+ .fontFamily('sans-serif')
+ .fontStyle(FontStyle.Normal)
+ .fontColor(Color.Red)
+ .textAlign(TextAlign.Center)
+ .onChange((value: string) => {
+ this.deviceId = parseInt(value)
+ }).width('100%')
+ .margin({top: 10})
+
+ Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center}) {
+ Button($r('app.string.subscribe')).onClick(() => {
+ try {
+ logger.info(TAG + this.realSensorName + 'subscribe in')
+ if (!this.supportSensorIdList.includes(this.sensors.get(this.realSensorName))) {
+ logger.info('This is not support, please change other sensorId!');
+ return
+ }
+ if(this.sensors.get(this.realSensorName) == 278) {
+ logger.info(TAG + this.sensors.get(this.realSensorName) + 'on in');
+ let atManager = AbilityAccessCtrl.createAtManager();
+ let context = getContext(this) as common.UIAbilityContext;
+ atManager.requestPermissionsFromUser(context, ['ohos.permission.READ_HEALTH_DATA'], (err, data)=>{
+ if (err) {
+ logger.info(TAG + 'grant READ_HEALTH_DATA failed:' + JSON.stringify(data));
+ return;
+ }
+ logger.info(TAG + 'data:' + JSON.stringify(data));
+ logger.info(TAG + 'data permissions:' + data.permissions);
+ logger.info(TAG + 'data authResults:' + data.authResults);
+ sensor.getSingleSensor(this.sensors.get(this.realSensorName), (err, data) => {
+ if(err) {
+ logger.error(TAG + JSON.stringify(err));
+ return;
+ }
+ if(data) {
+ const userOption = this.getUserOption();
+ sensor.on(this.sensors.get(this.realSensorName), (data:sensor.Response)=>{
+ logger.info(TAG + 'PEDOMETER: ' + JSON.stringify(data));
+ this.callbackContent = JSON.stringify(data);
+ }, userOption)
+ } else {
+ logger.info(TAG + 'Program run failed');
+ }
+ });
+ });
+ } else { //普通sensor
+ logger.info('before')
+ let countSame:number = 0;
+ let timestamp:number = 0;
+ let countSame2:number = 0;
+ let timestamp2:number = 0;
+ sensor.on(this.sensors.get(this.realSensorName), ((data:sensor.Response) => {
+ logger.info(TAG + 'callback: ' + JSON.stringify(data));
+ this.callbackContent = JSON.stringify(data)
+ if (data.timestamp - timestamp == 0) {
+ countSame = countSame + 1;
+ logger.info(TAG + 'callbackcountSame: ' + JSON.stringify(data));
+ }
+ timestamp = data.timestamp;
+ }), {'interval': this.sampleRate});
+ logger.info('left')
+
+ }
+ }catch(e) {
+ logger.info(TAG + 'subscribe exception in,msg:' + JSON.stringify(e))
+ logger.info(TAG + 'unSubscribe exception in,code:' + e.code + 'msg:' + e.message)
+ }
+ })
+
+ Button($r('app.string.unSubscribe')).onClick(() => {
+ logger.info(TAG + 'unSubscribe in');
+ try {
+ sensor.off(this.sensors.get(this.realSensorName));
+ }catch(e) {
+ logger.info(TAG + 'unSubscribe exception in,msg:' + JSON.stringify(e));
+ }
+ this.callbackContent = '';
+ })
+
+ Button($r('app.string.getSensorListByDeviceSync'))
+ .onClick(() => {
+ logger.info(TAG + 'getSensorListByDeviceSync in');
+ try {
+ let sensorInfoList = sensor.getSensorListByDeviceSync();
+ this.SensorListByDevice = 'sensorInfoList:' + JSON.stringify(sensorInfoList);
+ this.SensorListByDeviceList = sensorInfoList;
+ logger.info(TAG + 'unSubscribe exception in,msg:' + JSON.stringify(sensorInfoList))
+ } catch (err) {
+ logger.error('Error occurred: ' + JSON.stringify(err));
+ }
+ })
+
+ Button($r('app.string.getSingleSensorByDeviceSync'))
+ .onClick(() => {
+ if (!this.SensorListByDevice.length) {
+ this.promptAction.showToast({
+ message: 'Please click getSensorListByDeviceSync.',
+ duration: 2000
+ });
+ return;
+ }
+ this.dialogControllerList = new CustomDialogController({
+ autoCancel: false,
+ builder: SelectDialog({
+ title: 'select SensorId',
+ selectedIndex: this.selectedSensorId,
+ radioContent: this.SensorListByDeviceList.map((sensorInfo: sensor.Sensor) => {
+ return {
+ title: `${sensorInfo.sensorName}_${sensorInfo.sensorId}`,
+ action: async () => {
+ this.selectedSensorId = sensorInfo.sensorId;
+ try {
+ const checkRet = this.checkDeviceId();
+ const data = sensor.getSingleSensorByDeviceSync(this.selectedSensorId,
+ checkRet.ok ? checkRet.ret : undefined);
+ this.SensorListByDevice = 'sensorInfoList:' + JSON.stringify(data);
+ } catch (error) {
+ logger.error('Error occurred: ' + JSON.stringify(error));
+ }
+ }
+ } as SheetInfo
+ }),
+ }),
+ })
+ this.dialogControllerList.open();
+ })
+
+ Button($r('app.string.on')).fontSize(16).fontWeight(FontWeight.Bold).width('100%')
+ .onClick(() => {
+ logger.info("sensor.on('SensorStatusChange')");
+ try {
+ sensor.on('sensorStatusChange', this.sensorStatusChangeCallback);
+ this.callbackContent = 'on:sensorStatusChange'
+ } catch (error) {
+ let e: BusinessError.BusinessError = error as BusinessError.BusinessError;
+ logger.error(`Failed to invoke on. Code: ${e.code}, message: ${e.message}`);
+ }
+ })
+
+ Button($r('app.string.off')).fontSize(16).fontWeight(FontWeight.Bold).width('100%')
+ .onClick(() => {
+ try {
+ sensor.off('sensorStatusChange', this.sensorStatusChangeCallback);
+ this.callbackContent = 'off:sensorStatusChange'
+ } catch (error) {
+ let e: BusinessError.BusinessError = error as BusinessError.BusinessError;
+ logger.error(`Failed to invoke on. Code: ${e.code}, message: ${e.message}`);
+ }
+ })
+
+ Button($r('app.string.clean'))
+ .onClick(() => {
+ this.SensorListByDevice = '';
+ })
+
+ }.margin({top: 20})
+
+ Text(`${this.callbackContent}`)
+ .fontSize(20)
+ .margin({ top: 20 })
+
+ Text(`${this.SensorListByDevice}`)
+ .fontSize(20)
+ .margin({ top: 20 })
+ }
+ .height('100%')
+ .width('100%')
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/module.json5 b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e496606274732a346eaf8b2df96a601439353e91
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/module.json5
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "module": {
+ "name": "entry",
+ "type": "entry",
+ "description": "$string:module_desc",
+ "mainElement": "EntryAbility",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "requestPermissions": [
+ {
+ "name":"ohos.permission.ACCELEROMETER"
+ }
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ "abilities": [
+ {
+ "name": "EntryAbility",
+ "srcEntry": "./ets/entryability/EntryAbility.ets",
+ "description": "$string:EntryAbility_desc",
+ "icon": "$media:layered_image",
+ "label": "$string:EntryAbility_label",
+ "startWindowIcon": "$media:startIcon",
+ "startWindowBackground": "$color:start_window_background",
+ "exported": true,
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ]
+ }
+ ],
+ "extensionAbilities": [
+ {
+ "name": "EntryBackupAbility",
+ "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
+ "type": "backup",
+ "exported": false,
+ "metadata": [
+ {
+ "name": "ohos.extension.backup",
+ "resource": "$profile:backup_config"
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/element/color.json b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#FFFFFF"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/element/float.json b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/element/float.json
new file mode 100644
index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/element/float.json
@@ -0,0 +1,8 @@
+{
+ "float": [
+ {
+ "name": "page_text_font_size",
+ "value": "50fp"
+ }
+ ]
+}
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/element/string.json b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..53bb59a7664a16714f46e3a6d529a3b366cad672
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,44 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "subscribe",
+ "value": "subscribe"
+ },
+ {
+ "name": "unSubscribe",
+ "value": "unSubscribe"
+ },
+ {
+ "name": "getSensorListByDeviceSync",
+ "value": "getSensorListByDeviceSync"
+ },
+ {
+ "name": "getSingleSensorByDeviceSync",
+ "value": "getSingleSensorByDeviceSync"
+ },
+ {
+ "name": "on",
+ "value": "on SensorStatusChange"
+ },
+ {
+ "name": "off",
+ "value": "off SensorStatusChange"
+ },
+ {
+ "name": "clean",
+ "value": "clean"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "SensorJsSamples"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/background.png b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/background.png differ
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/foreground.png b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/foreground.png differ
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/layered_image.json b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/layered_image.json
@@ -0,0 +1,7 @@
+{
+ "layered-image":
+ {
+ "background" : "$media:background",
+ "foreground" : "$media:foreground"
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/startIcon.png b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/media/startIcon.png differ
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/profile/backup_config.json b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/profile/backup_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/profile/backup_config.json
@@ -0,0 +1,3 @@
+{
+ "allowToBackupRestore": true
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/profile/main_pages.json b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/dark/element/color.json b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/dark/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/main/resources/dark/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#000000"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/mock/mock-config.json5 b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/mock/mock-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/mock/mock-config.json5
@@ -0,0 +1,2 @@
+{
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/ohosTest/ets/test/Ability.test.ets b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7f30942b81554a399e89aa253c7089eca4f8d8d1
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
+
+export default function abilityTest() {
+ describe('ActsAbilityTest', () => {
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
+ beforeAll(() => {
+ // Presets an action, which is performed only once before all test cases of the test suite start.
+ // This API supports only one parameter: preset action function.
+ })
+ beforeEach(() => {
+ // Presets an action, which is performed before each unit test case starts.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: preset action function.
+ })
+ afterEach(() => {
+ // Presets a clear action, which is performed after each unit test case ends.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: clear action function.
+ })
+ afterAll(() => {
+ // Presets a clear action, which is performed after all test cases of the test suite end.
+ // This API supports only one parameter: clear action function.
+ })
+ it('assertContain', 0, () => {
+ // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
+ hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
+ let a = 'abc';
+ let b = 'b';
+ // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
+ expect(a).assertContain(b);
+ expect(a).assertEqual(a);
+ })
+ })
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/ohosTest/ets/test/List.test.ets b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..c64e0b06938d246ce044186d4b2d02b500a89e14
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/ohosTest/ets/test/List.test.ets
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/ohosTest/module.json5 b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..69026872775eebd0844900b225c411959ae5608b
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/ohosTest/module.json5
@@ -0,0 +1,12 @@
+{
+ "module": {
+ "name": "entry_test",
+ "type": "feature",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false
+ }
+}
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/test/List.test.ets b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a60c87c5cbb0badf7c3fd8975034590e6fafa992
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/test/List.test.ets
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/test/LocalUnit.test.ets b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..841bfd77e56060e50ec0924302a5ae624e76e3aa
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/entry/src/test/LocalUnit.test.ets
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
+
+export default function localUnitTest() {
+ describe('localUnitTest', () => {
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
+ beforeAll(() => {
+ // Presets an action, which is performed only once before all test cases of the test suite start.
+ // This API supports only one parameter: preset action function.
+ });
+ beforeEach(() => {
+ // Presets an action, which is performed before each unit test case starts.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: preset action function.
+ });
+ afterEach(() => {
+ // Presets a clear action, which is performed after each unit test case ends.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: clear action function.
+ });
+ afterAll(() => {
+ // Presets a clear action, which is performed after all test cases of the test suite end.
+ // This API supports only one parameter: clear action function.
+ });
+ it('assertContain', 0, () => {
+ // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
+ let a = 'abc';
+ let b = 'b';
+ // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
+ expect(a).assertContain(b);
+ expect(a).assertEqual(a);
+ });
+ });
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/hvigor/hvigor-config.json5 b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..dc688b0bfd4fcd92ebbb3049cf9de543104475a5
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/hvigor/hvigor-config.json5
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "modelVersion": "5.0.4",
+ "dependencies": {
+ },
+ "execution": {
+ // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */
+ // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */
+ // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */
+ // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */
+ // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */
+ },
+ "logging": {
+ // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
+ },
+ "debugging": {
+ // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */
+ },
+ "nodeOptions": {
+ // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/
+ // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/
+ }
+}
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/hvigorfile.ts b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6b365cacd0191d3b1178eb6b9807b1ae0add6271
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/hvigorfile.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { appTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
+}
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/oh-package.json5 b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..37fb982b14de9a0cc3674d27eb058307963dd748
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/oh-package.json5
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "modelVersion": "5.0.4",
+ "description": "Please describe the basic information.",
+ "dependencies": {
+ },
+ "devDependencies": {
+ "@ohos/hypium": "1.0.21",
+ "@ohos/hamock": "1.0.0"
+ }
+}
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/ohosTest.md b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/ohosTest.md
new file mode 100644
index 0000000000000000000000000000000000000000..f9f304b350a01b6a0933c6fb0cc38b2d0b3c8a9b
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/ohosTest.md
@@ -0,0 +1,17 @@
+# Sensor 测试用例归档
+
+## 用例表
+
+| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
+| --------------- | --------- | ------------------------------- | ---------------- | ---- | ---- |
+| | 设备正常运行 | | 成功拉起应用 | 是 | Pass |
+| 申请权限 | 成功拉起应用 | | 弹出提示框 | 是 | Pass |
+| 订阅传感器 | 选择一个传感器类型 | 点击subscribe按钮 | 订阅成功,数据上报正常 | 是 | Pass |
+| 去订阅传感器 | 选择一个传感器类型 | 点击unsubscribe按钮 | 去订阅成功,数据停止上报 | 是 | Pass |
+| 获取设备传感器信息列表 | 无 | 点击getSensorListDeviceSync按钮 | 设备传感器列表信息获取正常 | 是 | Pass |
+| 获取指定设备指定类型传感器信息 | 无 | 点击getSingleSensorByDeviceSync按钮 | 指定设备的指定传感器信息获取正常 | 是 | Pass |
+| 订阅扩展设备热插拔事件 | 无 | 点击on SensorStatusChange按钮 | 订阅正常 | 是 | Pass |
+| 去订阅扩展设备热插拔事件 | 无 | 点击off SensorStatusChange按钮 | 去订阅正常 | 是 | Pass |
+| 清除sensor信息列表 | 无 | 点击clean按钮 | 列表显示恢复默认 | 是 | Pass |
+
+
diff --git a/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/sensorSample.png b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/sensorSample.png
new file mode 100644
index 0000000000000000000000000000000000000000..ceab4102f4b9fee64028e8f4c0762a61af7b6b13
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Sensor/SensorJsSamples/sensorSample.png differ
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/.gitignore b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/.gitignore
@@ -0,0 +1,12 @@
+/node_modules
+/oh_modules
+/local.properties
+/.idea
+**/build
+/.hvigor
+.cxx
+/.clangd
+/.clang-format
+/.clang-tidy
+**/.test
+/.appanalyzer
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/app.json5 b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..d7b371e5e78c01738411299551204fdf71273cae
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/app.json5
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "app": {
+ "bundleName": "com.samples.vibrator",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:layered_image",
+ "label": "$string:app_name"
+ }
+}
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/element/string.json b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..527e18bbe6c1f194305ca535fc4d3f50b17a2c24
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "VibratorJsSamples"
+ }
+ ]
+}
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/media/background.png b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/media/background.png differ
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/media/foreground.png b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/media/foreground.png differ
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/media/layered_image.json b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/AppScope/resources/base/media/layered_image.json
@@ -0,0 +1,7 @@
+{
+ "layered-image":
+ {
+ "background" : "$media:background",
+ "foreground" : "$media:foreground"
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/README_zh.md b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..7a5ce43b216d9e78729149be7d8279887f1cd0b3
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/README_zh.md
@@ -0,0 +1,87 @@
+# vibrator js接口hap
+
+### 介绍
+
+本样例展示了vibrator模块js接口的使用样例,包含time,preset,file,pattern四种形式的振动,订阅去订阅外设热插拔事件、获取设备上马达信息等接口功能
+
+
+
+本示例用到了打开读取文件的操作[@kit.LocalizationKit](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-localization-kit/js-apis-resource-manager.md)
+错误信息[@kit.BasicServicesKit](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-base.md)
+
+振动相关功能[@kit.SensorServiceKit](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-sensor-service-kit/js-apis-vibrator.md)
+
+
+### 效果预览
+| 主页 |
+|------------------------------------------------|
+|
|
+
+依次介绍sample具有什么功能,怎样使用这些功能,以及使用后会达到什么效果;示例如下:
+
+1. 在主界面,可以点击Please select effectId文本框选择使用的effectId,effectId作为preset形式振动的固定形式参数;
+2. 在主界面,可以点击Please select usage文本框选择使用的usage信息,不选择会有默认值;
+3. 可以选设置deviceid,手机上多设备功能底层暂时不支持,只能选择本机的deviceid:-1
+4. 在主界面,点击file按钮可以下发工程中附带json文件的振动效果;
+5. 在主界面,点击preset按钮可以下发预选effectId的振动效果;
+6. 在主界面,点击time按钮可以下发默认的时长的振动效果;
+7. 在主界面,点击pattern:addContinuousEvent按钮可以下发自定义振动事件长事件振动效果;
+8. 在主界面,点击pattern:addTransientEvent按钮可以下发自定义振动事件短事件振动效果;
+9. 在主界面,点击stopVibration按钮可以实现停止振动的效果;
+10. 在主界面,点击on按钮和off按钮可以下发对设备热插拔事件的订阅和去订阅,此功能在手机上暂未实现;
+11. 在主界面,点击getVibratorInfoSync按钮可以实现对设备上马达器件列表信息的获取,并在下方显示;
+
+工程目录
+
+```
+entry
+| |--- src/main/
+| |--- module.json5 // vibrator模块配置hap类型:"type": "feature"
+| |---ets/pages
+| |---index.ets // vibrato组件接口实现页面
+```
+
+
+
+### 具体实现
+
+time,preset,file,pattern四种形式的振动,订阅去订阅外设热插拔事件、获取设备上马达信息等的功能接口封装在index,源码参考:[index.ets](./entry/src/main/ets/pages/index.ets)
+
+* file文件形式振动:使用Vibrator.startVibration接口的file形式来实现文件形式振动的下发。
+* preset文件形式振动:先使用窗口框选择Vibrator模块提供的effectId,然后使用Vibrator.startVibration接口使用preset形式来实现预置效果串形式振动的下发。
+* time文件形式振动:使用Vibrator.startVibration接口的time形式来下发指定时间形式的振动。
+* pattern文件形式振动:使用Vibrator.startVibration接口的pattern形式来实现ContinuousEvent和TransientEvent事件形式振动的下发。
+* 停止振动:使用Vibrator.stopVibration来停止振动。
+* 订阅去订阅外设热插拔事件,通过Vibrator.on和Vibrator.off来实现对扩设备热插拔事件订阅。
+* 获取设备上马达信息列表:通过Vibrator.getVibratorInfoSync接口来实现对本设备及扩展设备上马达列表的获取
+
+### 相关权限
+
+附上使用到权限和链接,示例如下:
+
+[ohos.permission.VIBRATE](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all.md#ohospermissionvibrate)
+
+### 依赖
+
+不涉及。
+
+### 约束与限制
+
+1.本示例仅支持标准系统上运行,支持设备:RK3568;
+
+2.本示例为Stage模型,仅支持API20版本SDK,SDK版本号(API Version 20 Beta),镜像版本号(4.1Beta)
+
+3.本示例需要使用DevEco Studio 5.0.4 Release (Build Version: 5.0.11.100, built on March 28, 2025)及以上版本才可编译运行。
+
+### 下载
+
+如需单独下载本工程,执行如下命令:
+```
+
+git init
+git config core.sparsecheckout true
+echo code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/ > .git/info/sparse-checkout
+git remote add origin https://gitee.com/openharmony/applications_app_samples.git
+git pull origin master
+
+```
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/build-profile.json5 b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..df1f453e84e588fa429b82dabf89e63fbefc722f
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/build-profile.json5
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "app": {
+ "signingConfigs": [],
+ "products": [
+ {
+ "name": "default",
+ "signingConfig": "default",
+ "compatibleSdkVersion": 20,
+ "compileSdkVersion": 20,
+ "runtimeOS": "OpenHarmony",
+ "buildOption": {
+ "strictMode": {
+ "caseSensitiveCheck": true,
+ "useNormalizedOHMUrl": true
+ }
+ }
+ }
+ ],
+ "buildModeSet": [
+ {
+ "name": "debug",
+ },
+ {
+ "name": "release"
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/code-linter.json5 b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/code-linter.json5
new file mode 100644
index 0000000000000000000000000000000000000000..5c4682f8164874ec7e9cb8f99ff8b3228ffbc126
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/code-linter.json5
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "files": [
+ "**/*.ets"
+ ],
+ "ignore": [
+ "**/src/ohosTest/**/*",
+ "**/src/test/**/*",
+ "**/src/mock/**/*",
+ "**/node_modules/**/*",
+ "**/oh_modules/**/*",
+ "**/build/**/*",
+ "**/.preview/**/*"
+ ],
+ "ruleSet": [
+ "plugin:@performance/recommended",
+ "plugin:@typescript-eslint/recommended"
+ ],
+ "rules": {
+ "@security/no-unsafe-aes": "error",
+ "@security/no-unsafe-hash": "error",
+ "@security/no-unsafe-mac": "warn",
+ "@security/no-unsafe-dh": "error",
+ "@security/no-unsafe-dsa": "error",
+ "@security/no-unsafe-ecdsa": "error",
+ "@security/no-unsafe-rsa-encrypt": "error",
+ "@security/no-unsafe-rsa-sign": "error",
+ "@security/no-unsafe-rsa-key": "error",
+ "@security/no-unsafe-dsa-key": "error",
+ "@security/no-unsafe-dh-key": "error",
+ "@security/no-unsafe-3des": "error"
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/.gitignore b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/build-profile.json5 b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..982dbb524bd63408e05cfbed7204dd87a31dd681
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/build-profile.json5
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ "files": [
+ "./obfuscation-rules.txt"
+ ]
+ }
+ }
+ }
+ },
+ ],
+ "targets": [
+ {
+ "name": "default"
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/hvigorfile.ts b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8774588471ede4c1563f09d9a1d22f764bb1fd9e
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/hvigorfile.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { hapTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
+}
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/obfuscation-rules.txt b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/obfuscation-rules.txt
@@ -0,0 +1,23 @@
+# Define project specific obfuscation rules here.
+# You can include the obfuscation configuration files in the current module's build-profile.json5.
+#
+# For more details, see
+# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
+
+# Obfuscation options:
+# -disable-obfuscation: disable all obfuscations
+# -enable-property-obfuscation: obfuscate the property names
+# -enable-toplevel-obfuscation: obfuscate the names in the global scope
+# -compact: remove unnecessary blank spaces and all line feeds
+# -remove-log: remove all console.* statements
+# -print-namecache: print the name cache that contains the mapping from the old names to new names
+# -apply-namecache: reuse the given cache file
+
+# Keep options:
+# -keep-property-name: specifies property names that you want to keep
+# -keep-global-name: specifies names that you want to keep in the global scope
+
+-enable-property-obfuscation
+-enable-toplevel-obfuscation
+-enable-filename-obfuscation
+-enable-export-obfuscation
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/oh-package.json5 b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..10cda399b0aec3099b257299a57d284393e4e55a
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/oh-package.json5
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "name": "entry",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {}
+}
+
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/ets/entryability/EntryAbility.ets b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..843c7f0c1f7b9a460e3dbbd2689e5b34016027d1
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { window } from '@kit.ArkUI';
+
+const DOMAIN = 0x0000;
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
+ this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
+ }
+
+ onDestroy(): void {
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
+ }
+
+ onWindowStageCreate(windowStage: window.WindowStage): void {
+ // Main window is created, set main page for this ability
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
+
+ windowStage.loadContent('pages/Index', (err) => {
+ if (err.code) {
+ hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
+ return;
+ }
+ hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
+ });
+ }
+
+ onWindowStageDestroy(): void {
+ // Main window is destroyed, release UI related resources
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
+ }
+
+ onForeground(): void {
+ // Ability has brought to foreground
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
+ }
+
+ onBackground(): void {
+ // Ability has back to background
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..4ce6449f0e91914e73d4502c9f2e8e9a395ea4b1
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit';
+
+const DOMAIN = 0x0000;
+
+export default class EntryBackupAbility extends BackupExtensionAbility {
+ async onBackup() {
+ hilog.info(DOMAIN, 'testTag', 'onBackup ok');
+ await Promise.resolve();
+ }
+
+ async onRestore(bundleVersion: BundleVersion) {
+ hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
+ await Promise.resolve();
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/ets/pages/Index.ets b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1fa6a900e04f4387820343a4312c31315d920fa4
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { vibrator } from '@kit.SensorServiceKit';
+import { resourceManager } from '@kit.LocalizationKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import hilog from '@ohos.hilog';
+
+
+const fileName: string = 'vibrator.json';
+let TAG = 'vibrator:'
+
+class Logger {
+ private domain: number = 0xC02701;
+ private prefix: string = '[Sample_Vibrator]'
+ private format: string = '%{public}, %{public}'
+ debug(...args: string[]) {
+ hilog.debug(this.domain, this.prefix, this.format, args)
+ }
+ info(...args: string[]) {
+ hilog.info(this.domain, this.prefix, this.format, args)
+ }
+ error(...args: string[]) {
+ hilog.error(this.domain, this.prefix, this.format, args)
+ }
+}
+const logger = new Logger();
+
+@Entry
+@Component
+struct Index {
+ @State message: string = 'Hello World';
+ @State timeout_10: number = 10;
+ @State timeout_20: number = 20;
+ @State
+ private vibratorStatusEvent: vibrator.VibratorStatusEvent = {
+ timestamp: 0,
+ deviceId: 0,
+ vibratorCount: 0,
+ isVibratorOnline: false
+ };
+ @State
+ private realEffectId: string = '';
+ @State
+ private realUsage: vibrator.Usage = 'unknown';
+ @State
+ private vibratorInfoContent: string = '';
+ private effectId: (string)[] = [
+ 'haptic.notice.warning',
+ 'haptic.notice.fail',
+ 'haptic.notice.success',
+ 'haptic.effect.soft',
+ 'haptic.effect.hard',
+ 'haptic.effect.sharp',
+ ];
+ private usage: (string)[] =
+ ['unknown', 'alarm', 'ring', 'notification', 'communication', 'touch', 'media', 'physicalFeedback',
+ 'simulateReality'];
+ private usageMap = new Map([
+ ['unknown', 'unknown'],
+ ['alarm', 'alarm'],
+ ['ring', 'ring'],
+ ['notification', 'notification'],
+ ['communication', 'communication'],
+ ['touch', 'touch'],
+ ['media', 'media'],
+ ['physicalFeedback', 'physicalFeedback'],
+ ['simulateReality', 'simulateReality'],
+ ]);
+ uiContext = this.getUIContext();
+ VibratorStateChangeCallback = (data: vibrator.VibratorStatusEvent) => {
+ this.vibratorStatusEvent = data;
+ logger.info('Vibrator plunged info:', JSON.stringify(data));
+ logger.info('on is end');
+ };
+
+ build() {
+ Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ TextInput({ placeholder: 'Please select effectId', text: this.realEffectId })
+ .placeholderColor('rgb(0,0,225)')
+ .placeholderFont({
+ size: 20,
+ weight: 100,
+ family: 'cursive',
+ style: FontStyle.Italic
+ })
+ .caretColor(Color.Blue)
+ .height(50)
+ .type(InputType.Normal)
+ .fontSize(20)
+ .fontWeight(FontWeight.Normal)
+ .fontFamily('sans-serif')
+ .fontStyle(FontStyle.Normal)
+ .fontColor(Color.Black)
+ .enableKeyboardOnFocus(false)
+ .textAlign(TextAlign.Center)
+ .borderStyle(BorderStyle.Solid)
+ .borderWidth(1)
+ .borderColor('rgb(0,0,225)')
+ .borderRadius(10)
+ .focusable(false)
+ .onClick(() => {
+ TextPickerDialog.show({
+ range: this.effectId,
+ selected: 0,
+ onAccept: (result: TextPickerResult) => {
+ this.realEffectId = result.value.toString();
+ logger.info('Succeed in starting vibration' + this.effectId);
+ },
+ onCancel: () => {
+ logger.info('Succeed in starting vibration' + this.effectId);
+ }
+ });
+ })
+ .width('80%')
+ .margin({ top: 10 })
+
+ TextInput({ placeholder: 'Please select usage', text: this.realUsage })
+ .placeholderColor('rgb(0,0,225)')
+ .placeholderFont({
+ size: 20,
+ weight: 100,
+ family: 'cursive',
+ style: FontStyle.Italic
+ })
+ .caretColor(Color.Blue)
+ .height(50)
+ .type(InputType.Normal)
+ .fontSize(20)
+ .fontWeight(FontWeight.Normal)
+ .fontFamily('sans-serif')
+ .fontStyle(FontStyle.Normal)
+ .fontColor(Color.Black)
+ .enableKeyboardOnFocus(false)
+ .textAlign(TextAlign.Center)
+ .borderStyle(BorderStyle.Solid)
+ .borderWidth(1)
+ .borderColor('rgb(0,0,225)')
+ .borderRadius(10)
+ .focusable(false)
+ .onClick(() => {
+ TextPickerDialog.show({
+ range: this.usage,
+ selected: 0,
+ onAccept: (resultUsage: TextPickerResult) => {
+ this.realUsage = this.usageMap.get(resultUsage.value.toString());
+ logger.info('Succeed in starting vibration' + this.effectId);
+ },
+ onCancel: () => {
+ logger.info('Succeed in starting vibration' + this.effectId);
+ }
+ });
+ })
+ .width('100%')
+ .margin({ top: 10 })
+
+ Row() {
+ Column() {
+ Button($r('app.string.file'))
+ .onClick(() => {
+ try {
+ let rawFd: resourceManager.RawFileDescriptor | undefined =
+ this.uiContext.getHostContext()?.resourceManager.getRawFdSync(fileName);
+ if (rawFd != undefined) {
+ vibrator.startVibration({
+ type: 'file',
+ hapticFd: { fd: rawFd.fd, offset: rawFd.offset, length: rawFd.length }
+ }, {
+ id: 1,
+ deviceId: -1,
+ usage: this.realUsage
+ }, (error: BusinessError) => {
+ if (error) {
+ logger.error(TAG + 'error in, msg:' + JSON.stringify(error));
+ return;
+ }
+ logger.info('Succeed in starting vibration');
+ });
+ }
+ this.uiContext.getHostContext()?.resourceManager.closeRawFdSync(fileName);
+ } catch (e) {
+ logger.error(TAG + 'Exception:', e);
+ }
+
+ })
+
+ Button($r('app.string.preset') + this.realEffectId)
+ .onClick(() => {
+ try {
+ // 查询是否支持'haptic.clock.timer'
+ vibrator.isSupportEffect(this.realEffectId, (err: BusinessError, state: boolean) => {
+ if (err) {
+ logger.error(`Failed to query effect. Code: ${err.code}, message: ${err.message}`);
+ return;
+ }
+ logger.info('Succeed in querying effect');
+ if (state) {
+ try {
+ // 使用startVibration需要添加ohos.permission.VIBRATE权限
+ vibrator.startVibration({
+ type: 'preset',
+ effectId: this.realEffectId,
+ count: 1,
+ intensity: 100
+ }, {
+ id: 1,
+ deviceId: -1,
+ usage: this.realUsage // 根据实际选择类型归属不同的开关管控
+ }, (error: BusinessError) => {
+ if (error) {
+ logger.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);
+ } else {
+ logger.info('Succeed in starting vibration');
+ }
+ });
+ } catch (error) {
+ let e: BusinessError = error as BusinessError;
+ logger.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
+ }
+ }
+ })
+ } catch (error) {
+ let e: BusinessError = error as BusinessError;
+ logger.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
+ }
+ })
+
+ Button($r('app.string.time'))
+ .onClick(() => {
+ try {
+ vibrator.startVibration(
+ {
+ type: 'time',
+ duration: 2000,
+ }, {
+ id: 1,
+ deviceId: -1,
+ usage: this.realUsage
+ }, (error: BusinessError) => {
+ if (error) {
+ logger.error(TAG + "error in, msg:" + JSON.stringify(error));
+ return;
+ }
+ logger.info('Succeed in starting vibration');
+ });
+ } catch (e) {
+ logger.error(TAG + 'Exception:', e);
+ }
+ })
+
+ Button($r('app.string.addTransientEvent'))
+ .onClick(() => {
+ let builder:vibrator.VibratorPatternBuilder = new vibrator.VibratorPatternBuilder();
+ try {
+ let param: vibrator.TransientParam = {
+ intensity: 80,
+ frequency: 70,
+ index: 0
+ }
+ builder.addTransientEvent(0, param);
+ logger.info(`addTransientEvent builder is ${builder.build()}`);
+ } catch (error) {
+ let e: BusinessError = error as BusinessError;
+ logger.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
+ }
+ try {
+ vibrator.startVibration({
+ type: "pattern",
+ pattern: builder.build()
+ }, {
+ id: 1,
+ deviceId: -1,
+ // 根据实际选择类型归属不同的开关管控
+ usage: this.realUsage
+ }, (error: BusinessError) => {
+ if (error) {
+ let e: BusinessError = error as BusinessError;
+ logger.error(`Vibrate fail. Code: ${e.code}, message: ${e.message}`);
+ } else {
+ logger.info(`vibrate success`);
+ }
+ });
+ } catch (error) {
+ let e: BusinessError = error as BusinessError;
+ logger.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
+ }
+ })
+
+ Button($r('app.string.addContinuousEvent'))
+ .onClick(() => {
+ let builder:vibrator.VibratorPatternBuilder = new vibrator.VibratorPatternBuilder();
+ try {
+ // VibratorCurvePoint参数最少设置4个,最大设置16个
+ let pointsMe: vibrator.VibratorCurvePoint[] = [
+ { time: 0, intensity: 0, frequency: -7 },
+ { time: 42, intensity: 1, frequency: -6 },
+ { time: 128, intensity: 0.94, frequency: -4 },
+ { time: 217, intensity: 0.63, frequency: -14 },
+ { time: 763, intensity: 0.48, frequency: -14 },
+ { time: 1125, intensity: 0.53, frequency: -10 },
+ { time: 1503, intensity: 0.42, frequency: -14 },
+ { time: 1858, intensity: 0.39, frequency: -14 },
+ { time: 2295, intensity: 0.34, frequency: -17 },
+ { time: 2448, intensity: 0.21, frequency: -14 },
+ { time: 2468, intensity: 0, frequency: -21 }
+ ]
+ let param: vibrator.ContinuousParam = {
+ intensity: 97,
+ frequency: 34,
+ points: pointsMe,
+ index: 0
+ }
+ builder.addContinuousEvent(0, 2468, param);
+ logger.info(`addContinuousEvent builder is ${builder.build()}`);
+ } catch (error) {
+ let e: BusinessError = error as BusinessError;
+ logger.error(`Exception. Code ${e.code}`);
+ }
+ try {
+ vibrator.startVibration({
+ type: 'pattern',
+ pattern: builder.build()
+ }, {
+ id: 1,
+ deviceId: -1,
+ // 根据实际选择类型归属不同的开关管控
+ usage: this.realUsage, // 根据实际选择类型归属不同的开关管控
+ }, (error: BusinessError) => {
+ if (error) {
+ let e: BusinessError = error as BusinessError;
+ logger.error(`Vibrate fail. Code: ${e.code}, message: ${e.message}`);
+ } else {
+ logger.info(`vibrate success`);
+ }
+ });
+ } catch (error) {
+ let e: BusinessError = error as BusinessError;
+ logger.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
+ }
+ })
+
+ Button($r('app.string.stopVibration'))
+ .onClick(() => {
+ try {
+ vibrator.stopVibration({
+ deviceId: -1,
+ vibratorId: 1
+ }).then(() => {
+ logger.info('stopVibration successfully');
+ }).catch((error: Error) => {
+ logger.error('stopVibration failed:', error.name, error.message);
+ });
+ } catch (error) {
+ logger.error('stopVibration Error:', error.code, error.message);
+ }
+ })
+
+ Button($r('app.string.on'))
+ .onClick(() => {
+ try {
+ vibrator.on('vibratorStateChange', this.VibratorStateChangeCallback);
+ } catch (err) {
+ logger.error('Error in GetVibratorList:', err);
+ }
+ })
+
+ Button($r('app.string.off'))
+ .onClick(() => {
+ try {
+ vibrator.off('vibratorStateChange', this.VibratorStateChangeCallback);
+ } catch (err) {
+ logger.error("Error in GetVibratorList:", err);
+ }
+ })
+
+ Button($r('app.string.getVibratorInfoSync'))
+ .onClick(async () => {
+ try {
+ let vibratorInfoList: vibrator.VibratorInfo[] = vibrator.getVibratorInfoSync({
+ deviceId: -1,
+ vibratorId: 1
+ });
+ this.vibratorInfoContent = JSON.stringify(vibratorInfoList)
+ } catch (err) {
+ logger.error('Error in GetVibratorList:', err);
+ }
+ logger.info('getVibratorInfoSync end');
+ })
+
+ Text(`${this.VibratorStateChangeCallback}`)
+ .fontSize(20)
+ .margin({ top: 20 })
+
+ Text(`${this.vibratorInfoContent}`)
+ .fontSize(20)
+ .margin({ top: 20 })
+ }
+ .width('100%')
+ }
+ .height('100%')
+ }
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/module.json5 b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c47d92fce6737d2d3f6b5408961a8b71d8986c18
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/module.json5
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "module": {
+ "name": "entry",
+ "type": "entry",
+ "description": "$string:module_desc",
+ "mainElement": "EntryAbility",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "requestPermissions": [
+ {
+ "name": "ohos.permission.VIBRATE",
+ "usedScene": {
+ "abilities": [
+ ".MainAbility"
+ ],
+ "when": "inuse"
+ }
+ }
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ "abilities": [
+ {
+ "name": "EntryAbility",
+ "srcEntry": "./ets/entryability/EntryAbility.ets",
+ "description": "$string:EntryAbility_desc",
+ "icon": "$media:layered_image",
+ "label": "$string:EntryAbility_label",
+ "startWindowIcon": "$media:startIcon",
+ "startWindowBackground": "$color:start_window_background",
+ "exported": true,
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ]
+ }
+ ],
+ "extensionAbilities": [
+ {
+ "name": "EntryBackupAbility",
+ "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
+ "type": "backup",
+ "exported": false,
+ "metadata": [
+ {
+ "name": "ohos.extension.backup",
+ "resource": "$profile:backup_config"
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/element/color.json b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#FFFFFF"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/element/float.json b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/element/float.json
new file mode 100644
index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/element/float.json
@@ -0,0 +1,8 @@
+{
+ "float": [
+ {
+ "name": "page_text_font_size",
+ "value": "50fp"
+ }
+ ]
+}
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/element/string.json b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..52f71581c8f41387fe07310a9d261ef1364e41e7
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,52 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "VibratorJsSamples"
+ },
+ {
+ "name": "file",
+ "value": "file"
+ },
+ {
+ "name": "preset",
+ "value": "preset:"
+ },
+ {
+ "name": "time",
+ "value": "time"
+ },
+ {
+ "name": "addTransientEvent",
+ "value": "pattern:addTransientEvent"
+ },
+ {
+ "name": "addContinuousEvent",
+ "value": "pattern:addContinuousEvent"
+ },
+ {
+ "name": "stopVibration",
+ "value": "stopVibration"
+ },
+ {
+ "name": "on",
+ "value": "on"
+ },
+ {
+ "name": "off",
+ "value": "off"
+ },
+ {
+ "name": "getVibratorInfoSync",
+ "value": "getVibratorInfoSync"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/background.png b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/background.png differ
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/foreground.png b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/foreground.png differ
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/layered_image.json b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/layered_image.json
@@ -0,0 +1,7 @@
+{
+ "layered-image":
+ {
+ "background" : "$media:background",
+ "foreground" : "$media:foreground"
+ }
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/startIcon.png b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/media/startIcon.png differ
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/profile/backup_config.json b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/profile/backup_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/profile/backup_config.json
@@ -0,0 +1,3 @@
+{
+ "allowToBackupRestore": true
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/profile/main_pages.json b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/dark/element/color.json b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/dark/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/dark/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#000000"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/rawfile/vibrator.json b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/rawfile/vibrator.json
new file mode 100644
index 0000000000000000000000000000000000000000..a1662f6885312c6e40f3db3c461cdbc83f151221
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/main/resources/rawfile/vibrator.json
@@ -0,0 +1,40 @@
+{
+ MetaData {
+ Create 2023-01-09,
+ Description TYPE_VIEW_FOCUSED vibrate pattern,
+ Version 1.0,
+ ChannelNumber 1
+ },
+ Channels [
+ {
+ Parameters {
+ Index 1
+ },
+ Pattern [
+ {
+ Event {
+ Type continuous,
+ StartTime 0,
+ Duration 15,
+ Parameters {
+ Intensity 100,
+ Frequency 50
+ }
+ }
+ },
+
+ {
+ Event {
+ Type continuous,
+ StartTime 25,
+ Duration 15,
+ Parameters {
+ Intensity 100,
+ Frequency 50
+ }
+ }
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/mock/mock-config.json5 b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/mock/mock-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/mock/mock-config.json5
@@ -0,0 +1,2 @@
+{
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/ohosTest/ets/test/Ability.test.ets b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7f30942b81554a399e89aa253c7089eca4f8d8d1
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
+
+export default function abilityTest() {
+ describe('ActsAbilityTest', () => {
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
+ beforeAll(() => {
+ // Presets an action, which is performed only once before all test cases of the test suite start.
+ // This API supports only one parameter: preset action function.
+ })
+ beforeEach(() => {
+ // Presets an action, which is performed before each unit test case starts.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: preset action function.
+ })
+ afterEach(() => {
+ // Presets a clear action, which is performed after each unit test case ends.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: clear action function.
+ })
+ afterAll(() => {
+ // Presets a clear action, which is performed after all test cases of the test suite end.
+ // This API supports only one parameter: clear action function.
+ })
+ it('assertContain', 0, () => {
+ // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
+ hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
+ let a = 'abc';
+ let b = 'b';
+ // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
+ expect(a).assertContain(b);
+ expect(a).assertEqual(a);
+ })
+ })
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/ohosTest/ets/test/List.test.ets b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..c64e0b06938d246ce044186d4b2d02b500a89e14
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/ohosTest/ets/test/List.test.ets
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/ohosTest/module.json5 b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..f6bdce9946cb02c0385e5a8836c133c93945013d
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/ohosTest/module.json5
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "module": {
+ "name": "entry_test",
+ "type": "feature",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false
+ }
+}
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/test/List.test.ets b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a60c87c5cbb0badf7c3fd8975034590e6fafa992
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/test/List.test.ets
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/test/LocalUnit.test.ets b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..841bfd77e56060e50ec0924302a5ae624e76e3aa
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/entry/src/test/LocalUnit.test.ets
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
+
+export default function localUnitTest() {
+ describe('localUnitTest', () => {
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
+ beforeAll(() => {
+ // Presets an action, which is performed only once before all test cases of the test suite start.
+ // This API supports only one parameter: preset action function.
+ });
+ beforeEach(() => {
+ // Presets an action, which is performed before each unit test case starts.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: preset action function.
+ });
+ afterEach(() => {
+ // Presets a clear action, which is performed after each unit test case ends.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: clear action function.
+ });
+ afterAll(() => {
+ // Presets a clear action, which is performed after all test cases of the test suite end.
+ // This API supports only one parameter: clear action function.
+ });
+ it('assertContain', 0, () => {
+ // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
+ let a = 'abc';
+ let b = 'b';
+ // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
+ expect(a).assertContain(b);
+ expect(a).assertEqual(a);
+ });
+ });
+}
\ No newline at end of file
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/hvigor/hvigor-config.json5 b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..dc688b0bfd4fcd92ebbb3049cf9de543104475a5
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/hvigor/hvigor-config.json5
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "modelVersion": "5.0.4",
+ "dependencies": {
+ },
+ "execution": {
+ // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */
+ // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */
+ // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */
+ // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */
+ // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */
+ },
+ "logging": {
+ // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
+ },
+ "debugging": {
+ // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */
+ },
+ "nodeOptions": {
+ // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/
+ // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/
+ }
+}
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/hvigorfile.ts b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6b365cacd0191d3b1178eb6b9807b1ae0add6271
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/hvigorfile.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { appTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
+}
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/oh-package.json5 b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..37fb982b14de9a0cc3674d27eb058307963dd748
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/oh-package.json5
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+{
+ "modelVersion": "5.0.4",
+ "description": "Please describe the basic information.",
+ "dependencies": {
+ },
+ "devDependencies": {
+ "@ohos/hypium": "1.0.21",
+ "@ohos/hamock": "1.0.0"
+ }
+}
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/ohosTest.md b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/ohosTest.md
new file mode 100644
index 0000000000000000000000000000000000000000..da1d7ee856145779b70cc1dd330fef5f22da0af0
--- /dev/null
+++ b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/ohosTest.md
@@ -0,0 +1,17 @@
+# vibrator测试用例归档
+
+## 用例表
+
+| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
+| ---------------- | ---------------------------- | ----------------------- | ---------- | ---- | ---- |
+| 拉起hap | 设备正常运行 | | 成功拉起应用 | 是 | Pass |
+| 申请权限 | 成功拉起应用 | | 弹出提示框 | 是 | Pass |
+| file类型震动 | 预置震动文件 | 点击file按钮 | 设备振动正常 | 是 | Pass |
+| preset类型震动 | 选择一个effectID | 点击preset按钮 | 设备振动正常 | 是 | Pass |
+| time类型震动 | 无 | 点击time按钮 | 设备振动正常 | 是 | Pass |
+| 短事件类型震动 | 无 | 点击addTransientEvent按钮 | 设备振动正常 | 是 | Pass |
+| 长事件类型震动 | 无 | 点击addContinuousEvent按钮 | 设备振动正常 | 是 | Pass |
+| 停止震动 | 无 | 点击stopVibration按钮 | 设备停止振动 | 是 | Pass |
+| 订阅扩展设备热插拔事件 | 无 | 点击on按钮 | 订阅正常 | 是 | Pass |
+| 去订阅扩展设备热插拔事件 | 无 | 点击off按钮 | 去订阅正常 | 是 | Pass |
+| 获取本设备及扩展设备马达信息列表 | 无 | 点击getVibratorInfoSync按钮 | 马达信息列表获取正常 | 是 | Pass |
diff --git a/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/vibratorSample.png b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/vibratorSample.png
new file mode 100644
index 0000000000000000000000000000000000000000..0143778af680fe3e942b09dc206d1142278661c3
Binary files /dev/null and b/code/BasicFeature/DeviceManagement/Vibrator/VibratorJsSamples/vibratorSample.png differ