Selaa lähdekoodia

补充蓝牙连接操作

bjb 5 päivää sitten
vanhempi
sitoutus
9b146f0870

+ 6 - 0
bozzys_sdk/.gitignore

@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test

+ 1 - 0
bozzys_sdk/Index.ets

@@ -0,0 +1 @@
+export { add } from './src/main/ets/utils/Calc';

+ 47 - 0
bozzys_sdk/build-profile.json5

@@ -0,0 +1,47 @@
+{
+  "apiType": "stageMode",
+  "buildOption": {
+    "externalNativeOptions": {
+      "path": "./src/main/cpp/CMakeLists.txt",
+      "arguments": "",
+      "cppFlags": ""
+    },
+    "resOptions": {
+      "copyCodeResource": {
+        "enable": false
+      }
+    }
+  },
+  "buildOptionSet": [
+    {
+      "name": "release",
+      "arkOptions": {
+        "obfuscation": {
+          "ruleOptions": {
+            "enable": false,
+            "files": [
+              "./obfuscation-rules.txt"
+            ]
+          },
+          "consumerFiles": [
+            "./consumer-rules.txt"
+          ]
+        }
+      },
+      "nativeLib": {
+        "debugSymbol": {
+          "strip": true,
+          "exclude": []
+        }
+      }
+    },
+  ],
+  "targets": [
+    {
+      "name": "default"
+    },
+    {
+      "name": "ohosTest"
+    }
+  ]
+}

+ 0 - 0
bozzys_sdk/consumer-rules.txt


+ 6 - 0
bozzys_sdk/hvigorfile.ts

@@ -0,0 +1,6 @@
+import { hspTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+  system: hspTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+  plugins: []       /* Custom plugin to extend the functionality of Hvigor. */
+}

+ 23 - 0
bozzys_sdk/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

+ 11 - 0
bozzys_sdk/oh-package.json5

@@ -0,0 +1,11 @@
+{
+  "name": "bozzys_sdk",
+  "version": "1.0.0",
+  "description": "Please describe the basic information.",
+  "main": "Index.ets",
+  "author": "",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "libbozzys_sdk.so": "file:./src/main/cpp/types/libbozzys_sdk"
+  }
+}

+ 15 - 0
bozzys_sdk/src/main/cpp/CMakeLists.txt

@@ -0,0 +1,15 @@
+# the minimum version of CMake.
+cmake_minimum_required(VERSION 3.5.0)
+project(myNpmLib)
+
+set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+if(DEFINED PACKAGE_FIND_FILE)
+    include(${PACKAGE_FIND_FILE})
+endif()
+
+include_directories(${NATIVERENDER_ROOT_PATH}
+                    ${NATIVERENDER_ROOT_PATH}/include)
+
+add_library(bozzys_sdk SHARED napi_init.cpp)
+target_link_libraries(bozzys_sdk PUBLIC libace_napi.z.so)

+ 53 - 0
bozzys_sdk/src/main/cpp/napi_init.cpp

