HarmonyOS 鸿蒙Next 蓝牙BLE协议示例代码

发布于 1周前 作者 wuwangju 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 蓝牙BLE协议示例代码

需要蓝牙BLE协议示例代码 

4 回复
主页MainPage上:

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

@Entry
@Component
struct Client {
  @State clientInstanceSwitch: boolean = false;
  @State scanSwitch: boolean = false;
  @State deviceFindSwitch: boolean = false;
  @State bleDevices: Array<ble.ScanResult> = []

  build() {
    Column({ space: 15 }) {
      Row() {
        Text('BLE扫描')
        Blank()
        Toggle({ type: ToggleType.Switch, isOn: this.scanSwitch })
          .onChange((isOn: boolean) => {
            if (isOn) {
              this.startScan()
            } else {
              this.stopScan()
            }
            console.info('ble server instanceSwitch status:' + isOn)
          })
      }
      .itemStyle()

      Column() {
        Row() {
          Text('订阅BLE设备')
          Blank()
          Toggle({ type: ToggleType.Switch, isOn: this.deviceFindSwitch })
            .onChange((isOn: boolean) => {
              if (isOn) {
                this.onBLEDeviceFind()
              } else {
                this.offBLEDeviceFind()
              }
              console.info('ble server instanceSwitch status:' + isOn)
            })
        }
        .itemStyle()
        .borderRadius({ topLeft: 10, topRight: 10 })

        Divider()
        Scroll() {
          if (this.bleDevices.length > 0) {
            List() {
              ForEach(this.bleDevices, (item: ble.ScanResult) => {
                ListItem() {
                  Navigator({ target: 'pages/ClientDetail', type: NavigationType.Push }) {
                    Text(item.deviceId)
                      .width('100%').textAlign(TextAlign.Start)
                  }
                  .params(item)
                }
              })
            }
          } else {
            Text('暂无设备发现')
          }
        }
        .itemStyle()
        .height(380)
        .borderRadius({ bottomLeft: 10, bottomRight: 10 })
        .scrollBar(BarState.Off)
      }
    }
    .height('100%')
    .width('100%')
    MainPage中:

    .padding({ left: 15, right: 15, top: 20, bottom: 20 })
      .backgroundColor($r('app.color.light_gray'))
  }

