HarmonyOSラーニングロードの開発 - ネットワークと接続(Bluetooth開発2)

BLE スキャンとブロードキャスト

シーン紹介

BLE スキャンとブロードキャストによって提供されるオープン機能により、指定されたステータスに応じて周辺デバイスを取得したり、BLE スキャンとブロードキャストを開始または停止したりできます。

インターフェースの説明

表 1  BLE セントラル デバイス管理クラス BleCentralManager のメイン インターフェイス

インターフェース名

機能説明

startScan(List<BleScanFilter> フィルター)

BLE Bluetooth スキャンを実行し、フィルターを使用して結果をフィルターします。

stopScan()

BLE Bluetooth スキャンを停止します。

getDevicesByStates(int[] 状態)

ステータスに基づいて接続されている周辺機器を取得します。

BleCentralManager(コンテキスト コンテキスト、BleCentralManagerCallback コールバック)

中央デバイス管理オブジェクトを取得します。

表 2  中央デバイス管理コールバック クラスのメイン インターフェイス BleCentralManagerCallback

インターフェース名

機能説明

scanResultEvent (BleScanResult 結果)

BLE デバイスへのスキャン結果のコールバック。

groupScanResultsEvent (List<BleScanResult> scanResults)

一連の BLE デバイスのスキャン結果のコールバック。

scanFailedEvent (int resultCode)

起動スキャン失敗時のコールバック。

表3  BLEブロードキャストに関連するBleAdvertiserクラスとBleAdvertiseCallbackクラスの主要インターフェース

インターフェース名

機能説明

BleAdvertiser(コンテキスト コンテキスト、BleAdvertiseCallback コールバック)

ブロードキャスト操作オブジェクトを取得するために使用されます。

startAdvertising(BleAdvertiseSettings 設定、BleAdvertiseData advData、BleAdvertiseData scanResponse)

BLE ブロードキャストの場合、最初のパラメータはブロードキャスト パラメータ、2 番目はブロードキャスト データ、3 番目のパラメータはスキャンとブロードキャスト データ パラメータの応答です。

stop広告()

BLEブロードキャストを停止します。

startResultEvent(int 結果)

ブロードキャストコールバック結果。

BLE スキャン用の中央デバイス

  1. BLE スキャンの前に、BleCentralManagerCallback クラスを継承して、scanResultEvent および scanFailedEvent コールバック関数を実装し、スキャン結果を受信する必要があります。
  2. BleCentralManager(BleCentralManagerCallback callback) インターフェイスを呼び出して、中央デバイス管理オブジェクトを取得します。
  3. スキャン フィルターを取得します。フィルターが空の場合はフィルターなしでスキャンし、startScan() を呼び出して BLE デバイスのスキャンを開始し、スキャンされた BLE デバイスをコールバックで取得します。
// 实现扫描回调
public class ScanCallback implements BleCentralManagerCallback{
    List<BleScanResult> results = new ArrayList<BleScanResult>();
    @Override
    public void scanResultEvent(BleScanResult resultCode) {
        // 对扫描结果进行处理
        results.add(resultCode);
    }
    @Override    
    public void scanFailedEvent(int resultCode) {        
        HiLog.warn(TAG,"Start Scan failed, Code: %{public}d", resultCode);    
    }
    @Override
    public void groupScanResultsEvent​(final List<BleScanResult> scanResults){
        // 对扫描结果进行处理
    }
}
// 获取中心设备管理对象
private ScanCallback centralManagerCallback = new ScanCallback();
private BleCentralManager centralManager = new BleCentralManager(context, centralManagerCallback);
// 创建扫描过滤器然后开始扫描
List<BleScanFilter> filters = new ArrayList<BleScanFilter>();
centralManager.startScan(filters);

BLEブロードキャストを行う周辺機器

  1. BLE ブロードキャストの前に、advertiseCallback クラスを継承して startResultEvent コールバックを実装し、ブロードキャスト結果を取得する必要があります。
  2. インターフェイス BleAdvertiser(Context context, BleAdvertiseCallback callback) を呼び出して広告オブジェクトを取得し、広告パラメータと広告データを構築します。
  3. startAdvertising(BleAdvertiseSettings settings, BleAdvertiseData advData, BleAdvertiseData scanResponse) インターフェイスを呼び出して、BLE ブロードキャストを開始します。