@@ -0,0 +1,53 @@
+#include "napi/native_api.h"
+
+static napi_value Add(napi_env env, napi_callback_info info)
+{
+    size_t argc = 2;
+    napi_value args[2] = {nullptr};
+
+    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
+
+    napi_valuetype valuetype0;
+    napi_typeof(env, args[0], &valuetype0);
+
+    napi_valuetype valuetype1;
+    napi_typeof(env, args[1], &valuetype1);
+
+    double value0;
+    napi_get_value_double(env, args[0], &value0);
+
+    double value1;
+    napi_get_value_double(env, args[1], &value1);
+
+    napi_value sum;
+    napi_create_double(env, value0 + value1, &sum);
+
+    return sum;
+
+}
+
+EXTERN_C_START
+static napi_value Init(napi_env env, napi_value exports)
+{
+    napi_property_descriptor desc[] = {
+        { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
+    };
+    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
+    return exports;
+}
+EXTERN_C_END
+
+static napi_module demoModule = {
+    .nm_version = 1,
+    .nm_flags = 0,
+    .nm_filename = nullptr,
+    .nm_register_func = Init,
+    .nm_modname = "bozzys_sdk",
+    .nm_priv = ((void*)0),
+    .reserved = { 0 },
+};
+
+extern "C" __attribute__((constructor)) void RegisterBozzys_sdkModule(void)
+{
+    napi_module_register(&demoModule);
+}

+ 1 - 0
bozzys_sdk/src/main/cpp/types/libbozzys_sdk/Index.d.ts

@@ -0,0 +1 @@
+export const add: (a: number, b: number) => number;

+ 6 - 0
bozzys_sdk/src/main/cpp/types/libbozzys_sdk/oh-package.json5

@@ -0,0 +1,6 @@
+{
+  "name": "libbozzys_sdk.so",
+  "types": "./Index.d.ts",
+  "version": "1.0.0",
+  "description": "Please describe the basic information."
+}

+ 146 - 0
bozzys_sdk/src/main/ets/ble/BleManager.ets

@@ -0,0 +1,146 @@
+import { ble, constant } from '@kit.ConnectivityKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+
+export class BleManager {
+  // 需要扫描的蓝牙设备
+  mac: string = ""
+  // mtu设置
+  mtu: number = 500
+  // 是否已经查找到
+  isFindDevice: boolean = false
+  // 当前持有的蓝牙设备
+  bleDevice: ble.ScanResult | undefined = undefined
+  // gatt连接对象
+  bleGatt: ble.GattClientDevice | undefined = undefined
+
+  constructor(mac: string) {
+    this.mac = mac
+  }
+
+  /**
+   * 蓝牙扫描监听
+   */
+  private onReceiveEvent = (data: Array<ble.ScanResult>) => {
+    // console.info("BleManager", 'BLE scan device find result: ' + JSON.stringify(data));
+    if (this.isFindDevice == true) {
+      return
+    }
+    data.forEach((device) => {
+      const byteArray = new Uint8Array(device.data.slice(49, 55))
+      let findMac = ""
+      for (let idx = 0; idx < byteArray.length; idx++) {
+        const byte = byteArray[idx]
+        findMac += byte.toString(16).padStart(2, "0").toUpperCase()
+        // 拼接:操作
+        if ((idx + 1) != byteArray.length) {
+          findMac += ":"
+        }
+      }
+      // console.log("BleManager", "data info ", findMac)
+      if (this.isFindDevice != true && findMac == this.mac) {
+        console.log("BleManager", "onReceiveEvent() find mac ", findMac, "device")
+        this.isFindDevice = true
+        this.bleDevice = device
+        this.stopScan()
+        this.innerConnect()
+        return
+      }
+    })
+  }
+  /**
+   * 蓝牙连接状态监听
+   */
+  private onBleConnectionStateChanged = (state: ble.BLEConnectionChangeState) => {
+    let status: ble.ProfileConnectionState = state.state;
+    console.info("BleManager", 'clientConnectStateChanged() connect state changed', status)
+    if (status == constant.ProfileConnectionState.STATE_CONNECTED) {
+      this.bleGatt?.getServices().then((services) => {
+        console.log("BleManager", "clientConnectStateChanged() getServices()", JSON.stringify(services))
+        // 发现完服务,设置mtu
+        try {
+          this.bleGatt?.setBLEMtuSize(this.mtu)
+        } catch (error) {
+          console.error("BleManager", "onBleConnectionStateChanged() setBLEMtuSize() failed", JSON.stringify(error))
+        }
+      }).catch(() => {
+      })
+    } else if (status == constant.ProfileConnectionState.STATE_DISCONNECTED) {
+      // 断开连接的操作
+      this.disconnect()
+    }
+  }
+  /**
+   * 特征变化监听
+   */
+  private onBleCharacteristicChanged = (ch: ble.BLECharacteristic) => {
+    console.log("BleManager", "onBleCharacteristicChanged()", JSON.stringify(ch))
+  }
+  /**
+   * 设置Mtu变化监听
+   */
+  private onBleMtuChanged = (mtu: number) => {
+    console.log("BleManager", "onBleMtuChanged()", mtu)
+  }
+
+  /**
+   * 执行蓝牙扫描和连接操作
+   */
+  connect() {
+    this.scan()
+  }
+
+  disconnect() {
+    try {
+      this.bleGatt?.off("BLEConnectionStateChange", this.onBleConnectionStateChanged)
+      this.bleGatt?.on("BLECharacteristicChange", this.onBleCharacteristicChanged)
+      this.bleGatt?.off("BLEMtuChange", this.onBleMtuChanged)
+      this.bleGatt?.disconnect()
+      this.bleGatt?.close()
+    } catch (e) {
+    }
+  }
+
+  /**
+   * 蓝牙扫描操作
+   */
+  private scan() {
+    try {
+      ble.on("BLEDeviceFind", this.onReceiveEvent)
+      ble.startBLEScan([{}], { dutyMode: ble.ScanDuty.SCAN_MODE_LOW_LATENCY })
+      console.log("BleManager", "scan() startBLEScan() success")
+    } catch (err) {
+      console.error("BleManager", 'scan() failed errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message)
+    }
+  }
+
+  /**
+   * 停止查找设备并移除扫描监听
+   */
+  private stopScan() {
+    try {
+      ble.off("BLEDeviceFind", this.onReceiveEvent)
+      ble.stopBLEScan()
+      console.log("BleManager", "stopScan() stopBLEScan() success")
+    } catch (error) {
+      console.log("BleManager", "stopScan() stopBLEScan() failed " + JSON.stringify(error))
+    } finally {
+      this.isFindDevice = false
+    }
+  }
+
+  /**
+   * 连接蓝牙设备
+   */
+  private innerConnect() {
+    try {
+      this.bleGatt = ble.createGattClientDevice(this.bleDevice?.deviceId ?? "")
+      this.bleGatt?.on("BLEConnectionStateChange", this.onBleConnectionStateChanged)
+      this.bleGatt?.on("BLECharacteristicChange", this.onBleCharacteristicChanged)
+      this.bleGatt?.on("BLEMtuChange", this.onBleMtuChanged)
+      this.bleGatt?.connect()
+      console.log("BleManager", "innerConnect() connect to", this.mac, "success")
+    } catch (e) {
+      console.log("BleManager", "innerConnect() can`t connect to", this.bleDevice?.deviceId, "error ", JSON.stringify(e))
+    }
+  }
+}

+ 26 - 0
bozzys_sdk/src/main/ets/pages/Index.ets

@@ -0,0 +1,26 @@
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import testNapi from 'libbozzys_sdk.so';
+
+const DOMAIN = 0x0000;
+
+@Entry
+@Component
+struct Index {
+  @State message: string = 'Hello World';
+
+  build() {
+    Row() {
+      Column() {
+        Text(this.message)
+          .fontSize($r('app.float.page_text_font_size'))
+          .fontWeight(FontWeight.Bold)
+          .onClick(() => {
+            this.message = 'Welcome';
+            hilog.info(DOMAIN, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.add(2, 3));
+          })
+      }
+      .width('100%')
+    }
+    .height('100%')
+  }
+}

+ 3 - 0
bozzys_sdk/src/main/ets/utils/Calc.ets

@@ -0,0 +1,3 @@
+export function add(a: number, b: number) {
+  return a + b;
+}

+ 21 - 0
bozzys_sdk/src/main/module.json5

@@ -0,0 +1,21 @@
+{
+  "module": {
+    "name": "bozzys_sdk",
+    "type": "shared",
+    "description": "$string:shared_desc",
+    "deviceTypes": [
+      "phone"
+    ],
+    "requestPermissions": [
+      {
+        "name": "ohos.permission.ACCESS_BLUETOOTH",
+        "reason": "$string:app_name"
+      },
+      {
+        "name": "ohos.permission.USE_BLUETOOTH"
+      }
+    ],
+    "deliveryWithInstall": true,
+    "pages": "$profile:main_pages"
+  }
+}

+ 8 - 0
bozzys_sdk/src/main/resources/base/element/float.json

@@ -0,0 +1,8 @@
+{
+  "float": [
+    {
+      "name": "page_text_font_size",
+      "value": "50fp"
+    }
+  ]
+}

+ 8 - 0
bozzys_sdk/src/main/resources/base/element/string.json

@@ -0,0 +1,8 @@
+{
+  "string": [
+    {
+      "name": "shared_desc",
+      "value": "description"
+    }
+  ]
+}

+ 5 - 0
bozzys_sdk/src/main/resources/base/profile/main_pages.json

@@ -0,0 +1,5 @@
+{
+  "src": [
+    "pages/Index"
+  ]
+}

+ 35 - 0
bozzys_sdk/src/ohosTest/ets/test/Ability.test.ets

@@ -0,0 +1,35 @@
+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);
+    })
+  })
+}

