HarmonyOS Ble蓝牙demo

HarmonyOS
2024-12-26 13:19:34
941浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
aquaa

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的样例:

demo代码总共有4个页面。一个util

主页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)
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.

上面发的是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)
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

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()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
分享
微博
QQ
微信
回复
2024-12-26 16:37:11
相关问题
HarmonyOS 蓝牙ble相关demo
830浏览 • 1回复 待解决
HarmonyOS ble蓝牙问题
956浏览 • 1回复 待解决
HarmonyOS 蓝牙BLE开发 Dome
1284浏览 • 1回复 待解决
HarmonyOS esp BLE蓝牙配网?
304浏览 • 1回复 待解决
HarmonyOS 蓝牙ble写入失败 2900099
946浏览 • 1回复 待解决
HarmonyOS 蓝牙ble模块getServices失败
950浏览 • 1回复 待解决
HarmonyOS 如何开发低功耗蓝牙ble
812浏览 • 1回复 待解决
HarmonyOS 蓝牙BLE使用是否需要定位
700浏览 • 1回复 待解决
HarmonyOS BLE蓝牙发送数据量大的问题
1198浏览 • 1回复 待解决
BLE蓝牙开发如何实现对智能灯的控制?
7563浏览 • 1回复 待解决
HarmonyOS 手机蓝牙相关的demo
870浏览 • 1回复 待解决
HarmonyOS有没有蓝牙相关的操作demo
1104浏览 • 1回复 待解决
HarmonyOS 有没有蓝牙,NFC相关的DEMO
1040浏览 • 1回复 待解决
提问
该提问已有2人参与 ,帮助了17人