问题现象
进入App内蓝牙设备列表,不显示设备,是什么原因导致的?
问题定位
- 检查从系统设置里是否能蓝牙搜索到附近设备:系统设置中可搜到附近设备,排除硬件问题。
- 检查是否配置权限接入了ohos.permission.ACCESS_BLUETOOTH:观察hilog日志,触发蓝牙扫描时未触发permission相关报错,并且返回了相关地址信息,说明蓝牙功能是可用的。
- 检查触发蓝牙扫描时的hilog信息,蓝牙扫描时的hilog结果(截取部分):
(operator():81)device: D0:1E:**:**:**:8D, len: 31
可见进入App蓝牙设备列表后有获取到附近设备的地址信息,但并未有相关设备名。
分析结论
根据问题定位现象可知,App能正常获取到地址信息。未能在App蓝牙设备页面显示应用信息,可能原因有:
- 缺少了通过设备地址获取设备名称的步骤。
- UI设计上缺少了列表显示设备信息的组件。
修改建议
- 在module.json5配置文件的requestPermissions标签中声明权限ohos.permission.ACCESS_BLUETOOTH。
- 在使用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]
});
};
}); - 使用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); - 完整示例代码如下:
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');
};
};