+ 5 - 0
bozzys_sdk/src/ohosTest/ets/test/List.test.ets

@@ -0,0 +1,5 @@
+import abilityTest from './Ability.test';
+
+export default function testsuite() {
+  abilityTest();
+}

+ 11 - 0
bozzys_sdk/src/ohosTest/module.json5

@@ -0,0 +1,11 @@
+{
+  "module": {
+    "name": "bozzys_sdk_test",
+    "type": "feature",
+    "deviceTypes": [
+      "phone"
+    ],
+    "deliveryWithInstall": true,
+    "installationFree": false
+  }
+}

+ 5 - 0
bozzys_sdk/src/test/List.test.ets

@@ -0,0 +1,5 @@
+import localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+  localUnitTest();
+}

+ 33 - 0
bozzys_sdk/src/test/LocalUnit.test.ets

@@ -0,0 +1,33 @@
+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);
+    });
+  });
+}

+ 12 - 0
build-profile.json5

@@ -51,6 +51,18 @@
           ]
         }
       ]
+    },
+    {
+      "name": "bozzys_sdk",
+      "srcPath": "./bozzys_sdk",
+      "targets": [
+        {
+          "name": "default",
+          "applyToProducts": [
+            "default"
+          ]
+        }
+      ]
     }
   ]
 }