  /**
   * 发起BLE扫描流程
   */
  startScan() {
    try {
      let scanFilter: ble.ScanFilter = {
        serviceUuid: "00001810-0000-1000-8000-00805F9B34FB"
      };

      let scanOptions: ble.ScanOptions = {
        interval: 500,
        dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
        matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE,
      }
      ble.startBLEScan([scanFilter], scanOptions);
      console.info('ble Client start BLE Scan success')
      this.scanSwitch = true;
    } catch (err) {
      console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  }

  /**
   * 关闭BLE扫描流程
   */
  stopScan() {
    try {
      ble.stopBLEScan();
      console.info('ble Client stop BLE Scan success')
      this.scanSwitch = false;
    } catch (err) {
      console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  }

  /**
   * 取消订阅BLE设备发现
   */
  onBLEDeviceFind() {
    ble.on('BLEDeviceFind', (data: Array<ble.ScanResult>) => {
      console.info('bluetooth device find on = ' + JSON.stringify(data));
      this.bleDevices = data;
    });
    this.deviceFindSwitch = true;
  }
  MainPage下:

  /**
   * 取消订阅BLE设备发现
   */
  offBLEDeviceFind() {
    ble.off('BLEDeviceFind', (data: Array<ble.ScanResult>) => {
      console.info('bluetooth device find off = ' + JSON.stringify(data));
      // this.bleDevices = data;
    });
    this.deviceFindSwitch = false;
  }
}

@Styles
function itemStyle() {
  .width('100%')
  .padding({ left: 15, right: 15, top: 8, bottom: 8 })
  .backgroundColor($r('app.color.white'))
  .borderRadius(10)
}
上面发的是clinet页面
mainpage页面:

import { router } from '@kit.ArkUI'
import PermissionsUtil from '../utils/PermissionsUtil'

@Entry
@Component
struct MainPage {
  aboutToAppear(): void {
    PermissionsUtil.requestPermissions(['ohos.permission.ACCESS_BLUETOOTH'])
  }

  build() {
    Column() {
      Button('客户端').onClick((event: ClickEvent) => {
        router.pushUrl({ url: "pages/Client" })
      })
        .width('50%')

      Button('服务端').onClick((event: ClickEvent) => {
        router.pushUrl({ url: "pages/Server" })
      })
        .width('50%')
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.SpaceAround)
  }
}
ClientDetail页面代码:

import { ble, constant } from '@kit.ConnectivityKit';
import { router } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct ClientDetail {
  device: ble.ScanResult = router.getParams() as ble.ScanResult;
  @State gattClient: ble.GattClientDevice | undefined = undefined;
  @State deviceName: string = '';
  @State gattServiceInfo: ble.GattService | undefined = undefined;
  @State connectSwitch: boolean = false;
  @State stateListenSwitch: boolean = false;
  @State connectStateSwitch: boolean = false;
  @State bleCharChangeSwitch: boolean = false;
  @State connectState: ble.ProfileConnectionState = constant.ProfileConnectionState.STATE_DISCONNECTED;
  @State characteristicValue: string = '';
  private serviceUuid = "00001810-0000-1000-8000-00805F9B34FB";
  @State writeValue: string = ''

  aboutToAppear(): void {
    if (!this.gattClient) {
      this.gattClient = ble.createGattClientDevice(this.device?.deviceId);
      this.getDeviceName()
    }
  }

  build() {
    Scroll() {
      Column({ space: 10 }) {
        Text() {
          Span('设备名称: ')
          Span(this.deviceName)
        }
        .itemStyle()

        Row() {
          Text('连接状态监听')
          Blank()
          Toggle({ type: ToggleType.Switch, isOn: this.stateListenSwitch })
            .onChange((isOn: boolean) => {
              if (isOn) {
                this.onBLEConnectionStateChange()
              } else {
                this.offBLEConnectionStateChange()
              }
              console.info('ble server instanceSwitch status:' + isOn)
            })
        }
        .itemStyle()

        Row() {
          Text('连接状态')
          Blank()
          if (this.connectState == constant.ProfileConnectionState.STATE_CONNECTING) {
            LoadingProgress().height(15).width(15)
          } else {
            Toggle({ type: ToggleType.Switch, isOn: this.connectStateSwitch })
              .enabled(false)
          }
        }
        .itemStyle()

        Row() {
          Text('连接开关')
          Blank()
          Toggle({ type: ToggleType.Switch, isOn: this.connectSwitch })
            .onChange((isOn: boolean) => {
              if (isOn) {
                this.connectServer()
              } else {
                this.disconnectServer()
              }
              console.info('ble server instanceSwitch status:' + isOn)
            })
        }
        .itemStyle()

        Column({ space: 10 }) {
          Button('服务发现').onClick((event: ClickEvent) => {
            this.getServices()
          })

          Scroll() {
            if (this.gattServiceInfo) {
              Text(JSON.stringify(this.gattServiceInfo))
            } else {
              Text('暂无数据')
            }
          }
          .height(100)
          .scrollBar(BarState.Off)
        }
        .itemStyle()

        Column({ space: 10 }) {
          Button('client端读取蓝牙低功耗设备特定服务的特征值').onClick((event: ClickEvent) => {
            this.readCharacteristicValue()
          })
          Scroll() {
            if (this.characteristicValue) {
              Text(JSON.stringify(this.characteristicValue))
            } else {
              Text('暂无数据')
            }
          }
          .height(100)
          .scrollBar(BarState.Off)
        }
        .itemStyle()

        Button('写描述符').onClick((event: ClickEvent) => {
          this.writeDescriptorValue()
}

更多关于HarmonyOS 鸿蒙Next 蓝牙BLE协议示例代码的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


Ble蓝牙相关资料可参考:
https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-bluetooth-ble-V5#blestartblescan
以及
https://gitee.com/openharmony/docs/tree/master/zh-cn/application-dev/connectivity/bluetooth
以下是一个相对完整的蓝牙通信ble的样例:

主页MainPage上:
import { ble } from '@kit.ConnectivityKit';
import { BusinessError } from '@kit.BasicServicesKit';
[@Entry](/user/Entry)
[@Component](/user/Component)
struct Client {
  [@State](/user/State) clientInstanceSwitch: boolean = false;
  [@State](/user/State) scanSwitch: boolean = false;
  [@State](/user/State) deviceFindSwitch: boolean = false;
  [@State](/user/State) bleDevices: Array<ble.ScanResult> = []
  build() {
    Column({ space: 15 }) {
      Row() {
        Text('BLE扫描')
        Blank()
        Toggle({ type: ToggleType.Switch, isOn: this.scanSwitch })
          .onChange((isOn: boolean) => {
            if (isOn) {
              this.startScan()
            } else {
              this.stopScan()
            }
            console.info('ble server instanceSwitch status:' + isOn)
          })
      }
      .itemStyle()
      Column() {
        Row() {
          Text('订阅BLE设备')
          Blank()
          Toggle({ type: ToggleType.Switch, isOn: this.deviceFindSwitch })
            .onChange((isOn: boolean) => {
              if (isOn) {
                this.onBLEDeviceFind()
              } else {
                this.offBLEDeviceFind()
              }
              console.info('ble server instanceSwitch status:' + isOn)
            })
        }
        .itemStyle()
        .borderRadius({ topLeft: 10, topRight: 10 })
        Divider()
        Scroll() {
          if (this.bleDevices.length > 0) {
            List() {
              ForEach(this.bleDevices, (item: ble.ScanResult) => {
                ListItem() {
                  Navigator({ target: 'pages/ClientDetail', type: NavigationType.Push }) {
                    Text(item.deviceId)
                      .width('100%').textAlign(TextAlign.Start)
                  }
                  .params(item)
                }
              })
            }
          } else {
            Text('暂无设备发现')
          }
        }
        .itemStyle()
        .height(380)
        .borderRadius({ bottomLeft: 10, bottomRight: 10 })
        .scrollBar(BarState.Off)
      }
    }
    .height('100%')
    .width('100%')
    MainPage中:
    .padding({ left: 15, right: 15, top: 20, bottom: 20 })
      .backgroundColor($r('app.color.light_gray'))
  }
  /**
   * 发起BLE扫描流程
   */
  startScan() {
    try {
      let scanFilter: ble.ScanFilter = {
        serviceUuid: "00001810-0000-1000-8000-00805F9B34FB"
      };
      let scanOptions: ble.ScanOptions = {
        interval: 500,
        dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
        matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE,
      }
      ble.startBLEScan([scanFilter], scanOptions);
      console.info('ble Client start BLE Scan success')
      this.scanSwitch = true;
    } catch (err) {
      console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  }
  /**
   * 关闭BLE扫描流程
   */
  stopScan() {
    try {
      ble.stopBLEScan();
      console.info('ble Client stop BLE Scan success')
      this.scanSwitch = false;
    } catch (err) {
      console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  }
  /**
   * 取消订阅BLE设备发现
   */
  onBLEDeviceFind() {
    ble.on('BLEDeviceFind', (data: Array<ble.ScanResult>) => {
      console.info('bluetooth device find on = ' + JSON.stringify(data));
      this.bleDevices = data;
    });
    this.deviceFindSwitch = true;
  }
  MainPage下:
  /**
   * 取消订阅BLE设备发现
   */
  offBLEDeviceFind() {
    ble.off('BLEDeviceFind', (data: Array<ble.ScanResult>) => {
      console.info('bluetooth device find off = ' + JSON.stringify(data));
      // this.bleDevices = data;
    });
    this.deviceFindSwitch = false;
  }
}
[@Styles](/user/Styles)
function itemStyle() {
  .width('100%')
  .padding({ left: 15, right: 15, top: 8, bottom: 8 })
  .backgroundColor($r('app.color.white'))
  .borderRadius(10)
}
上面发的是clinet页面
mainpage页面:
import { router } from '@kit.ArkUI'
import PermissionsUtil from '../utils/PermissionsUtil'
[@Entry](/user/Entry)
[@Component](/user/Component)
struct MainPage {
  aboutToAppear(): void {
    PermissionsUtil.requestPermissions(['ohos.permission.ACCESS_BLUETOOTH'])
  }
  build() {
    Column() {
      Button('客户端').onClick((event: ClickEvent) => {
        router.pushUrl({ url: "pages/Client" })
      })
        .width('50%')
      Button('服务端').onClick((event: ClickEvent) => {
        router.pushUrl({ url: "pages/Server" })
      })
        .width('50%')
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.SpaceAround)
  }
}
ClientDetail页面代码:
import { ble, constant } from '@kit.ConnectivityKit';
import { router } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
[@Entry](/user/Entry)
[@Component](/user/Component)
struct ClientDetail {
  device: ble.ScanResult = router.getParams() as ble.ScanResult;
  [@State](/user/State) gattClient: ble.GattClientDevice | undefined = undefined;
  [@State](/user/State) deviceName: string = '';
  [@State](/user/State) gattServiceInfo: ble.GattService | undefined = undefined;
  [@State](/user/State) connectSwitch: boolean = false;
  [@State](/user/State) stateListenSwitch: boolean = false;
  [@State](/user/State) connectStateSwitch: boolean = false;
  [@State](/user/State) bleCharChangeSwitch: boolean = false;
  [@State](/user/State) connectState: ble.ProfileConnectionState = constant.ProfileConnectionState.STATE_DISCONNECTED;
  [@State](/user/State) characteristicValue: string = '';
  private serviceUuid = "00001810-0000-1000-8000-00805F9B34FB";
  [@State](/user/State) writeValue: string = ''
  aboutToAppear(): void {
    if (!this.gattClient) {
      this.gattClient = ble.createGattClientDevice(this.device?.deviceId);
      this.getDeviceName()
    }
  }
  build() {
    Scroll() {
      Column({ space: 10 }) {
        Text() {
          Span('设备名称: ')
          Span(this.deviceName)
        }
        .itemStyle()
        Row() {
          Text('连接状态监听')
          Blank()
          Toggle({ type: ToggleType.Switch, isOn: this.stateListenSwitch })
            .onChange((isOn: boolean) => {
              if (isOn) {
                this.onBLEConnectionStateChange()
              } else {
                this.offBLEConnectionStateChange()
              }
              console.info('ble server instanceSwitch status:' + isOn)
            })
        }
        .itemStyle()
        Row() {
          Text('连接状态')
          Blank()
          if (this.connectState == constant.ProfileConnectionState.STATE_CONNECTING) {
            LoadingProgress().height(15).width(15)
          } else {
            Toggle({ type: ToggleType.Switch, isOn: this.connectStateSwitch })
              .enabled(false)
          }
        }
        .itemStyle()
        Row() {
          Text('连接开关')
          Blank()
          Toggle({ type: ToggleType.Switch, isOn: this.connectSwitch })
            .onChange((isOn: boolean) => {
              if (isOn) {
                this.connectServer()
              } else {
                this.disconnectServer()
              }
              console.info('ble server instanceSwitch status:' + isOn)
            })
        }
        .itemStyle()
        Column({ space: 10 }) {
          Button('服务发现').onClick((event: ClickEvent) => {
            this.getServices()
          })
          Scroll() {
            if (this.gattServiceInfo) {
              Text(JSON.stringify(this.gattServiceInfo))
            } else {
              Text('暂无数据')
            }
          }
          .height(100)
          .scrollBar(BarState.Off)
        }
        .itemStyle()
        Column({ space: 10 }) {
          Button('client端读取蓝牙低功耗设备特定服务的特征值').onClick((event: ClickEvent) => {
            this.readCharacteristicValue()
          })
          Scroll() {
            if (this.characteristicValue) {
              Text(JSON.stringify(this.characteristicValue))
            } else {
              Text('暂无数据')
            }
          }
          .height(100)
          .scrollBar(BarState.Off)
        }
        .itemStyle()
        Button('写描述符').onClick((event: ClickEvent) => {
          this.writeDescriptorValue() 
先搞懂蓝牙连接收发数据等系列流程,后续根据蓝牙ble模块提供得api就可以实现

HarmonyOS 鸿蒙Next 蓝牙BLE(Bluetooth Low Energy)协议示例代码如下,展示了如何初始化BLE并进行基本的扫描和连接操作。请注意,这只是一个简单的示例,实际应用中可能需要更复杂的错误处理和状态管理。

初始化BLE

#include <ohos/bluetooth_adapter.h>
#include <ohos/bluetooth_le_scanner.h>
#include <ohos/bluetooth_device.h>

BluetoothAdapter* adapter = BluetoothAdapter::GetDefaultAdapter();
if (adapter == nullptr || !adapter->IsEnabled()) {
    // BLE未启用或获取失败
    return;
}

BluetoothLeScanner* scanner = adapter->GetLeScanner();
if (scanner == nullptr) {
    // 获取扫描器失败
    return;
}

开始扫描

scanner->StartScan(
    [](const std::vector<BluetoothLeScanResult>& results) {
        // 处理扫描结果
    },
    [](int errorCode) {
        // 处理扫描错误
    }
);

连接到设备

BluetoothDevice* device = adapter->GetRemoteDevice("设备地址");
if (device != nullptr) {
    device->ConnectGatt(
        nullptr, //GattCallback可以为空,根据实际需求提供
        false // autoConnect
    );
}

此示例代码展示了如何在HarmonyOS鸿蒙Next系统中初始化蓝牙BLE、开始扫描设备以及连接到特定设备的基本步骤。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部