本文讲述的是在OpenHarmony轻量设备(L0设备)上进行BLE相关应用程序的开发。应用所在设备作为Gatt Client与其他Gatt Server设备进行连接和通信。

作为Gatt Client设备主要包含以下功能:

  • 设备扫描

  • 设备连接

  • 设备通信

  • 设备广播

一般在BLE应用中要先进行BLE设备扫描,从众多的BLE设备中选择需要的目标设备,而后再进行连接和通信。本文就重点讲述BLE设备的扫描。

BLE设备扫描接口

// 开始BLE扫描
startBLEScan(filters: Array<ScanFilter>, options?: ScanOptions): number
// 停止BLE扫描
stopBLEScan(): number
// 订阅BLE设备发现上报事件
on(type: 'BLEDeviceFind', callback: Callback<Array<ScanResult>>): number
// 取消订阅BLE设备发现上报事件
off(type: 'BLEDeviceFind', callback?: Callback<number, Array<ScanResult>>): number

详细的BLE接口说明请参考蓝牙ble模块

BLE设备扫描接口的使用

以下为BLE设备扫描的示例,代码启动设备扫描10秒钟,然后停止扫描。从扫描结果中选择符合要求的设备进行连接。

1、在开始启动扫描前,首先订阅BLE设备发现上报事件。

     订阅设备发现事件是以callback的形式注册设备发现的处理函数。callback函数的参数devices是当前所扫描到的设备数组。

     底层模块会多次调用callback函数通知应用层扫描的结果。以下示例代码中,将扫描结果先暂存到devList中,等扫描结束后再进行处理。

2、设置扫描参数,启动扫描。

      示例代码中没有设置扫描的过滤条件,实际应用中可以根据服务的UUID、设备的mac等设置过滤条件,加快筛选设备的效率。

// 根据服务UUID来过滤设备
let scanFilter = [{ serviceUuid: 'fff0' }];
ret = ble.startBLEScan(scanFilter);

    对于需要通过判断广播报文中某个字段来确定目标设备的场景下,扫描结果的结构ScanResult.data保存了扫描到的设备发送的广播包,可以直接解析广播报文中的数据来确定是否为目标设备。

3、随着BLE扫描发现设备,onFindBleDevice被调用。

     示例代码将发现的设备暂存到this.devList中待处理。

4、10秒超时后停止BLE扫描,选择合适的设备准备连接。

     示例代码中选择信号最强的设备保存到this.bestDev,待后续进行连接操作。

5、在当前页面或者程序退出时,取消订阅设备发现上报事件。

// scan.js

import ble from '@ohos.bluetooth.ble';

// 从扫描的设备中选择型号最强的设备
function findBestDev(devices)
{
    if (devices.length <= 0) {
        return null;
    }

    let best = devices[0];
    let rssi = devices[0].rssi;
    for (let i = 1; i < devices.length; i++) {
        if (rssi < devices[i].rssi) {
            rssi = devices[i].rssi;
            best = devices[i];
        }
    }
    return best;
}

export default {
    data: {
        devList: [],   // 保存扫描到的设备信息
        bestDev: null, // 保存选择要连接的设备
    },
    
    onFindBleDevice(devices) {
        console.debug(`bluetooth device find num ${devices.length}`);
        console.debug('bluetooth device find: ' + JSON.stringify(devices));
        
        if (devices.length == 0) {
            return;
        }
        if (this.devList.length > devices.length) {
            this.devList.length = 0;
        }
        
        for (let i = 0; i < devices.length; i++) {
            if (!devices[i].connectable) {
                console.debug(`device ${devices[i].deviceName} is not connectable!`);
                continue;
            }

            let dev = {
                mac: devices[i].deviceId,
                devName: devices[i].deviceName,
                rssi: devices[i].rssi
            };
            this.devList.push(dev);
        }
    },
    
    startScan() {
        // 启动扫描时,没有任何过滤条件
        let ret = ble.startBLEScan([]);
        if (ret != 0) {
            console.error(`start ble scan failed, ret=${ret}`);            
        }
    },
    
    stopScan() {
        let ret = ble.stopBLEScan();
        if (ret != 0) {
            console.error(`ble: stop ble scan failed, ret=${ret}`);              
        }
    },
    
    onReady() {
        let ret = ble.on('BLEDeviceFind', this.onFindBleDevice.bind(this));
        if (ret != 0) {
            console.error(`register ble device find failed, ret=${ret}`);  
            return;
        }
        
        this.startScan();
        // 扫描10秒后,就停止扫描,选择出一个信号最强的设备
        let self = this;
        setTimeout(() => {
            self.stopScan();
            self.bestDev = findBestDev(self.devList);
        }, 10000);        
    },
    
    onDestroy() {
        ble.off('BLEDeviceFind');
    },
}

 

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