// 实现BLE广播回调
private BleAdvertiseCallback advertiseCallback = new BleAdvertiseCallback() {
    @Override    
    public void startResultEvent(int result) {
        if(result == BleAdvertiseCallback.RESULT_SUCC){
            // 开始BLE广播成功
        }else {
            // 开始BLE广播失败
        }
    }
};
// 获取BLE广播对象
private BleAdvertiser advertiser = new BleAdvertiser(this,advertiseCallback);
// 创建BLE广播参数和数据
private BleAdvertiseData data = new BleAdvertiseData.Builder()           
                        .addServiceUuid(SequenceUuid.uuidFromString(Server_UUID)) // 添加服务的UUID                  
                        .addServiceData(SequenceUuid.uuidFromString(Server_UUID), new byte[]{0x11}) // 添加广播数据内容
                        .build();
private BleAdvertiseSettings advertiseSettings = new BleAdvertiseSettings.Builder()                        
                       .setConnectable(true) // 设置是否可连接广播
                       .setInterval(BleAdvertiseSettings.INTERVAL_SLOT_DEFAULT) // 设置广播间隔
                       .setTxPower(BleAdvertiseSettings.TX_POWER_DEFAULT) // 设置广播功率
                       .build();
// 开始广播
advertiser.startAdvertising(advertiseSettings, data, null);

BLE 中央デバイスが周辺デバイスとデータを交換する

シーン紹介

BLE 周辺デバイスと中央デバイスは GATT 接続を確立し、これを通じて中央デバイスはサービス、特性、記述子、RSSI、および周辺デバイスがサポートするその他のデータを取得できます。同時に、中央デバイスは周辺デバイスにデータを要求し、Characteristic や Descriptor などの特性値データを周辺デバイスに書き込むことができます。

インターフェースの説明

Bluetooth low Energy周辺機器操作クラスのBlePeripheralDeviceのインターフェース記述は以下のとおりです。

表 1  Bluetooth Low Energy 周辺機器の操作 API の概要

インターフェース名

機能説明

connect(boolean isAutoConnect、BlePeripheralCallback コールバック)

GATT ペリフェラルを再接続します。isAutoConnect は、自動的に接続するかどうかを示します。

DiscoverServices()

周辺機器によってサポートされるサービス、特性、および説明を検索します。

getServices()

ペリフェラルによってサポートされているすべての GATT サービスを取得します。

getService(UUID uuid)

UUID に基づいて、ペリフェラルによってサポートされている GATT サービスを取得します。

切断()

周辺機器から BLE 接続を切断します。

近い()

Bluetooth GATT クライアントを閉じます。

readCharacteristic(GattCharacteristic 特性)

周辺機器の GATT 特性を読み取ります。

writeCharacteristic(GattCharacteristic 特性)

指定されたペリフェラルの GATT 特性値を書き込みます。

setNotifyCharacteristic(GattCharacteristic 特性、ブール値有効)

指定したGATT機能の通知の有効/無効を設定します。

readDescriptor (GattDescriptor 記述子)

周辺機器の GATT 記述値を読み取ります。

writeDescriptor(GattDescriptor 記述子)

指定されたペリフェラルの GATT 記述値を書き込みます。

readRemoteRssiValue()

接続されている周辺機器の RSSI を読み取ります。

requestBleConnectionPriority(int connPriority)

リンクパラメータの更新を要求します。

requestBleMtuSize(int mtu)

特定の接続に使用する MTU サイズを要求します。

BlePeripheralCallbackのオペレーションコールバッククラスであるBlePeripheralCallbackのインターフェース説明は以下のとおりです。

表 2  Bluetooth Low Energy 周辺機器の操作コールバック API の概要

インターフェース名

機能説明

servicesDiscoveredEvent(int ステータス)

周辺サービスの更新によってトリガーされるコールバック。

connectionStateChangeEvent(int connectionState)

ペリフェラルの GATT 接続の状態が変化したときのコールバック。

characteristicReadEvent(GattCharacteristic 特性、int ret)

GATT 特性値読み取り操作のコールバック。

characteristicWriteEvent(GattCharacteristic 特性、int ret)

GATT 特性値の書き込み操作のコールバック。

characteristicChangedEvent(GattCharacteristic 特性)

周辺機能の通知によってトリガーされるコールバック。

descriptorReadEvent(GattDescriptor 記述子、int ret)

GATT 記述値読み取り操作のコールバック。

descriptorWriteEvent(GattDescriptor 記述子、int ret)

GATT 記述値の書き込み操作のコールバック。

readRemoteRssiEvent(int rssi, int ret)

