博客 / 詳情

返回

HarmonyOS 6.0 藍牙實現服務端和客户端通訊案例詳解

大家好,我是 V 哥。
以下基於 HarmonyOS 6.0 的藍牙 BLE 通訊案例詳解,模擬心率監測場景,實現服務端(Peripheral)廣播數據與客户端(Central)訂閲數據的功能流程:

聯繫V哥獲取 鴻蒙學習資料

關鍵步驟:

  1. 服務端(Peripheral):

    • 創建藍牙服務(GATT Server)
    • 添加服務(Service)和特徵(Characteristic)
    • 廣播服務
    • 當客户端連接後,定期更新心率特徵值並通過通知發送給客户端
  2. 客户端(Central):

    • 掃描BLE設備(按服務UUID過濾)
    • 連接目標設備
    • 發現服務及特徵
    • 訂閲特徵通知
    • 接收特徵值變化

以下是V哥整理的核心代碼邏輯。

注意:由於HarmonyOS 6.0可能使用新的API包(如@ohos.bluetooth等),我們需要參考最新官方文檔,但這裏以搜索結果為基礎,結合常見的BLE流程進行説明。


📡 一、服務端實現(廣播心率數據)**
1. 初始化藍牙服務**

import { bluetooth } from '@kit.ConnectivityKit';

// 定義服務UUID和特徵值(需與客户端匹配)
const SERVICE_UUID = '0000180D-0000-1000-8000-00805F9B34FB'; // 標準心率服務UUID
const CHARACTERISTIC_UUID = '00002A37-0000-1000-8000-00805F9B34FB'; // 心率測量特徵

// 創建GATT服務
let gattServer: bluetooth.GattServer = bluetooth.createGattServer();
let service: bluetooth.GattService = {
  serviceUuid: SERVICE_UUID,
  isPrimary: true,
  characteristics: [{
    characteristicUuid: CHARACTERISTIC_UUID,
    permissions: bluetooth.CharacteristicPermission.READ,
    properties: bluetooth.CharacteristicProperty.NOTIFY
  }]
};
gattServer.addService(service);

2. 開啓廣播併發送數據**

// 啓動BLE廣播
let advertiseSetting: bluetooth.AdvertiseSetting = {
  interval: 320, // 廣播間隔(單位0.625ms)
  txPower: 0,    // 發射功率
  connectable: true
};
gattServer.startAdvertising(advertiseSetting, {
  serviceUuids: [SERVICE_UUID] // 廣播的服務標識
});

// 模擬心率數據發送(定時更新)
setInterval(() => {
  const heartRate = Math.floor(Math.random() * 40) + 60; // 生成60~100隨機心率值
  const data = new Uint8Array([0x06, heartRate]); // 數據格式:Flags(06) + 心率值

  // 通知已連接的客户端
  gattServer.notifyCharacteristicChanged({
    serviceUuid: SERVICE_UUID,
    characteristicUuid: CHARACTERISTIC_UUID,
    deviceId: connectedDeviceId, // 連接的設備ID
    value: data.buffer            // ArrayBuffer格式數據
  });
}, 2000); // 每2秒發送一次

3. 處理客户端連接事件**

gattServer.on('connectionStateChange', (device: bluetooth.Device, state: number) => {
  if (state === bluetooth.ProfileConnectionState.STATE_CONNECTED) {
    console.log(`設備已連接: ${device.deviceId}`);
    connectedDeviceId = device.deviceId; // 保存連接的設備ID
  } else if (state === bluetooth.ProfileConnectionState.STATE_DISCONNECTED) {
    console.log('設備已斷開');
  }
});

📱 二、客户端實現(訂閲心率數據)**

1. 掃描並連接服務端

import { bluetooth } from '@kit.ConnectivityKit';

// 掃描指定服務的設備
let scanner: bluetooth.BLEScanner = bluetooth.createBLEScanner();
scroller.startScan({
  serviceUuids: [SERVICE_UUID] // 過濾目標服務
});

// 發現設備回調
scanner.on('deviceDiscover', (device: bluetooth.ScanResult) => {
  if (device.deviceName === "HeartRate_Server") { // 根據設備名過濾
    const gattClient: bluetooth.GattClientDevice = bluetooth.createGattClientDevice(device.deviceId);
    gattClient.connect(); // 連接服務端
  }
});

2. 訂閲特徵值通知**

// 連接成功後訂閲數據
gattClient.on('servicesDiscovered', () => {
  const service = gattClient.getService(SERVICE_UUID);
  const characteristic = service.getCharacteristic(CHARACTERISTIC_UUID);

  // 啓用特徵值通知
  characteristic.setCharacteristicChangeNotification(true).then(() => {
    characteristic.on('characteristicChange', (value: ArrayBuffer) => {
      const heartRate = new Uint8Array(value); // 解析心率值
      console.log(`實時心率: ${heartRate} BPM`);
    });
  });
});

3. 斷開連接處理**

gattClient.on('connectionStateChange', (state: number) => {
  if (state === bluetooth.ProfileConnectionState.STATE_DISCONNECTED) {
    console.log('已斷開服務端連接');
    scanner.stopScan(); // 停止掃描
  }
});

🔑 三、關鍵知識點**

  1. UUID 規範

    • 使用標準 UUID(如心率服務 0x180D)確保跨設備兼容性。
  2. 數據廣播

    • 服務端通過 notifyCharacteristicChanged() 主動推送數據,客户端無需輪詢。
  3. 權限配置

    • 需在 module.json5 中聲明藍牙權限:
      "requestPermissions": [{
        "name": "ohos.permission.USE_BLUETOOTH"
      }]
  4. 雙機調試

    • 需兩台 HarmonyOS 設備(或模擬器)分別運行服務端/客户端。

⚠️ 四、常見問題**

  1. 連接失敗

    • 檢查設備是否開啓藍牙可見性,並確認 SERVICE_UUID 完全匹配。
  2. 收不到通知

    • 客户端需先調用 setCharacteristicChangeNotification(true) 訂閲通知。
  3. 廣播功耗優化

    • 調整 AdvertiseSetting.interval 可平衡廣播頻率與功耗。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.