目录

App点击蓝牙设备列表不显示设备

问题现象

进入App内蓝牙设备列表,不显示设备,是什么原因导致的?

背景知识

问题定位

  1. 检查从系统设置里是否能蓝牙搜索到附近设备:系统设置中可搜到附近设备,排除硬件问题。
  2. 检查是否配置权限接入了ohos.permission.ACCESS_BLUETOOTH:观察hilog日志,触发蓝牙扫描时未触发permission相关报错,并且返回了相关地址信息,说明蓝牙功能是可用的。
  3. 检查触发蓝牙扫描时的hilog信息,蓝牙扫描时的hilog结果(截取部分):

    (operator():81)device: D0:1E:**:**:**:8D, len: 31

    可见进入App蓝牙设备列表后有获取到附近设备的地址信息,但并未有相关设备名。

分析结论

根据问题定位现象可知,App能正常获取到地址信息。未能在App蓝牙设备页面显示应用信息,可能原因有:

  1. 缺少了通过设备地址获取设备名称的步骤。
  2. UI设计上缺少了列表显示设备信息的组件。

修改建议

  1. 在module.json5配置文件的requestPermissions标签中声明权限ohos.permission.ACCESS_BLUETOOTH。
  2. 在使用connection.on('bluetoothDeviceFind')获取蓝牙设备相关信息后,通过connection.getRemoteDeviceName获取蓝牙设备的名称。示例代码如下:
    connection.on('bluetoothDeviceFind', (data: string[]) => {
      console.info(`data: ${JSON.stringify(data)} ${connection.getRemoteDeviceName(data[0])}`);
      if (!this.findList.find((item: Device) => item.deviceId === data[0])) {
        this.findList.push({
          name: connection.getRemoteDeviceName(data[0]),
          deviceId: data[0]
        });
      };
    });
  3. 使用ForEach结合List实现列表显示设备信息的组件。示例代码如下:
    List() {
      ForEach(this.findList, (item: Device) => {
        ListItem() {
          Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
            Column() {
              Text(`设备名称:${item?.name}`);
              Text(`设备id:${item?.deviceId}`).fontColor('#ffcbcbcb').fontSize(12);
            }
            .alignItems(HorizontalAlign.Start);
    
    
            Row({ space: 5 }) {
              Button('链接').width(60).height(20).fontSize(12).onClick(() => {
                try {
                  // 实际的地址可由扫描流程获取
                  connection.pairDevice(item.deviceId, () => {
                    this.getUIContext().getPromptAction().showToast({
                      message: '配对成功'
                    });
                  });
                } catch (err) {
                  console.error(`errCode: ${(err as BusinessError).code}, errMessage: ${(err as BusinessError).message}`);
                };
              });
            };
          }
          .height(50)
          .backgroundColor('#fff')
          .width('100%')
          .borderRadius(10)
          .padding(6);
        }.padding(4);
      });
    }
    .height(200)
    .width('100%')
    .flexGrow(1)
    .flexShrink(1)
    .flexBasis(1);
  4. 完整示例代码如下:
    import connection from '@ohos.bluetooth.connection';
    import { BusinessError } from '@ohos.base';
    import { PromptAction } from '@kit.ArkUI';
    import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
    import common from '@ohos.app.ability.common';
    
    
    interface Device {
      name?: string
      deviceId?: string
    };
    
    
    @Entry
    @Component
    struct Index {
      // 正确写法(Stage模型)
      private context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
      promptAction: PromptAction = this.getUIContext().getPromptAction();
    
    
      @State findList: Device[] = [];
    
    
      aboutToAppear(): void {
        const permissions: Array<Permissions> = ['ohos.permission.ACCESS_BLUETOOTH'];
        let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
        atManager.requestPermissionsFromUser(this.context, permissions).then(() => {
          // 授权成功
        }).catch((err: BusinessError) => {
          console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
        });
      };
    
    
      build() {
        Flex({ direction: FlexDirection.Column }) {
          Row() {
            Button('扫描蓝牙').onClick(() => {
              // 开启扫描
              try {
                connection.startBluetoothDiscovery();
                console.info('startBleScan success');
                this.getUIContext().getPromptAction().showToast({
                  message: '已打开'
                });
              } catch (err) {
                this.getUIContext().getPromptAction().showToast({
                  message: '蓝牙开关未打开'
                });
              };
    
    
              // 接收扫描结果
              connection.on('bluetoothDeviceFind', (data: string[]) => {
                console.info(`data: ${JSON.stringify(data)} ${connection.getRemoteDeviceName(data[0])}`);
                if (!this.findList.find((item: Device) => item.deviceId === data[0])) {
                  this.findList.push({
                    name: connection.getRemoteDeviceName(data[0]),
                    deviceId: data[0]
                  });
                };
              });
            });
    
    
            Button('停止扫描').onClick(() => {
              try {
                // 关闭扫描
                connection.stopBluetoothDiscovery();
                console.info('stopBleScan success');
                this.getUIContext().getPromptAction().showToast({
                  message: '停止扫描'
                });
              } catch (err) {
                this.getUIContext().getPromptAction().showToast({
                  message: '蓝牙已关闭'
                });
              };
            });
    
    
            Button('清空').onClick(() => {
              this.findList = [];
            });
          };
          List() {
            ForEach(this.findList, (item: Device) => {
              ListItem() {
                Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
                  Column() {
                    Text(`设备名称:${item?.name}`);
                    Text(`设备id:${item?.deviceId}`).fontColor('#ffcbcbcb').fontSize(12);
                  }
                  .alignItems(HorizontalAlign.Start);
    
    
                  Row({ space: 5 }) {
                    Button('链接').width(60).height(20).fontSize(12).onClick(() => {
                      try {
                        // 实际的地址可由扫描流程获取
                        connection.pairDevice(item.deviceId, () => {
                          this.getUIContext().getPromptAction().showToast({
                            message: '配对成功'
                          });
                        });
                      } catch (err) {
                        console.error(`errCode: ${(err as BusinessError).code}, errMessage: ${(err as BusinessError).message}`);
                      };
                    });
                  };
                }
                .height(50)
                .backgroundColor('#fff')
                .width('100%')
                .borderRadius(10)
                .padding(6);
              }.padding(4);
            });
          }
          .height(200)
          .width('100%')
          .flexGrow(1)
          .flexShrink(1)
          .flexBasis(1);
        }.padding(10).width('100%').height('100%').backgroundColor('#ffcdcdcd');
      };
    };