RSSI を読み取るためにペリフェラルによって送信されるコールバック。

mtuUpdateEvent(int mtu, int ret)

GATT デバイス リンクの MTU 変更通知のコールバック。

開発ステップ

  1. startScan() インターフェイスを呼び出して BLE スキャンを開始し、周辺デバイスを取得します。
  2. 获取到外围设备后,调用connect(boolean isAutoConnect, BlePeripheraCallback callback)建立与外围BLE设备的GATT连接,boolean参数isAutoConnect用于设置是否允许设备在可发现距离内自动建立GATT连接。
  3. 启动GATT连接后,会触发connectionStateChangeEvent(int connectionState)回调,根据回调结果判断是否连接GATT成功。
  4. 在GATT连接成功时,中心设备可以调用discoverServices()接口,获取外围设备支持的Services、Characteristics等特征值,在回调servicesDiscoveredEvent(int status)中获取外围设备支持的服务和特征值,并根据UUID判断是什么服务。
  5. 根据获取到的服务和特征值,调用read和write方法可以读取或者写入对应特征值数据。
private List<GattService> services;
// 创建扫描过滤器然后开始扫描
List<BleScanFilter> filters = new ArrayList<BleScanFilter>();
centralManager.startScan(filters);
// 与外围设备建立连接,允许自动回连,连接会触发connectionStateChangeEvent回调
private BlePeripheralDevice peripheralDevice = BlePeripheralDevice.createInstance(address); // address为远端设备地址
MyBlePeripheralCallback callback = new MyBlePeripheralCallback();
peripheralDevice.connect(true, callback);
// 连接后读取外围设备RSSI值,获取后触发readRemoteRssiEvent()回调
peripheralDevice.readRemoteRssiValue();

// 实现外围设备操作回调
private class MyBlePeripheralCallback extends BlePeripheralCallback {
    @Override
    public void connectionStateChangeEvent(int connectionState) { // GATT连接状态变化回调
        if (connectionState == ProfileBase.STATE_CONNECTED){
            peripheralDevice.discoverServices(); // 连接成功获取外围设备的Service
        } 
    }

    @Override
    public void servicesDiscoveredEvent(int status) { // 获取外围设备Service的回调
        if (status == BlePeripheralDevice.OPERATION_SUCC){
            services = peripheralDevice.getServices(); // 获取Service成功后获服务列表
            for (GattService service : services){
                // 对每个服务进行相应操作
            }
        }
    }

    @Override
    public void characteristicChangedEvent(GattCharacteristic charecteristic) { // 外围设备主动向中心设备发送特征值通知时触发回调
        // 根据通知的charecteristic获取特征值携带的数据
    }

    @Override
    public void characteristicWriteEvent(GattCharacteristic charecteristic, int ret) {
        if (ret == BlePeripheralDevice.OPERATION_SUCC){
            // 向外围设备写特征值数据成功后的操作
        }
    }

    @Override
    public void characteristicReadEvent(GattCharacteristic charecteristic, int ret) {
        if (ret == BlePeripheralDevice.OPERATION_SUCC){
            // 向外围设备读特征值数据成功后的操作
        }
    }

    @Override
    public void descriptorReadEvent(GattDescriptor descriptor, int ret) {
            // 向外围设备读描述值数据成功后的操作
    }

    @Override
    public void descriptorWriteEvent(GattDescriptor descriptor, int ret) {
           // 向外围设备写描述值数据成功后的操作
    }

    @Override
    public void readRemoteRssiEvent(int rssi, int ret) {   
        if (ret == BlePeripheralDevice.OPERATION_SUCC){
            // 读取外围设备RSSI值成功后的操作,对端RSSI值为rssi
        }
    }
}

BLE外围设备数据管理

场景介绍

BLE外围设备作为服务端,可以接收来自中心设备(客户端)的GATT连接请求,应答来自中心设备的特征值内容读取和写入请求,并向中心设备提供数据,从而实现信息交互和消息同步。同时外围设备还可以主动向中心设备发送数据。

接口说明

低功耗蓝牙外围设备操作类BlePeripheralManager的接口说明如下。

表1 外围设备管理API介绍

接口名

功能描述

BlePeripheralManager(Context context, BlePeripheralManagerCallback callback, int transport)

获取外围设备管理回调对象。

getServices()

获取外围设备的所有服务。

addService(GattService service)

将GATT服务加入服务端。

cancelConnection(BlePeripheralDevice device)

取消与中心设备的GATT连接。

