本文同步发表于微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、功能

  1. 主动配对设备 - 与目标蓝牙设备建立配对关系

  2. 连接设备profile能力 - 连接已配对设备支持的服务能力

前置条件

  • 蓝牙状态:必须确保蓝牙已开启(STATE_ONSTATE_BLE_ON状态)

  • 权限要求:需要申请ohos.permission.ACCESS_BLUETOOTH权限

  • 设备状态:目标设备必须处于可被发现状态

二、开发准备

2.1 权限申请

必需权限ohos.permission.ACCESS_BLUETOOTH

  • 申请步骤

    1. 在配置文件中声明权限

    2. 运行时向用户申请授权

2.2 API模块导入

需要导入多个相关模块以支持完整的配对与连接功能:

import { connection, a2dp, hfp, hid, baseProfile, constant, common } from '@kit.ConnectivityKit';
import { BusinessError } from '@kit.BasicServicesKit';

各模块作用

  • connection:蓝牙连接相关API

  • a2dp:高级音频分发协议支持

  • hfp:免提通话协议支持

  • hid:人机接口设备协议支持

  • baseProfile:基础profile状态管理

  • constant:常量定义(如profile UUID)

  • common:通用类型定义

  • BusinessError:错误处理

三、蓝牙配对功能

3.1 配对状态管理

3.1.1 配对状态类型
  • BOND_STATE_INVALID:未配对或配对无效

  • BOND_STATE_BONDED:已成功配对(目标状态)

  • BOND_STATE_BONDING:正在配对(中间状态)

3.1.2 订阅配对状态变化事件

目的:实时获取配对过程的状态变化

实现代码

// 定义配对状态变化回调函数
function onReceiveEvent(data: connection.BondStateParam) {
    console.info('pair result: ' + JSON.stringify(data));
}

try {
    // 发起订阅配对状态变化事件
    connection.on('bondStateChange', onReceiveEvent);
} catch (err) {
    console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}

触发场景

  1. 应用主动发起配对其他设备

  2. 其他设备主动配对本机设备

3.2 发起配对操作

3.2.1 配对前提条件
  • 目标设备状态:必须处于BOND_STATE_INVALID状态

3.2.2 用户交互流程

配对过程中,系统会弹出配对请求对话框,不同配对类型对话框样式可能不同:

  • 确认配对密钥(Confirm Passkey)模式:需要用户确认配对密钥

  • 用户授权:必须用户同意授权才能配对成功

3.2.3 地址类型说明

MAC地址处理机制

  • 实际MAC地址:属于用户隐私信息

  • 虚拟MAC地址:蓝牙子系统为每个蓝牙外设分配的地址

  • 映射关系:系统保存虚拟MAC地址与实际MAC地址的映射关系

3.2.4 API版本适配

API Version 20及以前(推荐)
特点:不需要关注目标设备的MAC地址类型

// 通过发现设备流程获取目标设备地址
let device = '66:66:66:66:66:66';

try {
    // 发起配对
    connection.pairDevice(device).then(() => {
        console.info('pairDevice');
    }, (error: BusinessError) => {
        console.error('pairDevice: errCode:' + error.code + ', errMessage:' + error.message);
    });
} catch (err) {
    console.error('startPair: errCode:' + err.code + ', errMessage:' + err.message);
}

API Version 21开始(需要指定地址类型)
特点:需要同时指定目标设备的MAC地址和地址类型

let btAddr: common.BluetoothAddress = {
    "address": '66:66:66:66:66:66',  // 目标设备的实际MAC地址或虚拟MAC地址
    "addressType": common.BluetoothAddressType.REAL,  // 相应的地址类型
}

try {
    // 发起配对
    connection.pairDevice(btAddr).then(() => {
        console.info('pairDevice');
    }, (error: BusinessError) => {
        console.error('pairDevice: errCode:' + error.code + ', errMessage:' + error.message);
    });
} catch (err) {
    console.error('startPair: errCode:' + err.code + ', errMessage:' + err.message);
}

