diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/.gitignore b/ConnectivityKit/Bluetooth/SerialCommunication/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/.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/ConnectivityKit/Bluetooth/SerialCommunication/AppScope/app.json5 b/ConnectivityKit/Bluetooth/SerialCommunication/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..2f23a8125eba63644dd59f3fe5c38e34af3e7192
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/AppScope/app.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.serialcommunication",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/AppScope/resources/base/element/string.json b/ConnectivityKit/Bluetooth/SerialCommunication/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..f7c89bfc2123d0cb53c842637d6dbd97c7ec3d55
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "SerialCommunication"
+ }
+ ]
+}
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/AppScope/resources/base/media/app_icon.png b/ConnectivityKit/Bluetooth/SerialCommunication/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3
Binary files /dev/null and b/ConnectivityKit/Bluetooth/SerialCommunication/AppScope/resources/base/media/app_icon.png differ
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/README.md b/ConnectivityKit/Bluetooth/SerialCommunication/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..8776066e678b3da7def02aeef556ba762a4cf4d8
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/README.md
@@ -0,0 +1,90 @@
+# 串行通信开发指导
+
+### 介绍
+
+本示例为开发指南中[蓝牙服务开发](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/bluetooth/Readme-CN.md)章节中**传输数据开发指导***示例代码的完整工程,该工程中展示的代码详细描述可查如下链接:
+
+[传输数据开发指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/bluetooth/spp-development-guide.md)
+
+### 效果预览
+|Serial Communication|
+|-------|
+|
|
+
+### 使用说明
+
+1. 启动应用,弹出申请蓝牙权限的弹窗,点击允许,打卡设备的蓝牙功能。
+2. 按照格式输入deviceId和uuid。
+3. 点击listenSocket创建服务器监听Socket。
+4. 点击ServerConnect,socket等待客户端连接,连接成功返回clientId,弹出弹窗提示。
+5. 点击connectDevice,连接对端设备。
+6. 点击writeData,向客户端写入数据。
+7. 点击subscribeEvent,订阅读请求事件。
+8. 点击subscribeEvent,取消订阅读请求事件。
+9. 点击closeServer,关闭服务。
+10. 单击closeClient,关闭客户端。
+
+### 工程目录
+```
+entry/src/main/ets/
+|---entryability
+| |---EntryAbility.ets
+|---entrybackupability
+| |---EntryBackupAbility.ets
+|---pages
+| |---Index.ets // 应用主页面
+```
+
+### 具体实现
+
+#### 服务端向客户端写入数据
+
+1. import需要的socket模块。
+2. 需要SystemCapability.Communication.Bluetooth.Core系统能力。
+3. 创开启设备蓝牙。
+4. 创建服务端socket,返回serverId。
+5. 服务端等待客户端连接,返回clientId。
+6. 服务端向客户端写入数据。
+7. (可选)服务端订阅客户端写入的数据。
+8. 注销服务端socket。
+9. 注销客户端socket。
+10. 错误码请参见[蓝牙服务子系统错误码](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-bluetoothManager.md).
+
+#### 通过socket连接对端设备
+
+1. import需要的socket模块。
+2. 需要SystemCapability.Communication.Bluetooth.Core系统能力。
+3. 开启设备蓝牙。
+4. 开启ble扫描,获取对端设备mac地址。
+5. 连接对端设备。
+6. 错误码请参见[蓝牙服务子系统错误码](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-bluetoothManager.md).
+
+### 相关权限
+
+[ohos.permission.ACCESS_BLUETOOTH](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all-user.md#ohospermissionaccess_bluetooth)
+
+### 依赖
+
+不涉及。
+
+### 约束与限制
+
+1. 本示例仅支持标准系统上运行,支持设备:华为手机。
+
+2. HarmonyOS系统:HarmonyOS 5.0.2 Release及以上。
+
+3. DevEco Studio版本:DevEco Studio 5.0.2 Release及以上。
+
+4. HarmonyOS SDK版本:HarmonyOS 5.0.2 Release及以上。
+
+### 下载
+
+如需单独下载本工程,执行如下命令:
+
+````
+git init
+git config core.sparsecheckout true
+echo ConnectivityKit/Bluetooth/SerialCommunication/ > .git/info/sparse-checkout
+git remote add origin https://gitee.com/harmonyos_samples/guide-snippets.git
+git pull origin master
+````
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/build-profile.json5 b/ConnectivityKit/Bluetooth/SerialCommunication/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..fb5a1ab654ae6715a0ab69a31900ad26dcf2487f
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/build-profile.json5
@@ -0,0 +1,57 @@
+/*
+ * 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": "5.0.2(14)",
+ "targetSdkVersion": "5.0.2(14)",
+ "runtimeOS": "HarmonyOS",
+ "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/ConnectivityKit/Bluetooth/SerialCommunication/code-linter.json5 b/ConnectivityKit/Bluetooth/SerialCommunication/code-linter.json5
new file mode 100644
index 0000000000000000000000000000000000000000..28586467ee7a761c737d8654a73aed6fddbc3c71
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/code-linter.json5
@@ -0,0 +1,35 @@
+/*
+ * 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": {
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/.gitignore b/ConnectivityKit/Bluetooth/SerialCommunication/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/build-profile.json5 b/ConnectivityKit/Bluetooth/SerialCommunication/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e7569e3056e27af38e9991b7ea73ec10f3ba8a05
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/build-profile.json5
@@ -0,0 +1,43 @@
+/*
+ * 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/ConnectivityKit/Bluetooth/SerialCommunication/entry/hvigorfile.ts b/ConnectivityKit/Bluetooth/SerialCommunication/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/ConnectivityKit/Bluetooth/SerialCommunication/entry/obfuscation-rules.txt b/ConnectivityKit/Bluetooth/SerialCommunication/entry/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/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/ConnectivityKit/Bluetooth/SerialCommunication/entry/oh-package.json5 b/ConnectivityKit/Bluetooth/SerialCommunication/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c9cb6c8174858277c9b0d465a51547dcab16d5ff
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/common/ToastReport.ets b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/common/ToastReport.ets
new file mode 100644
index 0000000000000000000000000000000000000000..80c12c4a9c04c5a82e2ed4e2278f2eceee52c93f
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/common/ToastReport.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 { promptAction } from '@kit.ArkUI'
+
+export class ToastReport {
+ public showResult(message: string) {
+ promptAction.showToast({
+ message: message,
+ duration: 2000,
+ showMode: promptAction.ToastShowMode.DEFAULT,
+ bottom: 80
+ })
+ }
+}
+
+let toastReport = new ToastReport();
+
+export default toastReport as ToastReport;
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/entryability/EntryAbility.ets b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..6c3ac9ef7691afaed75b57159c9f757ab0f65208
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,83 @@
+/*
+ * 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 from '@ohos.app.ability.AbilityConstant';
+import hilog from '@ohos.hilog';
+import UIAbility from '@ohos.app.ability.UIAbility';
+import Want from '@ohos.app.ability.Want';
+import window from '@ohos.window';
+import abilityAccessCtrl, { PermissionRequestResult, Permissions } from '@ohos.abilityAccessCtrl';
+import { BusinessError } from '@ohos.base';
+
+const permissions: Permissions[] = ['ohos.permission.ACCESS_BLUETOOTH'];
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
+ }
+
+ onDestroy(): void {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
+ }
+
+ onWindowStageCreate(windowStage: window.WindowStage): void {
+ // Main window is created, set main page for this ability
+ let context: Context = this.context;
+ let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
+ // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
+
+ atManager.requestPermissionsFromUser(context, permissions).then((data: PermissionRequestResult) => {
+ let grantStatus: number[] = data.authResults;
+ let length: number = grantStatus.length;
+ for (let i = 0; i < length; i++) {
+ if (grantStatus[i] === 0) {
+ // 用户授权,可以继续访问目标操作
+ } else {
+ // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
+ return;
+ }
+ }
+ // 授权成功
+ }).catch((err: BusinessError) => {
+ console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
+ })
+
+ // Main window is created, set main page for this ability
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
+
+ windowStage.loadContent('pages/Index', (err, data) => {
+ if (err.code) {
+ hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
+ return;
+ }
+ hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
+ });
+ }
+
+ onWindowStageDestroy(): void {
+ // Main window is destroyed, release UI related resources
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
+ }
+
+ onForeground(): void {
+ // Ability has brought to foreground
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
+ }
+
+ onBackground(): void {
+ // Ability has back to background
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
+ }
+}
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..b1e212947256c5533c7b06285a597c94f840a6e3
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
@@ -0,0 +1,27 @@
+/*
+ * 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';
+
+export default class EntryBackupAbility extends BackupExtensionAbility {
+ async onBackup() {
+ hilog.info(0x0000, 'testTag', 'onBackup ok');
+ }
+
+ async onRestore(bundleVersion: BundleVersion) {
+ hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/pages/Index.ets b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..540edc86a450de848ea7f068671ea19d93600a30
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,262 @@
+/*
+ * 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 { socket } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { ToastReport } from '../common/ToastReport';
+import util from '@ohos.util';
+
+const TAG: string = 'SerialCommunication';
+let encoder = new util.TextEncoder();
+
+@Entry
+@Component
+struct serialCommunication {
+ @State serverNumber: number = 0;
+ @State clientNumber: number = 1;
+ @State deviceId: string = '';
+ @State uuid: string = '00001101-0000-1000-8000-00805f9b34fb';
+ @State dataValue: string = '';
+ private toastReport: ToastReport = new ToastReport();
+
+ build() {
+ Column({ space: 12 }) {
+ Text('serial communication')
+ .fontSize(45)
+ .fontWeight(FontWeight.Bold)
+ .alignRules({
+ center: { anchor: '__container__', align: VerticalAlign.Top },
+ middle: { anchor: '__container__', align: HorizontalAlign.Center }
+ })
+
+ Text($r('app.string.deviceId_style'))
+ Row() {
+ Text('deviceId: ')
+
+ TextInput().onChange((value: string) => {
+ this.deviceId = value;
+ }).height('40vp').width('70%')
+ }.width('80%')
+
+ Text($r('app.string.uuid_style'))
+ Row() {
+ Text('uuid: ')
+
+ TextInput().onChange((value: string) => {
+ this.uuid = value;
+ }).height('40vp').width('70%')
+ }.width('80%')
+
+ Row() {
+ Text('dataValue: ')
+
+ TextInput().onChange((value: string) => {
+ this.dataValue = value;
+ }).height('40vp').width('70%')
+ }.width('80%')
+
+ // [Start server_write_client]
+ Button('listenSocket')
+ .width('50%')
+ .id('listenSocket')
+ .backgroundColor('#8CE072')
+ .onClick(() => {
+ let serverNumber = -1;
+ let sppOption: socket.SppOptions = {
+ uuid: this.uuid,
+ secure: true,
+ type: 0
+ };
+ try {
+ socket.sppListen('server1', sppOption, (code: BusinessError | null, serverSocketID: number) => {
+ if (code != null) {
+ console.error(TAG, 'sppListen error, code is ' + (code as BusinessError).code);
+ this.toastReport.showResult('sppListen error, code is ' + (code as BusinessError).code);
+ return;
+ } else {
+ serverNumber = serverSocketID;
+ this.serverNumber = serverNumber;
+ console.info(TAG, 'sppListen success, serverNumber = ' + serverNumber);
+ this.toastReport.showResult('sppListen success, serverNumber = ' + serverNumber)
+ }
+ });
+ } catch (err) {
+ console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ this.toastReport.showResult('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ }
+ })
+
+ Button('ServerConnect')
+ .width('50%')
+ .id('ServerConnect')
+ .backgroundColor('#8CE072')
+ .onClick(() => {
+ let clientNumber = -1;
+ try {
+
+ socket.sppAccept(this.serverNumber, (code: BusinessError | null, clientSocketID: number) => {
+ if (code != null) {
+ console.error(TAG, 'sppAccept error, code is ' + (code as BusinessError).code);
+ this.toastReport.showResult('sppAccept error, code is ' + (code as BusinessError).code);
+ return;
+ } else {
+ clientNumber = clientSocketID;
+ this.clientNumber = clientNumber
+ console.info(TAG, 'accept the client success');
+ this.toastReport.showResult('accept the client success');
+ }
+ })
+ console.info(TAG, 'waiting for client connection');
+ this.toastReport.showResult('waiting for client connection');
+ } catch (err) {
+ console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ this.toastReport.showResult('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+
+ }
+ })
+
+ // [Start socket_spp_connect]
+ Button('connectDevice')
+ .width('50%')
+ .backgroundColor('#8CE072')
+ .onClick(() => {
+ try {
+ socket.sppConnect(this.deviceId, {
+ uuid: this.uuid,
+ secure: true,
+ type: 0
+ }, (code: BusinessError | null, socketID: number) => {
+ if (code != null) {
+ console.error(TAG, 'sppConnect error, code = ' + (code as BusinessError).code);
+ this.toastReport.showResult('sppConnect error, code = ' + (code as BusinessError).code);
+ return;
+ }
+ console.info(TAG, 'sppConnect success, socketId = ' + socketID);
+ this.toastReport.showResult('sppConnect success, socketId = ' + socketID);
+ })
+ } catch (err) {
+ console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ this.toastReport.showResult('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ }
+ })
+ // [End socket_spp_connect]
+
+ Button('writeData')
+ .width('50%')
+ .id('writeData')
+ .backgroundColor('#8CE072')
+ .onClick(() => {
+ let array = new Uint8Array(this.dataValue.length);
+ encoder.encodeIntoUint8Array(this.dataValue, array);
+
+ try {
+ socket.sppWrite(this.clientNumber, array.buffer);
+ console.info(TAG, 'sppWrite success');
+ this.toastReport.showResult('sppWrite success');
+ } catch (err) {
+ console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ this.toastReport.showResult('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ }
+ })
+
+ Button('subscribeEvent')
+ .width('50%')
+ .id('subscribeEvent')
+ .backgroundColor('#8CE072')
+ .onClick(() => {
+ try {
+ socket.on('sppRead', this.clientNumber, (dataBuffer: ArrayBuffer) => {
+ const data = new Uint8Array(dataBuffer);
+ if (data != null) {
+ console.info(TAG, 'sppRead success, data = ' + JSON.stringify(data));
+ this.toastReport.showResult('sppRead success, data = ' + JSON.stringify(data));
+ } else {
+ console.error(TAG, 'sppRead error, data is null');
+ this.toastReport.showResult('sppRead error, data is null');
+ }
+ })
+ } catch (err) {
+ console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ this.toastReport.showResult('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ }
+ })
+
+ Button('unsubscribeEvent')
+ .width('50%')
+ .id('unsubscribeEvent')
+ .backgroundColor('#8CE072')
+ .onClick(() => {
+ try {
+ socket.off('sppRead', this.clientNumber, (dataBuffer: ArrayBuffer) => {
+ const data = new Uint8Array(dataBuffer);
+ if (data != null) {
+ console.info(TAG, 'offSppRead success, data = ' + JSON.stringify(data));
+ this.toastReport.showResult('offSppRead success, data = ' + JSON.stringify(data));
+ } else {
+ console.error(TAG, 'offSppRead error, data is null');
+ this.toastReport.showResult('offSppRead error, data is null');
+ }
+ })
+ } catch (err) {
+ console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ this.toastReport.showResult('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ }
+ })
+
+ Button('closeServer')
+ .width('50%')
+ .id('closeServer')
+ .backgroundColor('#8CE072')
+ .onClick(() => {
+ try {
+ socket.sppCloseServerSocket(this.serverNumber);
+ console.info(TAG, 'sppCloseServerSocket success');
+ this.toastReport.showResult('sppCloseServerSocket success');
+ } catch (err) {
+ console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ this.toastReport.showResult('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ }
+ })
+
+ Button('closeClient')
+ .width('50%')
+ .id('closeClient')
+ .backgroundColor('#8CE072')
+ .onClick(() => {
+ socket.sppCloseClientSocket(this.clientNumber);
+ console.info(TAG, 'sppCloseClientSocket success');
+ this.toastReport.showResult('sppCloseClientSocket success');
+ })
+ // [End server_write_client]
+ }
+ .width('100%')
+ .height('100%')
+ .backgroundColor('#E6F7FF')
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/module.json5 b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..a4d001e6eeef8773e6ce3eaea955215a716a5e75
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/module.json5
@@ -0,0 +1,74 @@
+/*
+ * 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"
+ ],
+ "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"
+ ]
+ }
+ ]
+ }
+ ],
+ "requestPermissions": [
+ {
+ "name": "ohos.permission.ACCESS_BLUETOOTH",
+ "reason": "$string:ACCESS_BLUETOOTH",
+ "usedScene": {
+ "when": "always"
+ }
+ }],
+ "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/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/element/color.json b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/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/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/element/string.json b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..b18a02c7dc4b7f418dae0fc0745f8bb13297849b
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,28 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "serial communication"
+ },
+ {
+ "name": "ACCESS_BLUETOOTH",
+ "value": "user"
+ },
+ {
+ "name": "deviceId_style",
+ "value": "deviceId格式为:11:22:33:44:55::66 ':'不可省略"
+ },
+ {
+ "name": "uuid_style",
+ "value": "uuid格式为:1111-2222-33333... '-'不可省略"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/background.png b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d
Binary files /dev/null and b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/background.png differ
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/foreground.png b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902
Binary files /dev/null and b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/foreground.png differ
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/layered_image.json b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/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/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/startIcon.png b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/media/startIcon.png differ
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/profile/backup_config.json b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/profile/backup_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/profile/backup_config.json
@@ -0,0 +1,3 @@
+{
+ "allowToBackupRestore": true
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/profile/main_pages.json b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/dark/element/color.json b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/main/resources/dark/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/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/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/mock/mock-config.json5 b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/mock/mock-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..b9a78e201535765168a92d3543c690273ecdc019
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/mock/mock-config.json5
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+{
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/ohosTest/ets/test/Ability.test.ets b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0f8ce9a2c012f8fe36114cef65216ef0b6254f41
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+ * 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/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/ohosTest/ets/test/List.test.ets b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1eac52fcebe8958e19a7b8fed2e8f39c520a3e42
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/ohosTest/ets/test/List.test.ets
@@ -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 abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/ohosTest/module.json5 b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c3fd9dda3040d888d9d8b0b62bcb5d3b6fbeb614
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/ohosTest/module.json5
@@ -0,0 +1,27 @@
+/*
+ * 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/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/test/List.test.ets b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f1186b1f53c3a70930921c5dbd1417332bec56c9
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/test/List.test.ets
@@ -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 localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/test/LocalUnit.test.ets b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7fc57c77dbf76d8df08a2b802a55b948e3fcf968
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/entry/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+ * 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/ConnectivityKit/Bluetooth/SerialCommunication/hvigor/hvigor-config.json5 b/ConnectivityKit/Bluetooth/SerialCommunication/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..1e473e424320d4e68b16737b289f5c851bb19d36
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/hvigor/hvigor-config.json5
@@ -0,0 +1,22 @@
+{
+ "modelVersion": "5.0.1",
+ "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/ConnectivityKit/Bluetooth/SerialCommunication/hvigorfile.ts b/ConnectivityKit/Bluetooth/SerialCommunication/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/ConnectivityKit/Bluetooth/SerialCommunication/oh-package.json5 b/ConnectivityKit/Bluetooth/SerialCommunication/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e41bae026aab3b50d0abb42fece08ba43b4a772b
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.1",
+ "description": "Please describe the basic information.",
+ "dependencies": {
+ },
+ "devDependencies": {
+ "@ohos/hypium": "1.0.19",
+ "@ohos/hamock": "1.0.0"
+ }
+}
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/ohosTest.md b/ConnectivityKit/Bluetooth/SerialCommunication/ohosTest.md
new file mode 100644
index 0000000000000000000000000000000000000000..732d974b0d1fc6710d07af1ec70e73314d90be6f
--- /dev/null
+++ b/ConnectivityKit/Bluetooth/SerialCommunication/ohosTest.md
@@ -0,0 +1,15 @@
+# 串行通信开发指导
+
+## 用例表
+
+| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
+| ----------------- | ------------ | ----------------- | ------------------------|--------- | -------- |
+| 应用正常启动 | 设备支持蓝牙 | 启动应用 | 进入应用界面,弹出申请蓝牙权限的弹窗 |否 | Pass |
+| 创建服务器监听 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 点击listenSocket | 弹出对应弹窗 |否 | Pass |
+| socket等待客户端连接 | 设备支持蓝牙,蓝牙权限申请成功 | 点击ServerConnect | 弹出对应弹窗 |否 | Pass |
+| 连接对端设备 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 点击connectDevice | 弹出对应弹窗 |否 |Pass |
+| 向客户端写入数据 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 点击writeData | 弹出对应弹窗 |否 | Pass |
+| 订阅读请求事件 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 点击subscribeEvent | 弹出对应弹窗 |否 | Pass |
+| 取消订阅读请求事件 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 点击unsubscribeEvent | 弹出对应弹窗 |否 | Pass |
+| 关闭服务 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开,已扫描到设备 | 点击closeServer | 弹出对应弹窗 |否 | Pass |
+| 关闭客户端 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开,已连接到设备 | 单击closeClient | 弹出对应弹窗 |否 | Pass |
diff --git a/ConnectivityKit/Bluetooth/SerialCommunication/screenshots/serialCommuniaction.jpeg b/ConnectivityKit/Bluetooth/SerialCommunication/screenshots/serialCommuniaction.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..2ae3408d74e0770e7786e632aad605719c3f29a9
Binary files /dev/null and b/ConnectivityKit/Bluetooth/SerialCommunication/screenshots/serialCommuniaction.jpeg differ
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/.gitignore b/ConnectivityKit/NFC/HCECardSimulationDevelopment/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/.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/ConnectivityKit/NFC/HCECardSimulationDevelopment/AppScope/app.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7c57137332b9d1e039984bb73cbd6713e5492589
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/AppScope/app.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.hcecardsimulationdevelopment",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/AppScope/resources/base/element/string.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..a5faca124a32379a45c663c85ff675480d1ee658
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "HCECardSimulationDevelopment"
+ }
+ ]
+}
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/AppScope/resources/base/media/app_icon.png b/ConnectivityKit/NFC/HCECardSimulationDevelopment/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3
Binary files /dev/null and b/ConnectivityKit/NFC/HCECardSimulationDevelopment/AppScope/resources/base/media/app_icon.png differ
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/README.md b/ConnectivityKit/NFC/HCECardSimulationDevelopment/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..7b8397ae343a895c336566a1f151210b1f59f5a6
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/README.md
@@ -0,0 +1,84 @@
+# HCE卡模拟开发指南
+
+### 介绍
+
+本示例通过使用[HCE卡模拟开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/nfc/nfc-hce-guide.md)中各场景的开发示例,展示在工程中,帮助开发者更好地理解HEC功能并合理使用。该工程中展示的代码详细描述可查如下链接:
+[HCE卡模拟开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/nfc/nfc-hce-guide.md)
+
+### 效果预览
+|启动界面|
+|-------|
+|
|
+
+### 使用说明
+
+1.启动应用
+2.应用停留在启动界面
+3.输出预期日志,功能启动
+
+### 工程目录
+```
+entry/src/main/ets/ # HCE应用前台刷卡
+|---entryability
+| |---EntryAbility.ets
+|---entrybackupability
+| |---EntryBackupAbility.ets
+|---pages
+| |---Index.ets
+entry1/src/main/ets/ # HCE应用后台刷卡
+|---entry1ability
+| |---Entry1Ability.ets
+|---entry1backupability
+| |---Entry1BackupAbility.ets
+|---pages
+| |---Index.ets
+```
+
+### 具体实现
+
+#### HCE应用前台刷卡
+1. 在module.json5文件中声明NFC卡模拟权限,以及声明HCE特定的action。
+2. import需要的NFC卡模拟模块和其他相关的模块。
+3. 判断设备是否支持NFC能力和HCE能力。
+4. 使能前台HCE应用程序优先处理NFC刷卡功能。
+5. 订阅HCE APDU数据的接收。
+6. 完成HCE刷卡APDU数据的接收和发送。
+7. 退出应用程序NFC刷卡页面时,退出前台优先功能。
+
+#### HCE应用后台刷卡
+1. 在module.json5文件中声明NFC卡模拟权限,声明HCE特定的action,声明应用能够处理的AID。
+2. import需要的NFC卡模拟模块和其他相关的模块。
+3. 判断设备是否支持NFC能力和HCE能力。
+4. 订阅HCE APDU数据的接收。
+5. 完成HCE刷卡APDU数据的接收和发送。
+6. 退出应用程序时,退出订阅功能。
+
+### 相关权限
+
+[ohos.permission.NFC_CARD_EMULATION](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all.md#ohospermissionnfc_card_emulation)
+
+### 依赖
+
+不涉及。
+
+### 约束与限制
+
+1. 本示例仅支持标准系统上运行,支持设备:华为手机。
+
+2. HarmonyOS系统:HarmonyOS 5.0.2 Release及以上。
+
+3. DevEco Studio版本:DevEco Studio 5.0.2 Release及以上。
+
+4. HarmonyOS SDK版本:HarmonyOS 5.0.2 Release及以上。
+
+### 下载
+
+如需单独下载本工程,执行如下命令:
+
+```
+git init
+git config core.sparsecheckout true
+echo ConnectivityKit/NFC/HCECardSimulationDevelopment/ > .git/info/sparse-checkout
+git remote add origin https://gitee.com/harmonyos_samples/guide-snippets.git
+git pull origin master
+```
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/build-profile.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..180f0c008e61f2b5aeab049a34dfd55e803113b3
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/build-profile.json5
@@ -0,0 +1,69 @@
+/*
+ * 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": "5.0.2(14)",
+ "targetSdkVersion": "5.0.2(14)",
+ "runtimeOS": "HarmonyOS",
+ "buildOption": {
+ "strictMode": {
+ "caseSensitiveCheck": true,
+ "useNormalizedOHMUrl": true
+ }
+ }
+ }
+ ],
+ "buildModeSet": [
+ {
+ "name": "debug",
+ },
+ {
+ "name": "release"
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "entry1",
+ "srcPath": "./entry1",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/code-linter.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/code-linter.json5
new file mode 100644
index 0000000000000000000000000000000000000000..28586467ee7a761c737d8654a73aed6fddbc3c71
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/code-linter.json5
@@ -0,0 +1,35 @@
+/*
+ * 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": {
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/.gitignore b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/build-profile.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e7569e3056e27af38e9991b7ea73ec10f3ba8a05
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/build-profile.json5
@@ -0,0 +1,43 @@
+/*
+ * 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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/hvigorfile.ts b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/obfuscation-rules.txt b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/oh-package.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c9cb6c8174858277c9b0d465a51547dcab16d5ff
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/ets/entryability/EntryAbility.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..eeb5607a72dd59148f34fbd691dd5dc120e5350b
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+// [Start front_hce_swipe_ets]
+import { cardEmulation } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { AsyncCallback } from '@kit.BasicServicesKit';
+import { AbilityConstant, UIAbility, Want, bundleManager } from '@kit.AbilityKit';
+
+let hceElementName: bundleManager.ElementName;
+let hceService: cardEmulation.HceService;
+
+const hceCommandCb : AsyncCallback = (error : BusinessError, hceCommand : number[]) => {
+ if (!error) {
+ if (hceCommand == null || hceCommand == undefined) {
+ hilog.error(0x0000, 'testTag', 'hceCommandCb has invalid hceCommand.');
+ return;
+ }
+ // 检查命令,并相应作出响应
+ hilog.info(0x0000, 'testTag', 'hceCommand = %{public}s', JSON.stringify(hceCommand));
+ let responseData = [0x90, 0x00]; // 根据接收到的不同命令更改响应
+ hceService.transmit(responseData).then(() => {
+ hilog.info(0x0000, 'testTag', 'hceService transmit Promise success.');
+ }).catch((err: BusinessError) => {
+ hilog.error(0x0000, 'testTag', 'hceService transmit Promise error = %{public}s', JSON.stringify(err));
+ });
+ } else {
+ hilog.error(0x0000, 'testTag', 'hceCommandCb error %{public}s', JSON.stringify(error));
+ }
+}
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
+
+ // 判断设备是否支持NFC能力和HCE能力
+ if (!canIUse("SystemCapability.Communication.NFC.Core")) {
+ hilog.error(0x0000, 'testTag', 'nfc unavailable.');
+ return;
+ }
+ if (!cardEmulation.hasHceCapability()) {
+ hilog.error(0x0000, 'testTag', 'hce unavailable.');
+ return;
+ }
+
+ hceElementName = {
+ bundleName: want.bundleName ?? '',
+ abilityName: want.abilityName ?? '',
+ moduleName: want.moduleName,
+ }
+ hceService = new cardEmulation.HceService();
+ }
+
+ onForeground() {
+ // 当前Ability已进入前台状态
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
+ if (hceElementName != undefined) {
+ try {
+ // 调用接口使能前台HCE应用程序优先处理NFC刷卡功能
+ let aidList = ["A0000000031010", "A0000000031011"];
+ hceService.start(hceElementName, aidList);
+
+ // 订阅HCE APDU数据的接收
+ hceService.on('hceCmd', hceCommandCb);
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'hceService.start error = %{public}s', JSON.stringify(error));
+ }
+ }
+ }
+
+ onBackground() {
+ // 当前Ability已回到后台状态
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
+ // 退出应用程序NFC标签页面时,调用tag模块退出前台优先功能
+ if (hceElementName != undefined) {
+ try {
+ hceService.stop(hceElementName);
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'hceService.stop error = %{public}s', JSON.stringify(error));
+ }
+ }
+ }
+}
+// [End front_hce_swipe_ets]
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..29feaca7669174be5c2b0e2366529ee94ab7e726
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
@@ -0,0 +1,27 @@
+/*
+ * 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';
+
+export default class EntryBackupAbility extends BackupExtensionAbility {
+ async onBackup() {
+ hilog.info(0x0000, 'testTag', 'onBackup ok');
+ }
+
+ async onRestore(bundleVersion: BundleVersion) {
+ hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/ets/pages/Index.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..cbe08e2badb66f54e7dbd5758f77de1b730d4f55
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+@Entry
+@Component
+struct Index {
+ @State message: string = 'HCE application front-end card swiping';
+
+ build() {
+ RelativeContainer() {
+ Text(this.message)
+ .fontSize(50)
+ .fontWeight(FontWeight.Bold)
+ .alignRules({
+ center: { anchor: '__container__', align: VerticalAlign.Center },
+ middle: { anchor: '__container__', align: HorizontalAlign.Center }
+ })
+ }
+ .height('100%')
+ .width('100%')
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/module.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..3a34e46f780871f5dcf39169e0347f369e016556
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/module.json5
@@ -0,0 +1,78 @@
+/*
+ * 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"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ // [Start front_hce_swipe]
+ "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",
+
+ // 添加nfc卡模拟操作以过滤此应用程序。
+ "ohos.nfc.cardemulation.action.HOST_APDU_SERVICE"
+ ]
+ }
+ ]
+ }
+ ],
+ "requestPermissions": [
+ {
+ // 添加nfc卡模拟的权限。
+ "name": "ohos.permission.NFC_CARD_EMULATION",
+ "reason": "$string:app_name"
+ }
+ ],
+ // [End front_hce_swipe]
+ "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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/element/color.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/element/string.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..2b5be9c46305dd75afc2ae0643b882fb4f7c4513
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "HCECardSimulationDevelopment"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/background.png b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d
Binary files /dev/null and b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/background.png differ
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/foreground.png b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902
Binary files /dev/null and b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/foreground.png differ
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/layered_image.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/startIcon.png b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/media/startIcon.png differ
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/profile/backup_config.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/profile/backup_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/profile/backup_config.json
@@ -0,0 +1,3 @@
+{
+ "allowToBackupRestore": true
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/profile/main_pages.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/dark/element/color.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/main/resources/dark/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/mock/mock-config.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/mock/mock-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..b9a78e201535765168a92d3543c690273ecdc019
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/mock/mock-config.json5
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+{
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/ohosTest/ets/test/Ability.test.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0f8ce9a2c012f8fe36114cef65216ef0b6254f41
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+ * 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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/ohosTest/ets/test/List.test.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1eac52fcebe8958e19a7b8fed2e8f39c520a3e42
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/ohosTest/ets/test/List.test.ets
@@ -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 abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/ohosTest/module.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c3fd9dda3040d888d9d8b0b62bcb5d3b6fbeb614
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/ohosTest/module.json5
@@ -0,0 +1,27 @@
+/*
+ * 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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/test/List.test.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f1186b1f53c3a70930921c5dbd1417332bec56c9
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/test/List.test.ets
@@ -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 localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/test/LocalUnit.test.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7fc57c77dbf76d8df08a2b802a55b948e3fcf968
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+ * 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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/.gitignore b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/build-profile.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e7569e3056e27af38e9991b7ea73ec10f3ba8a05
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/build-profile.json5
@@ -0,0 +1,43 @@
+/*
+ * 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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/hvigorfile.ts b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/obfuscation-rules.txt b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/oh-package.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c4e8768835e5e869bbd19dfb80d2e323afaa6f2d
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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": "entry1",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {}
+}
+
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/ets/entry1ability/Entry1Ability.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/ets/entry1ability/Entry1Ability.ets
new file mode 100644
index 0000000000000000000000000000000000000000..362517f8a635defbe444fdbb35c44aa678c4ae3f
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/ets/entry1ability/Entry1Ability.ets
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+// [Start back_hce_swipe_ets]
+import { cardEmulation } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { AsyncCallback } from '@kit.BasicServicesKit';
+import { AbilityConstant, UIAbility, Want, bundleManager } from '@kit.AbilityKit';
+
+let hceElementName : bundleManager.ElementName;
+let hceService: cardEmulation.HceService;
+
+const hceCommandCb : AsyncCallback = (error : BusinessError, hceCommand : number[]) => {
+ if (!error) {
+ if (hceCommand == null || hceCommand == undefined) {
+ hilog.error(0x0000, 'testTag', 'hceCommandCb has invalid hceCommand.');
+ return;
+ }
+
+ // 检查命令,然后发送响应。
+ hilog.info(0x0000, 'testTag', 'hceCommand = %{public}s', JSON.stringify(hceCommand));
+ let responseData = [0x90, 0x00]; // 根据接收到的不同命令更改响应。
+ hceService.transmit(responseData).then(() => {
+ hilog.info(0x0000, 'testTag', 'hceService transmit Promise success.');
+ }).catch((err: BusinessError) => {
+ hilog.error(0x0000, 'testTag', 'hceService transmit Promise error = %{public}s', JSON.stringify(err));
+ });
+ } else {
+ hilog.error(0x0000, 'testTag', 'hceCommandCb error %{public}s', JSON.stringify(error));
+ }
+}
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
+
+ // 判断设备是否支持NFC能力和HCE能力
+ if (!canIUse('SystemCapability.Communication.NFC.Core')) {
+ hilog.error(0x0000, 'testTag', 'nfc unavailable.');
+ return;
+ }
+ if (!cardEmulation.hasHceCapability()) {
+ hilog.error(0x0000, 'testTag', 'hce unavailable.');
+ return;
+ }
+
+ hceElementName = {
+ bundleName: want.bundleName ?? '',
+ abilityName: want.abilityName ?? '',
+ moduleName: want.moduleName,
+ }
+ hceService = new cardEmulation.HceService();
+ hceService.on('hceCmd', hceCommandCb);
+ }
+
+ onForeground() {
+ // 当前Ability已进入前台状态
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
+ }
+
+ onDestroy() {
+ // Ability已被销毁
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
+ // 退出应用程序NFC标签页面时,调用tag模块退出前台优先功能
+ if (hceElementName != undefined) {
+ try {
+ hceService.stop(hceElementName);
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'hceService.stop error = %{public}s', JSON.stringify(error));
+ }
+ }
+ }
+}
+// [End back_hce_swipe_ets]
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/ets/entry1backupability/Entry1BackupAbility.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/ets/entry1backupability/Entry1BackupAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..91e3598dd883515d5229ca7392d96868b0da5875
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/ets/entry1backupability/Entry1BackupAbility.ets
@@ -0,0 +1,27 @@
+/*
+ * 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';
+
+export default class Entry1BackupAbility extends BackupExtensionAbility {
+ async onBackup() {
+ hilog.info(0x0000, 'testTag', 'onBackup ok');
+ }
+
+ async onRestore(bundleVersion: BundleVersion) {
+ hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/ets/pages/Index.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a524a899a549432640d35fe5f53c3316a08dbfc7
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/ets/pages/Index.ets
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+@Entry
+@Component
+struct Index {
+ @State message: string = 'Hello World';
+
+ build() {
+ RelativeContainer() {
+ Text(this.message)
+ .id('HelloWorld')
+ .fontSize(50)
+ .fontWeight(FontWeight.Bold)
+ .alignRules({
+ center: { anchor: '__container__', align: VerticalAlign.Center },
+ middle: { anchor: '__container__', align: HorizontalAlign.Center }
+ })
+ }
+ .height('100%')
+ .width('100%')
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/module.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..ce1fb387b0cc6a390a3f17bb82c9bf11925243d0
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/module.json5
@@ -0,0 +1,87 @@
+/*
+ * 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": "entry1",
+ "type": "feature",
+ "description": "$string:module_desc",
+ "mainElement": "Entry1Ability",
+ "deviceTypes": [
+ "default"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ // [Start back_hce_swipe]
+ "abilities": [
+ {
+ "name": "Entry1Ability",
+ "srcEntry": "./ets/entry1ability/Entry1Ability.ets",
+ "description": "$string:Entry1Ability_desc",
+ "icon": "$media:layered_image",
+ "label": "$string:Entry1Ability_label",
+ "startWindowIcon": "$media:startIcon",
+ "startWindowBackground": "$color:start_window_background",
+ "exported": true,
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home",
+
+ // 添加nfc卡模拟操作以过滤此应用程序。
+ "ohos.nfc.cardemulation.action.HOST_APDU_SERVICE"
+ ]
+ }
+ ],
+ "metadata": [
+ {
+ "name": "payment-aid",
+ "value": "A0000000031010" // 将其更改为正确
+ },
+ {
+ "name": "other-aid",
+ "value": "A0000000031011" // 将其更改为正确
+ }
+ ]
+ }
+ ],
+ "requestPermissions": [
+ {
+ // 添加nfc卡模拟的权限。
+ "name": "ohos.permission.NFC_CARD_EMULATION",
+ "reason": "$string:app_name"
+ }
+ ],
+ // [End back_hce_swipe]
+ "extensionAbilities": [
+ {
+ "name": "Entry1BackupAbility",
+ "srcEntry": "./ets/entry1backupability/Entry1BackupAbility.ets",
+ "type": "backup",
+ "exported": false,
+ "metadata": [
+ {
+ "name": "ohos.extension.backup",
+ "resource": "$profile:backup_config"
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/element/color.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/element/string.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..bfacd4a9c18907308e10e501a9f6f42684c0587d
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "Entry1Ability_desc",
+ "value": "description"
+ },
+ {
+ "name": "Entry1Ability_label",
+ "value": "HCECardSimulationDevelopment1"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/background.png b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d
Binary files /dev/null and b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/background.png differ
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/foreground.png b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902
Binary files /dev/null and b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/foreground.png differ
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/layered_image.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/startIcon.png b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/media/startIcon.png differ
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/profile/backup_config.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/profile/backup_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/profile/backup_config.json
@@ -0,0 +1,3 @@
+{
+ "allowToBackupRestore": true
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/profile/main_pages.json b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/mock/mock-config.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/mock/mock-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..b9a78e201535765168a92d3543c690273ecdc019
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/mock/mock-config.json5
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+{
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/ohosTest/ets/test/Ability.test.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0f8ce9a2c012f8fe36114cef65216ef0b6254f41
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+ * 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/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/ohosTest/ets/test/List.test.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1eac52fcebe8958e19a7b8fed2e8f39c520a3e42
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/ohosTest/ets/test/List.test.ets
@@ -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 abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/ohosTest/module.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..dd5b7a003869fce5b11da19f1de9d791afb131b5
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/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": "entry1_test",
+ "type": "feature",
+ "deviceTypes": [
+ "default"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false
+ }
+}
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/test/List.test.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f1186b1f53c3a70930921c5dbd1417332bec56c9
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/test/List.test.ets
@@ -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 localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/test/LocalUnit.test.ets b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7fc57c77dbf76d8df08a2b802a55b948e3fcf968
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/entry1/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+ * 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/ConnectivityKit/NFC/HCECardSimulationDevelopment/hvigor/hvigor-config.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..d584c19c247db9a7caee4b606bb931aa9279c637
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/hvigor/hvigor-config.json5
@@ -0,0 +1,37 @@
+/*
+ * 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.1",
+ "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/ConnectivityKit/NFC/HCECardSimulationDevelopment/hvigorfile.ts b/ConnectivityKit/NFC/HCECardSimulationDevelopment/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4d72939a0516be957346941b6438580a93b15230
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/hvigorfile.ts
@@ -0,0 +1,21 @@
+/*
+ * 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/ConnectivityKit/NFC/HCECardSimulationDevelopment/oh-package.json5 b/ConnectivityKit/NFC/HCECardSimulationDevelopment/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e41bae026aab3b50d0abb42fece08ba43b4a772b
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.1",
+ "description": "Please describe the basic information.",
+ "dependencies": {
+ },
+ "devDependencies": {
+ "@ohos/hypium": "1.0.19",
+ "@ohos/hamock": "1.0.0"
+ }
+}
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/ohosTest.md b/ConnectivityKit/NFC/HCECardSimulationDevelopment/ohosTest.md
new file mode 100644
index 0000000000000000000000000000000000000000..8287c8a8cb2939182fdda647f92bae69cef3a282
--- /dev/null
+++ b/ConnectivityKit/NFC/HCECardSimulationDevelopment/ohosTest.md
@@ -0,0 +1,7 @@
+# HCE卡模拟开发示例代码工程化
+
+## 用例表
+
+| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
+| ----------------- | ------------ | ----------------- | ------------------------|--------- | -------- |
+| NFC功能正常启动 | 设备支持NFC | 启动应用 | 应用停留在启动界面,输出预期日志 |否 | Pass |
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/HCECardSimulationDevelopment/screenshots/image.jpeg b/ConnectivityKit/NFC/HCECardSimulationDevelopment/screenshots/image.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..9129c2132ae22b21a5134cd75d5433dace7e2234
Binary files /dev/null and b/ConnectivityKit/NFC/HCECardSimulationDevelopment/screenshots/image.jpeg differ
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/.gitignore b/ConnectivityKit/NFC/NFCReadAndWrite/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/.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/ConnectivityKit/NFC/NFCReadAndWrite/AppScope/app.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..f2ded1340c481d466911f3f14be5e604eaf80b9d
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/AppScope/app.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.nfcreadandwrite",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/AppScope/resources/base/element/string.json b/ConnectivityKit/NFC/NFCReadAndWrite/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..30b97e99fd5d77997e6b6ce93376d2083c053a91
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "NFCReadAndWrite"
+ }
+ ]
+}
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/AppScope/resources/base/media/app_icon.png b/ConnectivityKit/NFC/NFCReadAndWrite/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3
Binary files /dev/null and b/ConnectivityKit/NFC/NFCReadAndWrite/AppScope/resources/base/media/app_icon.png differ
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/README.md b/ConnectivityKit/NFC/NFCReadAndWrite/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b51be9b4f3271143f050b46e95e5787b217964d4
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/README.md
@@ -0,0 +1,84 @@
+# NFC标签读写开发指南
+
+### 介绍
+
+本示例通过使用[NFC标签读写开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/nfc/nfc-tag-access-guide.md)中各场景的开发示例,展示在工程中,帮助开发者更好地理解NFC标签读写功能并合理使用。该工程中展示的代码详细描述可查如下链接:
+[NFC标签读写开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/nfc/nfc-tag-access-guide.md)
+
+### 效果预览
+|启动界面|
+|-------|
+|
|
+
+### 使用说明
+
+1.启动应用
+2.应用停留在启动界面
+3.输出预期日志,功能启动
+
+### 工程目录
+```
+entry/src/main/ets/ # 前台读取标签
+|---entryability
+| |---EntryAbility.ets
+|---entrybackupability
+| |---EntryBackupAbility.ets
+|---pages
+| |---Index.ets
+entry1/src/main/ets/ # 后台读取标签
+|---entryability
+| |---EntryAbility.ets
+|---entrybackupability
+| |---EntryBackupAbility.ets
+|---pages
+| |---Index.ets
+```
+
+### 具体实现
+
+#### 前台读取标签
+
+1. 在module.json5文件中声明NFC标签读取的权限,以及声明NFC标签特定的action。
+2. import需要的tag模块和其他相关的模块。
+3. 判断设备是否支持NFC能力。
+4. 调用tag模块中前台优先的接口,使能前台应用程序优先处理所发现的NFC标签功能。
+5. 获取特定技术类型的NFC标签对象。
+6. 执行读写接口完成标签数据的读取或写入数据到标签。
+7. 退出应用程序NFC标签页面时,调用tag模块退出前台优先功能。
+
+#### 后台读取标签
+
+1. 在module.json5文件中声明NFC标签读取的权限,声明NFC标签特定的action,以及声明本应用程序的能够处理的NFC标签技术类型。
+2. import需要的tag模块和其他相关的模块。
+3. 获取特定技术类型的NFC标签对象。
+4. 执行读写接口完成标签数据的读取或写入数据到标签。
+
+### 相关权限
+
+[ohos.permission.NFC_TAG](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all.md#ohospermissionnfc_tag)
+
+### 依赖
+
+不涉及
+
+### 约束与限制
+
+1. 本示例仅支持标准系统上运行,支持设备:华为手机。
+
+2. HarmonyOS系统:HarmonyOS 5.0.2 Release及以上。
+
+3. DevEco Studio版本:DevEco Studio 5.0.2 Release及以上。
+
+4. HarmonyOS SDK版本:HarmonyOS 5.0.2 Release及以上。
+
+### 下载
+
+如需单独下载本工程,执行如下命令:
+
+````
+git init
+git config core.sparsecheckout true
+echo ConnectivityKit/NFC/NFCReadAndWrite/ > .git/info/sparse-checkout
+git remote add origin https://gitee.com/harmonyos_samples/guide-snippets.git
+git pull origin master
+````
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/build-profile.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..a06288f8a68a45ab04dd8f8d6b872b4dbf6cf41b
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/build-profile.json5
@@ -0,0 +1,69 @@
+/*
+ * 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": "5.0.2(14)",
+ "targetSdkVersion": "5.0.2(14)",
+ "runtimeOS": "HarmonyOS",
+ "buildOption": {
+ "strictMode": {
+ "caseSensitiveCheck": true,
+ "useNormalizedOHMUrl": true
+ }
+ }
+ }
+ ],
+ "buildModeSet": [
+ {
+ "name": "debug",
+ },
+ {
+ "name": "release"
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "entry1",
+ "srcPath": "./entry1",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/code-linter.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/code-linter.json5
new file mode 100644
index 0000000000000000000000000000000000000000..4bacc9e298b707e25577dbcef9e1c7c698880ecf
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/code-linter.json5
@@ -0,0 +1,35 @@
+/*
+ * 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": {
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/.gitignore b/ConnectivityKit/NFC/NFCReadAndWrite/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/build-profile.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..4e956928b47b71f85916d920e894e1272a61d125
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/build-profile.json5
@@ -0,0 +1,43 @@
+/*
+ * 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/ConnectivityKit/NFC/NFCReadAndWrite/entry/hvigorfile.ts b/ConnectivityKit/NFC/NFCReadAndWrite/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/ConnectivityKit/NFC/NFCReadAndWrite/entry/obfuscation-rules.txt b/ConnectivityKit/NFC/NFCReadAndWrite/entry/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/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/ConnectivityKit/NFC/NFCReadAndWrite/entry/oh-package.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..dbacc308e4f7758a11b72c6a2af812b2471a0e8a
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/ets/entryability/EntryAbility.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..d244d203a7ac9748313094b307a1437a9d9963d5
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+// [Start front_get_nfc_tag_ets]
+import { tag } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { AbilityConstant, UIAbility, Want, bundleManager } from '@kit.AbilityKit';
+
+let nfcTagElementName: bundleManager.ElementName;
+let foregroundRegister: boolean;
+
+async function readerModeCb(error : BusinessError, tagInfo : tag.TagInfo) {
+ if (!error) {
+ // 获取特定技术类型的NFC标签对象
+ if (tagInfo == null || tagInfo == undefined) {
+ hilog.error(0x0000, 'testTag', 'readerModeCb tagInfo is invalid');
+ return;
+ }
+ if (tagInfo.uid == null || tagInfo.uid == undefined) {
+ hilog.error(0x0000, 'testTag', 'readerModeCb uid is invalid');
+ return;
+ }
+ if (tagInfo.technology == null || tagInfo.technology == undefined || tagInfo.technology.length == 0) {
+ hilog.error(0x0000, 'testTag', 'readerModeCb technology is invalid');
+ return;
+ }
+
+ // 执行读写接口完成标签数据的读取或写入数据到标签
+ // 使用IsoDep技术访问这个NFC标签。
+ let isoDep : tag.IsoDepTag | null = null;
+ for (let i = 0; i < tagInfo.technology.length; i++) {
+ if (tagInfo.technology[i] == tag.ISO_DEP) {
+ try {
+ isoDep = tag.getIsoDep(tagInfo);
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'readerModeCb getIsoDep error = %{public}s', JSON.stringify(error));
+ return;
+ }
+ }
+ // 如果需要,使用其他技术访问这个NFC标签。
+ }
+ if (isoDep == undefined) {
+ hilog.error(0x0000, 'testTag', 'readerModeCb getIsoDep is invalid');
+ return;
+ }
+
+ // 使用IsoDep技术连接到这个NFC标签。
+ try {
+ isoDep.connect();
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.connect() error = %{public}s', JSON.stringify(error));
+ return;
+ }
+ if (!isoDep.isConnected()) {
+ hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.isConnected() false.');
+ return;
+ }
+
+ // 向连接的标签发送数据。
+ let cmdData = [0x01, 0x02, 0x03, 0x04]; // 请根据需要修改原始数据。
+ try {
+ isoDep.transmit(cmdData).then((response : number[]) => {
+ hilog.info(0x0000, 'testTag', 'readerModeCb isoDep.transmit() response = %{public}s.', JSON.stringify(response));
+ }).catch((err : BusinessError)=> {
+ hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.transmit() err = %{public}s.', JSON.stringify(err));
+ return;
+ });
+ } catch (businessError) {
+ hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.transmit() businessError = %{public}s.', JSON.stringify(businessError));
+ return;
+ }
+ } else {
+ hilog.info(0x0000, 'testTag', 'readerModeCb readerModeCb error %{public}s', JSON.stringify(error));
+ }
+}
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
+
+ // 判断设备是否支持NFC能力
+ if (!canIUse("SystemCapability.Communication.NFC.Core")) {
+ hilog.error(0x0000, 'testTag', 'nfc unavailable.');
+ return;
+ }
+
+ nfcTagElementName = {
+ bundleName: want.bundleName ?? '',
+ abilityName: want.abilityName ?? '',
+ moduleName: want.moduleName,
+ }
+ }
+
+ onForeground() {
+ // 当前Ability已进入前台状态
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
+ if (nfcTagElementName != undefined) {
+ // 调用tag模块中前台优先的接口,使能前台应用程序优先处理所发现的NFC标签功能
+ let techList : number[] = [tag.NFC_A, tag.NFC_B, tag.NFC_F, tag.NFC_V];
+ try {
+ tag.on('readerMode', nfcTagElementName, techList, readerModeCb);
+ foregroundRegister = true;
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'on readerMode error = %{public}s', JSON.stringify(error));
+ }
+ }
+ }
+
+ onBackground() {
+ // 当前Ability已回到后台状态
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
+ // 退出应用程序NFC标签页面时,调用tag模块退出前台优先功能
+ if (foregroundRegister) {
+ foregroundRegister = false;
+ try {
+ tag.off('readerMode', nfcTagElementName);
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'off readerMode error = %{public}s', JSON.stringify(error));
+ }
+ }
+ }
+}
+// [End front_get_nfc_tag_ets]
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..b1e212947256c5533c7b06285a597c94f840a6e3
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
@@ -0,0 +1,27 @@
+/*
+ * 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';
+
+export default class EntryBackupAbility extends BackupExtensionAbility {
+ async onBackup() {
+ hilog.info(0x0000, 'testTag', 'onBackup ok');
+ }
+
+ async onRestore(bundleVersion: BundleVersion) {
+ hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/ets/pages/Index.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..ba890239c7dea4abc424e1c36050ea9ae7295db0
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+@Entry
+@Component
+struct Index {
+ @State message: string = 'Front end reads tags';
+
+ build() {
+ RelativeContainer() {
+ Text(this.message)
+ .fontSize(50)
+ .fontWeight(FontWeight.Bold)
+ .alignRules({
+ center: { anchor: '__container__', align: VerticalAlign.Center },
+ middle: { anchor: '__container__', align: HorizontalAlign.Center }
+ })
+ }
+ .height('100%')
+ .width('100%')
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/module.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..b8826c54637287aa21c350e8e3ad3b2fd6cdf56e
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/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"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ // {Start front_get_nfc_tag]
+ "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",
+ "ohos.nfc.tag.action.TAG_FOUND"
+ ]
+ }
+ ]
+ }
+ ],
+ "requestPermissions": [
+ {
+ // 添加nfc标记操作的权限。
+ "name": "ohos.permission.NFC_TAG",
+ "reason": "$string:app_name"
+ }
+ ],
+ // [End front_get_nfc_tag]
+ "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/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/element/color.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/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/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/element/string.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..c175394ff25f5c39302e7dcd31e5ccfbf06eb01b
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "readAndWrite"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/background.png b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d
Binary files /dev/null and b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/background.png differ
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/foreground.png b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902
Binary files /dev/null and b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/foreground.png differ
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/layered_image.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/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/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/startIcon.png b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/media/startIcon.png differ
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/profile/backup_config.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/profile/backup_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/profile/backup_config.json
@@ -0,0 +1,3 @@
+{
+ "allowToBackupRestore": true
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/profile/main_pages.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/dark/element/color.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/main/resources/dark/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/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/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/mock/mock-config.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/mock/mock-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..a99e1d70a555e9935e93519642bb8d05bcb5a149
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/mock/mock-config.json5
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+{
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/ohosTest/ets/test/Ability.test.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0f8ce9a2c012f8fe36114cef65216ef0b6254f41
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+ * 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/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/ohosTest/ets/test/List.test.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f40533d1374f4046f8af1e7df6aa90157cb361d8
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/ohosTest/ets/test/List.test.ets
@@ -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 abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/ohosTest/module.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..be4685a172af804c5b26c0e3618bf770cf138e98
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/ohosTest/module.json5
@@ -0,0 +1,27 @@
+/*
+ * 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/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/test/List.test.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f1186b1f53c3a70930921c5dbd1417332bec56c9
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/test/List.test.ets
@@ -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 localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/test/LocalUnit.test.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..b7b035e9b66997b8cac57382753074ff60c3f5ee
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+ * 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/ConnectivityKit/NFC/NFCReadAndWrite/entry1/.gitignore b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/build-profile.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e7569e3056e27af38e9991b7ea73ec10f3ba8a05
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/build-profile.json5
@@ -0,0 +1,43 @@
+/*
+ * 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/ConnectivityKit/NFC/NFCReadAndWrite/entry1/hvigorfile.ts b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/ConnectivityKit/NFC/NFCReadAndWrite/entry1/obfuscation-rules.txt b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/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/ConnectivityKit/NFC/NFCReadAndWrite/entry1/oh-package.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c4e8768835e5e869bbd19dfb80d2e323afaa6f2d
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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": "entry1",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {}
+}
+
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/ets/entry1backupability/Entry1BackupAbility.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/ets/entry1backupability/Entry1BackupAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3a17c53f2e978fb7253194a198619c3f183107b5
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/ets/entry1backupability/Entry1BackupAbility.ets
@@ -0,0 +1,27 @@
+/*
+ * 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';
+
+export default class Entry1BackupAbility extends BackupExtensionAbility {
+ async onBackup() {
+ hilog.info(0x0000, 'testTag', 'onBackup ok');
+ }
+
+ async onRestore(bundleVersion: BundleVersion) {
+ hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/ets/entryability/EntryAbility.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..6817624c7c39356c31ccca986b5e08a00aca232f
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+// [Start back_get_nfc_tag_ets]
+ import { tag } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
+
+ // 获取特定技术类型的NFC标签对象
+ let tagInfo : tag.TagInfo;
+ try {
+ tagInfo = tag.getTagInfo(want);
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'getTagInfo error = %{public}s', JSON.stringify(error));
+ return;
+ }
+
+ if (tagInfo == null || tagInfo == undefined) {
+ hilog.error(0x0000, 'testTag', 'tagInfo is invalid');
+ return;
+ }
+ if (tagInfo.uid == null || tagInfo.uid == undefined) {
+ hilog.error(0x0000, 'testTag', 'uid is invalid');
+ return;
+ }
+ if (tagInfo.technology == null || tagInfo.technology == undefined || tagInfo.technology.length == 0) {
+ hilog.error(0x0000, 'testTag', 'technology is invalid');
+ return;
+ }
+
+ // 执行读写接口完成标签数据的读取或写入数据到标签
+ // 使用IsoDep技术访问这个NFC标签。
+ let isoDep : tag.IsoDepTag | null = null;
+ for (let i = 0; i < tagInfo.technology.length; i++) {
+ if (tagInfo.technology[i] == tag.ISO_DEP) {
+ try {
+ isoDep = tag.getIsoDep(tagInfo);
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'getIsoDep error = %{public}s', JSON.stringify(error));
+ return;
+ }
+ }
+ // 如果需要,使用其他技术访问这个NFC标签。
+ }
+ if (isoDep == undefined) {
+ hilog.error(0x0000, 'testTag', 'getIsoDep is invalid');
+ return;
+ }
+
+ // 使用IsoDep技术连接到这个NFC标签。
+ try {
+ isoDep.connect();
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'isoDep.connect() error = %{public}s', JSON.stringify(error));
+ return;
+ }
+ if (!isoDep.isConnected()) {
+ hilog.error(0x0000, 'testTag', 'isoDep.isConnected() false.');
+ return;
+ }
+
+ // 向连接的标签发送数据。
+ let cmdData = [0x01, 0x02, 0x03, 0x04]; // 请根据需要修改原始数据。
+ try {
+ isoDep.transmit(cmdData).then((response : number[]) => {
+ hilog.info(0x0000, 'testTag', 'isoDep.transmit() response = %{public}s.', JSON.stringify(response));
+ }).catch((err : BusinessError)=> {
+ hilog.error(0x0000, 'testTag', 'isoDep.transmit() err = %{public}s.', JSON.stringify(err));
+ return;
+ });
+ } catch (businessError) {
+ hilog.error(0x0000, 'testTag', 'isoDep.transmit() businessError = %{public}s.', JSON.stringify(businessError));
+ return;
+ }
+ }
+}
+// [End back_get_nfc_tag_ets]
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/ets/pages/Index.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a3795272228e2f6f649e50e5ebad7d4a2c8469d0
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/ets/pages/Index.ets
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+@Entry
+@Component
+struct Index {
+ @State message: string = 'Read tags in the background';
+
+ build() {
+ RelativeContainer() {
+ Text(this.message)
+ .fontSize(50)
+ .fontWeight(FontWeight.Bold)
+ .alignRules({
+ center: { anchor: '__container__', align: VerticalAlign.Center },
+ middle: { anchor: '__container__', align: HorizontalAlign.Center }
+ })
+ }
+ .height('100%')
+ .width('100%')
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/module.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..adbda334abb632003e9ecddb0c345bcf05fe798a
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/module.json5
@@ -0,0 +1,85 @@
+/*
+ * 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": "entry1",
+ "type": "feature",
+ "description": "$string:module_desc",
+ "mainElement": "EntryAbility",
+ "deviceTypes": [
+ "default"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ // [Start back_get_nfc_tag]
+ "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",
+ "ohos.nfc.tag.action.TAG_FOUND"
+ ],
+ "uris": [
+ {
+ "type":"tag-tech/NfcA"
+ },
+ {
+ "type":"tag-tech/IsoDep"
+ }
+ // 必要时添加其他技术,
+ // 例如: NfcB/NfcF/NfcV/Ndef/MifareClassic/MifareUL/NdefFormatable
+ ]
+ }
+ ]
+ }
+ ],
+ "requestPermissions": [
+ {
+ // 添加nfc标记操作的权限。
+ "name": "ohos.permission.NFC_TAG",
+ "reason": "$string:app_name"
+ }
+ ],
+ // [End back_get_nfc_tag]
+ "extensionAbilities": [
+ {
+ "name": "Entry1BackupAbility",
+ "srcEntry": "./ets/entry1backupability/Entry1BackupAbility.ets",
+ "type": "backup",
+ "exported": false,
+ "metadata": [
+ {
+ "name": "ohos.extension.backup",
+ "resource": "$profile:backup_config"
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/element/color.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/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/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/element/string.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..cf7f724d70ab2e12153e0432967d96330fcfb6ad
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "readAndWrite1"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/background.png b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d
Binary files /dev/null and b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/background.png differ
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/foreground.png b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902
Binary files /dev/null and b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/foreground.png differ
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/layered_image.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/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/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/startIcon.png b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/media/startIcon.png differ
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/profile/backup_config.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/profile/backup_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/profile/backup_config.json
@@ -0,0 +1,3 @@
+{
+ "allowToBackupRestore": true
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/profile/main_pages.json b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/mock/mock-config.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/mock/mock-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..b9a78e201535765168a92d3543c690273ecdc019
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/mock/mock-config.json5
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+{
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/ohosTest/ets/test/Ability.test.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0f8ce9a2c012f8fe36114cef65216ef0b6254f41
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+ * 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/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/ohosTest/ets/test/List.test.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1eac52fcebe8958e19a7b8fed2e8f39c520a3e42
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/ohosTest/ets/test/List.test.ets
@@ -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 abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/ohosTest/module.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..dd5b7a003869fce5b11da19f1de9d791afb131b5
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/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": "entry1_test",
+ "type": "feature",
+ "deviceTypes": [
+ "default"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false
+ }
+}
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/test/List.test.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f1186b1f53c3a70930921c5dbd1417332bec56c9
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/test/List.test.ets
@@ -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 localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/test/LocalUnit.test.ets b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7fc57c77dbf76d8df08a2b802a55b948e3fcf968
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/entry1/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+ * 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/ConnectivityKit/NFC/NFCReadAndWrite/hvigor/hvigor-config.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..3511c6358c656ebda11ff67ebc9dc6454caeaa69
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/hvigor/hvigor-config.json5
@@ -0,0 +1,37 @@
+/*
+ * 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.1",
+ "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/ConnectivityKit/NFC/NFCReadAndWrite/hvigorfile.ts b/ConnectivityKit/NFC/NFCReadAndWrite/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/ConnectivityKit/NFC/NFCReadAndWrite/oh-package.json5 b/ConnectivityKit/NFC/NFCReadAndWrite/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..87fd23ee937818091c08f0d203d079a91d3cf11b
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.1",
+ "description": "Please describe the basic information.",
+ "dependencies": {
+ },
+ "devDependencies": {
+ "@ohos/hypium": "1.0.19",
+ "@ohos/hamock": "1.0.0"
+ }
+}
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/ohosTest.md b/ConnectivityKit/NFC/NFCReadAndWrite/ohosTest.md
new file mode 100644
index 0000000000000000000000000000000000000000..4e057f15d29063614611820304830eb2fd93501b
--- /dev/null
+++ b/ConnectivityKit/NFC/NFCReadAndWrite/ohosTest.md
@@ -0,0 +1,7 @@
+# NFC标签读写示例代码工程化
+
+## 用例表
+
+| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
+| ----------------- | ------------ | ----------------- | ------------------------|--------- | -------- |
+| NFC功能正常启动 | 设备支持NFC | 启动应用 | 应用停留在启动界面,输出预期日志 |否 | Pass |
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/NFCReadAndWrite/screenshots/image.jpeg b/ConnectivityKit/NFC/NFCReadAndWrite/screenshots/image.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..9129c2132ae22b21a5134cd75d5433dace7e2234
Binary files /dev/null and b/ConnectivityKit/NFC/NFCReadAndWrite/screenshots/image.jpeg differ
diff --git a/ConnectivityKit/NFC/SecureElement/.gitignore b/ConnectivityKit/NFC/SecureElement/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/.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/ConnectivityKit/NFC/SecureElement/AppScope/app.json5 b/ConnectivityKit/NFC/SecureElement/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..5ff44d5fe96ed8c43ea03ac46515a572cbfb6a25
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/AppScope/app.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.nfc_se",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
diff --git a/ConnectivityKit/NFC/SecureElement/AppScope/resources/base/element/string.json b/ConnectivityKit/NFC/SecureElement/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..475ddaf762835a539225a2c288c4e6d03b1b3446
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "NFC_SE"
+ }
+ ]
+}
diff --git a/ConnectivityKit/NFC/SecureElement/AppScope/resources/base/media/app_icon.png b/ConnectivityKit/NFC/SecureElement/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3
Binary files /dev/null and b/ConnectivityKit/NFC/SecureElement/AppScope/resources/base/media/app_icon.png differ
diff --git a/ConnectivityKit/NFC/SecureElement/README.md b/ConnectivityKit/NFC/SecureElement/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..60b4877b1aba32e5d7919c5e6833caeb5ffe293e
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/README.md
@@ -0,0 +1,65 @@
+# 安全单元访问开发指南
+
+### 介绍
+
+本示例通过使用[安全单元访问开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/nfc/nfc-se-access-guide.md)中各场景的开发示例,展示在工程中,帮助开发者更好地理解HEC功能并合理使用。该工程中展示的代码详细描述可查如下链接:
+[安全单元访问开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/nfc/nfc-se-access-guide.md)
+
+### 效果预览
+|启动界面|
+|-------|
+|
|
+
+### 使用说明
+
+1.启动应用
+2.应用停留在启动界面
+3.输出预期日志,功能启动
+
+### 工程目录
+```
+entry/src/main/ets/
+|---entryability
+| |---EntryAbility.ets
+|---entrybackupability
+| |---EntryBackupAbility.ets
+|---pages
+| |---Index.ets
+```
+
+### 具体实现
+
+#### 应用程序访问安全单元
+1. import需要的安全单元模块。
+2. 判断设备是否支持安全单元能力。
+3. 访问安全单元,实现数据的读取或写入。
+
+### 相关权限
+
+不涉及
+
+### 依赖
+
+不涉及。
+
+### 约束与限制
+
+1. 本示例仅支持标准系统上运行,支持设备:华为手机。
+
+2. HarmonyOS系统:HarmonyOS 5.0.2 Release及以上。
+
+3. DevEco Studio版本:DevEco Studio 5.0.2 Release及以上。
+
+4. HarmonyOS SDK版本:HarmonyOS 5.0.2 Release及以上。
+
+### 下载
+
+如需单独下载本工程,执行如下命令:
+
+````
+git init
+git config core.sparsecheckout true
+echo ConnectivityKit/NFC/SecureElement/ > .git/info/sparse-checkout
+git remote add origin https://gitee.com/harmonyos_samples/guide-snippets.git
+git pull origin master
+````
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/build-profile.json5 b/ConnectivityKit/NFC/SecureElement/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..f28b03dd861d2e84e4ceca13985f36694429f8fc
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/build-profile.json5
@@ -0,0 +1,54 @@
+/*
+ * 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": "5.0.2(14)",
+ "targetSdkVersion": "5.0.2(14)",
+ "runtimeOS": "HarmonyOS",
+ "buildOption": {
+ "strictMode": {
+ "caseSensitiveCheck": true,
+ "useNormalizedOHMUrl": true
+ }
+ }
+ }
+ ],
+ "buildModeSet": [
+ {
+ "name": "release"
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/code-linter.json5 b/ConnectivityKit/NFC/SecureElement/code-linter.json5
new file mode 100644
index 0000000000000000000000000000000000000000..28586467ee7a761c737d8654a73aed6fddbc3c71
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/code-linter.json5
@@ -0,0 +1,35 @@
+/*
+ * 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": {
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/entry/.gitignore b/ConnectivityKit/NFC/SecureElement/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/entry/build-profile.json5 b/ConnectivityKit/NFC/SecureElement/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e7569e3056e27af38e9991b7ea73ec10f3ba8a05
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/build-profile.json5
@@ -0,0 +1,43 @@
+/*
+ * 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/ConnectivityKit/NFC/SecureElement/entry/hvigorfile.ts b/ConnectivityKit/NFC/SecureElement/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/ConnectivityKit/NFC/SecureElement/entry/obfuscation-rules.txt b/ConnectivityKit/NFC/SecureElement/entry/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/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/ConnectivityKit/NFC/SecureElement/entry/oh-package.json5 b/ConnectivityKit/NFC/SecureElement/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c9cb6c8174858277c9b0d465a51547dcab16d5ff
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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/ConnectivityKit/NFC/SecureElement/entry/src/main/ets/entryability/EntryAbility.ets b/ConnectivityKit/NFC/SecureElement/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a680111a4717a0a59153a21b5a944793178513f0
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+// [Start access_security_unit]
+import { omapi } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
+
+let seService : omapi.SEService;
+let seReaders : omapi.Reader[];
+let seSession : omapi.Session;
+let seChannel : omapi.Channel;
+let aidArray : number[] = [0xA0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10];
+let p2 : number = 0x00;
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
+
+ // 判断设备是否支持安全单元能力
+ if (!canIUse('SystemCapability.Communication.SecureElement')) {
+ hilog.error(0x0000, 'testTag', 'secure element unavailable.');
+ return;
+ }
+ hilog.info(0x0000, 'testTag', 'secure element available.');
+ this.omaTest();
+ }
+
+ private async omaTest () {
+ // 获取服务
+ await omapi.createService().then((data) => {
+ if (data == undefined || !data.isConnected()) {
+ hilog.error(0x0000, 'testTag', 'secure element service disconnected.');
+ return;
+ }
+ seService = data;
+ hilog.info(0x0000, 'testTag', 'secure element service connected.');
+ }).catch((error: BusinessError) => {
+ hilog.error(0x0000, 'testTag', 'createService error %{public}s', JSON.stringify(error));
+ return;
+ });
+
+ // 获取读卡器
+ try {
+ seReaders = seService.getReaders();
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'getReaders error %{public}s', JSON.stringify(error));
+ }
+ if (seReaders == undefined || seReaders.length == 0) {
+ hilog.error(0x0000, 'testTag', 'no valid reader found.');
+ seService.shutdown();
+ return;
+ }
+ let reader: (omapi.Reader | undefined);
+ for (let i = 0; i < seReaders.length; ++i) {
+ let r = seReaders[i];
+ if (r.getName().includes('SIM')) {
+ reader = r;
+ break;
+ }
+ }
+ if (reader == undefined) {
+ hilog.error(0x0000, 'testTag', 'no valid sim reader.');
+ return;
+ }
+ hilog.info(0x0000, 'testTag', 'reader is %{public}s', reader?.getName());
+
+ // 获取会话
+ try {
+ seSession = reader?.openSession() as omapi.Session;
+ } catch (error) {
+ hilog.error(0x0000, 'testTag', 'openSession error %{public}s', JSON.stringify(error));
+ }
+ if (seSession == undefined) {
+ hilog.error(0x0000, 'testTag', 'seSession invalid.');
+ seService.shutdown();
+ return;
+ }
+
+ // 获取通道
+ try {
+ // 修改此处的aid值以打开逻辑通道。
+ seChannel = await seSession.openLogicalChannel(aidArray, p2);
+ } catch (exception) {
+ hilog.error(0x0000, 'testTag', 'openLogicalChannel exception %{public}s', JSON.stringify(exception));
+ }
+
+ if (seChannel == undefined) {
+ hilog.error(0x0000, 'testTag', 'seChannel invalid.');
+ return;
+ }
+
+ // 发送数据
+ let cmdData = [0x01, 0x02, 0x03, 0x04]; // 请根据需要修改原始数据。
+ try {
+ let response: number[] = await seChannel.transmit(cmdData)
+ hilog.info(0x0000, 'testTag', 'seChannel.transmit() response = %{public}s.', JSON.stringify(response));
+ } catch (exception) {
+ hilog.error(0x0000, 'testTag', 'seChannel.transmit() exception = %{public}s.', JSON.stringify(exception));
+ }
+
+ // 关闭通道。必须确保最后关闭通道。
+ try {
+ seChannel.close();
+ } catch (exception) {
+ hilog.error(0x0000, 'testTag', 'seChannel.close() exception = %{public}s.', JSON.stringify(exception));
+ }
+
+ }
+}
+// [End access_security_unit]
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/ConnectivityKit/NFC/SecureElement/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..b1e212947256c5533c7b06285a597c94f840a6e3
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
@@ -0,0 +1,27 @@
+/*
+ * 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';
+
+export default class EntryBackupAbility extends BackupExtensionAbility {
+ async onBackup() {
+ hilog.info(0x0000, 'testTag', 'onBackup ok');
+ }
+
+ async onRestore(bundleVersion: BundleVersion) {
+ hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/main/ets/pages/Index.ets b/ConnectivityKit/NFC/SecureElement/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7534811edebd35404f010e92b0a312b9dbdd3e2a
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+@Entry
+@Component
+struct Index {
+ @State message: string = 'SecureElement';
+
+ build() {
+ RelativeContainer() {
+ Text(this.message)
+ .id('SecureElement')
+ .fontSize(50)
+ .fontWeight(FontWeight.Bold)
+ .alignRules({
+ center: { anchor: '__container__', align: VerticalAlign.Center },
+ middle: { anchor: '__container__', align: HorizontalAlign.Center }
+ })
+ }
+ .height('100%')
+ .width('100%')
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/main/module.json5 b/ConnectivityKit/NFC/SecureElement/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..4144486d1af4c03b0d767cce1cda86fc0d697f91
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/main/module.json5
@@ -0,0 +1,66 @@
+/*
+ * 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"
+ ],
+ "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/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/element/color.json b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/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/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/element/string.json b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..7f9c2173321d80ccb6d42ebf0e748a88209d63b2
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "SecureElement"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/background.png b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d
Binary files /dev/null and b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/background.png differ
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/foreground.png b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902
Binary files /dev/null and b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/foreground.png differ
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/layered_image.json b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/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/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/startIcon.png b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/media/startIcon.png differ
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/profile/backup_config.json b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/profile/backup_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/profile/backup_config.json
@@ -0,0 +1,3 @@
+{
+ "allowToBackupRestore": true
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/profile/main_pages.json b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/dark/element/color.json b/ConnectivityKit/NFC/SecureElement/entry/src/main/resources/dark/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/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/ConnectivityKit/NFC/SecureElement/entry/src/mock/mock-config.json5 b/ConnectivityKit/NFC/SecureElement/entry/src/mock/mock-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..b9a78e201535765168a92d3543c690273ecdc019
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/mock/mock-config.json5
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+{
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/ohosTest/ets/test/Ability.test.ets b/ConnectivityKit/NFC/SecureElement/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..8630f0493ae875a1eb88b53bbaf9de8a2c7c359f
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+ * 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/ConnectivityKit/NFC/SecureElement/entry/src/ohosTest/ets/test/List.test.ets b/ConnectivityKit/NFC/SecureElement/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f40533d1374f4046f8af1e7df6aa90157cb361d8
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/ohosTest/ets/test/List.test.ets
@@ -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 abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/ohosTest/module.json5 b/ConnectivityKit/NFC/SecureElement/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c3fd9dda3040d888d9d8b0b62bcb5d3b6fbeb614
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/ohosTest/module.json5
@@ -0,0 +1,27 @@
+/*
+ * 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/ConnectivityKit/NFC/SecureElement/entry/src/test/List.test.ets b/ConnectivityKit/NFC/SecureElement/entry/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f1186b1f53c3a70930921c5dbd1417332bec56c9
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/test/List.test.ets
@@ -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 localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/entry/src/test/LocalUnit.test.ets b/ConnectivityKit/NFC/SecureElement/entry/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7fc57c77dbf76d8df08a2b802a55b948e3fcf968
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/entry/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+ * 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/ConnectivityKit/NFC/SecureElement/hvigor/hvigor-config.json5 b/ConnectivityKit/NFC/SecureElement/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..1e473e424320d4e68b16737b289f5c851bb19d36
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/hvigor/hvigor-config.json5
@@ -0,0 +1,22 @@
+{
+ "modelVersion": "5.0.1",
+ "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/ConnectivityKit/NFC/SecureElement/hvigorfile.ts b/ConnectivityKit/NFC/SecureElement/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/ConnectivityKit/NFC/SecureElement/oh-package.json5 b/ConnectivityKit/NFC/SecureElement/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..14655ea1c07e1b7b8b8eb3d9f6813577b90f6a0f
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.1",
+ "description": "Please describe the basic information.",
+ "dependencies": {
+ },
+ "devDependencies": {
+ "@ohos/hypium": "1.0.19",
+ "@ohos/hamock": "1.0.0"
+ }
+}
diff --git a/ConnectivityKit/NFC/SecureElement/ohosTest.md b/ConnectivityKit/NFC/SecureElement/ohosTest.md
new file mode 100644
index 0000000000000000000000000000000000000000..f3c71387def5a32481b0aba1d60b71e7c4d08f64
--- /dev/null
+++ b/ConnectivityKit/NFC/SecureElement/ohosTest.md
@@ -0,0 +1,7 @@
+# 安全单元访问示例代码工程化
+
+## 用例表
+
+| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
+| ----------------- | ------------ | ----------------- | ------------------------|--------- | -------- |
+| NFC功能正常启动 | 设备支持NFC | 启动应用 | 应用停留在启动界面,输出预期日志 |否 | Pass |
\ No newline at end of file
diff --git a/ConnectivityKit/NFC/SecureElement/screenshots/image.jpeg b/ConnectivityKit/NFC/SecureElement/screenshots/image.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..9129c2132ae22b21a5134cd75d5433dace7e2234
Binary files /dev/null and b/ConnectivityKit/NFC/SecureElement/screenshots/image.jpeg differ
diff --git a/ConnectivityKit/Wlan/.gitignore b/ConnectivityKit/Wlan/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..6ff06d2ba5623824e833c16a55976cec28edb64e
--- /dev/null
+++ b/ConnectivityKit/Wlan/.gitignore
@@ -0,0 +1,13 @@
+/node_modules
+/local.properties
+/.idea
+**/build
+/.hvigor
+.cxx
+/.clangd
+/.clang-format
+/.clang-tidy
+/package-lock.json
+/entry/package-lock.json
+**/oh_modules
+**/oh-package-lock.json5
diff --git a/ConnectivityKit/Wlan/AppScope/app.json5 b/ConnectivityKit/Wlan/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e0496f6b4e7a904203f9287389efebd1bef41e1d
--- /dev/null
+++ b/ConnectivityKit/Wlan/AppScope/app.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.
+*/
+
+{
+ "app": {
+ "bundleName": "com.samples.wlan",
+ "vendor": "samples",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name",
+ "distributedNotificationEnabled": true
+ }
+}
diff --git a/ConnectivityKit/Wlan/AppScope/resources/base/element/string.json b/ConnectivityKit/Wlan/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..561c62fe0815ac0ebb4f356e0b8b261b504c64be
--- /dev/null
+++ b/ConnectivityKit/Wlan/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "Wlan"
+ }
+ ]
+}
diff --git a/ConnectivityKit/Wlan/AppScope/resources/base/media/app_icon.png b/ConnectivityKit/Wlan/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3
Binary files /dev/null and b/ConnectivityKit/Wlan/AppScope/resources/base/media/app_icon.png differ
diff --git a/ConnectivityKit/Wlan/README_zh.md b/ConnectivityKit/Wlan/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..25811dced647943900b63e1ef682d6141a4121f2
--- /dev/null
+++ b/ConnectivityKit/Wlan/README_zh.md
@@ -0,0 +1,89 @@
+# P2P模式开发指南
+
+### 介绍
+
+本示例通过将[Connectivity Kit指南文档](https://gitee.com/openharmony/docs/tree/master/zh-cn/application-dev/connectivity)中各场景的开发示例,展示在工程中,帮助开发者更好地理解ArkUI提供的组件及组件属性并合理使用。该工程中展示的代码详细描述可查如下链接:
+[P2P模式开发](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/wlan/p2p-development-guide.md)。
+[Wi-Fi扫描](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/wlan/scan-development-guide.md)。
+[STA模式开发](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/wlan/sta-development-guide.md)。
+
+### 效果预览
+|应用界面|
+|主页 |建议网络连接 | WiFi列表 |
+|---------------------------------------------|---------------------------------------|-----------------------------------------|
+||||
+|P2p测试 |P2p连接 | 创建群组 |
+|---------------------------------------------|---------------------------------------|-----------------------------------------|
+||||
+
+
+|获取真实BSSID授权 |
+|-----------------------------------------|
+| |
+
+### 使用说明
+
+1. 启动应用后会判断WLAN是否激活,如果是激活状态,点击wifi列表会扫描并展示可用WiFi列表;
+2. 点击首页建议击网络连接,填写可选参数,连接建议网络;
+3. 点击首页P2p测试,进行P2p连接和创建群组场景测试。
+
+### 工程目录
+```
+entry/src/main/ets/
+|---component
+| |---P2pView.ets // P2p列表详情页
+| |---TitleBar.ets // 页面头部组件
+| |---WifiView.ets // wifi列表详情页
+|---entryability
+| |---EntryAbility.ets // 应用入口,在这里请求相关权限和进入首页
+|---pages
+| |---Index.ets // 首页
+| |---AvailableWifi.ets // 热点扫描信息列表
+| |---WifiConnect.ets // 建议网络连接
+| |---P2pTest.ets // P2p测试场景
+| |---AvailableP2p.ets // P2p扫描信息列表
+| |---P2pSetting.ets // 创建群组
+```
+
+### 具体实现
+
+* 开始测试前需打开设备WiFi,
+首页:[Index.ets](entry/src/main/ets/pages/Index.ets)。
+
+* 建议网络连接:[WifiConnect.ets](entry/src/main/ets/pages/WifiConnect.ets),根据提示填写参数信息通过connectwifi()发起连接。
+* wifi的扫描功能:首页点击wifi列表,在[AvailableWifi.ets](entry/src/main/ets/pages/AvailableWifi.ets) 通过(entry/src/main/ets/component/WifiView.ets)显示每一个WiFi信息,调用getScanInfos()获取扫描结果,调用定时器每3s获取一次。
+* P2p场景测试:
+ *p2p连接:[AvailableP2p.ets.ets](entry/src/main/ets/pages/AvailableP2p.ets) 通过(entry/src/main/ets/component/P2pView.ets)显示每一个P2p信息,点击列表信息通过connectP2p()函数发起连接。
+ *创建P2P群组:在[P2pSetting.ets](entry/src/main/ets/pages/P2pSetting.ets) 填写参数信息通过createGroup()来创建群组。
+### 相关权限
+
+[ohos.permission.GET_WIFI_INFO](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all.md#ohospermissionget_wifi_info)
+
+[ohos.permission.SET_WIFI_INFO](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all.md#ohospermissionset_wifi_info)
+
+[ohos.permission.GET_WIFI_PEERS_MAC](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/restricted-permissions.md#ohospermissionget_wifi_peers_mac)
+### 依赖
+
+不涉及。
+
+### 约束与限制
+
+1. 本示例仅支持标准系统上运行,支持设备:华为手机。
+
+2. 本示例需要使用DevEco Studio 6.0.0 及以上版本才可编译运行。
+
+3. 本示例已适配API version 20版本SDK,本示例需要使用@ohos.wifiManager系统权限的系统接口。使用Full SDK时需要手动从镜像站点获取,并在DevEco Studio中替换,具体操作可参考[替换指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/faqs/full-sdk-switch-guide.md/) 。
+
+4. 本示例需要使用ohos.permission.GET_WIFI_INFO、ohos.permission.SET_WIFI_INFO的权限为system_grant级别、ohos.permission.GET_WIFI_PEERS_MAC的权限为system_basic级别(相关权限级别可通过[权限定义列表](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all.md) 查看),需要手动配置对应级别的权限签名。
+
+### 下载
+
+如需单独下载本工程,执行如下命令:
+
+```
+git init
+git config core.sparsecheckout true
+echo ConnectivityKit/Wlan > .git/info/sparse-checkout
+git remote add origin https://gitee.com/harmonyos_samples/guide-snippets.git
+git pull origin master
+```
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/build-profile.json5 b/ConnectivityKit/Wlan/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..05d4900f0cdd772b39ebd218eaa7eea491e7b352
--- /dev/null
+++ b/ConnectivityKit/Wlan/build-profile.json5
@@ -0,0 +1,44 @@
+/*
+ * 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": {
+ "products": [
+ {
+ "name": "default",
+ "bundleName": "com.samples.wlan",
+ "signingConfig": "default",
+ "compatibleSdkVersion": "6.0.0(20)",
+ "targetSdkVersion": "6.0.0(20)",
+ "runtimeOS": "HarmonyOS",
+ }
+ ],
+ "signingConfigs": []
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/code-linter.json5 b/ConnectivityKit/Wlan/code-linter.json5
new file mode 100644
index 0000000000000000000000000000000000000000..4bacc9e298b707e25577dbcef9e1c7c698880ecf
--- /dev/null
+++ b/ConnectivityKit/Wlan/code-linter.json5
@@ -0,0 +1,35 @@
+/*
+ * 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": {
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/.gitignore b/ConnectivityKit/Wlan/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e5d65b11d36650f2d90d25facccfec45a382e931
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/.gitignore
@@ -0,0 +1,4 @@
+/node_modules
+/.preview
+/build
+/.cxx
diff --git a/ConnectivityKit/Wlan/entry/build-profile.json5 b/ConnectivityKit/Wlan/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..a2d361ac657af1056e243fd093bc2d16bf8089b6
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/build-profile.json5
@@ -0,0 +1,28 @@
+/*
+ * 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": {
+ },
+ "targets": [
+ {
+ "name": "default"
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/hvigorfile.ts b/ConnectivityKit/Wlan/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..94b039ca97168c2ece09f5559b156db2a19d82e1
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/hvigorfile.ts
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+export { hapTasks } from '@ohos/hvigor-ohos-plugin'
diff --git a/ConnectivityKit/Wlan/entry/obfuscation-rules.txt b/ConnectivityKit/Wlan/entry/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f722a31cae22b03ec6440126cb942bc1faa09884
--- /dev/null
+++ b/ConnectivityKit/Wlan/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 hilog.info* 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/ConnectivityKit/Wlan/entry/oh-package.json5 b/ConnectivityKit/Wlan/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..73bef04acf22052af438cef69617a83c0d269719
--- /dev/null
+++ b/ConnectivityKit/Wlan/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.
+ */
+
+{
+ "license": "ISC",
+ "devDependencies": {},
+ "name": "entry",
+ "description": "example description",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {}
+}
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/component/P2pView.ets b/ConnectivityKit/Wlan/entry/src/main/ets/component/P2pView.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0762f36fa11abf2b5c11d5c2e1de1a9c082193fe
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/component/P2pView.ets
@@ -0,0 +1,86 @@
+/**
+ * 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 wifi from '@ohos.wifiManager';
+import hilog from '../model/Logger'
+
+/**
+ * P2pView Component of p2p test
+ */
+const TAG = 'wifiTestApp [P2pView]'
+
+@Component
+export struct P2pView {
+ private p2p!: wifi.WifiP2pDevice
+ private securityString: Resource = $r('app.string.useful')
+ private p2pConnectState: number = 0
+ @StorageLink('p2pLinkedDeviceName') p2pLinkedDeviceName: string = ''
+ @State isLock: boolean = true
+
+ aboutToAppear() {
+ hilog.info(TAG , `aboutToAppear ${ JSON.stringify(this.p2p) }`)
+
+ this.p2pConnectState = AppStorage.get('p2pConnectState') !
+ this.p2pLinkedDeviceName = AppStorage.get('p2pLinkedDeviceName') !
+ if ( this.p2p ) {
+ hilog.info(TAG , 'this.p2p is true');
+ } else {
+ hilog.info(TAG , 'this.p2p is false');
+ }
+ }
+
+ build() {
+ Row() {
+ Column() {
+ if ( this.p2p ) {
+ if ( this.p2p.deviceName ) {
+ Text(this.p2p.deviceName)
+ .fontSize(20)
+ .width('100%')
+ }
+ }
+ if ( this.p2pConnectState == 1 && this.p2pLinkedDeviceName == this.p2p.deviceName ) {
+ Text($r('app.string.p2pConnected'))
+ .fontSize(18)
+ .fontColor(Color.Gray)
+ .width('100%')
+ } else {
+ Text($r('app.string.useful'))
+ .fontSize(18)
+ .fontColor(Color.Gray)
+ .width('100%')
+ }
+ }
+ .layoutWeight(1)
+
+ Stack({ alignContent : Alignment.BottomEnd }) {
+ Image($r('app.media.wifi'))
+ .height(30).width(30)
+ .objectFit(ImageFit.Contain)
+ if ( this.isLock ) {
+ Image($r('app.media.lock'))
+ .objectFit(ImageFit.Contain)
+ .width(15).height(15)
+ }
+ }
+ .width(40).height(40)
+ .margin({ right : 10 })
+ }
+ .backgroundColor(Color.White)
+ .width('100%')
+ .padding(10)
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/component/TitleBar.ets b/ConnectivityKit/Wlan/entry/src/main/ets/component/TitleBar.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7db1022c4ad667775de2c56df899b286a364944d
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/component/TitleBar.ets
@@ -0,0 +1,43 @@
+/*
+ * 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 router from '@ohos.router'
+
+@Component
+export struct TitleBar {
+ build() {
+ Row() {
+ Text($r('app.string.EntryAbility_label'))
+ .fontColor(Color.White)
+ .fontSize(25)
+ .layoutWeight(1)
+
+ Button() {
+ Image($r('app.media.about'))
+ .size({ width: 60, height: '95%' })
+ .objectFit(ImageFit.Contain)
+ }
+ .id('about')
+ .type(ButtonType.Normal)
+ .height('90%')
+ .backgroundColor($r('app.color.button_color'))
+ }
+ .width('100%')
+ .height('8%')
+ .constraintSize({ minHeight: 50 })
+ .padding({ left: 15 })
+ .backgroundColor($r('app.color.button_color'))
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/component/WifiView.ets b/ConnectivityKit/Wlan/entry/src/main/ets/component/WifiView.ets
new file mode 100644
index 0000000000000000000000000000000000000000..d131f13061f2f76d74098c2ef6f0c20c219f9385
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/component/WifiView.ets
@@ -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.
+ */
+
+import hilog from '../model/Logger'
+import wifi from '@ohos.wifiManager'
+
+const TAG: string = 'WifiView'
+
+@Component
+export struct WifiView {
+ private wifi: wifi.WifiScanInfo | null = null;
+ private securityString: Resource = $r('app.string.encryption')
+ @State isLock: boolean = true
+
+ aboutToAppear() {
+ hilog.debug(TAG, `aboutToAppear ${JSON.stringify(this.wifi)}`)
+ if (this.wifi) {
+ if (this.wifi.securityType) {
+ if ((this.wifi.securityType as number) === 0 || this.wifi.securityType === 1) {
+ this.securityString = $r('app.string.open')
+ this.isLock = false
+ }
+ }
+ }
+ }
+
+ build() {
+ Row() {
+ Column() {
+ if (this.wifi) {
+ if (this.wifi.ssid) {
+ Text(this.wifi.ssid)
+ .fontSize(20)
+ .width('100%')
+ }
+ }
+ Text(this.securityString)
+ .fontSize(18)
+ .fontColor(Color.Gray)
+ .width('100%')
+ }
+ .layoutWeight(1)
+
+ Stack({ alignContent: Alignment.BottomEnd }) {
+ Image($r('app.media.wifi'))
+ .height(30)
+ .width(30)
+ .objectFit(ImageFit.Contain)
+ if (this.isLock) {
+ Image($r('app.media.lock'))
+ .objectFit(ImageFit.Contain)
+ .width(15)
+ .height(15)
+ }
+ }
+ .width(40)
+ .height(40)
+ .margin({ right: 10 })
+ }
+ .backgroundColor(Color.White)
+ .width('100%')
+ .padding(10)
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/entryability/EntryAbility.ets b/ConnectivityKit/Wlan/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f09ffa4749ac2516f3fe0b40c2e75cc950a8470e
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,64 @@
+/*
+ * 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 '../model/Logger'
+import UIAbility from '@ohos.app.ability.UIAbility';
+import Window from '@ohos.window'
+import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
+import type { Permissions } from '@ohos.abilityAccessCtrl';
+import Want from '@ohos.app.ability.Want';
+import AbilityConstant from '@ohos.app.ability.AbilityConstant';
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
+ hilog.info('Ability onCreate')
+ const PERMISSIONS: Array = ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'];
+ try {
+ abilityAccessCtrl.createAtManager().requestPermissionsFromUser(this.context, PERMISSIONS);
+ } catch (err) {
+ hilog.info(`catch err->${JSON.stringify(err)}`);
+ }
+ }
+
+ onDestroy() {
+ hilog.info('Ability onDestroy')
+ }
+
+ onWindowStageCreate(windowStage: Window.WindowStage) {
+ hilog.info('Ability onWindowStageCreate')
+ windowStage.loadContent('pages/Index', (err, data) => {
+ if (err.code) {
+ hilog.error(`Failed to load the content. Cause: ${JSON.stringify(err)}`)
+ return
+ }
+ hilog.info(`Succeeded in loading the content. Data: ${JSON.stringify(data)}`)
+ })
+ }
+
+ onWindowStageDestroy() {
+ // Main window is destroyed, release UI related resources
+ hilog.info('Ability onWindowStageDestroy')
+ }
+
+ onForeground() {
+ // Ability has brought to foreground
+ hilog.info('Ability onForeground')
+ }
+
+ onBackground() {
+ // Ability has back to background
+ hilog.info('Ability onBackground')
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/model/Logger.ets b/ConnectivityKit/Wlan/entry/src/main/ets/model/Logger.ets
new file mode 100644
index 0000000000000000000000000000000000000000..9c1934088d95910eece5e056d78eedcec2946977
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/model/Logger.ets
@@ -0,0 +1,53 @@
+/*
+ * 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';
+
+class Logger {
+ private domain: number;
+ private prefix: string;
+ private format: string = '%{public}s';
+
+ constructor(prefix: string) {
+ this.prefix = prefix;
+ this.domain = 0x0001; // 设置域名
+ }
+
+ debug(...args: string[]) {
+ hilog.debug(this.domain, this.prefix, this.format, args);
+ }
+
+ info(...args: string[]) {
+ hilog.info(this.domain, this.prefix, this.format, args);
+ }
+
+ warn(...args: string[]) {
+ hilog.warn(this.domain, this.prefix, this.format, args);
+ }
+
+ error(...args: string[]) {
+ hilog.error(this.domain, this.prefix, this.format, args);
+ }
+
+ fatal(...args: string[]) {
+ hilog.fatal(this.domain, this.prefix, this.format, args);
+ }
+
+ isLoggable(level: number) {
+ hilog.isLoggable(this.domain, this.prefix, level);
+ }
+}
+
+export default new Logger('[Sample_NetConnection_Exploitation]');
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/pages/AvailableP2p.ets b/ConnectivityKit/Wlan/entry/src/main/ets/pages/AvailableP2p.ets
new file mode 100644
index 0000000000000000000000000000000000000000..9a4606a8902bf9d424fe6dd3f92e68334464be9a
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/pages/AvailableP2p.ets
@@ -0,0 +1,138 @@
+/**
+ * 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 promptAction from '@ohos.promptAction';
+import hilog from '../model/Logger';
+import wifi from '@ohos.wifiManager';
+import { P2pView } from '../component/P2pView';
+
+const TAG = 'availableP2p';
+
+/**
+ * available p2p page of WiFi test
+ */
+@Entry
+@Component
+struct WifiConnect {
+ @State p2pList: Array = []
+ @State p2pLinkedInfo: wifi.WifiP2pLinkedInfo | null = null;
+ private selectIndex: number = - 1
+ @State isSwitchOn: boolean = false;
+
+ addListener() {
+ // 连接状态改变时,修改连接信息
+ hilog.info(TAG, 'addListener');
+ wifi.on('p2pConnectionChange', async wifiP2pLinkedInfo => {
+ hilog.info('p2p connection change receive event: ' + JSON.stringify(wifiP2pLinkedInfo));
+ this.p2pLinkedInfo = wifiP2pLinkedInfo
+ let connectState = wifiP2pLinkedInfo.connectState
+ let p2pConnectionMessage = ''
+ switch ( connectState ) {
+ case 0:
+ p2pConnectionMessage = 'DISCONNECTED!';
+ this.p2pLinkedInfo = null
+ promptAction.showToast({ message : 'connect disabled' })
+ break;
+ case 1:
+ p2pConnectionMessage = 'CONNECTED!';
+ promptAction.showToast({ message : 'connect success' })
+ let curGp = await wifi.getCurrentGroup()
+ AppStorage.setOrCreate('p2pLinkedDeviceName', curGp.groupName)
+ break;
+ default:
+ p2pConnectionMessage = '未知状态';
+ break;
+ }
+ AppStorage.setOrCreate('p2pConnectState', connectState)
+ })
+
+ wifi.on('p2pPeerDeviceChange', async (_: wifi.WifiP2pDevice[]) => {
+ hilog.info(TAG, 'p2pPeerDeviceChange:', JSON.stringify(_))
+ try {
+ let devices = await wifi.getP2pPeerDevices()
+ this.p2pList = devices
+ } catch (e) {
+ hilog.info(JSON.stringify(e))
+ }
+ })
+ }
+
+ aboutToAppear() {
+ // 如果wifi是开的,就记录下状态,然后扫描p2p设备,并获取连接信息
+ if (!wifi.isWifiActive()) {
+ promptAction.showToast({ message : 'place active wifi' })
+ return
+ }
+ this.isSwitchOn = true;
+ wifi.startDiscoverDevices()
+ this.addListener();
+ }
+
+ aboutToDisappear() {
+ wifi.off('p2pPeerDeviceChange')
+ wifi.off('p2pConnectionChange')
+ }
+
+
+ connectP2p(p2pScanInfo: wifi.WifiP2pDevice) {
+ promptAction.showToast({ message : 'connect to device' })
+ hilog.info(TAG , `connect deviceAddress=${ p2pScanInfo.deviceAddress }`)
+ hilog.info(TAG , `p2pScanInfo:` + JSON.stringify(p2pScanInfo))
+ let config: wifi.WifiP2PConfig = {
+ deviceAddress : p2pScanInfo.deviceAddress,
+ netId : - 2 ,
+ deviceAddressType: 1,
+ passphrase : '' ,
+ groupName : '' ,
+ goBand : 0
+ }
+ wifi.p2pConnect(config)
+ }
+
+
+ build() {
+ Column() {
+ Row() {
+ Text($r('app.string.p2p_available'))
+ .fontSize(22)
+ .fontWeight(FontWeight.Bold)
+ .height(40)
+ }
+ .width('100%')
+ .padding({ left: 16, right: 16 })
+
+ List({ space: 5 }) {
+ ForEach(this.p2pList , (item: wifi.WifiP2pDevice , index: number) => {
+ ListItem() {
+ P2pView({ p2p : item })
+ }
+ .onClick(() => {
+ hilog.info(TAG , 'p2p click')
+ this.selectIndex = index
+ if ( this.p2pLinkedInfo !== null && this.p2pLinkedInfo.connectState == 1 ) {
+ promptAction.showToast({ message : 'this p2p is connected' })
+ return
+ }
+ this.connectP2p(item)
+ })
+ } , (item: wifi.WifiP2pDevice) => JSON.stringify(item));
+ }
+ .layoutWeight(1)
+ .divider({ strokeWidth : 1 , color : Color.Gray , startMargin : 10 , endMargin : 10 })
+ .margin(10)
+ }
+ .margin({ top : 15 , bottom : 100 })
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/pages/AvailableWifi.ets b/ConnectivityKit/Wlan/entry/src/main/ets/pages/AvailableWifi.ets
new file mode 100644
index 0000000000000000000000000000000000000000..288377b09672653f5206b8be523fe5c35ab4185b
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/pages/AvailableWifi.ets
@@ -0,0 +1,126 @@
+/*
+ * 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 '../model/Logger'
+import { WifiView } from '../component/WifiView'
+import wifi from '@ohos.wifiManager'
+
+const TAG = 'AvailableWiFi'
+let self: AvailableWifi | null = null;
+@Entry
+@Component
+export struct AvailableWifi {
+ @State wifilist: Array = []
+ @State wifilisttest: Array = []
+ @State isSwitchOn: boolean = false;
+ private linkedInfo: wifi.WifiLinkedInfo | null = null;
+ @State isLinked: boolean = false;
+
+ // 扫描wifi
+ async getScanInfos() {
+ // 不停地扫描wifi
+ let result: wifi.WifiScanInfo[] = await wifi.getScanInfoList();
+
+ if (this.isSwitchOn) {
+ setTimeout(async () => {
+ this.wifilist = result
+ await this.getScanInfos();
+ }, 3000)
+ }
+ }
+
+ addListener() {
+ // 连接状态改变时,修改连接信息
+ wifi.on('wifiConnectionChange', async state => {
+ hilog.info(TAG, `wifiConnectionChange: ${state}`);
+ await this.getLinkedInfo();
+ })
+ // wifi状态改变时,先清空wifi列表,然后判断是否是开启状态,如果是就扫描
+ wifi.on('wifiStateChange', state => {
+ hilog.info(TAG, `wifiStateLisener state: ${state}`);
+ if (state === 1) { // 1: wifi is enable, 0:wifi is disable
+ this.isSwitchOn = true;
+ this.getScanInfos();
+ }
+ if (state === 0) { // 1: wifi is enable, 0:wifi is disable
+ this.isSwitchOn = false;
+ }
+ })
+ }
+
+ async getLinkedInfo() {
+ try {
+ let wifiLinkedInfo = await wifi.getLinkedInfo();
+ if (wifiLinkedInfo === null || wifiLinkedInfo.bssid === '') {
+ this.isLinked = false;
+ this.linkedInfo = null;
+ return;
+ }
+ this.isLinked = true;
+ this.linkedInfo = wifiLinkedInfo;
+ } catch (err) {
+ hilog.info(`getLinkedInfo failed err is ${JSON.stringify(err)}`);
+ }
+ }
+
+ aboutToAppear() {
+ if (wifi.isWifiActive()) {
+ hilog.info(TAG, 'wifi is active');
+ this.isSwitchOn = true;
+ this.getScanInfos();
+ this.getLinkedInfo();
+ }
+ hilog.info(TAG, 'wifi is disabled');
+ // 启动监听
+ this.addListener();
+ }
+
+ aboutToDisappear() {
+ wifi.off('wifiConnectionChange');
+ wifi.off('wifiStateChange');
+ }
+
+ build() {
+ Column() {
+ Row() {
+ Text($r('app.string.wlan'))
+ .fontSize(22)
+ .fontWeight(FontWeight.Bold)
+ .height(40)
+ Column() {
+ Toggle({ type: ToggleType.Switch, isOn: this.isSwitchOn })
+ .id('switch')
+ .onChange((isOn: boolean) => {
+ hilog.info(`wifi swtich is: ${isOn}`);
+ this.wifilist = this.wifilisttest
+ })
+ }
+ }
+ .width('100%')
+ .padding({ left: 16, right: 16 })
+
+ List({ space: 5 }) {
+ ForEach(this.isSwitchOn ? this.wifilist : this.wifilisttest, (wifiItem: wifi.WifiScanInfo) => {
+ ListItem() {
+ WifiView({ wifi: wifiItem })
+ }
+ }, (wifiItem: wifi.WifiScanInfo) => JSON.stringify(wifiItem));
+ }
+ }
+ .width('100%')
+ .height('100%')
+ .backgroundColor($r('app.color.index_bg'))
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/pages/Index.ets b/ConnectivityKit/Wlan/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..35bc487e9a01002278ae2b4338d6ab6512f329a6
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,74 @@
+/*
+ * 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 '../model/Logger';
+import { TitleBar } from '../component/TitleBar';
+import router from '@ohos.router'
+
+const TAG = 'Index';
+
+@Entry
+@Component
+struct Index {
+ build() {
+ Column({ space: 5 }) {
+ TitleBar()
+ Text($r('app.string.wifi_List'))
+ .fontColor(Color.Black)
+ .fontSize(20)
+ .layoutWeight(1)
+ .constraintSize({ minHeight: 50 })
+ .padding({ left: 15 })
+ .borderRadius(5)
+ .width('100%')
+ // .fontColor($r('app.color.text_color'))
+ .backgroundColor($r('app.color.button_color2'))
+ .onClick(() => {
+ router.pushUrl({ url: 'pages/AvailableWifi' })
+ })
+
+ Text($r('app.string.wifi_Connect'))
+ .fontColor(Color.Black)
+ .fontSize(20)
+ .layoutWeight(1)
+ .constraintSize({ minHeight: 50 })
+ .padding({ left: 15 })
+ .borderRadius(5)
+ .width('100%')
+ // .fontColor($r('app.color.text_color'))
+ .backgroundColor($r('app.color.text_color'))
+ .onClick(() => {
+ router.pushUrl({ url: 'pages/WifiConnect' })
+ })
+
+ Text($r('app.string.p2p_test'))
+ .fontColor(Color.Black)
+ .fontSize(20)
+ .layoutWeight(1)
+ .constraintSize({ minHeight: 50 })
+ .padding({ left: 15 })
+ .borderRadius(5)
+ .width('100%')
+ // .fontColor($r('app.color.text_color'))
+ .backgroundColor($r('app.color.index_background'))
+ .onClick(() => {
+ router.pushUrl({ url: 'pages/P2pTest' })
+ })
+ }
+ .width('100%')
+ .height('8%')
+ .backgroundColor($r('app.color.index_bg'))
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/pages/P2pSetting.ets b/ConnectivityKit/Wlan/entry/src/main/ets/pages/P2pSetting.ets
new file mode 100644
index 0000000000000000000000000000000000000000..2a9393ac3f16c600547c9aadaa65023686dc0815
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/pages/P2pSetting.ets
@@ -0,0 +1,180 @@
+/*
+ * 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 '../model/Logger';
+import router from '@ohos.router'
+import wifi from '@ohos.wifiManager';
+import promptAction from '@ohos.promptAction'
+
+const TAG = 'p2pSetting'
+
+@Entry
+@Component
+struct p2pSetting {
+ @State deviceAddress: string = '';
+ @State netId: number = - 2;
+ @State passphrase: string = '';
+ @State groupName: string = ''
+ @State goBand: number = 0;
+
+ aboutToAppear() {
+ AppStorage.setOrCreate('deviceAddress' , this.deviceAddress)
+ AppStorage.setOrCreate('netId' , this.netId)
+ AppStorage.setOrCreate('passphrase' , this.passphrase)
+ AppStorage.setOrCreate('groupName' , this.groupName)
+ AppStorage.setOrCreate('goBand' , this.goBand)
+ }
+
+
+ async createGroup() {
+ try {
+ let deviceInfo = await wifi.getP2pLocalDevice()
+ let config:wifi.WifiP2PConfig = {
+ deviceAddress: deviceInfo.deviceAddress,
+ netId: this.netId,
+ passphrase: this.passphrase,
+ groupName: this.groupName,
+ goBand: this.goBand,
+ }
+ hilog.info(`deviceAddress: ${config.deviceAddress}, netId: ${config.netId}, pwd: ${config.passphrase}, gpname: ${config.groupName}, goBand: ${config.goBand}`)
+ wifi.createGroup(config)
+ promptAction.showToast({ message : 'createGroup success' })
+ } catch (e) {
+ hilog.info(TAG, `createGroup Error: ${JSON.stringify(e)}`)
+ }
+ }
+
+ build() {
+ Column() {
+ Row() {
+ Text('deviceAddress:').fontSize(16).width(120)
+ TextInput({ text : this.deviceAddress , placeholder : 'input peripheral deviceId.' })
+ .fontSize('15vp')
+ .onChange((strInput: string) => {
+ this.deviceAddress = strInput;
+ //判断合法性
+ if ( strInput.length >= 1 ) {
+ AppStorage.setOrCreate('deviceAddress' , this.deviceAddress);
+ }
+ })
+ .width('80%')
+ .borderRadius(1)
+ }
+ .backgroundColor($r('app.color.moon'))
+ .padding(5)
+ .justifyContent(FlexAlign.Start)
+ .alignItems(VerticalAlign.Center)
+
+ Column() {
+ Stack().height('0.25vp').backgroundColor('#000000');
+ Column() {
+ Row() {
+ Text('netId:').fontSize(15).width(60);
+ TextInput({ text : this.netId.toString() , placeholder : '-2' })
+ .fontSize('15vp')
+ .onChange((strInput: string) => {
+ this.netId = parseInt(strInput);
+ //判断合法性
+ if ( strInput.length >= 1 ) {
+ AppStorage.setOrCreate('netId' , this.netId);
+ }
+ })
+ .width('80%')
+ .borderRadius(1)
+ }
+ .padding(5)
+ .justifyContent(FlexAlign.Start)
+ .alignItems(VerticalAlign.Center)
+ .backgroundColor($r('app.color.spring'))
+
+ Row() {
+ Text('passphrase:').fontSize(15).width(100);
+ TextInput({ text : this.passphrase , placeholder : 'input passphrase' })
+ .fontSize('15vp')
+ .onChange((strInput: string) => {
+ this.passphrase = strInput;
+ if ( strInput.length >= 1 ) {
+ AppStorage.setOrCreate('passphrase' , this.passphrase);
+ }
+ })
+ .width('80%')
+ .borderRadius(1)
+ }
+ .backgroundColor($r('app.color.spring'))
+ .padding(5)
+ .justifyContent(FlexAlign.Start)
+ .alignItems(VerticalAlign.Center)
+
+ Row() {
+ Text('groupName:').fontSize(15).width(100);
+ TextInput({ text : this.groupName , placeholder : 'testGroup' })
+ .fontSize('15vp')
+ .onChange((strInput: string) => {
+ this.groupName = strInput;
+ if ( strInput.length >= 1 ) {
+ AppStorage.setOrCreate('groupName' , this.groupName);
+ }
+ })
+ .width('80%')
+ .borderRadius(1)
+ }
+ .backgroundColor($r('app.color.spring'))
+ .padding(5)
+ .justifyContent(FlexAlign.Start)
+ .alignItems(VerticalAlign.Center)
+
+ Row() {
+ Text('goBand:').fontSize(15).width(80);
+ TextInput({ text : this.goBand.toString() , placeholder : '0' })
+ .fontSize('15vp')
+ .onChange((strInput: string) => {
+ this.goBand = Number(strInput);
+ if ( strInput.length >= 1 ) {
+ AppStorage.setOrCreate('goBand' , this.goBand);
+ }
+ })
+ .width('80%')
+ .borderRadius(1)
+ }
+ .backgroundColor($r('app.color.spring'))
+ .padding(5)
+ .justifyContent(FlexAlign.Start)
+ .alignItems(VerticalAlign.Center)
+
+ }
+
+ Stack().height('0.25vp').backgroundColor('#000000');
+ }
+
+ Row() {
+ Button($r('app.string.create_group'))// .dialogButtonStyle()
+ .fontSize('16fp')
+ .onClick(() => {
+ if(this.passphrase === '' || this.groupName === '') {
+ hilog.info(TAG, 'ssid || preSharedKey is null');
+ promptAction.showToast({ message : 'passphrase or groupName is null' })
+ return;
+ }
+ this.createGroup();
+ })
+ .height('100%')
+ }
+ .width('50%')
+ .height('6%')
+ .justifyContent(FlexAlign.SpaceBetween)
+ }
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/pages/P2pTest.ets b/ConnectivityKit/Wlan/entry/src/main/ets/pages/P2pTest.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f1aea01713a51e7e7add41fb3346afb8f9ae884b
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/pages/P2pTest.ets
@@ -0,0 +1,59 @@
+/*
+ * 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 '../model/Logger';
+import { TitleBar } from '../component/TitleBar';
+import router from '@ohos.router'
+
+const TAG = 'Index';
+
+@Entry
+@Component
+struct P2pTest {
+ build() {
+ Column({ space: 5 }) {
+ Text($r('app.string.p2p_Connect'))
+ .fontColor(Color.Black)
+ .fontSize(20)
+ .layoutWeight(1)
+ .constraintSize({ minHeight: 50 })
+ .padding({ left: 15 })
+ .borderRadius(5)
+ .width('100%')
+ // .fontColor($r('app.color.text_color'))
+ .backgroundColor($r('app.color.moon'))
+ .onClick(() => {
+ router.pushUrl({ url: 'pages/AvailableP2p' })
+ })
+
+ Text($r('app.string.create_group_test'))
+ .fontColor(Color.Black)
+ .fontSize(20)
+ .layoutWeight(1)
+ .constraintSize({ minHeight: 50 })
+ .padding({ left: 15 })
+ .borderRadius(5)
+ .width('100%')
+ // .fontColor($r('app.color.text_color'))
+ .backgroundColor($r('app.color.cyan'))
+ .onClick(() => {
+ router.pushUrl({ url: 'pages/P2pSetting' })
+ })
+ }
+ .width('100%')
+ .height('8%')
+ .backgroundColor($r('app.color.index_bg'))
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/ets/pages/WifiConnect.ets b/ConnectivityKit/Wlan/entry/src/main/ets/pages/WifiConnect.ets
new file mode 100644
index 0000000000000000000000000000000000000000..c1406a79d55a00996a070274f6e6a2736d12a24c
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/ets/pages/WifiConnect.ets
@@ -0,0 +1,207 @@
+/*
+ * 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 '../model/Logger'
+import promptAction from '@ohos.promptAction'
+import wifi from '@ohos.wifiManager'
+import router from '@ohos.router'
+
+const TAG = 'WifiConnect'
+@Entry
+@Component
+struct WifiConnect {
+ ssid: string = ''
+ password: string = ''
+ selectedSecurityType: wifi.WifiSecurityType = wifi.WifiSecurityType.WIFI_SEC_TYPE_INVALID
+ private linkedInfo: wifi.WifiLinkedInfo | null = null;
+ @State isLinked: boolean = false;
+ @State isSwitchOn: boolean = false;
+ @State wifiCandidateConfig: wifi.WifiDeviceConfig = {
+ ssid: '',
+ bssid: '',
+ preSharedKey: '',
+ isHiddenSsid: false,
+ securityType: 0
+ }
+ private controller: CustomDialogController | null = null;
+
+ async connectwifi(deviceConfig: wifi.WifiDeviceConfig) {
+ try {
+ promptAction.showToast({ message : 'connect to wifi' })
+ hilog.info(`connectwifi failed err is ${JSON.stringify(deviceConfig)}`);
+ wifi.addCandidateConfig(deviceConfig).then(result => {
+ // 连接指定网络
+ wifi.connectToCandidateConfig(result);
+ this.getLinkedInfo()
+ });
+ }catch(error){
+ hilog.error('sun failed:' + JSON.stringify(error));
+ }
+ }
+
+ async getLinkedInfo() {
+ try {
+ let wifiLinkedInfo = await wifi.getLinkedInfo();
+ if (wifiLinkedInfo === null || wifiLinkedInfo.bssid === '') {
+ this.isLinked = false;
+ this.linkedInfo = null;
+ return;
+ }
+ this.isLinked = true;
+ this.linkedInfo = wifiLinkedInfo;
+ } catch (err) {
+ hilog.info(`getLinkedInfo failed err is ${JSON.stringify(err)}`);
+ }
+ }
+
+ addListener() {
+ // 连接状态改变时,修改连接信息
+ wifi.on('wifiConnectionChange', async state => {
+ hilog.info(TAG, `wifiConnectionChange: ${state}`);
+ await this.getLinkedInfo();
+ })
+ }
+
+ aboutToAppear() {
+ // 如果wifi是开的,就记录下状态,然后扫描wifi,并获取连接信息
+ if (wifi.isWifiActive()) {
+ hilog.info(TAG, 'wifi is active');
+ this.isSwitchOn = true;
+ }
+ hilog.info(TAG, 'wifi is disabled');
+ // 启动监听
+ this.addListener();
+ }
+
+ build() {
+ Column() {
+ Column() {
+ Row() {
+ Text('ssid').fontSize('16fp').width('18%')
+ TextInput({ placeholder: $r('app.string.input_candidate_wifi_ssid') })
+ .placeholderColor(Color.Grey)
+ .placeholderFont({ size: '16fp' })
+ .caretColor(Color.Blue)
+ .width('80%')
+ .fontSize('16fp')
+ .fontColor($r('app.color.title_black_color'))
+ .onChange((value: string) => {
+ this.wifiCandidateConfig.ssid = value;
+ })
+ }
+ .width('100%')
+ .margin({ top: '3%' })
+
+ // .height( CommonConstants.TEXT_INPUT_HEIGHT )
+ // .backgroundColor( $r( 'app.color.input_background' ) )
+ Row() {
+ Text('bssid').fontSize('16fp').width('18%')
+ TextInput({ placeholder: $r('app.string.input_candidate_wifi_bssid') })
+ .placeholderColor(Color.Grey)
+ .placeholderFont({ size: '16fp' })
+ .caretColor(Color.Blue)
+ .width('80%')
+ .fontSize('16fp')
+ .fontColor($r('app.color.title_black_color'))
+ .onChange((value: string) => {
+ this.wifiCandidateConfig.bssid = value;
+ })
+ }
+ .width('100%')
+ .margin({ top: '3%' })
+
+ Row() {
+ Text('preSharedKey').fontSize('16fp').width('28%')
+ TextInput({ placeholder: $r('app.string.input_candidate_wifi_preSharedKey') })
+ .placeholderColor(Color.Grey)
+ .placeholderFont({ size: '16fp' })
+ .caretColor(Color.Blue)
+ .width('70%')
+ .fontSize('16fp')
+ .fontColor($r('app.color.title_black_color'))
+ .onChange((value: string) => {
+ this.wifiCandidateConfig.preSharedKey = value;
+ })
+ }
+ .width('100%')
+ .margin({ top: '3%' })
+
+
+ Row() {
+ Text('isHiddenSsid').fontSize('16fp').width('28%')
+ TextInput({ placeholder: $r('app.string.input_candidate_wifi_isHiddenSsid') })
+ .placeholderColor(Color.Grey)
+ .placeholderFont({ size: '16fp' })
+ .caretColor(Color.Blue)
+ .width('70%')
+ .fontSize('16fp')
+ .fontColor($r('app.color.title_black_color'))
+ .onChange((value: string) => {
+ this.wifiCandidateConfig.isHiddenSsid = parseInt(value, 10) === 1;
+ })
+ }
+ .width('100%')
+ .margin({ top: '3%' })
+
+ Row() {
+ Text('securityType').fontSize('16fp').width('28%')
+ Column() {
+ Select([
+ { value: 'WIFI_SEC_TYPE_INVALID' },
+ { value: 'WIFI_SEC_TYPE_OPEN' },
+ { value: 'WIFI_SEC_TYPE_PSK' },
+ { value: 'WIFI_SEC_TYPE_SAE' }
+ ])
+ .fontColor($r('app.color.title_black_color'))
+ .optionBgColor($r('app.color.input_background'))
+ .selectedOptionBgColor($r('app.color.input_background'))
+ .selectedOptionFontColor($r('app.color.input_background'))
+ .selected(0)
+ .value('WIFI_SEC_TYPE_INVALID')
+ .font({ size: 16 })
+ .selectedOptionFont({ size: 17 })
+ .optionFont({ size: 15 })
+ .width('100%')
+ .onSelect((index: number) => {
+ this.wifiCandidateConfig.securityType = index;
+ })
+ }
+ .width('70%')
+ .borderRadius(1)
+ }
+ .justifyContent(FlexAlign.Start)
+ .alignItems(VerticalAlign.Center)
+ .width('100%')
+ .margin({ top: '3%' })
+
+ Row() {
+ Button($r('app.string.confirm_button'))// .dialogButtonStyle()
+ .onClick(() => {
+ if(this.wifiCandidateConfig.ssid === '' || this.wifiCandidateConfig.preSharedKey === '') {
+ hilog.info(TAG, 'ssid || preSharedKey is null');
+ promptAction.showToast({ message : 'ssid or preSharedKey is null' })
+ return;
+ }
+ this.connectwifi(this.wifiCandidateConfig);
+ })
+ .height('100%')
+ }
+ .width('70')
+ .height('6%')
+ .justifyContent(FlexAlign.SpaceBetween)
+ }
+ }
+ }
+ }
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/module.json5 b/ConnectivityKit/Wlan/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..f2740de4e12488dbc998b6d84ca8709c002bff4f
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/module.json5
@@ -0,0 +1,84 @@
+/*
+ * 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": "MainAbility",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ "requestPermissions": [
+ {
+ "name": "ohos.permission.GET_WIFI_INFO",
+ "reason": "$string:GET_WIFI_INFO",
+ "usedScene": {
+ "abilities": [
+ "MainAbility"
+ ],
+ "when": "inuse"
+ },
+ },
+ {
+ "name": "ohos.permission.SET_WIFI_INFO",
+ "reason": "$string:SET_WIFI_INFO",
+ "usedScene": {
+ "abilities": [
+ "MainAbility"
+ ],
+ "when": "inuse"
+ }
+ },
+ {
+ "name": "ohos.permission.GET_WIFI_PEERS_MAC",
+ "reason": "$string:GET_WIFI_PEERS_MAC",
+ "usedScene": {
+ "abilities": [
+ "MainAbility"
+ ],
+ "when": "inuse"
+ }
+ },
+ ],
+ "abilities": [
+ {
+ "srcEntry": "./ets/entryability/EntryAbility.ets",
+ "name": "EntryAbility",
+ "description": "$string:EntryAbility_desc",
+ "icon": "$media:icon",
+ "label": "$string:EntryAbility_label",
+ "startWindowIcon": "$media:icon",
+ "startWindowBackground": "$color:start_window_background",
+ "visible": true,
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/resources/base/element/color.json b/ConnectivityKit/Wlan/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..8919d0f5d480b0f118a27e07cf79019aeb1ae73a
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,60 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#FFFFFF"
+ },
+ {
+ "name": "index_bg",
+ "value": "#F5F5F5"
+ },
+ {
+ "name": "button_color",
+ "value": "#0D9FFB"
+ },
+ {
+ "name": "button_color1",
+ "value": "#007AFF"
+ },
+ {
+ "name": "button_color2",
+ "value": "#D7ECF1"
+ },
+ {
+ "name": "title_black_color",
+ "value": "#182431"
+ },
+ {
+ "name": "cyan",
+ "value": "#70919F"
+ },
+ {
+ "name": "spring",
+ "value": "#F5FFFA"
+ },
+ {
+ "name": "moon",
+ "value": "#D7ECF1"
+ },
+ {
+ "name": "main_blue",
+ "value": "#007DFF"
+ },
+ {
+ "name": "index_background",
+ "value": "#E8E7EB"
+ },
+ {
+ "name": "intput_background",
+ "value": "#D9B612"
+ },
+ {
+ "name": "input_background",
+ "value": "#D9B612"
+ },
+ {
+ "name": "text_color",
+ "value": "#8F8F8F"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/resources/base/element/string.json b/ConnectivityKit/Wlan/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..3511e0933d77c6a5b80711513af7ec2cf54f262b
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,156 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "Wlan"
+ },
+ {
+ "name": "entry_MainAbility",
+ "value": "eTSWLAN"
+ },
+ {
+ "name": "description_mainability",
+ "value": "eTSWLAN Ability"
+ },
+ {
+ "name": "cancel",
+ "value": "Cancel"
+ },
+ {
+ "name": "sure",
+ "value": "Sure"
+ },
+ {
+ "name": "wlan",
+ "value": "WLAN"
+ },
+ {
+ "name": "available_wlan",
+ "value": "Available WLAN"
+ },
+ {
+ "name": "wifi_List",
+ "value": "wifi_List"
+ },
+ {
+ "name": "connected",
+ "value": "connected"
+ },
+ {
+ "name": "ip_address",
+ "value": "IP address:"
+ },
+ {
+ "name": "gate_way",
+ "value": "Gateway:"
+ },
+ {
+ "name": "net_mask",
+ "value": "Netmask:"
+ },
+ {
+ "name": "primary_dns",
+ "value": "Primary Dns IP address:"
+ },
+ {
+ "name": "second_dns",
+ "value": "Second DNS IP address:"
+ },
+ {
+ "name": "server_ip",
+ "value": "DHCP server IP:"
+ },
+ {
+ "name": "lease_duration",
+ "value": "IP address lease duration:"
+ },
+ {
+ "name": "country_code",
+ "value": "Country code:"
+ },
+ {
+ "name": "infrastructure_feature",
+ "value": "Infrastructure Feature:"
+ },
+ {
+ "name": "ghz_feature",
+ "value": "5 GHz Feature:"
+ },
+ {
+ "name": "gas_anqp_feature",
+ "value": "GAS/ANQP Feature:"
+ },
+ {
+ "name": "wifi_direct",
+ "value": "WiFi-Direct Feature:"
+ },
+ {
+ "name": "soft_ap",
+ "value": "Soft AP Feature:"
+ },
+ {
+ "name": "wifi_aware",
+ "value": "WiFi Aware Feature:"
+ },
+ {
+ "name": "encryption",
+ "value": "encrypted"
+ },
+ {
+ "name": "open",
+ "value": "open"
+ },
+ {
+ "name": "location_permission",
+ "value": "Allow app to obtain device location information"
+ },
+ {
+ "name": "approximately_location_permission",
+ "value": "Allow app to obtain device ambiguous location information"
+ },
+ {
+ "name": "GET_WIFI_INFO",
+ "value": "Allow applications to obtain Wi Fi information"
+ },
+ {
+ "name": "SET_WIFI_INFO",
+ "value": "Allow applications to configure Wi Fi devices"
+ },
+ {
+ "name": "GET_WIFI_INFO_INTERNAL",
+ "value": "Allow system processes to obtain Wi Fi related parameters"
+ },
+ {
+ "name": "GET_WIFI_PEERS_MAC",
+ "value": "Allow applications to obtain the MAC address of peer Wi Fi devices"
+ },
+ {
+ "name": "GET_WIFI_LOCAL_MAC",
+ "value": "Allow applications to obtain the MAC address of local Wi Fi devices"
+ },
+ {
+ "name": "GET_WIFI_CONFIG",
+ "value": "Allow applications to obtain Wi Fi configuration information"
+ },
+ {
+ "name": "SET_WIFI_CONFIG",
+ "value": "Allow applications to configure Wi Fi information"
+ },
+ {
+ "name": "MANAGE_WIFI_CONNECTION",
+ "value": "Allow applications to manage Wi Fi connections"
+ },
+ {
+ "name": "MANAGE_WIFI_HOTSPOT",
+ "value": "Allow applications to turn on or off Wi Fi hotspots"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/resources/base/media/about.png b/ConnectivityKit/Wlan/entry/src/main/resources/base/media/about.png
new file mode 100644
index 0000000000000000000000000000000000000000..2613fc352850e45f0582fa825183e3928cef3378
Binary files /dev/null and b/ConnectivityKit/Wlan/entry/src/main/resources/base/media/about.png differ
diff --git a/ConnectivityKit/Wlan/entry/src/main/resources/base/media/ic_back.png b/ConnectivityKit/Wlan/entry/src/main/resources/base/media/ic_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..9f793557fd1ba7a4941e2ba4dea6fc2316eb5f24
Binary files /dev/null and b/ConnectivityKit/Wlan/entry/src/main/resources/base/media/ic_back.png differ
diff --git a/ConnectivityKit/Wlan/entry/src/main/resources/base/media/icon.png b/ConnectivityKit/Wlan/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/ConnectivityKit/Wlan/entry/src/main/resources/base/media/icon.png differ
diff --git a/ConnectivityKit/Wlan/entry/src/main/resources/base/media/lock.png b/ConnectivityKit/Wlan/entry/src/main/resources/base/media/lock.png
new file mode 100644
index 0000000000000000000000000000000000000000..b78d86d2fc3afcc542f069b75ada2338fcf1a71a
Binary files /dev/null and b/ConnectivityKit/Wlan/entry/src/main/resources/base/media/lock.png differ
diff --git a/ConnectivityKit/Wlan/entry/src/main/resources/base/media/wifi.png b/ConnectivityKit/Wlan/entry/src/main/resources/base/media/wifi.png
new file mode 100644
index 0000000000000000000000000000000000000000..7017ea920f2683095b49d9f8221e40d7697f9943
Binary files /dev/null and b/ConnectivityKit/Wlan/entry/src/main/resources/base/media/wifi.png differ
diff --git a/ConnectivityKit/Wlan/entry/src/main/resources/base/profile/main_pages.json b/ConnectivityKit/Wlan/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..ae818d5d433790df8603e9ed8d082b79f411f166
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,10 @@
+{
+ "src": [
+ "pages/Index",
+ "pages/AvailableWifi",
+ "pages/WifiConnect",
+ "pages/P2pTest",
+ "pages/P2pSetting",
+ "pages/AvailableP2p"
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/resources/en_US/element/string.json b/ConnectivityKit/Wlan/entry/src/main/resources/en_US/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..53657655fc0157d5558c4210dc1a5f41095285c6
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/resources/en_US/element/string.json
@@ -0,0 +1,232 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "Wlan"
+ },
+ {
+ "name": "entry_MainAbility",
+ "value": "eTSWLAN"
+ },
+ {
+ "name": "description_mainability",
+ "value": "eTSWLAN Ability"
+ },
+ {
+ "name": "cancel",
+ "value": "Cancel"
+ },
+ {
+ "name": "wlan",
+ "value": "WLAN"
+ },
+ {
+ "name": "sure",
+ "value": "Sure"
+ },
+ {
+ "name": "available_wlan",
+ "value": "Available WLAN"
+ },
+ {
+ "name": "connected",
+ "value": "Connected"
+ },
+ {
+ "name": "about",
+ "value": "About"
+ },
+ {
+ "name": "ip_address",
+ "value": "IP address:"
+ },
+ {
+ "name": "gate_way",
+ "value": "Gateway:"
+ },
+ {
+ "name": "net_mask",
+ "value": "Netmask:"
+ },
+ {
+ "name": "primary_dns",
+ "value": "Primary Dns IP address:"
+ },
+ {
+ "name": "second_dns",
+ "value": "Second DNS IP address:"
+ },
+ {
+ "name": "server_ip",
+ "value": "DHCP server IP:"
+ },
+ {
+ "name": "lease_duration",
+ "value": "IP address lease duration:"
+ },
+ {
+ "name": "country_code",
+ "value": "Country code:"
+ },
+ {
+ "name": "infrastructure_feature",
+ "value": "Infrastructure Feature:"
+ },
+ {
+ "name": "ghz_feature",
+ "value": "5 GHz Feature:"
+ },
+ {
+ "name": "gas_anqp_feature",
+ "value": "GAS/ANQP Feature:"
+ },
+ {
+ "name": "wifi_List",
+ "value": "wifi_List"
+ },
+ {
+ "name": "getScanInfoList",
+ "value": "ȡɨ"
+ },
+ {
+ "name": "wifi_Connect",
+ "value": ""
+ },
+ {
+ "name": "cancel_button",
+ "value": "ȡ"
+ },
+ {
+ "name": "confirm_button",
+ "value": "ȷ"
+ },
+ {
+ "name": "input_candidate_wifi_bssid",
+ "value": "ѡWiFibssid(MAC) (ɲ)"
+ },
+ {
+ "name": "input_candidate_wifi_preSharedKey",
+ "value": "ѡWiFi"
+ },
+ {
+ "name": "input_candidate_wifi_isHiddenSsid",
+ "value": "10 (ɲ;1:ture,0:false)"
+ },
+ {
+ "name": "add_task",
+ "value": "Ӻѡwifi"
+ },
+ {
+ "name": "p2p_available",
+ "value": "Ե豸"
+ },
+ {
+ "name": "p2p_test",
+ "value": "p2p"
+ },
+ {
+ "name": "create_group_test",
+ "value": "Ⱥ"
+ },
+ {
+ "name": "create_group",
+ "value": "Ⱥ"
+ },
+ {
+ "name": "useful",
+ "value": ""
+ },
+ {
+ "name": "p2pConnected",
+ "value": ""
+ },
+ {
+ "name": "input_candidate_wifi",
+ "value": "ѡWiFi"
+ },
+ {
+ "name": "input_candidate_wifi_ssid",
+ "value": "ѡWiFiSSID"
+ },
+ {
+ "name": "p2p_Connect",
+ "value": "p2p"
+ },
+ {
+ "name": "cancle_button",
+ "value": "cancle"
+ },
+ {
+ "name": "wifi_direct",
+ "value": "WiFi-Direct Feature:"
+ },
+ {
+ "name": "soft_ap",
+ "value": "Soft AP Feature:"
+ },
+ {
+ "name": "wifi_aware",
+ "value": "WiFi Aware Feature:"
+ },
+ {
+ "name": "encryption",
+ "value": "encrypted"
+ },
+ {
+ "name": "open",
+ "value": "open"
+ },
+ {
+ "name": "location_permission",
+ "value": "Allow app to obtain device location information"
+ },
+ {
+ "name": "approximately_location_permission",
+ "value": "Allow app to obtain device ambiguous location information"
+ },
+ {
+ "name": "GET_WIFI_INFO",
+ "value": "Allow applications to obtain Wi Fi information"
+ },
+ {
+ "name": "SET_WIFI_INFO",
+ "value": "Allow applications to configure Wi Fi devices"
+ },
+ {
+ "name": "GET_WIFI_INFO_INTERNAL",
+ "value": "Allow system processes to obtain Wi Fi related parameters"
+ },
+ {
+ "name": "GET_WIFI_PEERS_MAC",
+ "value": "Allow applications to obtain the MAC address of peer Wi Fi devices"
+ },
+ {
+ "name": "GET_WIFI_LOCAL_MAC",
+ "value": "Allow applications to obtain the MAC address of local Wi Fi devices"
+ },
+ {
+ "name": "GET_WIFI_CONFIG",
+ "value": "Allow applications to obtain Wi Fi configuration information"
+ },
+ {
+ "name": "SET_WIFI_CONFIG",
+ "value": "Allow applications to configure Wi Fi information"
+ },
+ {
+ "name": "MANAGE_WIFI_CONNECTION",
+ "value": "Allow applications to manage Wi Fi connections"
+ },
+ {
+ "name": "MANAGE_WIFI_HOTSPOT",
+ "value": "Allow applications to turn on or off Wi Fi hotspots"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/main/resources/zh_CN/element/string.json b/ConnectivityKit/Wlan/entry/src/main/resources/zh_CN/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..d8484995039bd0b90dfb845c4095af4da6a633b0
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/main/resources/zh_CN/element/string.json
@@ -0,0 +1,232 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "模块描述"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "Wlan"
+ },
+ {
+ "name": "entry_MainAbility",
+ "value": "eTSWLAN"
+ },
+ {
+ "name": "description_mainability",
+ "value": "eTSWLAN Ability"
+ },
+ {
+ "name": "cancel",
+ "value": "取消"
+ },
+ {
+ "name": "sure",
+ "value": "确定"
+ },
+ {
+ "name": "wlan",
+ "value": "WLAN"
+ },
+ {
+ "name": "available_wlan",
+ "value": "可用WLAN"
+ },
+ {
+ "name": "connected",
+ "value": "已连接"
+ },
+ {
+ "name": "about",
+ "value": "关于"
+ },
+ {
+ "name": "ip_address",
+ "value": "IP地址:"
+ },
+ {
+ "name": "gate_way",
+ "value": "网关:"
+ },
+ {
+ "name": "net_mask",
+ "value": "掩码:"
+ },
+ {
+ "name": "primary_dns",
+ "value": "主DNS服务器:"
+ },
+ {
+ "name": "second_dns",
+ "value": "备DNS服务器:"
+ },
+ {
+ "name": "server_ip",
+ "value": "DHCP服务端ip:"
+ },
+ {
+ "name": "lease_duration",
+ "value": "IP地址租用时长:"
+ },
+ {
+ "name": "country_code",
+ "value": "国家码:"
+ },
+ {
+ "name": "infrastructure_feature",
+ "value": "基础结构模式特性:"
+ },
+ {
+ "name": "ghz_feature",
+ "value": "5 GHz 宽带特性:"
+ },
+ {
+ "name": "gas_anqp_feature",
+ "value": "GAS/ANQP特性:"
+ },
+ {
+ "name": "wifi_List",
+ "value": "Wi-Fi 列表"
+ },
+ {
+ "name": "getScanInfoList",
+ "value": "获取扫描结果"
+ },
+ {
+ "name": "wifi_Connect",
+ "value": "建议网络连接"
+ },
+ {
+ "name": "cancel_button",
+ "value": "取消"
+ },
+ {
+ "name": "confirm_button",
+ "value": "确定"
+ },
+ {
+ "name": "input_candidate_wifi_bssid",
+ "value": "输入候选WiFi的bssid(MAC) (可不填)"
+ },
+ {
+ "name": "input_candidate_wifi_preSharedKey",
+ "value": "输入候选WiFi密码"
+ },
+ {
+ "name": "input_candidate_wifi_isHiddenSsid",
+ "value": "输入1或0 (可不填;1:ture,0:false)"
+ },
+ {
+ "name": "add_task",
+ "value": "添加候选wifi"
+ },
+ {
+ "name": "p2p_available",
+ "value": "对等设备"
+ },
+ {
+ "name": "p2p_test",
+ "value": "p2p测试"
+ },
+ {
+ "name": "create_group_test",
+ "value": "创建群组测试"
+ },
+ {
+ "name": "create_group",
+ "value": "创建群组"
+ },
+ {
+ "name": "useful",
+ "value": "可用"
+ },
+ {
+ "name": "p2pConnected",
+ "value": "已连接"
+ },
+ {
+ "name": "input_candidate_wifi",
+ "value": "输入候选WiFi的配置"
+ },
+ {
+ "name": "input_candidate_wifi_ssid",
+ "value": "输入候选WiFi的SSID"
+ },
+ {
+ "name": "p2p_Connect",
+ "value": "p2p连接"
+ },
+ {
+ "name": "cancle_button",
+ "value": "cancle"
+ },
+ {
+ "name": "wifi_direct",
+ "value": "WiFi-Direct特性:"
+ },
+ {
+ "name": "soft_ap",
+ "value": "Soft AP特性:"
+ },
+ {
+ "name": "wifi_aware",
+ "value": "WiFi Aware组网特性:"
+ },
+ {
+ "name": "encryption",
+ "value": "加密"
+ },
+ {
+ "name": "open",
+ "value": "开放"
+ },
+ {
+ "name": "location_permission",
+ "value": "允许应用获取设备位置信息"
+ },
+ {
+ "name": "approximately_location_permission",
+ "value": "允许应用获取设备模糊位置信息"
+ },
+ {
+ "name": "GET_WIFI_INFO",
+ "value": "允许应用获取Wi-Fi信息"
+ },
+ {
+ "name": "SET_WIFI_INFO",
+ "value": "允许应用配置Wi-Fi设备"
+ },
+ {
+ "name": "GET_WIFI_INFO_INTERNAL",
+ "value": "允许系统进程获取Wi-Fi相关参数"
+ },
+ {
+ "name": "GET_WIFI_PEERS_MAC",
+ "value": "允许应用获取对端Wi-Fi设备的MAC地址"
+ },
+ {
+ "name": "GET_WIFI_LOCAL_MAC",
+ "value": "允许应用获取本机的Wi-Fi设备的MAC地址"
+ },
+ {
+ "name": "GET_WIFI_CONFIG",
+ "value": "允许应用获取Wi-Fi的配置信息"
+ },
+ {
+ "name": "SET_WIFI_CONFIG",
+ "value": "允许应用配置Wi-Fi信息"
+ },
+ {
+ "name": "MANAGE_WIFI_CONNECTION",
+ "value": "允许应用管理Wi-Fi的连接"
+ },
+ {
+ "name": "MANAGE_WIFI_HOTSPOT",
+ "value": "允许应用开启或关闭Wi-Fi热点"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/mock/mock-config.json5 b/ConnectivityKit/Wlan/entry/src/mock/mock-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..fec94bcaee89632a26be6c4862a88acf88d0daad
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/mock/mock-config.json5
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+ {
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/ohosTest/ets/test/Ability.test.ets b/ConnectivityKit/Wlan/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0f8ce9a2c012f8fe36114cef65216ef0b6254f41
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+ * 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/ConnectivityKit/Wlan/entry/src/ohosTest/ets/test/List.test.ets b/ConnectivityKit/Wlan/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1eac52fcebe8958e19a7b8fed2e8f39c520a3e42
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/ohosTest/ets/test/List.test.ets
@@ -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 abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/ohosTest/module.json5 b/ConnectivityKit/Wlan/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c3fd9dda3040d888d9d8b0b62bcb5d3b6fbeb614
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/ohosTest/module.json5
@@ -0,0 +1,27 @@
+/*
+ * 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/ConnectivityKit/Wlan/entry/src/test/List.test.ets b/ConnectivityKit/Wlan/entry/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f1186b1f53c3a70930921c5dbd1417332bec56c9
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/test/List.test.ets
@@ -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 localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/entry/src/test/LocalUnit.test.ets b/ConnectivityKit/Wlan/entry/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7fc57c77dbf76d8df08a2b802a55b948e3fcf968
--- /dev/null
+++ b/ConnectivityKit/Wlan/entry/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+ * 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/ConnectivityKit/Wlan/hvigor/hvigor-config.json5 b/ConnectivityKit/Wlan/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..48fb346926eb36f8b2c028fd4319ac3e56165409
--- /dev/null
+++ b/ConnectivityKit/Wlan/hvigor/hvigor-config.json5
@@ -0,0 +1,5 @@
+{
+ "modelVersion": "5.0.5",
+ "dependencies": {
+ }
+}
diff --git a/ConnectivityKit/Wlan/hvigorfile.ts b/ConnectivityKit/Wlan/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..64b143a6ae9b2db7e61a01fbe50ae7b5634a80a1
--- /dev/null
+++ b/ConnectivityKit/Wlan/hvigorfile.ts
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+export { appTasks } from '@ohos/hvigor-ohos-plugin'
+
diff --git a/ConnectivityKit/Wlan/oh-package.json5 b/ConnectivityKit/Wlan/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..5f609682201b4eeccf312f5e6781abddb98c23c7
--- /dev/null
+++ b/ConnectivityKit/Wlan/oh-package.json5
@@ -0,0 +1,27 @@
+/*
+ * 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.5",
+ "license": "ISC",
+ "devDependencies": {
+ "@ohos/hypium": "1.0.6"
+ },
+ "name": "wlan",
+ "description": "example description",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {},
+}
diff --git a/ConnectivityKit/Wlan/ohosTest.md b/ConnectivityKit/Wlan/ohosTest.md
new file mode 100644
index 0000000000000000000000000000000000000000..e02cd4bf9d24860a970a0dcdae8402b7dc317bc5
--- /dev/null
+++ b/ConnectivityKit/Wlan/ohosTest.md
@@ -0,0 +1,10 @@
+# P2P模式开发测试用例归档
+
+## 用例表
+
+| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
+| ------------ | ------------ | ------------------------------ | ------------ | -------- | -------- |
+| 拉起应用 | 设备正常运行 |点击运行 | 成功拉起应用 | 否 | Pass |
+| 主页点击create group按钮 | 打开WLAN,位于主页 |点击create group按钮 | 主页显示success文字 | 否 | Pass |
+| 主页connect按钮点击 | 打开WLAN,点击create group按钮后,位于主页 |点击connect按钮 | 输出预期日志 | 否 | Pass |
+| 主页delete group按钮点击 | 打开WLAN,点击create group按钮后,位于主页 |点击delete group按钮 | 主页显示的文字被清除 | 否 | Pass |
\ No newline at end of file
diff --git a/ConnectivityKit/Wlan/screenshots/GET_WIFI_PEERS_MAC.png b/ConnectivityKit/Wlan/screenshots/GET_WIFI_PEERS_MAC.png
new file mode 100644
index 0000000000000000000000000000000000000000..9735598afc20df84495b15be119750bd92d62f87
Binary files /dev/null and b/ConnectivityKit/Wlan/screenshots/GET_WIFI_PEERS_MAC.png differ
diff --git a/ConnectivityKit/Wlan/screenshots/connect_wifi.png b/ConnectivityKit/Wlan/screenshots/connect_wifi.png
new file mode 100644
index 0000000000000000000000000000000000000000..29cfe4907984c6cc08f7dbafe51e47e74a0bcb2b
Binary files /dev/null and b/ConnectivityKit/Wlan/screenshots/connect_wifi.png differ
diff --git a/ConnectivityKit/Wlan/screenshots/creatgroup.png b/ConnectivityKit/Wlan/screenshots/creatgroup.png
new file mode 100644
index 0000000000000000000000000000000000000000..595e57bc6496d660ee664ea5cec294c43668cc4d
Binary files /dev/null and b/ConnectivityKit/Wlan/screenshots/creatgroup.png differ
diff --git a/ConnectivityKit/Wlan/screenshots/main.png b/ConnectivityKit/Wlan/screenshots/main.png
new file mode 100644
index 0000000000000000000000000000000000000000..8c495d76df076285552397b93e61f7e45423dc15
Binary files /dev/null and b/ConnectivityKit/Wlan/screenshots/main.png differ
diff --git a/ConnectivityKit/Wlan/screenshots/p2pconnect.png b/ConnectivityKit/Wlan/screenshots/p2pconnect.png
new file mode 100644
index 0000000000000000000000000000000000000000..e97c119452864f0314a52a4214b3dad983277719
Binary files /dev/null and b/ConnectivityKit/Wlan/screenshots/p2pconnect.png differ
diff --git a/ConnectivityKit/Wlan/screenshots/p2ptest.png b/ConnectivityKit/Wlan/screenshots/p2ptest.png
new file mode 100644
index 0000000000000000000000000000000000000000..3253280d50a04e481c52386af3daaf838bb799e4
Binary files /dev/null and b/ConnectivityKit/Wlan/screenshots/p2ptest.png differ
diff --git a/ConnectivityKit/Wlan/screenshots/wifi_list.png b/ConnectivityKit/Wlan/screenshots/wifi_list.png
new file mode 100644
index 0000000000000000000000000000000000000000..b80efef376dc41afe8a990444e05dd5f612cc410
Binary files /dev/null and b/ConnectivityKit/Wlan/screenshots/wifi_list.png differ
diff --git a/bluetoothSample/.gitignore b/bluetoothSample/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b
--- /dev/null
+++ b/bluetoothSample/.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/bluetoothSample/AppScope/app.json5 b/bluetoothSample/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..61caeed5dbf7384b2ef5286b72d2f4fa90ff6784
--- /dev/null
+++ b/bluetoothSample/AppScope/app.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.bluetoothsample",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
diff --git a/bluetoothSample/AppScope/resources/base/element/string.json b/bluetoothSample/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..1407cd98b64bd01f972867509cd51773c70b1f73
--- /dev/null
+++ b/bluetoothSample/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "bluetoothSample"
+ }
+ ]
+}
diff --git a/bluetoothSample/AppScope/resources/base/media/app_icon.png b/bluetoothSample/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3
Binary files /dev/null and b/bluetoothSample/AppScope/resources/base/media/app_icon.png differ
diff --git a/bluetoothSample/README.md b/bluetoothSample/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..46ad38cf598e77be8453c60ebb66e442c700650c
--- /dev/null
+++ b/bluetoothSample/README.md
@@ -0,0 +1,153 @@
+# 蓝牙示例代码工程化
+
+### 介绍
+
+本示例为开发指南中[蓝牙服务开发](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/bluetooth/Readme-CN.md)章节中**蓝牙设置**,**广播与扫描**,**通用属性协议**示例代码的完整工程,该工程中展示的代码详细描述可查如下链接:
+
+[蓝牙设置](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/bluetooth/br-development-guide.md)
+[广播与扫描](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/bluetooth/ble-development-guide.md)
+[通用属性协议](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/connectivity/bluetooth/gatt-development-guide.md)
+
+### 效果预览
+|Scan界面| Bonded界面 | Adveriser界面| Switch界面|
+|-------|---------|--------|----------|
+|
|
|
|
|
+
+### 使用说明
+
+1. 启动应用,蓝牙权限申请点击同意。
+2. 切换到SWITCH页面,单击开启蓝牙,等待上方蓝牙状态变为BlueTooth State: Connected。
+3. 在SCAN页面单击设置过滤参数,可以设置扫描的过滤参数。
+4. 单击开始扫描,设备开始扫描设备,扫描到的设备ID会以弹窗形式展示,单击刷新,可以更新下方的设备列表。
+5. 单击停止扫描,停止扫描设备。
+6. 单击设备列表里的connect,连接设备,设备信息会在上方循环播放展示。
+7. 切换GATT页面,填写读写特征值和描述符的过滤参数,上方输入框为写特征值和描述符的过滤参数。
+8. 单击发现服务,可以获取已连接设备的服务列表,获得的内容在上方显示。
+9. 单击写特征值或写描述符,根据上方过滤参数写入特征值和描述符。
+10. 单击读特征值或描述符,读取特征值和描述符,读取到的内容以弹窗形式显示。
+11. 单击断开连接,断开与当前设备的连接。
+12. 在Adveriser界面,单击注册服务,可以注册服务,单击注销服务,可以注销服务。
+13. 单击订阅读写特征值可以订阅读写特征值的操作。
+14. 单击设置广播内容,在打开的弹窗中设置广播的内容和参数。
+15. 单击开始广播,设备开始进行广播操作。
+16. 单击暂停广播,设备暂时停止广播。
+17. 单击继续广播,设备继续进行广播。
+18. 单击关闭广播,设备停止广播操作,关闭广播服务。
+19. 切换到SWITCH界面,单击关闭蓝牙,关闭设备的蓝牙服务。
+
+### 工程目录
+```
++--- src
+| +--- main
+| | +--- ets
+| | | +--- bluetoothService
+| | | | +--- BluetoothAdvertising.ets
+| | | | +--- BluetoothScan.ets
+| | | | +--- BluetoothSwitch.ets
+| | | | +--- GattClientManager.ets
+| | | | +--- GattServerManager.ets
+| | | +--- common
+| | | | +--- AdvertisingDialog.ets
+| | | | +--- ScanData.ets
+| | | | +--- ScanDialog.ets
+| | | | +--- ToastReport.ets
+| | | +--- entryability
+| | | | +--- EntryAbility.ets
+| | | +--- entrybackupability
+| | | | +--- EntryBackupAbility.ets
+| | | +--- pages
+| | | | +--- Index.ets
+
+```
+
+### 具体实现
+
+#### 蓝牙设置
+
+1. import需要的access模块。
+
+2. 需要SystemCapability.Communication.Bluetooth.Core系统能力。
+
+3. 开启蓝牙。
+
+4. 关闭蓝牙。
+
+5. 错误码请参见[蓝牙服务子系统错误码](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-bluetoothManager.md)。
+
+6. 如何验证: 执行开启蓝牙代码,记录日志“bluetooth statues: STATE_ON”,则表示开启蓝牙成功。执行关闭蓝牙代码,记录日志“bluetooth statues: STATE_OFF”,则表示蓝牙关闭成功。
+
+#### 广播与扫描开发指导
+
+##### 开启/关闭广播
+
+1. import需要的ble模块。
+2. 开启设备的蓝牙。
+3. 需要SystemCapability.Communication.Bluetooth.Core系统能力。
+4. 开启广播,对端设备扫描该广播。
+5. 关闭广播。
+6. 错误码请参见[蓝牙服务子系统错误码](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-bluetoothManager.md)。
+
+##### 开启/关闭扫描
+
+1. import需要的ble模块。
+2. 开启设备的蓝牙。
+3. 需要SystemCapability.Communication.Bluetooth.Core系统能力。
+4. 对端设备开启广播。
+5. 本端设备开启扫描,获取扫描结果。
+6. 关闭扫描。
+7. 错误码请参见[蓝牙服务子系统错误码](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-bluetoothManager.md)。
+
+#### 通用属性协议开发指导
+
+##### 连接server端读取和写入信息
+
+1. import需要的ble模块。
+2. 创建gattClient实例对象。
+3. 连接gattServer。
+4. 读取gattServer的特征值和描述符。
+5. 向gattServer写入特征值和描述符。
+6. 断开连接,销毁gattClient实例。
+7. 错误码请参见[蓝牙服务子系统错误码](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-bluetoothManager.md)。
+
+##### server端操作services和通知客户端信息
+
+1. import需要的ble模块。
+2. 创建gattServer实例对象。
+3. 添加services信息。
+4. 当向gattServer写入特征值通知gattClient。
+5. 移除services信息。
+6. 注销gattServer实例。
+7. 错误码请参见[蓝牙服务子系统错误码](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-bluetoothManager.md)。
+
+### 相关权限
+
+[ohos.permission.USE_BLUETOOTH](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all.md#ohospermissionuse_bluetooth)
+
+[ohos.permission.DISCOVER_BLUETOOTH](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all.md#ohospermissiondiscover_bluetooth)
+
+[ohos.permission.ACCESS_BLUETOOTH](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/permissions-for-all-user.md#ohospermissionaccess_bluetooth)
+### 依赖
+
+不涉及
+
+### 约束与限制
+
+1. 本示例仅支持标准系统上运行,支持设备:华为手机。
+
+2. HarmonyOS系统:HarmonyOS 5.0.2 Release及以上。
+
+3. DevEco Studio版本:DevEco Studio 5.0.2 Release及以上。
+
+4. HarmonyOS SDK版本:HarmonyOS 5.0.2 Release及以上。
+
+### 下载
+
+如需单独下载本工程,执行如下命令:
+
+````
+git init
+git config core.sparsecheckout true
+echo bluetoothSample/ > .git/info/sparse-checkout
+git remote add origin https://gitee.com/harmonyos_samples/guide-snippets.git
+git pull origin master
+````
\ No newline at end of file
diff --git a/bluetoothSample/build-profile.json5 b/bluetoothSample/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..51fb5b5e20c1d0fee9e4950e526867440b4eb48f
--- /dev/null
+++ b/bluetoothSample/build-profile.json5
@@ -0,0 +1,57 @@
+/*
+ * 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": "5.0.2(14)",
+ "targetSdkVersion": "5.0.2(14)",
+ "runtimeOS": "HarmonyOS",
+ "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/bluetoothSample/code-linter.json5 b/bluetoothSample/code-linter.json5
new file mode 100644
index 0000000000000000000000000000000000000000..28586467ee7a761c737d8654a73aed6fddbc3c71
--- /dev/null
+++ b/bluetoothSample/code-linter.json5
@@ -0,0 +1,35 @@
+/*
+ * 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": {
+ }
+}
\ No newline at end of file
diff --git a/bluetoothSample/entry/.gitignore b/bluetoothSample/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/bluetoothSample/entry/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/bluetoothSample/entry/build-profile.json5 b/bluetoothSample/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e7569e3056e27af38e9991b7ea73ec10f3ba8a05
--- /dev/null
+++ b/bluetoothSample/entry/build-profile.json5
@@ -0,0 +1,43 @@
+/*
+ * 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/bluetoothSample/entry/hvigorfile.ts b/bluetoothSample/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3
--- /dev/null
+++ b/bluetoothSample/entry/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/bluetoothSample/entry/obfuscation-rules.txt b/bluetoothSample/entry/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/bluetoothSample/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/bluetoothSample/entry/oh-package.json5 b/bluetoothSample/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c9cb6c8174858277c9b0d465a51547dcab16d5ff
--- /dev/null
+++ b/bluetoothSample/entry/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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/bluetoothSample/entry/src/main/ets/bluetoothService/BluetoothAdvertising.ets b/bluetoothSample/entry/src/main/ets/bluetoothService/BluetoothAdvertising.ets
new file mode 100644
index 0000000000000000000000000000000000000000..bcba2b8db0f36d93056e5cad460cf48707182874
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/bluetoothService/BluetoothAdvertising.ets
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+
+// [Start open_close_advertising]
+import { ble } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { ToastReport } from '../common/ToastReport';
+
+const TAG: string = 'BleAdvertisingManager';
+
+export class BleAdvertisingManager {
+ private advHandle: number = 0xFF; // default invalid value
+ private manufactureValueBuffer: Uint8Array = new Uint8Array();
+ private serviceUuids: string = '00001888-0000-1000-8000-00805f9b34fb';
+ private serviceBuffer = new Uint8Array();
+ private manufactureId: number = 0;
+ private includeDeviceName: boolean = false;
+ public toastReport: ToastReport = new ToastReport();
+
+ public setAdvertisingParameter(manufactureId?: number, manufactureValueBuffer?: Uint8Array,
+ serviceUuids?: string, serviceBuffer?: Uint8Array, includeDeviceName?: boolean) {
+ if (manufactureId != undefined) {
+ this.manufactureId = Number(manufactureId);
+ console.info(TAG, 'manufactureId is ' + manufactureId);
+ }
+ if (manufactureValueBuffer != undefined) {
+ console.info(TAG, 'manufactureValueBuffer is ' + manufactureValueBuffer);
+ this.manufactureValueBuffer = manufactureValueBuffer;
+ } else {
+
+ }
+ if (serviceUuids) {
+ this.serviceUuids = serviceUuids;
+ }
+ if (serviceBuffer) {
+ this.serviceBuffer = serviceBuffer;
+ }
+ this.includeDeviceName = includeDeviceName ? true : false;
+ }
+
+ // 1 订阅广播状态
+ public onAdvertisingStateChange() {
+ try {
+ ble.on('advertisingStateChange', (data: ble.AdvertisingStateChangeInfo) => {
+ console.info(TAG, 'bluetooth advertising state = ' + JSON.stringify(data));
+ AppStorage.setOrCreate('advertiserState', data.state);
+ });
+ } catch (err) {
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 2 首次启动广播
+ public async startAdvertising() {
+ // 2.1 设置广播发送的参数
+ console.info('startAdvertising 2.1')
+ let setting: ble.AdvertiseSetting = {
+ interval: 160,
+ txPower: 0,
+ connectable: true
+ };
+ // 2.2 构造广播数据
+ console.info('startAdvertising 2.2')
+ let manufactureValueBuffer = new Uint8Array(4);
+ manufactureValueBuffer[0] = 1;
+ manufactureValueBuffer[1] = 2;
+ manufactureValueBuffer[2] = 3;
+ manufactureValueBuffer[3] = 4;
+ let serviceValueBuffer = new Uint8Array(4);
+ serviceValueBuffer[0] = 5;
+ serviceValueBuffer[1] = 6;
+ serviceValueBuffer[2] = 7;
+ serviceValueBuffer[3] = 8;
+ let manufactureDataUnit: ble.ManufactureData = {
+ manufactureId: this.manufactureId,
+ manufactureValue: this.manufactureValueBuffer.buffer
+ };
+ let serviceDataUnit: ble.ServiceData = {
+ serviceUuid: this.serviceUuids,
+ serviceValue: this.serviceBuffer.buffer
+ };
+ let advData: ble.AdvertiseData = {
+ serviceUuids: [this.serviceUuids],
+ manufactureData: [manufactureDataUnit],
+ serviceData: [serviceDataUnit],
+ includeDeviceName: this.includeDeviceName // 表示是否携带设备名,可选参数。注意带上设备名时广播包长度不能超出31个字节。
+ };
+ let advResponse: ble.AdvertiseData = {
+ serviceUuids: [this.serviceUuids],
+ manufactureData: [manufactureDataUnit],
+ serviceData: [serviceDataUnit]
+ };
+ // 2.3 构造广播启动完整参数AdvertisingParams
+ console.info('startAdvertising 2.3')
+ let advertisingParams: ble.AdvertisingParams = {
+ advertisingSettings: setting,
+ advertisingData: advData,
+ advertisingResponse: advResponse,
+ duration: 0 // 可选参数,若大于0,则广播发送一段时间后,则会临时停止,可重新启动发送
+ }
+
+ // 2.4 首次启动广播,且获取所启动广播的标识ID
+ console.info('startAdvertising 2.4')
+ try {
+ this.onAdvertisingStateChange();
+ this.advHandle = await ble.startAdvertising(advertisingParams);
+ this.toastReport.showResult('bluetooth startAdvertising start success');
+ console.info('startAdvertising succeed');
+ } catch (err) {
+ this.toastReport.showResult('bluetooth startAdvertising start fail');
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 4 临时停止广播,该广播资源仍然存在
+ public async disableAdvertising() {
+ // 4.1 构造临时停止广播参数
+ console.info('disableAdvertising 4.1')
+ let advertisingDisableParams: ble.AdvertisingDisableParams = {
+ advertisingId: this.advHandle // 使用首次启动广播时获取到的广播标识ID
+ }
+ // 4.2 临时停止
+ console.info('disableAdvertising 4.2')
+ try {
+ await ble.disableAdvertising(advertisingDisableParams);
+ this.toastReport.showResult('bluetooth disableAdvertising');
+ console.info('bluetooth disableAdvertising success');
+ } catch (err) {
+ this.toastReport.showResult('bluetooth disableAdvertising fail');
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 5 再次启动广播
+ public async enableAdvertising(enableDuration: number) {
+ // 5.1 构造临时启动广播参数
+ console.info('enableAdvertising 5.1')
+ let advertisingEnableParams: ble.AdvertisingEnableParams = {
+ advertisingId: this.advHandle, // 使用首次启动广播时获取到的广播标识ID
+ duration: enableDuration
+ }
+ // 5.2 再次启动
+ console.info('enableAdvertising 5.2')
+ try {
+ this.toastReport.showResult('bluetooth enableAdvertising continue');
+ await ble.enableAdvertising(advertisingEnableParams);
+ } catch (err) {
+ this.toastReport.showResult('bluetooth enableAdvertising fail');
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 6 完全关闭广播,释放广播资源
+ public async stopAdvertising() {
+ try {
+ this.toastReport.showResult('bluetooth advertising stop success');
+ await ble.stopAdvertising(this.advHandle);
+ ble.off('advertisingStateChange', (data: ble.AdvertisingStateChangeInfo) => {
+ console.info(TAG, 'bluetooth advertising state = ' + JSON.stringify(data));
+ this.toastReport.showResult('bluetooth advertising stop');
+ });
+ } catch (err) {
+ this.toastReport.showResult('bluetooth advertising stop fail');
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+}
+
+let bleAdvertisingManager = new BleAdvertisingManager();
+
+export default bleAdvertisingManager as BleAdvertisingManager;
+// [End open_close_advertising]
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/main/ets/bluetoothService/BluetoothScan.ets b/bluetoothSample/entry/src/main/ets/bluetoothService/BluetoothScan.ets
new file mode 100644
index 0000000000000000000000000000000000000000..8aa2cecd90b87c3bae89f8d6fc682c9d145093e4
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/bluetoothService/BluetoothScan.ets
@@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+
+// [Start open_close_scan]
+import { ble } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { ScanData } from '../common/ScanData';
+import { ToastReport } from '../common/ToastReport';
+
+const TAG: string = 'BleScanManager';
+
+const BLE_ADV_TYPE_FLAG = 0x01;
+const BLE_ADV_TYPE_16_BIT_SERVICE_UUIDS_INCOMPLETE = 0x02;
+const BLE_ADV_TYPE_16_BIT_SERVICE_UUIDS_COMPLETE = 0x03;
+const BLE_ADV_TYPE_32_BIT_SERVICE_UUIDS_INCOMPLETE = 0x04;
+const BLE_ADV_TYPE_32_BIT_SERVICE_UUIDS_COMPLETE = 0x05;
+const BLE_ADV_TYPE_128_BIT_SERVICE_UUIDS_INCOMPLETE = 0x06;
+const BLE_ADV_TYPE_128_BIT_SERVICE_UUIDS_COMPLETE = 0x07;
+const BLE_ADV_TYPE_LOCAL_NAME_SHORT = 0x08;
+const BLE_ADV_TYPE_LOCAL_NAME_COMPLETE = 0x09;
+const BLE_ADV_TYPE_TX_POWER_LEVEL = 0x0A;
+const BLE_ADV_TYPE_16_BIT_SERVICE_SOLICITATION_UUIDS = 0x14;
+const BLE_ADV_TYPE_128_BIT_SERVICE_SOLICITATION_UUIDS = 0x15;
+const BLE_ADV_TYPE_32_BIT_SERVICE_SOLICITATION_UUIDS = 0x1F;
+const BLE_ADV_TYPE_16_BIT_SERVICE_DATA = 0x16;
+const BLE_ADV_TYPE_32_BIT_SERVICE_DATA = 0x20;
+const BLE_ADV_TYPE_128_BIT_SERVICE_DATA = 0x21;
+const BLE_ADV_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
+
+const BLUETOOTH_UUID_16_BIT_LENGTH = 2;
+const BLUETOOTH_UUID_32_BIT_LENGTH = 4;
+const BLUETOOTH_UUID_128_BIT_LENGTH = 16;
+
+const BLUETOOTH_MANUFACTURE_ID_LENGTH = 2;
+
+export class BleScanManager {
+ private interval: number = 0;
+ private manufactureId: number = 4567;
+ private deviceName: string | undefined = '';
+ private deviceId: string | undefined = '';
+ private scanDataList: ScanData[] = [];
+ public toastReport: ToastReport = new ToastReport();
+
+ public setScanParameter(interval?: string, manufactureId?: string, deviceName?: string | undefined,
+ deviceId?: string | undefined) {
+ if (interval != undefined) {
+ this.interval = Number(interval);
+ console.info(TAG, 'interval is' + interval);
+ }
+ if (manufactureId != undefined) {
+ console.info(TAG, 'manufactureId is' + manufactureId);
+ this.manufactureId = Number(manufactureId);
+ }
+ this.deviceName = deviceName;
+ this.deviceId = deviceId;
+ }
+
+ public getScanData(): ScanData[] {
+ return this.scanDataList;
+ }
+
+ // 1 订阅扫描结果
+ public onScanResult() {
+ ble.on('BLEDeviceFind', (data: Array) => {
+ if (data.length > 0) {
+ console.info(TAG, 'BLE scan result = ' + data[0].deviceId);
+ this.parseScanResult(data[0].data);
+ // [StartExclude open_close_scan]
+ this.toastReport.showResult(data[0].deviceId);
+ if (!this.scanDataList.some(item => item.getDeviceName() === data[0].deviceName)) {
+ this.scanDataList.push(new ScanData(data[0].deviceId, data[0].deviceName, data[0].rssi, data[0].connectable,
+ new Uint8Array(data[0].data)));
+ }
+ // [EndExclude open_close_scan]
+ }
+ });
+ }
+
+ private parseScanResult(data: ArrayBuffer) {
+ let advData = new Uint8Array(data);
+ if (advData.byteLength == 0) {
+ console.warn(TAG, 'nothing, adv data length is 0');
+ return;
+ }
+ console.info(TAG, 'advData: ' + JSON.stringify(advData));
+
+ let advFlags: number = -1;
+ let txPowerLevel: number = -1;
+ let localName: string = '';
+ let serviceUuids: string[] = [];
+ let serviceSolicitationUuids: string[] = [];
+ let serviceDatas: Record = {};
+ let manufactureSpecificDatas: Record = {};
+
+ let curPos = 0;
+ while (curPos < advData.byteLength) {
+ let length = advData[curPos++];
+ if (length == 0) {
+ break;
+ }
+ let advDataLength = length - 1;
+ let advDataType = advData[curPos++];
+ switch (advDataType) {
+ case BLE_ADV_TYPE_FLAG:
+ advFlags = advData[curPos];
+ break;
+ case BLE_ADV_TYPE_LOCAL_NAME_SHORT:
+ case BLE_ADV_TYPE_LOCAL_NAME_COMPLETE:
+ localName = advData.slice(curPos, curPos + advDataLength).toString();
+ break;
+ case BLE_ADV_TYPE_TX_POWER_LEVEL:
+ txPowerLevel = advData[curPos];
+ break;
+ case BLE_ADV_TYPE_16_BIT_SERVICE_UUIDS_INCOMPLETE:
+ case BLE_ADV_TYPE_16_BIT_SERVICE_UUIDS_COMPLETE:
+ this.parseServiceUuid(BLUETOOTH_UUID_16_BIT_LENGTH, curPos, advDataLength, advData, serviceUuids);
+ break;
+ case BLE_ADV_TYPE_32_BIT_SERVICE_UUIDS_INCOMPLETE:
+ case BLE_ADV_TYPE_32_BIT_SERVICE_UUIDS_COMPLETE:
+ this.parseServiceUuid(BLUETOOTH_UUID_32_BIT_LENGTH, curPos, advDataLength, advData, serviceUuids);
+ break;
+ case BLE_ADV_TYPE_128_BIT_SERVICE_UUIDS_INCOMPLETE:
+ case BLE_ADV_TYPE_128_BIT_SERVICE_UUIDS_COMPLETE:
+ this.parseServiceUuid(BLUETOOTH_UUID_128_BIT_LENGTH, curPos, advDataLength, advData, serviceUuids);
+ break;
+ case BLE_ADV_TYPE_16_BIT_SERVICE_SOLICITATION_UUIDS:
+ this.parseServiceSolicitationUuid(BLUETOOTH_UUID_16_BIT_LENGTH, curPos, advDataLength,
+ advData, serviceSolicitationUuids);
+ break;
+ case BLE_ADV_TYPE_32_BIT_SERVICE_SOLICITATION_UUIDS:
+ this.parseServiceSolicitationUuid(BLUETOOTH_UUID_32_BIT_LENGTH, curPos, advDataLength,
+ advData, serviceSolicitationUuids);
+ break;
+ case BLE_ADV_TYPE_128_BIT_SERVICE_SOLICITATION_UUIDS:
+ this.parseServiceSolicitationUuid(BLUETOOTH_UUID_128_BIT_LENGTH, curPos, advDataLength,
+ advData, serviceSolicitationUuids);
+ break;
+ case BLE_ADV_TYPE_16_BIT_SERVICE_DATA:
+ this.parseServiceData(BLUETOOTH_UUID_16_BIT_LENGTH, curPos, advDataLength, advData, serviceDatas);
+ break;
+ case BLE_ADV_TYPE_32_BIT_SERVICE_DATA:
+ this.parseServiceData(BLUETOOTH_UUID_32_BIT_LENGTH, curPos, advDataLength, advData, serviceDatas);
+ break;
+ case BLE_ADV_TYPE_128_BIT_SERVICE_DATA:
+ this.parseServiceData(BLUETOOTH_UUID_128_BIT_LENGTH, curPos, advDataLength, advData, serviceDatas);
+ break;
+ case BLE_ADV_TYPE_MANUFACTURER_SPECIFIC_DATA:
+ this.parseManufactureData(curPos, advDataLength, advData, manufactureSpecificDatas);
+ break;
+ default:
+ break;
+ }
+ curPos += advDataLength;
+ }
+ }
+
+ private parseServiceUuid(uuidLength: number, curPos: number, advDataLength: number,
+ advData: Uint8Array, serviceUuids: string[]) {
+ while (advDataLength > 0) {
+ let tmpData: Uint8Array = advData.slice(curPos, curPos + uuidLength);
+ serviceUuids.push(this.getUuidFromUint8Array(uuidLength, tmpData));
+ advDataLength -= uuidLength;
+ curPos += uuidLength;
+ }
+ }
+
+ private parseServiceSolicitationUuid(uuidLength: number, curPos: number, advDataLength: number,
+ advData: Uint8Array, serviceSolicitationUuids: string[]) {
+ while (advDataLength > 0) {
+ let tmpData: Uint8Array = advData.slice(curPos, curPos + uuidLength);
+ serviceSolicitationUuids.push(this.getUuidFromUint8Array(uuidLength, tmpData));
+ advDataLength -= uuidLength;
+ curPos += uuidLength;
+ }
+ }
+
+ private getUuidFromUint8Array(uuidLength: number, uuidData: Uint8Array): string {
+ let uuid = '';
+ let temp: string = '';
+ for (let i = uuidLength - 1; i > -1; i--) {
+ temp += uuidData[i].toString(16).padStart(2, '0');
+ }
+ switch (uuidLength) {
+ case BLUETOOTH_UUID_16_BIT_LENGTH:
+ uuid = `0000${temp}-0000-1000-8000-00805F9B34FB`;
+ break;
+ case BLUETOOTH_UUID_32_BIT_LENGTH:
+ uuid = `${temp}-0000-1000-8000-00805F9B34FB`;
+ break;
+ case BLUETOOTH_UUID_128_BIT_LENGTH:
+ uuid = `${temp.substring(0, 8)}-${temp.substring(8, 12)}-${temp.substring(12, 16)}-${temp.substring(16,
+ 20)}-${temp.substring(20, 32)}`;
+ break;
+ default:
+ break;
+ }
+ return uuid;
+ }
+
+ private parseServiceData(uuidLength: number, curPos: number, advDataLength: number,
+ advData: Uint8Array, serviceDatas: Record) {
+ let tmpUuid: Uint8Array = advData.slice(curPos, curPos + uuidLength);
+ let tmpValue: Uint8Array = advData.slice(curPos + uuidLength, curPos + advDataLength);
+ serviceDatas[tmpUuid.toString()] = tmpValue;
+ }
+
+ private parseManufactureData(curPos: number, advDataLength: number,
+ advData: Uint8Array, manufactureSpecificDatas: Record) {
+ let manufactureId: number = (advData[curPos + 1] << 8) + advData[curPos];
+ let tmpValue: Uint8Array = advData.slice(curPos + BLUETOOTH_MANUFACTURE_ID_LENGTH, curPos + advDataLength);
+ manufactureSpecificDatas[manufactureId] = tmpValue;
+ }
+
+ // 2 开启扫描
+ public startScan() {
+ console.info(TAG, 'startBleScan success 1');
+ // 2.1 构造扫描过滤器,需要能够匹配预期的广播包内容
+ let manufactureId = this.manufactureId;
+ let manufactureDataMask: Uint8Array = new Uint8Array([0xFF, 0xFF, 0xFF, 0xFF]);
+ let scanFilter: ble.ScanFilter = {
+ // 根据业务实际情况定义过滤器
+ manufactureId: manufactureId,
+ // manufactureData: manufactureData.buffer,
+ manufactureDataMask: manufactureDataMask.buffer,
+ };
+ // [StartExclude open_close_scan]
+ if (this.deviceName) {
+ console.info('===lyk=== deviceName is not null ' + this.deviceName)
+ scanFilter.name = this.deviceName;
+ }
+ if (this.deviceId) {
+ scanFilter.deviceId = this.deviceId;
+ }
+ // [EndExclude open_close_scan]
+
+ // 2.2 构造扫描参数
+ let scanOptions: ble.ScanOptions = {
+ interval: this.interval,
+ dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
+ matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE,
+ }
+ try {
+ // [StartExclude open_close_scan]
+ this.scanDataList = [];
+ // [EndExclude open_close_scan]
+ this.onScanResult(); // 订阅扫描结果
+ ble.startBLEScan([scanFilter], scanOptions);
+ // [StartExclude open_close_scan]
+ this.toastReport.showResult('startBleScan success');
+ // [EndExclude open_close_scan]
+ console.info(TAG, 'startBleScan success');
+ } catch (err) {
+ // [StartExclude open_close_scan]
+ this.toastReport.showResult('startBleScan fail');
+ // [EndExclude open_close_scan]
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 3 关闭扫描
+ public stopScan() {
+ try {
+ ble.off('BLEDeviceFind', (data: Array) => { // 取消订阅扫描结果
+ console.info(TAG, 'off success');
+ });
+ ble.stopBLEScan();
+ // [StartExclude open_close_scan]
+ this.toastReport.showResult('stopBleScan success');
+ // [EndExclude open_close_scan]
+ console.info(TAG, 'stopBleScan success');
+ } catch (err) {
+ // [StartExclude open_close_scan]
+ this.toastReport.showResult('stopBleScan fail');
+ // [EndExclude open_close_scan]
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+}
+
+let bleScanManager = new BleScanManager();
+
+export default bleScanManager as BleScanManager;
+// [End open_close_scan]
diff --git a/bluetoothSample/entry/src/main/ets/bluetoothService/BluetoothSwitch.ets b/bluetoothSample/entry/src/main/ets/bluetoothService/BluetoothSwitch.ets
new file mode 100644
index 0000000000000000000000000000000000000000..5b10dd2adb8c4e4c2203f8d15408b98ee53e5e2e
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/bluetoothService/BluetoothSwitch.ets
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+// [Start open_close_bluetooth]
+import { access } from '@kit.ConnectivityKit';
+
+export class BluetoothSwitch {
+ public openBluetooth() {
+
+ access.off('stateChange');
+ access.enableBluetooth();
+ access.on('stateChange', (data) => {
+ let btStateMessage = '';
+ switch (data) {
+ case 0:
+ btStateMessage += 'STATE_OFF';
+ break;
+ case 1:
+ btStateMessage += 'STATE_TURNING_ON';
+ break;
+ case 2:
+ btStateMessage += 'STATE_ON';
+ break;
+ case 3:
+ btStateMessage += 'STATE_TURNING_OFF';
+ break;
+ case 4:
+ btStateMessage += 'STATE_BLE_TURNING_ON';
+ break;
+ case 5:
+ btStateMessage += 'STATE_BLE_ON';
+ break;
+ case 6:
+ btStateMessage += 'STATE_BLE_TURNING_OFF';
+ break;
+ default:
+ btStateMessage += 'unknown status';
+ break;
+ }
+ if (btStateMessage == 'STATE_ON') {
+ access.off('stateChange');
+ }
+ console.info('bluetooth statues: ' + btStateMessage);
+ });
+ }
+
+ public closeBluetooth() {
+ access.off('stateChange');
+ access.disableBluetooth();
+ access.on('stateChange', (data) => {
+ let btStateMessage = '';
+ switch (data) {
+ case 0:
+ btStateMessage += 'STATE_OFF';
+ break;
+ case 1:
+ btStateMessage += 'STATE_TURNING_ON';
+ break;
+ case 2:
+ btStateMessage += 'STATE_ON';
+ break;
+ case 3:
+ btStateMessage += 'STATE_TURNING_OFF';
+ break;
+ case 4:
+ btStateMessage += 'STATE_BLE_TURNING_ON';
+ break;
+ case 5:
+ btStateMessage += 'STATE_BLE_ON';
+ break;
+ case 6:
+ btStateMessage += 'STATE_BLE_TURNING_OFF';
+ break;
+ default:
+ btStateMessage += 'unknown status';
+ break;
+ }
+ if (btStateMessage == 'STATE_OFF') {
+ access.off('stateChange');
+ }
+ });
+ }
+}
+// [End open_close_bluetooth]
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/main/ets/bluetoothService/GattClientManager.ets b/bluetoothSample/entry/src/main/ets/bluetoothService/GattClientManager.ets
new file mode 100644
index 0000000000000000000000000000000000000000..745998b1d900c8c1ac7fe3bd76253b7cadac20af
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/bluetoothService/GattClientManager.ets
@@ -0,0 +1,405 @@
+/*
+ * 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.
+ */
+
+// [Start generic_attribute]
+import { ble } from '@kit.ConnectivityKit';
+import { constant } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { ToastReport } from '../common/ToastReport';
+import util from '@ohos.util';
+
+const TAG: string = 'GattClientManager';
+// [StartExclude generic_attribute]
+let encoder = new util.TextEncoder();
+// [EndExclude generic_attribute]
+
+export class GattData {
+ public serviceUuid: string = '00001810-0000-1000-8000-00805F9B34FB';
+ public characteristicUuid: string = '00001820-0000-1000-8000-00805F9B34FB';
+ public descriptorUuid: string = '00002902-0000-1000-8000-00805F9B34FB';
+ public characteristicValue: string = '';
+ public descriptorValue: string = '';
+}
+
+export class GattClientManager {
+ public device: string | undefined = undefined;
+ public gattClient: ble.GattClientDevice | undefined = undefined;
+ public connectState: ble.ProfileConnectionState = constant.ProfileConnectionState.STATE_DISCONNECTED;
+ public myServiceUuid: string = '00001810-0000-1000-8000-00805F9B34FB';
+ public myCharacteristicUuid: string = '00001820-0000-1000-8000-00805F9B34FB';
+ public myDescriptorUuid: string = '00002902-0000-1000-8000-00805F9B34FB'; // 2902一般用于notification或者indication
+ public myCharacteristicValue: string = ''
+ public myDescriptorValue: string = ''
+ public serviceResult: string = '';
+ public found: boolean = false;
+ public toastReport: ToastReport = new ToastReport();
+
+ // 构造BLEDescriptor
+ private initDescriptor(des: string, value: ArrayBuffer): ble.BLEDescriptor {
+ let descriptor: ble.BLEDescriptor = {
+ serviceUuid: this.myServiceUuid,
+ characteristicUuid: this.myCharacteristicUuid,
+ descriptorUuid: des,
+ descriptorValue: value
+ };
+ return descriptor;
+ }
+
+ // 构造BLECharacteristic
+ private initCharacteristic(): ble.BLECharacteristic {
+ let descriptors: ble.BLEDescriptor[] = [];
+ let desLength = this.myDescriptorValue.length;
+ let descBuffer = new ArrayBuffer(desLength);
+ let descValue = new Uint8Array(descBuffer);
+ encoder.encodeIntoUint8Array(this.myCharacteristicValue, descValue);
+ descriptors[0] = this.initDescriptor(this.myDescriptorUuid, descBuffer);
+ let length = this.myCharacteristicValue.length;
+ let charBuffer = new ArrayBuffer(length);
+ let charValue = new Uint8Array(charBuffer);
+ encoder.encodeIntoUint8Array(this.myCharacteristicValue, charValue);
+ let characteristic: ble.BLECharacteristic = {
+ serviceUuid: this.myServiceUuid,
+ characteristicUuid: this.myCharacteristicUuid,
+ characteristicValue: charBuffer,
+ descriptors: descriptors
+ };
+ return characteristic;
+ }
+
+ private logCharacteristic(char: ble.BLECharacteristic) {
+ let message = 'logCharacteristic uuid:' + char.characteristicUuid + '\n';
+ let value = new Uint8Array(char.characteristicValue);
+ message += 'logCharacteristic value: ';
+ for (let i = 0; i < char.characteristicValue.byteLength; i++) {
+ message += value[i] + ' ';
+ }
+ console.info(TAG, message);
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult(message);
+ // [EndExclude generic_attribute]
+ }
+
+ private logDescriptor(des: ble.BLEDescriptor) {
+ let message = 'logDescriptor uuid:' + des.descriptorUuid + '\n';
+ let value = new Uint8Array(des.descriptorValue);
+ message += 'logDescriptor value: ';
+ for (let i = 0; i < des.descriptorValue.byteLength; i++) {
+ message += value[i] + ' ';
+ }
+ console.info(TAG, message);
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult(message);
+ // [EndExclude generic_attribute]
+ }
+
+ private checkService(services: Array): boolean {
+ for (let i = 0; i < services.length; i++) {
+ if (services[i].serviceUuid != this.myServiceUuid) {
+ continue;
+ }
+ for (let j = 0; j < services[i].characteristics.length; j++) {
+ if (services[i].characteristics[j].characteristicUuid != this.myCharacteristicUuid) {
+ continue;
+ }
+ for (let k = 0; k < services[i].characteristics[j].descriptors.length; k++) {
+ if (services[i].characteristics[j].descriptors[k].descriptorUuid == this.myDescriptorUuid) {
+ console.info(TAG, 'find expected service from server');
+ return true;
+ }
+ }
+ }
+ }
+ console.error(TAG, 'no expected service from server');
+ return false;
+ }
+
+ public getResult(): string {
+ return this.serviceResult;
+ }
+
+ public setGattData(data: GattData) {
+ this.myServiceUuid = data.serviceUuid;
+ this.myCharacteristicUuid = data.characteristicUuid;
+ this.myDescriptorUuid = data.descriptorUuid;
+ this.myCharacteristicValue = data.characteristicValue;
+ this.myDescriptorValue = data.descriptorValue;
+ }
+
+ // 1. 订阅连接状态变化事件
+ public onGattClientStateChange() {
+ if (!this.gattClient) {
+ console.error(TAG, 'no gattClient');
+ return;
+ }
+ try {
+ this.gattClient.on('BLEConnectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => {
+ let state = '';
+ switch (stateInfo.state) {
+ case 0:
+ state = 'DISCONNECTED';
+ break;
+ case 1:
+ state = 'CONNECTING';
+ break;
+ case 2:
+ state = 'CONNECTED';
+ break;
+ case 3:
+ state = 'DISCONNECTING';
+ break;
+ default:
+ state = 'undefined';
+ break;
+ }
+ console.info(TAG, 'onGattClientStateChange: device=' + stateInfo.deviceId + ', state=' + state);
+ if (stateInfo.deviceId == this.device) {
+ this.connectState = stateInfo.state;
+ }
+ });
+ } catch (err) {
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 2. client端主动连接时调用
+ public startConnect(peerDevice: string | undefined) { // 对端设备一般通过ble scan获取到
+ if (this.connectState != constant.ProfileConnectionState.STATE_DISCONNECTED || peerDevice == undefined) {
+ console.error(TAG, 'startConnect failed');
+ return;
+ }
+ console.info(TAG, 'startConnect ' + peerDevice);
+ this.device = peerDevice;
+ // 2.1 使用device构造gattClient,后续的交互都需要使用该实例
+ this.gattClient = ble.createGattClientDevice(peerDevice);
+ try {
+ this.onGattClientStateChange(); // 2.2 订阅连接状态
+ this.gattClient.connect(); // 2.3 发起连接
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('startConnect success');
+ console.info(TAG, 'startConnect success');
+ // [EndExclude generic_attribute]
+ } catch (err) {
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('startConnect fail');
+ // [EndExclude generic_attribute]
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 3. client端连接成功后,需要进行服务发现
+ public async discoverServices() {
+ if (!this.gattClient) {
+ console.info(TAG, 'no gattClient');
+ return;
+ }
+ console.info(TAG, 'discoverServices');
+ try {
+ await this.gattClient.getServices().then((result: Array) => {
+ console.info(TAG, 'getServices success: ' + JSON.stringify(result));
+ // [StartExclude generic_attribute]
+ this.serviceResult = JSON.stringify(result);
+ this.toastReport.showResult('getServices success: ' + JSON.stringify(result));
+ // [EndExclude generic_attribute]
+ this.found = this.checkService(result); // 要确保server端的服务内容有业务所需要的服务
+ });
+ } catch (err) {
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('getServices fail');
+ // [EndExclude generic_attribute]
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 4. 在确保拿到了server端的服务结果后,he
+ public readCharacteristicValue() {
+ if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
+ console.error(TAG, 'no gattClient or not connected');
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('no gattClient or not connected');
+ // [EndExclude generic_attribute]
+ return;
+ }
+ if (!this.found) { // 要确保server端有对应的characteristic
+ console.error(TAG, 'no characteristic from server');
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('no characteristic from server');
+ // [EndExclude generic_attribute]
+ return;
+ }
+
+ let characteristic = this.initCharacteristic();
+ console.info(TAG, 'readCharacteristicValue');
+ try {
+ this.gattClient.readCharacteristicValue(characteristic).then((outData: ble.BLECharacteristic) => {
+ this.logCharacteristic(outData);
+ })
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('readCharacteristicValue success');
+ // [EndExclude generic_attribute]
+ } catch (err) {
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('readCharacteristicValue fail');
+ // [EndExclude generic_attribute]
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 5. 在确保拿到了server端的服务结果后,写入server端特定服务的特征值时调用
+ public writeCharacteristicValue() {
+ if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
+ console.error(TAG, 'no gattClient or not connected');
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('no gattClient or not connected');
+ // [EndExclude generic_attribute]
+ return;
+ }
+ if (!this.found) { // 要确保server端有对应的characteristic
+ console.error(TAG, 'no characteristic from server');
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('no characteristic from server');
+ // [EndExclude generic_attribute]
+ return;
+ }
+
+ let characteristic = this.initCharacteristic();
+ console.info(TAG, 'writeCharacteristicValue');
+ try {
+ this.gattClient.writeCharacteristicValue(characteristic, ble.GattWriteType.WRITE, (err) => {
+ if (err) {
+ console.error(TAG,
+ 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ return;
+ }
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('writeCharacteristicValue success');
+ // [EndExclude generic_attribute]
+ console.info(TAG, 'writeCharacteristicValue success');
+ });
+ } catch (err) {
+ // [StartExclude generic_attribute]
+ console.info(TAG, 'writeCharacteristicValue fail');
+ this.toastReport.showResult('writeCharacteristicValue fail');
+ // [EndExclude generic_attribute]
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 6. 在确保拿到了server端的服务结果后,读取server端特定服务的描述符时调用
+ public readDescriptorValue() {
+ if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
+ console.error(TAG, 'no gattClient or not connected');
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('no gattClient or not connected');
+ // [EndExclude generic_attribute]
+ return;
+ }
+ if (!this.found) { // 要确保server端有对应的descriptor
+ console.error(TAG, 'no descriptor from server');
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('no descriptor from server');
+ // [EndExclude generic_attribute]
+ return;
+ }
+
+ let descBuffer = new ArrayBuffer(0);
+ let descriptor = this.initDescriptor(this.myDescriptorUuid, descBuffer);
+ console.info(TAG, 'readDescriptorValue');
+ try {
+ this.gattClient.readDescriptorValue(descriptor).then((outData: ble.BLEDescriptor) => {
+ this.logDescriptor(outData);
+ });
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('readDescriptorValue success');
+ // [EndExclude generic_attribute]
+ } catch (err) {
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('readDescriptorValue fail');
+ // [EndExclude generic_attribute]
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 7. 在确保拿到了server端的服务结果后,写入server端特定服务的描述符时调用
+ public writeDescriptorValue() {
+ if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
+ console.error(TAG, 'no gattClient or not connected');
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('no gattClient or not connected');
+ // [EndExclude generic_attribute]
+ return;
+ }
+ if (!this.found) { // 要确保server端有对应的descriptor
+ console.error(TAG, 'no descriptor from server');
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('no descriptor from server');
+ // [EndExclude generic_attribute]
+ return;
+ }
+
+ let length = this.myDescriptorValue.length;
+ let descBuffer = new ArrayBuffer(length);
+ let descValue = new Uint8Array(descBuffer);
+ encoder.encodeIntoUint8Array(this.myDescriptorValue, descValue);
+ let descriptor = this.initDescriptor(this.myDescriptorUuid, descBuffer);
+ console.info(TAG, 'writeDescriptorValue');
+ try {
+ this.gattClient.writeDescriptorValue(descriptor, (err) => {
+ if (err) {
+ console.error(TAG,
+ 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ return;
+ }
+ console.info(TAG, 'writeDescriptorValue success');
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('writeDescriptorValue success');
+ // [EndExclude generic_attribute]
+ });
+ } catch (err) {
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('writeDescriptorValue fail');
+ // [EndExclude generic_attribute]
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 8.client端主动断开时调用
+ public stopConnect() {
+ if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
+ console.error(TAG, 'no gattClient or not connected');
+ return;
+ }
+
+ console.info(TAG, 'stopConnect ' + this.device);
+ try {
+ this.gattClient.disconnect(); // 8.1 断开连接
+ this.gattClient.off('BLEConnectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => {
+ });
+ this.gattClient.close() // 8.2 如果不再使用此gattClient,则需要close
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('stopConnect success');
+ // [EndExclude generic_attribute]
+ } catch (err) {
+ // [StartExclude generic_attribute]
+ this.toastReport.showResult('stopConnect fail');
+ // [EndExclude generic_attribute]
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+}
+
+let gattClientManager = new GattClientManager();
+
+export default gattClientManager as GattClientManager;
+// [End generic_attribute]
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/main/ets/bluetoothService/GattServerManager.ets b/bluetoothSample/entry/src/main/ets/bluetoothService/GattServerManager.ets
new file mode 100644
index 0000000000000000000000000000000000000000..aa38c2fb43a87c6f629c9894e4e3283cdc51546e
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/bluetoothService/GattServerManager.ets
@@ -0,0 +1,297 @@
+/*
+ * 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.
+ */
+
+// [Start gatt_server_manage]
+import { ble } from '@kit.ConnectivityKit';
+import { constant } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { ToastReport } from '../common/ToastReport'
+
+const TAG: string = 'GattServerManager';
+
+export class GattServerManager {
+ public gattServer: ble.GattServer = ble.createGattServer();
+ public connectState: ble.ProfileConnectionState = constant.ProfileConnectionState.STATE_DISCONNECTED;
+ public myServiceUuid: string = '00001810-0000-1000-8000-00805F9B34FB';
+ public myCharacteristicUuid: string = '00001820-0000-1000-8000-00805F9B34FB';
+ public myFirstDescriptorUuid: string = '00002902-0000-1000-8000-00805F9B34FB'; // 2902一般用于notification或者indication
+ public mySecondDescriptorUuid: string = '00002903-0000-1000-8000-00805F9B34FB';
+ public toastReport: ToastReport = new ToastReport();
+
+ // 构造BLEDescriptor
+ private initDescriptor(des: string, value: ArrayBuffer): ble.BLEDescriptor {
+ let descriptor: ble.BLEDescriptor = {
+ serviceUuid: this.myServiceUuid,
+ characteristicUuid: this.myCharacteristicUuid,
+ descriptorUuid: des,
+ descriptorValue: value
+ };
+ return descriptor;
+ }
+
+ // 构造BLECharacteristic
+ private initCharacteristic(): ble.BLECharacteristic {
+ let descriptors: ble.BLEDescriptor[] = [];
+ let descBuffer = new ArrayBuffer(2);
+ let descValue = new Uint8Array(descBuffer);
+ descValue[0] = 31;
+ descValue[1] = 32;
+ descriptors[0] = this.initDescriptor(this.myFirstDescriptorUuid, new ArrayBuffer(2));
+ descriptors[1] = this.initDescriptor(this.mySecondDescriptorUuid, descBuffer);
+ let charBuffer = new ArrayBuffer(2);
+ let charValue = new Uint8Array(charBuffer);
+ charValue[0] = 21;
+ charValue[1] = 22;
+ let characteristic: ble.BLECharacteristic = {
+ serviceUuid: this.myServiceUuid,
+ characteristicUuid: this.myCharacteristicUuid,
+ characteristicValue: charBuffer,
+ descriptors: descriptors
+ };
+ return characteristic;
+ }
+
+ // 1. 订阅连接状态变化事件
+ public onGattServerStateChange() {
+ if (!this.gattServer) {
+ console.error(TAG, 'no gattServer');
+ return;
+ }
+ try {
+ this.gattServer.on('connectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => {
+ let state = '';
+ switch (stateInfo.state) {
+ case 0:
+ state = 'DISCONNECTED';
+ break;
+ case 1:
+ state = 'CONNECTING';
+ break;
+ case 2:
+ state = 'CONNECTED';
+ break;
+ case 3:
+ state = 'DISCONNECTING';
+ break;
+ default:
+ state = 'undefined';
+ break;
+ }
+ console.info(TAG, 'onGattServerStateChange: device=' + stateInfo.deviceId + ', state=' + state);
+ });
+ } catch (err) {
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 2. server端注册服务时调用
+ public registerServer() {
+ let characteristics: ble.BLECharacteristic[] = [];
+ let characteristic = this.initCharacteristic();
+ characteristics.push(characteristic);
+ let gattService: ble.GattService = {
+ serviceUuid: this.myServiceUuid,
+ isPrimary: true,
+ characteristics: characteristics
+ };
+
+ console.info(TAG, 'registerServer ' + this.myServiceUuid);
+ try {
+ // this.gattServer = ble.createGattServer(); 初始化时已经构造,去除报错// 2.1 构造gattServer,后续的交互都需要使用该实例
+ this.onGattServerStateChange(); // 2.2 订阅连接状态
+ this.gattServer.addService(gattService);
+ this.toastReport.showResult('registerServer success');
+ } catch (err) {
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ this.toastReport.showResult('registerServer failed');
+ }
+ }
+
+ // 3. 订阅来自gattClient的读取特征值请求时调用
+ public onCharacteristicRead() {
+ if (!this.gattServer) {
+ console.error(TAG, 'no gattServer');
+ return;
+ }
+
+ console.info(TAG, 'onCharacteristicRead');
+ try {
+ this.gattServer.on('characteristicRead', (charReq: ble.CharacteristicReadRequest) => {
+ let deviceId: string = charReq.deviceId;
+ let transId: number = charReq.transId;
+ let offset: number = charReq.offset;
+ console.info(TAG, 'receive characteristicRead');
+ let rspBuffer = new ArrayBuffer(2);
+ let rspValue = new Uint8Array(rspBuffer);
+ rspValue[0] = 21;
+ rspValue[1] = 22;
+ let serverResponse: ble.ServerResponse = {
+ deviceId: deviceId,
+ transId: transId,
+ status: 0, // 0表示成功
+ offset: offset,
+ value: rspBuffer
+ };
+
+ try {
+ this.gattServer.sendResponse(serverResponse);
+ } catch (err) {
+ console.error(TAG,
+ 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ });
+ } catch (err) {
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 4. 订阅来自gattClient的写入特征值请求时调用
+ public onCharacteristicWrite() {
+ if (!this.gattServer) {
+ console.error(TAG, 'no gattServer');
+ return;
+ }
+
+ console.info(TAG, 'onCharacteristicWrite');
+ try {
+ this.gattServer.on('characteristicWrite', (charReq: ble.CharacteristicWriteRequest) => {
+ let deviceId: string = charReq.deviceId;
+ let transId: number = charReq.transId;
+ let offset: number = charReq.offset;
+ console.info(TAG, 'receive characteristicWrite: needRsp=' + charReq.needRsp);
+ if (!charReq.needRsp) {
+ return;
+ }
+ let rspBuffer = new ArrayBuffer(0);
+ let serverResponse: ble.ServerResponse = {
+ deviceId: deviceId,
+ transId: transId,
+ status: 0, // 0表示成功
+ offset: offset,
+ value: rspBuffer
+ };
+
+ try {
+ this.gattServer.sendResponse(serverResponse);
+ } catch (err) {
+ console.error(TAG,
+ 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ });
+ } catch (err) {
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 5. 订阅来自gattClient的读取描述符请求时调用
+ public onDescriptorRead() {
+ if (!this.gattServer) {
+ console.error(TAG, 'no gattServer');
+ return;
+ }
+
+ console.info(TAG, 'onDescriptorRead');
+ try {
+ this.gattServer.on('descriptorRead', (desReq: ble.DescriptorReadRequest) => {
+ let deviceId: string = desReq.deviceId;
+ let transId: number = desReq.transId;
+ let offset: number = desReq.offset;
+ console.info(TAG, 'receive descriptorRead');
+ let rspBuffer = new ArrayBuffer(2);
+ let rspValue = new Uint8Array(rspBuffer);
+ rspValue[0] = 31;
+ rspValue[1] = 32;
+ let serverResponse: ble.ServerResponse = {
+ deviceId: deviceId,
+ transId: transId,
+ status: 0, // 0表示成功
+ offset: offset,
+ value: rspBuffer
+ };
+
+ try {
+ this.gattServer.sendResponse(serverResponse);
+ } catch (err) {
+ console.error(TAG,
+ 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ });
+ } catch (err) {
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 6. 订阅来自gattClient的写入描述符请求时调用
+ public onDescriptorWrite() {
+ if (!this.gattServer) {
+ console.error(TAG, 'no gattServer');
+ return;
+ }
+
+ console.info(TAG, 'onDescriptorWrite');
+ try {
+ this.gattServer.on('descriptorWrite', (desReq: ble.DescriptorWriteRequest) => {
+ let deviceId: string = desReq.deviceId;
+ let transId: number = desReq.transId;
+ let offset: number = desReq.offset;
+ console.info(TAG, 'receive descriptorWrite: needRsp=' + desReq.needRsp);
+ if (!desReq.needRsp) {
+ return;
+ }
+ let rspBuffer = new ArrayBuffer(0);
+ let serverResponse: ble.ServerResponse = {
+ deviceId: deviceId,
+ transId: transId,
+ status: 0, // 0表示成功
+ offset: offset,
+ value: rspBuffer
+ };
+
+ try {
+ this.gattServer.sendResponse(serverResponse);
+ } catch (err) {
+ console.error(TAG,
+ 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ });
+ } catch (err) {
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+
+ // 7. server端删除服务,不再使用时调用
+ public unRegisterServer() {
+ if (!this.gattServer) {
+ console.error(TAG, 'no gattServer');
+ return;
+ }
+
+ console.info(TAG, 'unRegisterServer ' + this.myServiceUuid);
+ try {
+ this.gattServer.removeService(this.myServiceUuid); // 7.1 删除服务
+ this.gattServer.off('connectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => { // 7.2 取消订阅连接状态
+ });
+ this.gattServer.close() // 7.3 如果不再使用此gattServer,则需要close
+ this.toastReport.showResult('unRegisterServer');
+ } catch (err) {
+ console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
+ }
+ }
+}
+
+let gattServerManager = new GattServerManager();
+
+export default gattServerManager as GattServerManager;
+// [End gatt_server_manage]
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/main/ets/common/AdvertisingDialog.ets b/bluetoothSample/entry/src/main/ets/common/AdvertisingDialog.ets
new file mode 100644
index 0000000000000000000000000000000000000000..5fe1d7d47cefc85fa90a9a96ba9c99fe3a30b0ca
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/common/AdvertisingDialog.ets
@@ -0,0 +1,159 @@
+/*
+ * 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 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 { util } from '@kit.ArkTS';
+
+@CustomDialog
+@Component
+export struct AdvertisingDialog {
+ @Link textValueOfAdvManufactureId: string;
+ @Link inputValueOfAdvManufactureId: string;
+ @Link textValueOfAdvManufactureValueBuffer: string;
+ @Link inputValueOfAdvManufactureValueBuffer: Uint8Array;
+ @Link textValueOfAdvServiceUuids: string;
+ @Link inputValueOfAdvServiceUuids: string;
+ @Link textValueOfAdvServiceBuffer: string;
+ @Link inputValueOfAdvServiceBuffer: Uint8Array;
+ @Link textValueOfAdvIncludeDeviceName: string;
+ @Link inputValueOfAdvIncludeDeviceName: boolean;
+ decoder = new util.TextDecoder();
+ controller?: CustomDialogController
+ cancel: () => void = () => {
+ }
+ confirm: () => void = () => {
+ }
+
+ build() {
+ Column() {
+ Text('set advertising parameters').fontSize(20).margin({ top: 10, bottom: 10 });
+ Row() {
+ Text('ManufactureValueBuffer')
+ .margin(5)
+ .width('30%')
+ TextInput({ text: this.textValueOfAdvManufactureValueBuffer })
+ .height(40)
+ .width('65%')
+ .onChange((value: string) => {
+ this.textValueOfAdvManufactureValueBuffer = value;
+ })
+ .margin(5)
+ }
+
+ Row() {
+ Text('manufactureId')
+ .width('30%')
+ .margin(5)
+ TextInput({ text: this.textValueOfAdvManufactureId })
+ .height(40)
+ .width('65%')
+ .onChange((value: string) => {
+ this.textValueOfAdvManufactureId = value;
+ })
+ .margin(5)
+ }
+
+ Row() {
+ Text('serviceBuffer')
+ .width('30%')
+ .margin(5)
+ TextInput({ text: this.textValueOfAdvServiceBuffer })
+ .height(40)
+ .width('65%')
+ .onChange((value: string) => {
+ this.textValueOfAdvServiceBuffer = value;
+ })
+ .margin(5)
+ }
+
+ Row() {
+ Text('serviceUuids')
+ .width('30%')
+ .margin(5)
+ TextInput({ text: this.textValueOfAdvServiceUuids })
+ .height(40)
+ .width('65%')
+ .onChange((value: string) => {
+ this.textValueOfAdvServiceUuids = value;
+ })
+ .margin(5)
+ }
+
+ Row() {
+ Text('enableIncludeDeviceName')
+ .width('30%')
+ .margin(5)
+ TextInput({ text: this.textValueOfAdvIncludeDeviceName })
+ .height(40)
+ .width('65%')
+ .onChange((value: string) => {
+ this.textValueOfAdvIncludeDeviceName = value;
+ })
+ .margin(5)
+ }
+
+
+ Flex({ justifyContent: FlexAlign.SpaceAround }) {
+ Button('cancel')
+ .onClick(() => {
+ if (this.controller != undefined) {
+ this.controller.close();
+ this.cancel();
+ }
+ }).backgroundColor(0xffffff).fontColor(Color.Black)
+
+ Button('clean up')
+ .onClick(() => {
+ this.textValueOfAdvManufactureValueBuffer = '';
+ this.textValueOfAdvManufactureId = '';
+ this.textValueOfAdvServiceUuids = '';
+ this.textValueOfAdvServiceBuffer = '';
+ this.textValueOfAdvIncludeDeviceName = '';
+ this.inputValueOfAdvManufactureValueBuffer = new Uint8Array(0);
+ this.inputValueOfAdvManufactureId = '';
+ this.inputValueOfAdvServiceUuids = '00001888-0000-1000-8000-00805f9b34fb';
+ this.inputValueOfAdvServiceBuffer = new Uint8Array(0);
+ this.inputValueOfAdvIncludeDeviceName = false;
+ }).backgroundColor(0xffffff).fontColor(Color.Red)
+
+ Button('confirm')
+ .onClick(() => {
+ if (this.controller != undefined) {
+ let manufactureValueBuffer = new Uint8Array(this.textValueOfAdvManufactureValueBuffer.length);
+ for (let i = 0; i < this.textValueOfAdvManufactureValueBuffer.length; i++) {
+ manufactureValueBuffer[i] = parseInt(this.textValueOfAdvManufactureValueBuffer[i], 10);
+ }
+ let serviceBuffer = new Uint8Array(this.textValueOfAdvServiceBuffer.length);
+ for (let i = 0; i < this.textValueOfAdvManufactureValueBuffer.length; i++) {
+ manufactureValueBuffer[i] = parseInt(this.textValueOfAdvManufactureValueBuffer[i], 10);
+ }
+ this.inputValueOfAdvServiceBuffer = serviceBuffer;
+ this.inputValueOfAdvManufactureValueBuffer = manufactureValueBuffer;
+ this.inputValueOfAdvManufactureId = this.textValueOfAdvManufactureId;
+ if (this.textValueOfAdvServiceUuids) {
+ this.inputValueOfAdvServiceUuids = this.textValueOfAdvServiceUuids;
+ }
+ if (this.textValueOfAdvIncludeDeviceName) {
+ this.inputValueOfAdvIncludeDeviceName = true;
+ } else {
+ this.inputValueOfAdvIncludeDeviceName = false;
+ }
+ this.controller.close();
+ this.confirm();
+ }
+ }).backgroundColor(0xffffff).fontColor(Color.Red)
+ }.margin({ bottom: 10 })
+ }.borderRadius(10)
+ }
+}
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/main/ets/common/ScanData.ets b/bluetoothSample/entry/src/main/ets/common/ScanData.ets
new file mode 100644
index 0000000000000000000000000000000000000000..4c5d3b83333bac97a2ca46df7aa81a78ef4bffee
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/common/ScanData.ets
@@ -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.
+ */
+
+export class ScanData {
+ private deviceId: string = '';
+ private deviceName: string = '';
+ private rssi: number = 0;
+ private connectable: boolean = false;
+ private data: Uint8Array = new Uint8Array([0xFF, 0xFF, 0xFF, 0xFF]);
+
+ constructor(deviceId: string = '', deviceName: string = 'null', rssi: number = 0, connectable: boolean = false,
+ data: Uint8Array = new Uint8Array([0xFF, 0xFF, 0xFF, 0xFF])) {
+ this.deviceId = deviceId;
+ this.deviceName = deviceName;
+ this.rssi = rssi;
+ this.connectable = connectable;
+ this.data = data;
+ }
+
+ public setDeviceId(deviceId: string) {
+ this.deviceId = deviceId;
+ }
+
+ public setData(data: Uint8Array) {
+ this.data = data;
+ }
+
+ public getDeviceId(): string {
+ return this.deviceId;
+ }
+
+ public getData(): Uint8Array {
+ return this.data;
+ }
+
+ public setDeviceName(deviceName: string) {
+ this.deviceName = deviceName;
+ }
+
+ public getDeviceName(): string {
+ return this.deviceName;
+ }
+
+ public setRssi(rssi: number) {
+ this.rssi = rssi;
+ }
+
+ public getRssi(): number {
+ return this.rssi;
+ }
+
+ public setConnectable(connectable: boolean) {
+ this.connectable = connectable;
+ }
+
+ public getConnectable(): boolean {
+ return this.connectable;
+ }
+}
+
+let scanData = new ScanData();
+
+export default scanData as ScanData;
+
diff --git a/bluetoothSample/entry/src/main/ets/common/ScanDialog.ets b/bluetoothSample/entry/src/main/ets/common/ScanDialog.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a5d99a4f8d98f5798269e6f696772a918b15a5fa
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/common/ScanDialog.ets
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+@CustomDialog
+@Component
+export struct ScanDialog {
+ @Link textValueOfInterval: string;
+ @Link inputValueOfInterval: string;
+ @Link textValueOfManufactureId: string;
+ @Link inputValueOfManufactureId: string;
+ @Link textValueOfDeviceName: string;
+ @Link inputValueOfDeviceName: string;
+ @Link textValueOfDeviceId: string;
+ @Link inputValueOfDeviceId: string;
+ controller?: CustomDialogController
+ cancel: () => void = () => {
+ }
+ confirm: () => void = () => {
+ }
+
+ build() {
+ Column() {
+ Text('set scan filtering parameters').fontSize(20).margin({ top: 10, bottom: 10 });
+ Row() {
+ Text('interval')
+ .width('30%')
+ .margin(5)
+ TextInput({ placeholder: 'default is 0', text: this.textValueOfInterval })
+ .height(40)
+ .width('65%')
+ .onChange((value: string) => {
+ this.textValueOfInterval = value;
+ })
+
+ }
+
+ Row() {
+ Text('manufactureId')
+ .width('30%')
+ .margin(5)
+ TextInput({ placeholder: 'default is 4567', text: this.textValueOfManufactureId })
+ .height(40)
+ .width('65%')
+ .onChange((value: string) => {
+ this.textValueOfManufactureId = value;
+ })
+ }
+
+ Row() {
+ Text('deviceName')
+ .width('30%')
+ .margin(5)
+ TextInput({ placeholder: 'default is \'\'', text: this.textValueOfDeviceName })
+ .height(40)
+ .width('65%')
+ .onChange((value: string) => {
+ this.textValueOfDeviceName = value;
+ })
+ }
+
+ Row() {
+ Text('deviceId')
+ .width('30%')
+ .margin(5)
+ TextInput({ placeholder: 'default is \'\'', text: this.textValueOfDeviceId })
+ .height(40)
+ .width('65%')
+ .onChange((value: string) => {
+ this.textValueOfDeviceId = value;
+ })
+ }
+
+ Flex({ justifyContent: FlexAlign.SpaceAround }) {
+ Button('cancel')
+ .onClick(() => {
+ if (this.controller != undefined) {
+ this.controller.close();
+ this.cancel();
+ }
+ }).backgroundColor(0xffffff).fontColor(Color.Black)
+
+ Button('clean up')
+ .onClick(() => {
+ this.textValueOfInterval = '';
+ this.inputValueOfInterval = '0';
+ this.textValueOfManufactureId = '';
+ this.inputValueOfManufactureId = '4567';
+ this.textValueOfDeviceName = '';
+ this.inputValueOfDeviceName = '';
+ this.textValueOfDeviceId = '';
+ this.inputValueOfDeviceId = '';
+ }).backgroundColor(0xffffff).fontColor(Color.Red)
+
+ Button('confirm')
+ .onClick(() => {
+ if (this.controller != undefined) {
+ this.inputValueOfInterval = this.textValueOfInterval;
+ this.inputValueOfManufactureId = this.textValueOfManufactureId;
+ this.inputValueOfDeviceName = this.textValueOfDeviceName;
+ this.inputValueOfDeviceId = this.textValueOfDeviceId;
+ this.controller.close();
+ this.confirm();
+ }
+ }).backgroundColor(0xffffff).fontColor(Color.Red)
+ }.margin({ bottom: 10 })
+ }.borderRadius(10)
+ }
+}
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/main/ets/common/ToastReport.ets b/bluetoothSample/entry/src/main/ets/common/ToastReport.ets
new file mode 100644
index 0000000000000000000000000000000000000000..80c12c4a9c04c5a82e2ed4e2278f2eceee52c93f
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/common/ToastReport.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 { promptAction } from '@kit.ArkUI'
+
+export class ToastReport {
+ public showResult(message: string) {
+ promptAction.showToast({
+ message: message,
+ duration: 2000,
+ showMode: promptAction.ToastShowMode.DEFAULT,
+ bottom: 80
+ })
+ }
+}
+
+let toastReport = new ToastReport();
+
+export default toastReport as ToastReport;
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/main/ets/entryability/EntryAbility.ets b/bluetoothSample/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..6c3ac9ef7691afaed75b57159c9f757ab0f65208
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,83 @@
+/*
+ * 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 from '@ohos.app.ability.AbilityConstant';
+import hilog from '@ohos.hilog';
+import UIAbility from '@ohos.app.ability.UIAbility';
+import Want from '@ohos.app.ability.Want';
+import window from '@ohos.window';
+import abilityAccessCtrl, { PermissionRequestResult, Permissions } from '@ohos.abilityAccessCtrl';
+import { BusinessError } from '@ohos.base';
+
+const permissions: Permissions[] = ['ohos.permission.ACCESS_BLUETOOTH'];
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
+ }
+
+ onDestroy(): void {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
+ }
+
+ onWindowStageCreate(windowStage: window.WindowStage): void {
+ // Main window is created, set main page for this ability
+ let context: Context = this.context;
+ let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
+ // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
+
+ atManager.requestPermissionsFromUser(context, permissions).then((data: PermissionRequestResult) => {
+ let grantStatus: number[] = data.authResults;
+ let length: number = grantStatus.length;
+ for (let i = 0; i < length; i++) {
+ if (grantStatus[i] === 0) {
+ // 用户授权,可以继续访问目标操作
+ } else {
+ // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
+ return;
+ }
+ }
+ // 授权成功
+ }).catch((err: BusinessError) => {
+ console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
+ })
+
+ // Main window is created, set main page for this ability
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
+
+ windowStage.loadContent('pages/Index', (err, data) => {
+ if (err.code) {
+ hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
+ return;
+ }
+ hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
+ });
+ }
+
+ onWindowStageDestroy(): void {
+ // Main window is destroyed, release UI related resources
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
+ }
+
+ onForeground(): void {
+ // Ability has brought to foreground
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
+ }
+
+ onBackground(): void {
+ // Ability has back to background
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
+ }
+}
diff --git a/bluetoothSample/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/bluetoothSample/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..b1e212947256c5533c7b06285a597c94f840a6e3
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
@@ -0,0 +1,27 @@
+/*
+ * 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';
+
+export default class EntryBackupAbility extends BackupExtensionAbility {
+ async onBackup() {
+ hilog.info(0x0000, 'testTag', 'onBackup ok');
+ }
+
+ async onRestore(bundleVersion: BundleVersion) {
+ hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
+ }
+}
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/main/ets/pages/Index.ets b/bluetoothSample/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..c4d89de113d5f77385eb2659cafc3d5209f45036
--- /dev/null
+++ b/bluetoothSample/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,532 @@
+/*
+ * 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 { BleAdvertisingManager } from '../bluetoothService/BluetoothAdvertising';
+import { BleScanManager } from '../bluetoothService/BluetoothScan';
+import { BluetoothSwitch } from '../bluetoothService/BluetoothSwitch'
+import { GattClientManager, GattData } from '../bluetoothService/GattClientManager';
+import { GattServerManager } from '../bluetoothService/GattServerManager';
+import { ScanData } from '../common/ScanData';
+import { ScanDialog } from '../common/ScanDialog';
+import { AdvertisingDialog } from '../common/AdvertisingDialog';
+import access from '@ohos.bluetooth.access';
+import { ToastReport } from '../common/ToastReport';
+import { ble } from '@kit.ConnectivityKit';
+import { AsyncCallback, BusinessError } from '@kit.BasicServicesKit';
+
+
+@Entry
+@Component
+struct bluetoothSample {
+ private bluetoothSwitch: BluetoothSwitch = new BluetoothSwitch();
+ private bleScanManager: BleScanManager = new BleScanManager();
+ private bleAdvertisingManager: BleAdvertisingManager = new BleAdvertisingManager();
+ private gattServerManager: GattServerManager = new GattServerManager();
+ private gattClientManager: GattClientManager = new GattClientManager();
+ @State scanData: ScanData[] = [];
+ @State textValueOfDeviceName: string | undefined = '';
+ @State inputValueOfDeviceName: string | undefined = '';
+ @State textValueOfDeviceId: string | undefined = '';
+ @State inputValueOfDeviceId: string | undefined = '';
+ @State scanFlag: Boolean = true;
+ @State textValueOfInterval: string = '';
+ @State inputValueOfInterval: string = '';
+ @State textValueOfManufactureId: string = '';
+ @State textValueOfAdvManufactureId: string = '';
+ @State inputValueOfManufactureId: string = '';
+ @State inputValueOfAdvManufactureId: string = '';
+ @State textValueOfManufactureValueBuffer: string = '';
+ @State textValueOfAdvManufactureValueBuffer: string = '';
+ @State inputValueOfAdvManufactureValueBuffer: Uint8Array = new Uint8Array;
+ @State inputValueOfAdvServiceBuffer: Uint8Array = new Uint8Array;
+ @State inputValueOfAdvServiceUuids: string = '';
+ @State inputValueOfAdvIncludeDeviceName: boolean = false;
+ @State textValueOfAdvIncludeDeviceName: string = '';
+ @State textValueOfAdvServiceBuffer: string = '';
+ @State textValueOfAdvServiceUuids: string = '';
+ @State currentIndex: number = 0;
+ @State gattState: number = 0;
+ @State serviceResult: string = '';
+ @State refresh: boolean = false;
+ @State marText: string = '';
+ gattData: GattData = new GattData();
+ connectDeviceId: string = '';
+ scroller: Scroller = new Scroller();
+ @StorageLink('advertiserState') @Watch('onAdvertiserStateChange') advertiserState: ble.AdvertisingState =
+ ble.AdvertisingState.STOPPED;
+
+ onAdvertiserStateChange() {
+ console.info(`onAdvertiserStateChange: advertiserState = ${JSON.stringify(this.advertiserState)}`)
+ }
+
+ getAdvertiserStateDescription(): ResourceStr {
+ let description = 'Stopped'
+ switch (this.advertiserState) {
+ case ble.AdvertisingState.STARTED:
+ description = 'Started';
+ break
+ case ble.AdvertisingState.ENABLED:
+ description = 'Enable';
+ break
+ case ble.AdvertisingState.DISABLED:
+ description = 'Disabled';
+ break
+ case ble.AdvertisingState.STOPPED:
+ description = 'Stopped';
+ break
+ }
+ return description
+ }
+
+ @Builder
+ tabBuilder(title: ResourceStr, targetIndex: number) {
+ Column() {
+ Text(title)
+ .fontColor(this.currentIndex === targetIndex ? '#F111C1' : '#6B6B6B')
+ }
+ }
+
+ @State state: number = access.getState();
+
+ public FlushBlueToothState(): access.BluetoothState {
+ return this.state = access.getState();
+ }
+
+ advDialogController: CustomDialogController | null = new CustomDialogController({
+ builder: AdvertisingDialog({
+ cancel: () => {
+ this.onCancel()
+ },
+ confirm: () => {
+ this.onAccept()
+ },
+ textValueOfAdvManufactureId: $textValueOfAdvManufactureId,
+ inputValueOfAdvManufactureId: $inputValueOfAdvManufactureId,
+ textValueOfAdvManufactureValueBuffer: $textValueOfAdvManufactureValueBuffer,
+ inputValueOfAdvManufactureValueBuffer: $inputValueOfAdvManufactureValueBuffer,
+ textValueOfAdvServiceUuids: $textValueOfAdvServiceUuids,
+ inputValueOfAdvServiceUuids: $inputValueOfAdvServiceUuids,
+ textValueOfAdvServiceBuffer: $textValueOfAdvServiceBuffer,
+ inputValueOfAdvServiceBuffer: $inputValueOfAdvServiceBuffer,
+ textValueOfAdvIncludeDeviceName: $textValueOfAdvIncludeDeviceName,
+ inputValueOfAdvIncludeDeviceName: $inputValueOfAdvIncludeDeviceName
+ }),
+ cancel: this.exitApp,
+ autoCancel: true,
+ onWillDismiss: (dismissDialogAction: DismissDialogAction) => {
+ console.info('reason=' + JSON.stringify(dismissDialogAction.reason))
+ console.log('dialog onWillDismiss')
+ if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {
+ dismissDialogAction.dismiss()
+ }
+ if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {
+ dismissDialogAction.dismiss()
+ }
+ },
+ alignment: DialogAlignment.Top,
+ offset: { dx: 0, dy: -20 },
+ gridCount: 4,
+ customStyle: false,
+ cornerRadius: 10,
+ })
+ scanDialogController: CustomDialogController | null = new CustomDialogController({
+ builder: ScanDialog({
+ cancel: () => {
+ this.onCancel()
+ },
+ confirm: () => {
+ this.onAccept()
+ },
+ textValueOfInterval: $textValueOfInterval,
+ inputValueOfInterval: $inputValueOfInterval,
+ textValueOfManufactureId: $textValueOfManufactureId,
+ inputValueOfManufactureId: $inputValueOfManufactureId,
+ textValueOfDeviceName: $textValueOfDeviceName,
+ inputValueOfDeviceName: $inputValueOfDeviceName,
+ textValueOfDeviceId: $textValueOfDeviceId,
+ inputValueOfDeviceId: $inputValueOfDeviceId,
+ }),
+ cancel: this.exitApp,
+ autoCancel: true,
+ onWillDismiss: (dismissDialogAction: DismissDialogAction) => {
+ console.info('reason=' + JSON.stringify(dismissDialogAction.reason))
+ console.log('dialog onWillDismiss')
+ if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {
+ dismissDialogAction.dismiss()
+ }
+ if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {
+ dismissDialogAction.dismiss()
+ }
+ },
+ alignment: DialogAlignment.Top,
+ offset: { dx: 0, dy: -20 },
+ gridCount: 4,
+ customStyle: false,
+ cornerRadius: 10,
+ })
+
+ aboutToDisappear() {
+ this.scanDialogController = null
+ }
+
+ onCancel() {
+ }
+
+ onAccept() {
+ }
+
+ exitApp() {
+ }
+
+ build() {
+ Column() {
+ Row() {
+ Text('Bluetooth')
+ .width('100%')
+ .textAlign(TextAlign.Center)
+ .fontSize(30)
+ }
+
+ Column() {
+ Text('BlueTooth State: ' + (this.state ? 'Connected' : 'Disconnected'))
+ .margin(10)
+ Text('BleState: ' + this.getAdvertiserStateDescription())
+ .fontColor(Color.Red)
+ .margin(10)
+ if (this.marText) {
+ Marquee({ src: this.marText, start: true })
+ .margin(10)
+ }
+ }
+
+ Tabs() {
+ TabContent() {
+ Column({ space: 5 }) {
+ Column({ space: 5 }) {
+ Button($r('app.string.Set_filtering_parameters'))
+ .width('80%')
+ .onClick(() => {
+ if (this.scanDialogController != null) {
+ this.scanDialogController.open();
+ }
+ })
+ Button($r('app.string.StartScan'))
+ .width('80%')
+ .onClick(() => {
+ this.bleScanManager.setScanParameter(this.inputValueOfInterval, this.inputValueOfManufactureId,
+ this.inputValueOfDeviceName, this.inputValueOfDeviceId);
+ this.bleScanManager.startScan();
+ })
+ Button($r('app.string.StopScan'))
+ .width('80%')
+ .onClick(() => {
+ this.bleScanManager.stopScan();
+ this.scanFlag = false;
+ })
+ Button($r('app.string.Refresh'))
+ .width('80%')
+ .backgroundColor(Color.Red)
+ .onClick(() => {
+ this.scanData = this.bleScanManager.getScanData();
+ })
+ }
+ .height('25%')
+ .margin({ top: 5 })
+
+ Scroll(this.scroller) {
+ Column() {
+ ForEach(this.scanData, (item: ScanData) => {
+ Row() {
+ Text('deviceId: ' + item.getDeviceId() + '\n' + 'deviceName: ' + item.getDeviceName() + '\n' +
+ 'rssi: ' + item.getRssi() + '\n' + 'connectable: ' + item.getConnectable())
+ .width('70%')
+ .height(100)
+ .backgroundColor(0xFFFFFF)
+ .borderRadius(15)
+ .fontSize(16)
+ .textAlign(TextAlign.JUSTIFY)
+ .margin(10)
+
+ Button('connect')
+ .width('20%')
+ .margin(10)
+ .onClick(() => {
+ this.connectDeviceId = item.getDeviceId();
+ this.gattClientManager.startConnect(this.connectDeviceId);
+ this.marText = 'deviceId: ' + item.getDeviceId() + ' deviceName: ' + item.getDeviceName() +
+ ' rssi: ' + item.getRssi() + ' connectable: ' + item.getConnectable();
+ })
+ }
+ .backgroundColor(0xFFFFFF)
+ .borderRadius(15)
+ .margin(10)
+ });
+
+ }.width('100%')
+ }
+ .margin({ top: 5 })
+ .height('55%')
+ .scrollable(ScrollDirection.Vertical)
+ .scrollBar(BarState.On)
+ .scrollBarColor(Color.White)
+ .scrollBarWidth(10)
+ .friction(0.6)
+ .edgeEffect(EdgeEffect.None)
+ .onWillScroll((xOffset: number, yOffset: number) => {
+ console.info(xOffset + ' ' + yOffset);
+ })
+ }
+ .height('100%')
+ }
+ .backgroundColor(Color.Gray)
+ .tabBar(this.tabBuilder('SCANNER', 0))
+
+ TabContent() {
+ Column({ space: 5 }) {
+ Scroll() {
+ Text(this.serviceResult)
+ .width('100%')
+ .height('100%')
+ .margin(30)
+ }
+ .width('80%')
+ .height('20%')
+
+ Row() {
+ Text('serviceUuid: ')
+
+ TextInput().onChange((value: string) => {
+ this.gattData.serviceUuid = value;
+ }).height('40vp').width('70%')
+ }.width('80%')
+
+ Row() {
+ Text('characteristicUuid: ')
+
+ TextInput().onChange((value: string) => {
+ this.gattData.characteristicUuid = value;
+ }).height('40vp').width('70%')
+ }.width('80%')
+
+ Row() {
+ Text('descriptorUuid: ')
+
+ TextInput().onChange((value: string) => {
+ this.gattData.descriptorUuid = value;
+ }).height('40vp').width('70%')
+ }.width('80%')
+
+ Row() {
+ Text('characteristicValue: ')
+
+ TextInput().onChange((value: string) => {
+ this.gattData.characteristicValue = value;
+ }).height('40vp').width('70%')
+ }.width('80%')
+
+ Row() {
+ Text('descriptorValue: ')
+
+ TextInput().onChange((value: string) => {
+ this.gattData.descriptorValue = value;
+ }).height('40vp').width('70%')
+ }.width('80%')
+
+ Button($r('app.string.DiscoverService'))
+ .width('80%')
+ .onClick(() => {
+ this.gattClientManager.discoverServices().then(() => {
+ this.serviceResult = this.gattClientManager.getResult();
+ })
+ })
+
+ Row({ space: 30 }) {
+ Button($r('app.string.readChar'))
+ .width('30%')
+ .onClick(() => {
+ this.gattClientManager.readCharacteristicValue();
+ })
+
+ Button($r('app.string.writeChar'))
+ .width('30%')
+ .onClick(() => {
+ this.gattClientManager.setGattData(this.gattData);
+ this.gattClientManager.writeCharacteristicValue();
+ })
+ }
+
+ Row({ space: 30 }) {
+
+ Button($r('app.string.readDes'))
+ .width('30%')
+ .onClick(() => {
+ this.gattClientManager.readDescriptorValue();
+ })
+
+ Button($r('app.string.writeDes'))
+ .width('30%')
+ .onClick(() => {
+ this.gattClientManager.setGattData(this.gattData);
+ this.gattClientManager.writeDescriptorValue();
+ })
+ }
+
+ Button($r('app.string.disconnect'))
+ .width('80%')
+ .backgroundColor(Color.Red)
+ .onClick(() => {
+ this.gattClientManager.stopConnect();
+ this.marText = '';
+ this.serviceResult = '';
+ })
+ }
+ .width('100%')
+ .height('100%')
+ }
+ .backgroundColor(Color.Pink)
+ .tabBar(this.tabBuilder('GATT', 1))
+ .width('100%')
+ .height('100%')
+
+ TabContent() {
+ Row() {
+ Column({ space: 12 }) {
+ Button($r('app.string.registerServer'))
+ .width('80%')
+ .onClick(() => {
+ this.gattServerManager.registerServer();
+ })
+
+ Button($r('app.string.unRegisterServer'))
+ .width('80%')
+ .onClick(() => {
+ this.gattServerManager.unRegisterServer();
+ })
+
+ Button($r('app.string.RegisterReadChar'))
+ .width('80%')
+ .onClick(() => {
+ this.gattServerManager.onCharacteristicRead();
+ })
+
+ Button($r('app.string.RegisterWriteChar'))
+ .width('80%')
+ .onClick(() => {
+ this.gattServerManager.onCharacteristicWrite();
+ })
+
+ Button($r('app.string.RegisterReadDes'))
+ .width('80%')
+ .onClick(() => {
+ this.gattServerManager.onDescriptorRead();
+ })
+
+ Button($r('app.string.RegisterWriteDes'))
+ .width('80%')
+ .onClick(() => {
+ this.gattServerManager.onDescriptorWrite();
+ })
+ }
+ .width('50%')
+
+ Column({ space: 12 }) {
+ Button($r('app.string.setAdv'))
+ .width('80%')
+ .onClick(() => {
+ this.advDialogController?.open();
+ })
+
+ Button($r('app.string.startAdv'))
+ .width('80%')
+ .onClick(() => {
+ this.bleAdvertisingManager.setAdvertisingParameter(Number(this.inputValueOfAdvManufactureId),
+ this.inputValueOfAdvManufactureValueBuffer, this.inputValueOfAdvServiceUuids,
+ this.inputValueOfAdvServiceBuffer, this.inputValueOfAdvIncludeDeviceName);
+ this.bleAdvertisingManager.startAdvertising();
+ })
+
+ Button($r('app.string.stopAdv'))
+ .width('80%')
+ .onClick(() => {
+ console.info('disable Advertising');
+ this.bleAdvertisingManager.disableAdvertising();
+ console.info('Advertising over');
+ })
+
+ Button($r('app.string.continueAdv'))
+ .width('80%')
+ .onClick(() => {
+ this.bleAdvertisingManager.enableAdvertising(0);
+ })
+
+ Button($r('app.string.closeAdv'))
+ .width('80%')
+ .onClick(() => {
+ this.bleAdvertisingManager.stopAdvertising();
+ })
+ }
+ .width('50%')
+ }
+ }
+
+ .backgroundColor(Color.Orange)
+ .tabBar(this.tabBuilder('ADVERTISER', 2))
+
+ TabContent() {
+ Column({ space: 12 }) {
+ Button($r('app.string.openBlueTooth'))
+ .width('80%')
+ .onClick(() => {
+ this.state = access.getState();
+ if (this.state == 0) {
+ this.bluetoothSwitch.openBluetooth();
+ }
+ setTimeout(() => {
+ this.state = access.getState();
+ }, 2000)
+ setTimeout(() => {
+ this.state = access.getState();
+ }, 5000)
+ })
+
+ Button($r('app.string.closeBlueTooth'))
+ .width('80%')
+ .onClick(() => {
+ this.state = access.getState();
+ if (this.state == 2) {
+ try {
+ this.bluetoothSwitch.closeBluetooth();
+ } catch (err) {
+ console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
+ (err as BusinessError).message);
+ }
+ }
+ setTimeout(() => {
+ this.state = access.getState();
+ }, 2000)
+ })
+ }
+ }
+ .backgroundColor(Color.Yellow)
+ .tabBar(this.tabBuilder('SWITCH', 3))
+ }
+ .onChange((index: number) => {
+ this.currentIndex = index
+ })
+ .backgroundColor('#F1F3F5')
+ }
+ }
+}
+
diff --git a/bluetoothSample/entry/src/main/module.json5 b/bluetoothSample/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..34afbf7be55e682e1b5f892898bb9a8b732199df
--- /dev/null
+++ b/bluetoothSample/entry/src/main/module.json5
@@ -0,0 +1,83 @@
+/*
+ * 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"
+ ],
+ "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"
+ ]
+ }
+ ]
+ }
+ ],
+ "requestPermissions": [
+ {
+ "name": 'ohos.permission.USE_BLUETOOTH',
+ "reason": "$string:USE_BLUETOOTH"
+ },
+ {
+ "name": 'ohos.permission.DISCOVER_BLUETOOTH',
+ "reason": "$string:DISCOVER_BLUETOOTH"
+ },
+ {
+ "name": "ohos.permission.ACCESS_BLUETOOTH",
+ "reason": "$string:ACCESS_BLUETOOTH",
+ "usedScene": {
+ "when": "always"
+ }
+ }
+ ],
+ "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/bluetoothSample/entry/src/main/resources/base/element/color.json b/bluetoothSample/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/bluetoothSample/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/bluetoothSample/entry/src/main/resources/base/element/string.json b/bluetoothSample/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..6de3499e04e0d44732c2a453022b25feda1cf467
--- /dev/null
+++ b/bluetoothSample/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,119 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "bluetoothSample"
+ },
+ {
+ "name": "ACCESS_BLUETOOTH",
+ "value": "允许应用接入蓝牙并使用蓝牙能力,例如配对、连接外围设备等。"
+ },
+ {
+ "name": "DISCOVER_BLUETOOTH",
+ "value": "允许应用配置本地蓝牙,查找远端设备且与之配对连接。"
+ },{
+ "name": "USE_BLUETOOTH",
+ "value": "允许应用查看蓝牙的配置。"
+ },
+ {
+ "name": "RegisterReadChar",
+ "value": "订阅读特征值"
+ },
+ {
+ "name": "RegisterWriteChar",
+ "value": "订阅写特征值"
+ },
+ {
+ "name": "RegisterReadDes",
+ "value": "订阅读描述符"
+ },
+ {
+ "name": "RegisterWriteDes",
+ "value": "订阅写描述符"
+ },
+ {
+ "name": "registerServer",
+ "value": "注册服务"
+ },
+ {
+ "name": "unRegisterServer",
+ "value": "注销服务"
+ },
+ {
+ "name": "Set_filtering_parameters",
+ "value": "设置过滤参数"
+ },
+ {
+ "name": "StartScan",
+ "value": "开始扫描"
+ },
+ {
+ "name": "StopScan",
+ "value": "停止扫描"
+ },
+ {
+ "name": "Refresh",
+ "value": "刷新"
+ },
+ {
+ "name": "DiscoverService",
+ "value": "发现服务"
+ },
+ {
+ "name": "readChar",
+ "value": "读特征值"
+ },
+ {
+ "name": "writeChar",
+ "value": "写特征值"
+ },
+ {
+ "name": "readDes",
+ "value": "读描述符"
+ },
+ {
+ "name": "writeDes",
+ "value": "写描述符"
+ },
+ {
+ "name": "disconnect",
+ "value": "断开连接"
+ },
+ {
+ "name": "startAdv",
+ "value": "开始广播"
+ },
+ {
+ "name": "stopAdv",
+ "value": "暂停广播"
+ },
+ {
+ "name": "continueAdv",
+ "value": "继续广播"
+ },
+ {
+ "name": "closeAdv",
+ "value": "关闭广播"
+ },
+ {
+ "name": "setAdv",
+ "value": "设置广播内容"
+ },
+ {
+ "name": "openBlueTooth",
+ "value": "开启蓝牙"
+ },
+ {
+ "name": "closeBlueTooth",
+ "value": "关闭蓝牙"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/main/resources/base/media/background.png b/bluetoothSample/entry/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d
Binary files /dev/null and b/bluetoothSample/entry/src/main/resources/base/media/background.png differ
diff --git a/bluetoothSample/entry/src/main/resources/base/media/foreground.png b/bluetoothSample/entry/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902
Binary files /dev/null and b/bluetoothSample/entry/src/main/resources/base/media/foreground.png differ
diff --git a/bluetoothSample/entry/src/main/resources/base/media/layered_image.json b/bluetoothSample/entry/src/main/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/bluetoothSample/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/bluetoothSample/entry/src/main/resources/base/media/startIcon.png b/bluetoothSample/entry/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/bluetoothSample/entry/src/main/resources/base/media/startIcon.png differ
diff --git a/bluetoothSample/entry/src/main/resources/base/profile/backup_config.json b/bluetoothSample/entry/src/main/resources/base/profile/backup_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a
--- /dev/null
+++ b/bluetoothSample/entry/src/main/resources/base/profile/backup_config.json
@@ -0,0 +1,3 @@
+{
+ "allowToBackupRestore": true
+}
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/main/resources/base/profile/main_pages.json b/bluetoothSample/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/bluetoothSample/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/bluetoothSample/entry/src/main/resources/dark/element/color.json b/bluetoothSample/entry/src/main/resources/dark/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499
--- /dev/null
+++ b/bluetoothSample/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/bluetoothSample/entry/src/mock/mock-config.json5 b/bluetoothSample/entry/src/mock/mock-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..b9a78e201535765168a92d3543c690273ecdc019
--- /dev/null
+++ b/bluetoothSample/entry/src/mock/mock-config.json5
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+{
+}
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/ohosTest/ets/test/Ability.test.ets b/bluetoothSample/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0f8ce9a2c012f8fe36114cef65216ef0b6254f41
--- /dev/null
+++ b/bluetoothSample/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+ * 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/bluetoothSample/entry/src/ohosTest/ets/test/List.test.ets b/bluetoothSample/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1eac52fcebe8958e19a7b8fed2e8f39c520a3e42
--- /dev/null
+++ b/bluetoothSample/entry/src/ohosTest/ets/test/List.test.ets
@@ -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 abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/ohosTest/module.json5 b/bluetoothSample/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..be4685a172af804c5b26c0e3618bf770cf138e98
--- /dev/null
+++ b/bluetoothSample/entry/src/ohosTest/module.json5
@@ -0,0 +1,27 @@
+/*
+ * 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/bluetoothSample/entry/src/test/List.test.ets b/bluetoothSample/entry/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f1186b1f53c3a70930921c5dbd1417332bec56c9
--- /dev/null
+++ b/bluetoothSample/entry/src/test/List.test.ets
@@ -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 localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/bluetoothSample/entry/src/test/LocalUnit.test.ets b/bluetoothSample/entry/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7fc57c77dbf76d8df08a2b802a55b948e3fcf968
--- /dev/null
+++ b/bluetoothSample/entry/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+ * 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/bluetoothSample/hvigor/hvigor-config.json5 b/bluetoothSample/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..d584c19c247db9a7caee4b606bb931aa9279c637
--- /dev/null
+++ b/bluetoothSample/hvigor/hvigor-config.json5
@@ -0,0 +1,37 @@
+/*
+ * 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.1",
+ "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/bluetoothSample/hvigorfile.ts b/bluetoothSample/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775
--- /dev/null
+++ b/bluetoothSample/hvigorfile.ts
@@ -0,0 +1,6 @@
+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/bluetoothSample/oh-package.json5 b/bluetoothSample/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e41bae026aab3b50d0abb42fece08ba43b4a772b
--- /dev/null
+++ b/bluetoothSample/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.1",
+ "description": "Please describe the basic information.",
+ "dependencies": {
+ },
+ "devDependencies": {
+ "@ohos/hypium": "1.0.19",
+ "@ohos/hamock": "1.0.0"
+ }
+}
diff --git a/bluetoothSample/ohosTest.md b/bluetoothSample/ohosTest.md
new file mode 100644
index 0000000000000000000000000000000000000000..ed4f1cc491b31ec684327d49506f8387bfd5502e
--- /dev/null
+++ b/bluetoothSample/ohosTest.md
@@ -0,0 +1,32 @@
+# 蓝牙示例代码工程化
+
+## 用例表
+
+| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
+| ----------------- | ------------ | ----------------- | ------------------------|--------- | -------- |
+| 应用正常启动 | 设备支持蓝牙 | 启动应用 | 进入应用界面,弹出申请蓝牙权限的弹窗 |否 | Pass |
+| 应用正常获取蓝牙权限 | 设备支持蓝牙,申请蓝牙权限的弹窗点击“允许” | 切换到SIWITCH界面,点击打开蓝牙 | 弹出三方应用申请蓝牙权限的弹窗 |否 | Pass |
+| 应用成功打开蓝牙 | 设备支持蓝牙,蓝牙权限申请成功。 | 切换到SIWITCH界面,点击开启蓝牙,在弹窗中点击“开启” | 设备打开蓝牙功能,上方Bluetooth State变为Connected |否 | Pass |
+| 可以正确设置扫描的过滤参数 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开。 | 在SCAN界面,点击“设置过滤参数”,输入过滤参数,点击confirm,点击开始扫描 | 设备根据过滤参数正确过滤扫描设备 |否 | Pass |
+| 正常扫描设备 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在SCAN界面,点击开始扫描 | 设备开始扫描设备,设备Id在下方以弹窗形式显示 |否 | Pass |
+| 显示扫描到的设备 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在SCAN界面,出现过设备Id的弹窗后,点击刷新 | 扫描到的设备信息在下方以列表形式展示 |否 | Pass |
+| 关闭扫描 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在SCAN界面,点击开始扫描后,点击关闭扫描 | 弹出停止扫描的弹窗 |否 | Pass |
+| 连接设备 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开,已扫描到设备 | 在SCAN界面,点击下方设备列表的connect按钮 | 弹出连接成功的弹窗,设备信息开始在上方循环播放 |否 | Pass |
+| 发现服务 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开,已连接到设备 | 在GATT界面,点击发现服务按钮 | 弹出扫描到的服务内容的弹窗,并在上方文本框显示 |否 | Pass |
+| 读特征值 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开,已连接到设备 | 在GATT界面,设置过滤参数后,点击读特征值 | 弹出弹窗,显示读取结果 |否 | Pass |
+| 读描述符 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开,已连接到设备 | 在GATT界面,设置过滤参数后,点击读描述符 | 弹出弹窗,显示读取结果 |否 | Pass |
+| 写特征值 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开,已连接到设备 | 在GATT界面,设置过滤参数后,点击写特征值 | 弹出弹窗,显示写入结果 |否 | Pass |
+| 写描述符 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开,已连接到设备 | 在GATT界面,设置过滤参数后,点击写描述符 | 弹出弹窗,显示写入结果 |否 | Pass |
+| 断开连接 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开,已连接到设备 | 在GATT界面,点击断开连接 | 弹出弹窗,显示断开连接成功 |否 | Pass |
+| 注册服务 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击注册服务按钮 | 弹出弹窗,显示注册服务成功 |否 | Pass |
+| 注销服务 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击注销服务按钮 | 弹出弹窗,显示注销服务成功 |否 | Pass |
+| 订阅读特征值 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击订阅读特征值按钮 | 弹出弹窗,显示订阅读特征值成功 |否 | Pass |
+| 订阅写特征值 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击订阅写特征值按钮 | 弹出弹窗,显示订阅写特征值成功 |否 | Pass |
+| 订阅读描述符 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击订阅读描述符按钮 | 弹出弹窗,显示订阅读描述符成功 |否 | Pass |
+| 订阅写描述符 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击订阅写描述符按钮 | 弹出弹窗,显示订阅写描述符成功 |否 | Pass |
+| 设置广播内容 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击设置广播内容按钮 | 弹出参数弹窗,输入信息设置广播内容 |否 | Pass |
+| 开始广播 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击开始广播按钮 | 弹出弹窗,提示开始广播 |否 | Pass |
+| 暂停广播 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击暂停广播按钮 | 弹出弹窗,提示暂停广播 |否 | Pass |
+| 继续广播 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击继续广播按钮 | 弹出弹窗,提示继续广播 |否 | Pass |
+| 停止广播 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在ADVERISER界面,点击停止广播按钮 | 弹出弹窗,提示停止广播 |否 | Pass |
+| 关闭蓝牙 | 设备支持蓝牙,蓝牙权限申请成功,蓝牙已打开 | 在SWITCH界面,点击关闭蓝牙按钮 | 设备关闭蓝牙,上方BlueTooth State变为 Disconnected |否 | Pass |
diff --git a/bluetoothSample/screenshots/ADVERISER.jpeg b/bluetoothSample/screenshots/ADVERISER.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..b0f2594ab6497ebc164c1dcbd168d546af2cf648
Binary files /dev/null and b/bluetoothSample/screenshots/ADVERISER.jpeg differ
diff --git a/bluetoothSample/screenshots/BONDED.jpeg b/bluetoothSample/screenshots/BONDED.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..da73c70a851c4679a221b379e491e5e8fcf85a4c
Binary files /dev/null and b/bluetoothSample/screenshots/BONDED.jpeg differ
diff --git a/bluetoothSample/screenshots/SCAN.jpeg b/bluetoothSample/screenshots/SCAN.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..7b4fcb903d500c6a3bfdedc2b430444e57ea29e8
Binary files /dev/null and b/bluetoothSample/screenshots/SCAN.jpeg differ
diff --git a/bluetoothSample/screenshots/SWITCH.jpeg b/bluetoothSample/screenshots/SWITCH.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..cc3838867521b92fb7fc8c1eafbe423372276834
Binary files /dev/null and b/bluetoothSample/screenshots/SWITCH.jpeg differ