clearServices()

删除所有的GATT服务。

close()

关闭GATT服务端。

getDevicesByStates(int[] states)

通过状态获取连接的中心设备列表。

notifyCharacteristicChanged(BlePeripheralDevice device, GattCharacteristic characteristic, boolean confirm)

通知中心设备特征值出现变化。

removeGattService(GattService service)

移除特定的服务。

sendResponse(BlePeripheralDevice device, int requestId, int status, int offset, byte[] value)

发送回复给中心设备。

低功耗蓝牙外围设备管理回调类BlePeripheralManagerCallback的接口说明如下。

表2 外围设备管理回调API介绍

接口名

功能描述

receiveCharacteristicReadEvent(BlePeripheralDevice device, int requestId, int offset, GattCharacteristic characteristic)

收到中心设备对特征值的读取请求回调。

receiveCharacteristicWriteEvent(BlePeripheralDevice device, int requestId, GattCharacteristic characteristic, boolean isPrep, boolean needRsp, int offset, byte[] value)

收到中心设备对特征值的写入请求。

connectionStateChangeEvent(BlePeripheralDevice device, int interval, int latency, int timeout, int status)

中心设备连接事件回调。

receiveDescriptorReadEvent(BlePeripheralDevice device, int transId, int offset, GattDescriptor descriptor)

收到中心设备对描述值的读取请求回调。

receiveDescriptorWriteRequestEvent(BlePeripheralDevice device, int transId, GattDescriptor descriptor, boolean isPrep, boolean needRsp, int offset, byte[] value)

收到中心设备对描述值的写入请求回调。

executeWriteEvent(BlePeripheralDevice device, int requestId, boolean execute)

向中心设备执行写入操作的回调。

mtuUpdateEvent(BlePeripheralDevice device, int mtu)

中心设备MTU值变化的回调。

notificationSentEvent(BlePeripheralDevice device, int status)

向中心设备发送通知的回调。

serviceAddedEvent(int status, GattService service)

向外围设备添加服务结果回调。

开发步骤

  1. 调用BlePeripheralManager(Context context, BlePeripheralManagerCallback callback, int transport)接口创建外围设备服务端并开启服务。
  2. 调用GattService(UUID uuid, boolean isPrimary)接口创建服务对象,向外围设备添加服务。
  3. 从回调接口onCharacteristicWriteRequest中获取中心设备发送来的消息,调用notifyCharacteristicChanged接口向中心设备发送通知。
private BlePeripheralDevice blePeripheralDevice;
private MyBlePeripheralManagerCallback peripheralManagerCallback = new MyBlePeripheralManagerCallback();
// 创建外围设备服务端并开启服务
private BlePeripheralManager peripheralManager = new BlePeripheralManager(this, peripheralManagerCallback, 0);
// 创建服务对象,向外围设备添加服务
private GattService service = new GattService(UUID.fromString(Service_UUID), true);
private GattCharacteristic writeCharacteristic = new GattCharacteristic(Character_UUID, 
GattCharacteristic.PROPERTY_WRITE, GattCharacteristic.PROPERTY_WRITE);
service.addCharacteristic(writeCharacteristic);
peripheralManager.addServerService(service);
// 向中心设备发送通知
writeCharacteristic.setValue(data);
peripheralManager.notifyCharacteristicChanged(blePeripheralDevice, writeCharacteristic, false);

// 外围设备管理回调
public class MyBlePeripheralManagerCallback extends BlePeripheralManagerCallback {
    // 中心设备向外围设备写入数据回调
    @Override
    public void receiveCharacteristicWriteEvent(BlePeripheralDevice device, int requestId, 
        GattCharacteristic characteristic, boolean isPrep, boolean needRsp, int offset, byte[] value){ 
            // 中心设备写入外围设备的数据为value,对数据进行处理
    }
    // 外围设备连接状态变化回调
    @Override
    public void connectionStateChangeEvent(BlePeripheralDevice device, int interval, int latency, int timeout, int status){
        if (status == ProfileBase.STATE_CONNECTED) {
            // 中心设备连接服务端成功
            blePeripheralDevice = device;
        }
    }
    // 向中心设备发送通知回调
    @Override
    public void notificationSentEvent(BlePeripheralDevice device, int status){
        if (status == BlePeripheralDevice.OPERATION_SUCC) {
            // 向对中心设备发送通知成功回调
        }
    }
}

おすすめ

転載: blog.csdn.net/weixin_47094733/article/details/131469226