HarmonyOS鸿蒙Next中HID BLE设备配对后如何自动连接

HarmonyOS鸿蒙Next中HID BLE设备配对后如何自动连接 hid配对后没有自动连接的问题

配对以后 HID不能自动连接,需要手工去系统蓝牙设置里点一下。系统api 如何实现 。

Android 中 BluetoothDevice.createBond() 会自动连接上hid

目前的代码

// 发起配对请求
connection.pairDevice(deviceId).then(() => {
  hilog.info(DOMAIN, TAG, '配对请求已发送,等待用户确认');
  this.bondInitiated = true;
}).catch((err: BusinessError) => {
  hilog.error(DOMAIN, TAG, '配对失败: %{public}d - %{public}s', err.code, err.message);
  this.bondInitiated = false;
  // 可以通知UI配对失败
  this.notifyState(DeviceState.DISCONNECTED);
});

求解答


更多关于HarmonyOS鸿蒙Next中HID BLE设备配对后如何自动连接的实战教程也可以访问 https://www.itying.com/category-93-b0.html

7 回复

【背景知识】

  • 从API16版本开始,@ohos.bluetooth.connection模块提供了connectAllowedProfiles接口,支持对HFP、HID、A2DP设备主动发起连接。
  • 从API12版本开始,@ohos.bluetooth.connection模块提供了getRemoteProfileUuids接口,可用于查询对端蓝牙设备的profile协议能力,建议仅对已配对的设备调用该方法。

【解决方案】

  • 当与HID设备完成配对,调用connectAllowedProfiles接口成功建立连接后,后续每次重新打开蓝牙开关,系统都可以自动与HID设备建立连接。参考如下代码:
import { connection } from '@kit.ConnectivityKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct connectAllowedProfiles {
  connectAllowedProfiles() {
    // 发起蓝牙配对请求,此处的mac需要提前获取
    connection.pairDevice('xx.xx.xx.xx', (err: BusinessError) => {
      console.info(`pairDevice, device name err:${err}`);
    });

    // 订阅蓝牙配对状态变化事件
    connection.on('bondStateChange', (data: connection.BondStateParam) => {
      // 蓝牙已配对
      if (data.state === connection.BondState.BOND_STATE_BONDED) {
        // 调用getRemoteProfileUuids接口获取对端蓝牙支持的Profile类型
        connection.getRemoteProfileUuids(data.deviceId,
          (err: BusinessError, dataArray: Array<connection.ProfileUuids>) => {
            console.error(`getRemoteProfileUuids errCode: ${(err as BusinessError).code}, errMessage: ${(err as BusinessError).message}, dataArray: ${dataArray}`);
            // 当dataArray中支持类型包含A2DP、HFP和HID其中的一种,可调用connectAllowedProfiles接口发起连接。
            connection.connectAllowedProfiles(data.deviceId, (err: BusinessError) => {
              if (err) {
                console.error(`connectAllowedProfiles errCode: ${(err as BusinessError).code}, errMessage: ${(err as BusinessError).message}`);
                return;
              }
              console.info('connectAllowedProfiles');
            });
          });
      }
    });
  }

  build() {
    Column() {
      Button('connect Allowed Profiles')
        .onClick(() => {
          // 创建蓝牙配对状态变化监听,发起蓝牙配对,连接蓝牙
          this.connectAllowedProfiles();
        });
    };
  }
}
  • 如果在系统蓝牙界面使用手动点击的方式与HID设备建立连接,需要在已配对的设备配置信息中打开‘输入设备’开关,才能实现稳定回连。

参考文档:HID蓝牙配对后如何实现自动连接

更多关于HarmonyOS鸿蒙Next中HID BLE设备配对后如何自动连接的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


// 蓝牙已配对
if (data.state === connection.BondState.BOND_STATE_BONDED) {
  // 调用getRemoteProfileUuids接口获取对端蓝牙支持的Profile类型
  connection.getRemoteProfileUuids(data.deviceId,
    (err: BusinessError, dataArray: Array<connection.ProfileUuids>) => {
      console.error(`getRemoteProfileUuids errCode: ${(err as BusinessError).code}, errMessage: ${(err as BusinessError).message}, dataArray: ${dataArray}`);
      // 当dataArray中支持类型包含A2DP、HFP和HID其中的一种,可调用connectAllowedProfiles接口发起连接。
      connection.connectAllowedProfiles(data.deviceId, (err: BusinessError) => {
        if (err) {
          console.error(`connectAllowedProfiles errCode: ${(err as BusinessError).code}, errMessage: ${(err as BusinessError).message}`);
          return;
        }
        console.info('connectAllowedProfiles');
      });
    });
}

上面这段调用,好像需要加一个延时,直接上面的代码,没有自动连接成功。请确认。

// 蓝牙已配对
if (data.state === connection.BondState.BOND_STATE_BONDED) {
    setTimeout(async () => {
      ...
    }, 2000);
}

开发者你好,方便的话可以提供下您这边设备版本、DevEco Studio版本信息以及日志信息以便进一步分析吗? 麻烦开发者在复现问题后,记录问题时间点获取下hilog和HCI日志,日志获取方式:

  • hdc file recv /data/log/hilog ./hilog,输出hilog日志
  • hdc file recv data/log/bt/ ./btlog3,输出HCI日志

获取日志后可以打包通过写回答中的附件方式上传下日志压缩包。

应该100%能出现。
hid 配对后在订阅的事件回调里 connection.connectAllowedProfiles,直接调用不会连接成功