四、连接设备profile能力

4.1 连接时机与条件

4.1.1 连接前提
  1. 设备已配对:目标设备必须已成功配对(BOND_STATE_BONDED

  2. profile支持:设备必须支持相关profile能力

4.1.2 可连接profile类型

connectAllowedProfiles方法支持连接的profile包括:

  1. A2DP:高级音频分发协议(高质量音频传输)

  2. HFP:免提通话协议(语音通话)

  3. HID:人机接口设备协议(键盘、鼠标等)

4.2 设备profile能力查询

4.2.1 能力获取机制
  • 配对过程中:蓝牙子系统会自动查询和保存目标设备支持的所有profile能力

  • 配对完成后:应用可以主动查询目标设备的profile能力

4.2.2 查询方法
// 查询设备支持的profile UUID列表
let uuids = await connection.getRemoteProfileUuids(device);
4.2.3 连接时间窗口
  • 最佳时机:配对完成后30秒内发起连接

  • 原因:确保设备处于可连接状态

4.3 连接实现流程

4.3.1 创建profile实例
// 创建各profile实例
let a2dpSrc = a2dp.createA2dpSrcProfile();    // A2DP源设备(音频发送端)
let hfpAg = hfp.createHfpAgProfile();         // HFP音频网关(手机端)
let hidHost = hid.createHidHostProfile();     // HID主机设备(接收端)
4.3.2 订阅连接状态变化
// 定义A2DP连接状态变化回调函数
function onA2dpConnectStateChange(data: baseProfile.StateChangeParam) {
    console.info(`A2DP State: ${JSON.stringify(data)}`);
}

// 定义HFP连接状态变化回调函数
function onHfpConnectStateChange(data: baseProfile.StateChangeParam) {
    console.info(`HFP State: ${JSON.stringify(data)}`);
}

// 定义HID连接状态变化回调函数
function onHidConnectStateChange(data: baseProfile.StateChangeParam) {
    console.info(`HID State: ${JSON.stringify(data)}`);
}

try {
    // 订阅各profile连接状态变化事件
    a2dpSrc.on('connectionStateChange', onA2dpConnectStateChange);
    hfpAg.on('connectionStateChange', onHfpConnectStateChange);
    hidHost.on('connectionStateChange', onHidConnectStateChange);
} catch (err) {
    console.error('订阅连接状态失败');
}
4.3.3 发起连接
// 发起连接目标设备支持的profile
connection.connectAllowedProfiles(device).then(() => {
    console.info('connectAllowedProfiles');
}, (error: BusinessError) => {
    console.error('errCode:' + error.code + ',errMessage' + error.message);
});

五、注意事项

5.1 权限与状态管理

  1. 权限验证:确保已获得蓝牙访问权限

  2. 蓝牙状态:使用功能前检查蓝牙是否已开启

  3. 配对状态:发起连接前确认设备已成功配对

5.2 用户交互

  1. 配对确认:配对过程需要用户明确授权

  2. 连接时机:配对完成后尽快发起连接

  3. 错误提示:提供友好的错误提示和恢复建议

5.3 API版本兼容

  1. 配对方式选择:根据API版本选择合适的配对方法

  2. 地址类型处理:API 21+需要指定设备地址类型

  3. 虚拟地址映射:了解系统对MAC地址的处理机制

5.4 错误处理策略

  1. 网络异常:处理设备不可达或连接超时

  2. 用户拒绝:处理用户拒绝配对授权的情况

  3. 设备不支持:处理设备不支持特定profile的情况

  4. 状态异常:处理配对或连接过程中的异常状态

5.5 核心流程

  1. 准备阶段:申请权限、导入模块、检查蓝牙状态

  2. 配对阶段:订阅配对状态、发起配对请求、处理用户授权

  3. 连接阶段:查询profile能力、订阅连接状态、发起连接

5.6 资源管理

  1. 事件监听:及时注册和注销事件监听器

  2. 实例管理:合理管理profile实例生命周期

  3. 内存释放:使用完毕后及时释放资源

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