大家好,我是 V 哥。
以下基於 HarmonyOS 6.0 的藍牙 BLE 通訊案例詳解,模擬心率監測場景,實現服務端(Peripheral)廣播數據與客户端(Central)訂閲數據的功能流程:
聯繫V哥獲取 鴻蒙學習資料
關鍵步驟:
-
服務端(Peripheral):
- 創建藍牙服務(GATT Server)
- 添加服務(Service)和特徵(Characteristic)
- 廣播服務
- 當客户端連接後,定期更新心率特徵值並通過通知發送給客户端
-
客户端(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(); // 停止掃描
}
});
🔑 三、關鍵知識點**
-
UUID 規範
- 使用標準 UUID(如心率服務
0x180D)確保跨設備兼容性。
- 使用標準 UUID(如心率服務
-
數據廣播
- 服務端通過
notifyCharacteristicChanged()主動推送數據,客户端無需輪詢。
- 服務端通過
-
權限配置
- 需在
module.json5中聲明藍牙權限:
"requestPermissions": [{ "name": "ohos.permission.USE_BLUETOOTH" }] - 需在
-
雙機調試
- 需兩台 HarmonyOS 設備(或模擬器)分別運行服務端/客户端。
⚠️ 四、常見問題**
-
連接失敗
- 檢查設備是否開啓藍牙可見性,並確認
SERVICE_UUID完全匹配。
- 檢查設備是否開啓藍牙可見性,並確認
-
收不到通知
- 客户端需先調用
setCharacteristicChangeNotification(true)訂閲通知。
- 客户端需先調用
-
廣播功耗優化
- 調整
AdvertiseSetting.interval可平衡廣播頻率與功耗。
- 調整