HarmonyOS 鸿蒙Next中BLE相关问题

HarmonyOS 鸿蒙Next中BLE相关问题 1、默认的MTU是多少,以及如何获取MTU

2、如何自动连接设备,目前没有看到相关API(Android有)

6 回复

默认MTU值:

默认MTU范围为22-512字节,实际默认初始值为23字节;应用层可用数据量为MTU值减3字节

MTU获取方式:

监听MTU变更事件获取实际值:

// 监听MTU变更
ble.on('BLEMtuChange', (mtu: number) => {
  console.log(`当前MTU: ${mtu}`) // 实际可用数据量为mtu-3
})

设置自定义MTU值:

gattClient.setBLEMtuSize(40) // 设置后触发BLEMtuChange事件

自动连接实现

当前无显式自动连接接口,可以使用createGattClientDevice创建持久化连接对象,通过设备状态监听实现重连

// 1. 创建持久化连接实例
let gattClient = ble.createGattClientDevice('XX:XX:XX:XX:XX:XX')

// 2. 监听连接状态
ble.on('BLEConnectionStateChange', (state: constant.ProfileConnectionState) => {
  if (state === constant.ProfileConnectionState.STATE_DISCONNECTED) {
    // 3. 触发重连
    gattClient.connect()
  }
})

// 4. 主动发起首次连接
gattClient.connect((err: BusinessError) => {
  if (err) console.error('连接失败:', err)
})

更多关于HarmonyOS 鸿蒙Next中BLE相关问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


与对端设备第一次连接后,发起蓝牙配对,配对完成后,蓝牙虚拟MAC地址会被固化。后续无需重复建立蓝牙扫描,调用getPairedDevices接口就可以从已配对列表中获取对端蓝牙的虚拟MAC地址,向对端设备发起连接

import { ble, connection, constant } from "@kit.ConnectivityKit";
import { BusinessError } from "@kit.BasicServicesKit";

@Entry
@Component
struct Reconnect {
  @State gattClient: ble.GattClientDevice | undefined = undefined;
  @State deviceName: string = 'name';

  Reconnect() {
    // 先查询已配对设备列表,判断需要连接的设备是否在已配对设备列表中存在。
    let devices = connection.getPairedDevices()
    for (let index = 0; index < devices.length; index++) {
      let name = connection.getRemoteDeviceName(devices[index])
      // 需要连接的设备在已配对设备列表中存在,无需发起扫描,直接创建实例进行连接。
      if (name === this.deviceName) {
        // 创建ble蓝牙client实例
        this.gattClient = ble.createGattClientDevice(devices[index])
        // 连接前先创建连接状态回调监听
        this.onBLEConnectionStateChange()
        // 连接ble蓝牙
        this.gattClient.connect()
        return;
      }
    }
    // 需要连接的设备在已配对设备列表中不存在,开启常规ble蓝牙连接流程。
    // 订阅BLE设备发现
    this.onBLEDeviceFind()
    // 过滤参数可根据实际场景进行设置
    let scanFilter: ble.ScanFilter = {
      name: this.deviceName
    };
    // 扫描参数可根据实际场景配置
    let scanOptions: ble.ScanOptions = {
      interval: 500,
      dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
      matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE,
    }
    ble.startBLEScan([scanFilter], scanOptions)
  }

  onBLEDeviceFind() {
    ble.on('BLEDeviceFind', (data: Array<ble.ScanResult>) => {
      // 发现设备,创建实例进行连接。
      this.gattClient = ble.createGattClientDevice(data[0].deviceId)
      // 连接前先创建连接状态回调监听
      this.onBLEConnectionStateChange()
      // 连接ble蓝牙
      this.gattClient.connect()
      // 连接成后,将已连接设备加入配对列表。
      // 注意:加入配对列表时机并不固定,可根据实际场景来进行变更。
      connection.pairDevice(data[0].deviceId, (err: BusinessError) => {
        console.info('pairDevice err');
      });
    });
  }

  onBLEConnectionStateChange() {
    this.gattClient?.on('BLEConnectionStateChange', (state: ble.BLEConnectionChangeState) => {
      if (state.state === constant.ProfileConnectionState.STATE_DISCONNECTED) {
        // 如果蓝牙意外断开了连接,可以在此处重新发起连接,以达到意外断连快速回连能力。
        // 不过需要保证此时this.gattClient实例没有被销毁。
        this.gattClient?.connect()
      }
    })
  }

  build() {
    Column() {
      Button() {
        Text('ble蓝牙连接/支持快速回连')
      }
      .onClick(() => {
        // 发起连接
        this.Reconnect();
      })
    }
  }
}

MTU是协商出来的,是两端设备连接后协商一个两端都能接受的MTU,通过setBLEMtuSize方法来协商,用BLEMtuChange事件监听获取,如果不调用setBLEMtuSize方法就默认23。

setMtu() {
  // 创建client端实例
  this.gattClient = ble.createGattClientDevice(this.deviceMAC)
  // 订阅ble蓝牙连接状态监听事件
  this.gattClient.on('BLEConnectionStateChange', (state: ble.BLEConnectionChangeState) => {
    // state.state返回结果为2时,表示client端同server端成功建立了连接
    if (state.state === constant.ProfileConnectionState.STATE_CONNECTED) {
      // 调用setBLEMtuSize接口,同server端协商MTU,参数取值范围23~517
      this.gattClient.setBLEMtuSize(128)
    }
  })
  // 订阅MTU协商结果监听事件
  this.gattClient.on('BLEMtuChange', (mtu: number) => {
    // MTU协商结果监听回调,回调触发,表示协商成功
    console.info('BLEMtuChange, mtu: ' + mtu);
  });
  // 连接server端ble蓝牙
  this.gattClient.connect()
}

MTU这个跟Android是一致的,那自动重连呢?

鸿蒙Next中BLE开发使用@ohos.bluetooth接口。主要类包括BluetoothHost(主机管理)、GattClient(客户端操作)、GattServer(服务端操作)。关键流程:1.通过bluetooth.getHost()获取主机实例;2.使用startBluetoothDiscovery()扫描设备;3.通过GattClient.connect()连接目标设备;4.数据交互使用writeCharacteristicValue()和readCharacteristicValue()。需在config.json中声明ohos.permission.USE_BLUETOOTH权限。BLE服务发现通过discoverServices()完成。

关于HarmonyOS Next中BLE相关问题的解答:

  1. MTU问题:
  • 默认MTU为23字节(与蓝牙标准一致)
  • 获取MTU方法: 通过调用BluetoothGatt#getMtu()方法获取当前连接的MTU值 需要先建立GATT连接后才能获取有效值
  1. 自动连接设备:
  • HarmonyOS Next目前没有提供类似Android的自动连接API
  • 替代方案:
  1. 使用BluetoothDevice#createBond()建立绑定
  2. 通过系统广播监听设备可用状态
  3. 当设备可用时主动调用connectGatt()
  4. 建议配合后台任务实现自动重连逻辑

注:实际开发时需注意设备绑定状态管理和连接超时处理。

回到顶部