设备:基本设备都能出现。matepad mini、MatePad Pro、MatePad 灵动
DevEco Studio 版本:应该跟这个没有关系。我现在用的DevEco Studio 6.0.2 Release

就是

// 订阅蓝牙配对状态变化事件
connection.on(‘bondStateChange’, (data: connection.BondStateParam) => {

// 蓝牙已配对  
if (data.state === connection.BondState.BOND_STATE_BONDED) {  
        //  这里调用  connection.connectAllowedProfiles  直接调用 没有连接  
        // 延时调用 ,而且好像500ms以上 ,才能连接 setTimeout(async () => { connection.connectAllowedProfiles }, 1000);  
}  

}

请帮忙排查,给出解决方案,应该很容易复现的

// 蓝牙已配对
if (data.state === connection.BondState.BOND_STATE_BONDED) {
  // 调用getRemoteProfileUuids接口获取对端蓝牙支持的Profile类型
  connection.getRemoteProfileUuids(data.deviceId,
    (err: BusinessError, dataArray: Array<connection.ProfileUuids>) => {
      console.error(`getRemoteProfileUuids errCode: ${(err as BusinessError).code}, errMessage: ${(err as BusinessError).message}, dataArray: ${dataArray}`);
      // 当dataArray中支持类型包含A2DP、HFP和HID其中的一种,可调用connectAllowedProfiles接口发起连接。
      connection.connectAllowedProfiles(data.deviceId, (err: BusinessError) => {
        if (err) {
          console.error(`connectAllowedProfiles errCode: ${(err as BusinessError).code}, errMessage: ${(err as BusinessError).message}`);
          return;
        }
        console.info('connectAllowedProfiles');
      });
    });
}

上面这段调用,好像需要加一个延时,直接上面的代码,没有自动连接成功。请确认。

// 蓝牙已配对
if (data.state === connection.BondState.BOND_STATE_BONDED) {
    setTimeout(async () => {
      ...
    }, 2000);
}

在HarmonyOS Next中,HID BLE设备配对后,系统会自动管理连接。应用可通过bluetoothManagerconnect方法触发连接,或依赖系统自动重连机制。配对信息会持久化,下次设备在范围内且蓝牙开启时,系统通常会尝试自动连接。应用可监听bluetoothManagerstateChange事件来获取连接状态。

在HarmonyOS Next中,HID BLE设备配对后实现自动连接,核心在于正确使用bluetoothManager.Gatt的API进行连接操作,而不是依赖配对API本身。

配对(pairDevice)与连接是两个独立的操作。配对成功仅代表设备建立了信任关系,并不会自动建立GATT连接。你需要主动调用connectGatt方法。

以下是实现自动连接的关键步骤:

  1. 监听配对状态变化:在配对请求发起后,你需要注册一个BluetoothStateObserver来监听设备的绑定状态。当状态变为BondState.BONDED(值为2)时,表示配对成功。

  2. 在配对成功后发起连接:在配对成功的回调中,立即调用connectGatt方法建立GATT连接。

修改后的代码逻辑示例:

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

// 1. 发起配对请求
connection.pairDevice(deviceId).then(() => {
  hilog.info(DOMAIN, TAG, '配对请求已发送,等待用户确认');
  this.bondInitiated = true;

  // 2. 注册监听器,监听此设备的绑定状态变化
  let observer: bluetoothManager.BluetoothStateObserver = {
    onDeviceStateChanged: (device: bluetoothManager.BluetoothDevice, state: number) => {
      // 检查是否为当前目标设备且状态变为“已配对”
      if (device.deviceId === deviceId && state === bluetoothManager.BondState.BONDED) {
        hilog.info(DOMAIN, TAG, '设备配对成功,开始尝试自动连接...');
        
        // 3. 配对成功后,立即发起GATT连接
        // 注意:这里需要你的GattClient实例,通常在应用初始化时创建
        // gattClient 应已通过 bluetoothManager.Gatt.createGattClientDevice(device) 创建
        this.gattClient.connectGatt().then(() => {
          hilog.info(DOMAIN, TAG, 'GATT连接已建立');
          this.notifyState(DeviceState.CONNECTED);
        }).catch((connectErr: BusinessError) => {
          hilog.error(DOMAIN, TAG, 'GATT连接失败: %{public}d', connectErr.code);
          this.notifyState(DeviceState.DISCONNECTED);
        });
        
        // 可选:移除监听器
        bluetoothManager.unregisterStateObserver(observer);
      }
    }
  };
  
  // 注册状态监听器
  bluetoothManager.registerStateObserver(observer);
  
}).catch((err: BusinessError) => {
  hilog.error(DOMAIN, TAG, '配对失败: %{public}d', err.code);
  this.bondInitiated = false;
  this.notifyState(DeviceState.DISCONNECTED);
});

关键点说明:

  • 配对与连接分离:HarmonyOS Next的蓝牙API设计清晰区分了配对(建立信任)和连接(建立通信链路)。pairDevice只负责前者。
  • 连接主体:连接操作由GattClient对象执行,而非BluetoothDevice。你需要先通过bluetoothManager.Gatt.createGattClientDevice(device)为已配对的设备创建一个GattClient实例,然后调用其connectGatt方法。
  • 监听器管理:在连接尝试完成后(无论成功与否),建议注销监听器以避免内存泄漏和重复触发。

请确保你的代码中已经正确初始化了GattClient。这样,当用户在系统弹窗中确认配对后,你的应用就能自动完成后续的连接流程,无需用户再手动操作。

回到顶部