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

一、功能与开发准备

1.1 功能

  1. 扫描周边蓝牙设备 - 搜索发现附近可用的蓝牙设备

  2. 设置本机蓝牙扫描模式 - 控制本机被其他设备发现的权限

  3. 查找已配对设备信息 - 访问已建立配对关系的设备

1.2 前置条件

  • 周边设备:必须处于可被发现状态

  • 本机状态:蓝牙必须已开启(STATE_ONSTATE_BLE_ON

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

1.3 开发准备步骤

  1. 申请蓝牙权限:参考鸿蒙官方文档中的权限声明和授权申请指南

  2. 导入API模块

import { connection } from '@kit.ConnectivityKit';
import { BusinessError } from '@kit.BasicServicesKit';

二、扫描周边蓝牙设备

2.1 说明

  • 扫描:也称为"搜索"、"发现"或"查找"

  • 必要条件:周边设备必须处于可被发现状态

  • 扫描时长:约12秒

  • 资源消耗:扫描过程消耗蓝牙硬件资源,找到设备后应尽快停止

2.2 API版本差异

2.2.1 API Version 18+(推荐)

支持获取完整设备信息,包括:

  • 设备地址(deviceId)

  • 信号强度(rssi)

  • 设备名称(name)

  • 设备类型(deviceType)

事件名称'discoveryResult'
数据类型Array<connection.DiscoveryResult>

2.2.2 API Version 17及以下

仅支持获取设备地址信息

事件名称'bluetoothDeviceFind'
数据类型Array<string>

2.3 实现流程

步骤1:订阅扫描结果上报事件
// 定义扫描结果上报回调函数
function onReceiveEvent(data: Array<connection.DiscoveryResult>) {
    console.info('bluetooth device: ' + JSON.stringify(data));
}

try {
    // 发起订阅
    connection.on('discoveryResult', onReceiveEvent);
} catch (err) {
    console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
步骤2:发起设备扫描
try {
    // 判断本机设备是否正在进行扫描
    let scan = connection.isBluetoothDiscovering();
    if (!scan) {
        // 若当前不处于扫描过程,则开始扫描设备
        connection.startBluetoothDiscovery();
    }
} catch (err) {
    console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
步骤3:停止设备扫描(重要)
// 定义扫描结果上报回调函数
function onReceiveEvent(data: Array<string>) {
    console.info('bluetooth device: ' + JSON.stringify(data));
}

try {
    // 判断本机设备是否正在进行扫描
    let scan = connection.isBluetoothDiscovering();
    if (scan) {
        // 若当前处于扫描过程,则停止扫描设备
        connection.stopBluetoothDiscovery();
    }
    // 若不再需要使用扫描,可以取消订阅扫描上报结果
    connection.off('discoveryResult', onReceiveEvent);
} catch (err) {
    console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}

三、设置本机蓝牙扫描模式

3.1 扫描模式说明

本机蓝牙扫描模式控制本机设备是否可以被周边其他设备扫描到或连接上。

3.1.1 扫描模式类型
  1. SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE

    • 可被扫描和可被连接

    • 系统行为:系统设置应用打开蓝牙后,若设置界面在前台,设置为此模式

  2. SCAN_MODE_CONNECTABLE

    • 仅可被连接(不可被扫描发现)

    • 系统行为:系统设置应用打开蓝牙后,若设置界面在后台,设置为此模式

3.1.2 注意事项
  • 非系统应用:一般不需要关注此模式设置

  • 系统设置应用:决定如何设置扫描模式

3.2 实现代码

try {
    // 获取当前本机的扫描模式
    let scanMode: connection.ScanMode = connection.getBluetoothScanMode();
    console.info('scanMode: ' + scanMode);
    
    if (scanMode != connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE) {
        // 将本机设备的扫描模式设置为可被发现和可被连接
        connection.setBluetoothScanMode(connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE, 0);
    }
} catch (err) {
    console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}

四、查找已配对设备信息

4.1 说明

  • 目的:在发起扫描前,检查设备是否已配对,减少不必要的扫描流程

  • 应用:对已配对设备可直接发起连接和数据传输

4.2 实现代码

try {
    // 获取已配对设备信息
    let devices = connection.getPairedDevices();
    console.info('pairedDevices: ' + JSON.stringify(devices));
    
    // 若已知道设备地址,可主动查询该设备是否是已配对的
    if (devices.length > 0) {
        let pairState = connection.getPairState(devices[0]);
        console.info('device: ' + devices[0] + ' pairState is ' + pairState);
    }
} catch (err) {
    console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}

五、完整示例

import { connection } from '@kit.ConnectivityKit';
import { BusinessError } from '@kit.BasicServicesKit';

export class DiscoveryDeviceManager {
    // 定义扫描结果上报回调函数
    onReceiveEvent = (data: Array<string>) => {
        console.info('bluetooth device: ' + JSON.stringify(data));
    };

    // 1. 开始发现设备
    public startDiscovery() {
        try {
            connection.on('bluetoothDeviceFind', this.onReceiveEvent);
        } catch (err) {
            console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
        }
        
        try {
            // 判断本机设备是否正在进行扫描
            let scan = connection.isBluetoothDiscovering();
            if (!scan) {
                // 若当前不处于扫描过程,则开始扫描设备
                connection.startBluetoothDiscovery();
            }
        } catch (err) {
            console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
        }
    }

    // 2. 停止发现设备
    public stopDiscovery() {
        try {
            // 判断本机设备是否正在进行扫描
            let scan = connection.isBluetoothDiscovering();
            if (scan) {
                // 若当前处于扫描过程,则停止扫描设备
                connection.stopBluetoothDiscovery();
            }
            // 若不再需要使用扫描,可以取消订阅扫描上报结果
            connection.off('bluetoothDeviceFind', this.onReceiveEvent);
        } catch (err) {
            console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
        }
    }

    // 3. 设置扫描模式
    public setScanMode() {
        try {
            // 获取当前本机的扫描模式
            let scanMode: connection.ScanMode = connection.getBluetoothScanMode();
            console.info('scanMode: ' + scanMode);
            
            if (scanMode != connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE) {
                // 将本机设备的扫描模式设为可被发现和可被连接
                connection.setBluetoothScanMode(connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE, 0);
            }
        } catch (err) {
            console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
        }
    }

    // 4. 获取已配对设备
    public getPairedDevices() {
        try {
            // 获取已配对设备信息
            let devices = connection.getPairedDevices();
            console.info('pairedDevices: ' + JSON.stringify(devices));
            
            // 若已知道设备地址,可主动查询该设备是否是已配对的
            if (devices.length > 0) {
                let pairState = connection.getPairState(devices[0]);
                console.info('device: ' + devices[0] + ' pairState is ' + pairState);
            }
        } catch (err) {
            console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
        }
    }
}

// 创建实例并导出
let discoveryDeviceManager = new DiscoveryDeviceManager();
export default discoveryDeviceManager as DiscoveryDeviceManager;

方法说明

startDiscovery() 方法
  • 功能:启动设备扫描

  • 执行流程

    1. 注册扫描结果监听器

    2. 检查当前扫描状态

    3. 如果未在扫描中,则启动扫描

stopDiscovery() 方法
  • 功能:停止设备扫描

  • 执行流程

    1. 检查当前扫描状态

    2. 如果在扫描中,则停止扫描

    3. 注销扫描结果监听器

setScanMode() 方法
  • 功能:设置本机扫描模式

  • 执行流程

    1. 获取当前扫描模式

    2. 如果不是目标模式,则设置为可被发现和可被连接模式

  • 注意:duration参数为0表示永久有效

getPairedDevices() 方法
  • 功能:获取已配对设备列表

  • 执行流程

    1. 获取所有已配对设备地址

    2. 可进一步查询特定设备的配对状态

  • 场景:在扫描前先检查设备是否已配对

备注:

  1. 合理使用配对信息:先检查已配对设备,减少不必要的扫描

  2. 扫描不到设备:确保目标设备蓝牙已开启且可被发现

  3. 重复设备发现:确保每次扫描前后正确注册和注销监听器

总结

核心功能

  1. 设备扫描:使用startBluetoothDiscovery()stopBluetoothDiscovery()控制扫描过程

  2. 结果监听:通过on('discoveryResult')on('bluetoothDeviceFind')接收扫描结果

  3. 模式设置:使用setBluetoothScanMode()控制本机可见性

  4. 配对查询:使用getPairedDevices()getPairState()访问配对信息

开发流程

  1. 准备阶段:申请权限,导入模块

  2. 初始化阶段:设置扫描模式,注册监听器

  3. 执行阶段:启动扫描,处理结果,及时停止

  4. 清理阶段:注销监听器,释放资源

Logo

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

更多推荐