+ 3 - 1
entry/oh-package.json5

@@ -5,6 +5,8 @@
   "main": "",
   "author": "",
   "license": "",
-  "dependencies": {}
+  "dependencies": {
+    "bozzys_sdk": "file:../bozzys_sdk"
+  }
 }
 

+ 10 - 2
entry/src/main/ets/pages/PageHomeComponents/TabHome.ets

@@ -1,5 +1,7 @@
-import { VMHome } from '../../vm/VMHome'
-import { VMTabHome } from '../../vm/VMTabHome'
+import { VMHome } from '../../vm/VMHome';
+import { VMTabHome } from '../../vm/VMTabHome';
+import { abilityAccessCtrl } from '@kit.AbilityKit';
+import { BleManager } from 'bozzys_sdk/src/main/ets/ble/BleManager';
 
 /**
  * 首页Tab页面
@@ -70,6 +72,12 @@ export struct TabHome {
         Stack() {
           Image($r("app.media.settings")).width(18).height(18).fillColor(Color.White)
         }.width(36).height(24).onClick(() => {
+          // const am = abilityAccessCtrl.createAtManager()
+          // am.requestPermissionsFromUser(this.getUIContext().getHostContext(), ["ohos.permission.ACCESS_BLUETOOTH"]).then((data) => {
+          //   console.log("权限请求", JSON.stringify(data))
+          // })
+          const bm = new BleManager("CC:BA:97:21:71:CA")
+          bm.connect()
         })
       }
       .width("100%")

+ 3 - 3
entry/src/main/ets/vm/VMLogin.ets

@@ -21,12 +21,12 @@ export class VMLogin {
   login(skip: Function) {
     if (this.account.trim() == "") {
       const msg = this.loginType == 0 ? "请输入手机号" : "请输入用户名"
-      promptAction.openToast({ message: msg })
+      promptAction.openToast({ message: msg }).catch()
       return
     }
     if (this.code == "") {
       const msg = this.loginType == 0 ? "请输入验证码" : "请输入密码"
-      promptAction.openToast({ message: msg })
+      promptAction.openToast({ message: msg }).catch()
       return
     }
     hideKeyboard()
@@ -36,7 +36,7 @@ export class VMLogin {
       Storage.setToken(rsp.token)
       Storage.setUsername(rsp.nickName)
       Loading.hideLoading()
-      promptAction.openToast({ message: '登录成功' })
+      promptAction.openToast({ message: '登录成功' }).catch()
       skip()
     }).catch(() => {
       Loading.hideLoading()