【鸿蒙开发实战篇】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. 初始化蓝牙服务

typescript 复制代码
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. 开启广播并发送数据

typescript 复制代码
// 启动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. 处理客户端连接事件

typescript 复制代码
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. 扫描并连接服务端
typescript 复制代码
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. 订阅特征值通知

typescript 复制代码
// 连接成功后订阅数据
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. 断开连接处理

typescript 复制代码
gattClient.on('connectionStateChange', (state: number) => {
  if (state === bluetooth.ProfileConnectionState.STATE_DISCONNECTED) {
    console.log('已断开服务端连接');
    scanner.stopScan(); // 停止扫描
  }
});

🔑 三、关键知识点

  1. UUID 规范
    • 使用标准 UUID(如心率服务 0x180D)确保跨设备兼容性。
  2. 数据广播
    • 服务端通过 notifyCharacteristicChanged() 主动推送数据,客户端无需轮询。
  3. 权限配置
    • 需在 module.json5 中声明蓝牙权限:
json 复制代码
     "requestPermissions": [{
       "name": "ohos.permission.USE_BLUETOOTH"
     }]
  1. 双机调试
    • 需两台 HarmonyOS 设备(或模拟器)分别运行服务端/客户端。

⚠️ 四、常见问题

  1. 连接失败
    • 检查设备是否开启蓝牙可见性,并确认 SERVICE_UUID 完全匹配。
  2. 收不到通知
    • 客户端需先调用 setCharacteristicChangeNotification(true) 订阅通知。
  3. 广播功耗优化
    • 调整 AdvertiseSetting.interval 可平衡广播频率与功耗。
相关推荐
liulian09169 小时前
Flutter for OpenHarmony 跨平台开发:BMI计算器功能实战指南
flutter·华为
xmdy586612 小时前
Flutter+开源鸿蒙实战|智安盾电商溯源平台Day1 项目搭建与整体方案拆解
flutter·开源·harmonyos
nashane13 小时前
HarmonyOS 6学习:应用签名文件丢失处理与更新完全指南
学习·华为·harmonyos·harmonyos 5
笔触狂放14 小时前
【项目】基于ArkTS的老年人智能应用开发(1)
harmonyos·arkts·鸿蒙
byte轻骑兵15 小时前
【HID】规范精讲[8]: 蓝牙HID核心之L2CAP层——无线人机交互的通信桥梁设计解析
人工智能·人机交互·蓝牙·键盘·hid
24白菜头16 小时前
【无标题】
c++·笔记·学习·harmonyos
LeesonWong17 小时前
Neo 构建鸿蒙应用【二】:技术路线全解
harmonyos
LeesonWong17 小时前
Neo 构建鸿蒙应用【三】:实战社交应用与工程感悟
harmonyos
xmdy586618 小时前
Flutter+开源鸿蒙实战|智联邻里Day6 引入GetX全局架构+升级版下拉刷新+Toast弹窗+网络状态监听
flutter·开源·harmonyos
斯班奇的好朋友阿法法19 小时前
鸿蒙 vs iOS vs 微信小程序:开发平台全面对比
ios·微信小程序·harmonyos