HarmonyOS 鸿蒙Next中设置手机可被其他蓝牙设备发现不成功
HarmonyOS 鸿蒙Next中设置手机可被其他蓝牙设备发现不成功
// 设置设备可被发现
async makeDiscoverable() {
try {
// 先确保蓝牙已开启
if (!this.getBluetoothState()) {
await this.enableBluetooth();
// new Promise(resolve => setTimeout(resolve, 1000)); // 等待蓝牙开启
}
// 设置可被发现时长(最多300秒)
const visibilityDuration = 120; // 2分钟
connection.setBluetoothScanMode(connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE, visibilityDuration);
// 设置设备名称
connection.setLocalName(this.deviceName);
this.isVisible = true;
this.remainingTime = visibilityDuration;
// 更新剩余时间
let intervalId = setInterval(() => {
if (this.remainingTime > 0) {
this.remainingTime -= 1;
} else {
clearInterval(intervalId);
this.isVisible = false;
}
}, 1000);
this.promptAction.showToast({message: '设备可见性已开启,其他设备可发现本机', duration: 2000});
} catch (err) {
this.promptAction.showToast({message: `设置失败: ${err.message}`, duration: 3000});
console.error(`makeDiscoverable failed, code is ${(err as BusinessError).code}, message is ${(err as BusinessError).message}`);
}
}
报错201,这是什么原因?
module.json5已设置了相关权限
"requestPermissions": [{
"name": "ohos.permission.ACCESS_BLUETOOTH",
"reason": "$string:reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.DISCOVER_BLUETOOTH"
}]
更多关于HarmonyOS 鸿蒙Next中设置手机可被其他蓝牙设备发现不成功的实战教程也可以访问 https://www.itying.com/category-93-b0.html
BLE扫描主要分为被动扫描和主动扫描两种模式。被动扫描是指设备监听周围的广播信息,不主动发起连接请求;而主动扫描则会在接收到广播的同时,向广播设备发送扫描请求,以获取更详尽的设备信息。
服务端:
- 调用access.getState()接口,查询设备的蓝牙状态。根据返回结果BluetoothState的值来判断蓝牙是否开启。
- 调用startAdvertising()接口,开启广播。只有服务端先开启广播,客户端才能搜索到设备。
- 当完成广播时,调用stopAdvertising()接口,停止广播。
客户端:
- 与服务端步骤1相同。
- 调用startBLEScan接口,可通过options参数传入设置的扫描参数,进行扫描。
- 调用on(‘BLEDeviceFind’)方法订阅BLE设备发现上报事件,并处理扫描到的结果。
- 调用connect()接口,连接远端蓝牙低功耗设备。
- 当断开连接时,调用stopBLEScan()接口,停止蓝牙扫描。
楼主尝试下面文档对你有没有帮助:
低功耗蓝牙基础使用-网络 - 华为HarmonyOS开发者
更多关于HarmonyOS 鸿蒙Next中设置手机可被其他蓝牙设备发现不成功的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
虽然已配置ACCESS_BLUETOOTH和DISCOVER_BLUETOOTH权限,但缺少关键权限MANAGE_BLUETOOTH和定位权限LOCATION:
"requestPermissions": [
{
"name": "ohos.permission.MANAGE_BLUETOOTH"
},
{
"name": "ohos.permission.LOCATION"
}
]
仅静态声明权限不够,需通过用户主动授权弹窗获取动态权限,应在调用setBluetoothScanMode前执行代码:
import { abilityAccessCtrl } from '@kit.AbilityKit';
const permissions: Array<string> = [
'ohos.permission.MANAGE_BLUETOOTH',
'ohos.permission.LOCATION'
];
abilityAccessCtrl.requestPermissionsFromUser(this.context, permissions).then(...)
完整权限配置参考:
"requestPermissions": [
{
"name": "ohos.permission.ACCESS_BLUETOOTH",
"reason": "$string:reason",
"usedScene": { "abilities": ["EntryAbility"], "when": "always" }
},
{
"name": "ohos.permission.DISCOVER_BLUETOOTH"
},
{
"name": "ohos.permission.MANAGE_BLUETOOTH"
},
{
"name": "ohos.permission.LOCATION"
}
]
// 动态申请权限
async requestPermissions() {
let atManager = abilityAccessCtrl.createAtManager();
try {
await atManager.requestPermissionsFromUser(getContext(this), [
'ohos.permission.USE_BLUETOOTH',
'ohos.permission.DISCOVER_BLUETOOTH',
'ohos.permission.LOCATION',
'ohos.permission.MANAGE_BLUETOOTH'
]);
return await this.checkPermissions();
} catch (err) {
console.error(`requestPermissionsFromUser failed, code is ${(err as BusinessError).code}, message is ${(err as BusinessError).message}`);
return false;
}
}
报错原因是因为没有向用户授权权限导致的,ohos.permission.ACCESS_BLUETOOTH权限需要向用户授权。
示例代码如下:
import { BusinessError } from '@kit.BasicServicesKit';
import { PromptAction, UIContext } from '@kit.ArkUI';
import { connection } from '@kit.ConnectivityKit';
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
const permissions: Array<Permissions> = ['ohos.permission.ACCESS_BLUETOOTH'];
// 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗。
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作。
} else {
// 当用户拒绝授权时,系统应提示用户必须授予相应权限才能使用当前页面的功能,并指导用户前往系统设置开启所需权限。
return;
}
}
// 授权成功
}).catch((err: BusinessError) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
}
@Entry
@Component
struct Index {
@State isVisible: boolean = false;
@State remainingTime: number = 0;
uiContext: UIContext = this.getUIContext();
promptAction: PromptAction = this.uiContext.getPromptAction();
aboutToAppear(): void {
const context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
reqPermissionsFromUser(permissions, context);
}
// 设置设备可被发现
async makeDiscoverable() {
try {
// 先确保蓝牙已开启
// if (!this.getBluetoothState()) {
// await this.enableBluetooth();
// // new Promise(resolve => setTimeout(resolve, 1000)); // 等待蓝牙开启
// }
// 设置可被发现时长(最多300秒)
const visibilityDuration = 120; // 2分钟
connection.setBluetoothScanMode(connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE,
visibilityDuration);
// 设置为可连接可发现才可被对端设备扫描到,可以连接。
// connection.setBluetoothScanMode(connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE, 100);
// 设置设备名称
// connection.setLocalName(this.deviceName);
this.isVisible = true;
this.remainingTime = visibilityDuration;
// 更新剩余时间
let intervalId = setInterval(() => {
if (this.remainingTime > 0) {
this.remainingTime -= 1;
} else {
clearInterval(intervalId);
this.isVisible = false;
}
}, 1000);
this.promptAction.showToast({ message: '设备可见性已开启,其他设备可发现本机', duration: 2000 });
} catch (err) {
this.promptAction.showToast({ message: `设置失败: ${err.message}`, duration: 3000 });
console.error(`makeDiscoverable failed, code is ${(err as BusinessError).code}, message is ${(err as BusinessError).message}`);
}
}
build() {
Column() {
Button('开启蓝牙').width(100).height(100)
.onClick(async () => {
await this.makeDiscoverable()
})
}
}
}
上面的module.json5已经设置了,
module.json5中设置了ohos.permission.ACCESS_BLUETOOTH后,还是需要向用户授权的,
示例代码就是这段
const permissions: Array<Permissions> = ['ohos.permission.ACCESS_BLUETOOTH'];
// 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗。
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作。
} else {
// 当用户拒绝授权时,系统应提示用户必须授予相应权限才能使用当前页面的功能,并指导用户前往系统设置开启所需权限。
return;
}
}
// 授权成功
}).catch((err: BusinessError) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
}
真详细
学习了
很不错
在HarmonyOS Next中,蓝牙可见性设置失败可能由以下原因导致:
- 蓝牙功能未开启或设备未进入可发现模式
- 系统权限配置问题,检查蓝牙相关权限是否授予
- 设备硬件或驱动异常
- 系统版本存在兼容性问题
请确认:
- 已开启蓝牙并设置为可发现状态
- 在设置中检查应用权限管理
- 重启设备后重试操作
如问题持续存在,可能是系统底层服务异常。
错误代码201通常表示权限不足或权限未正确配置。检查发现您已声明ohos.permission.ACCESS_BLUETOOTH
和ohos.permission.DISCOVER_BLUETOOTH
权限,但需要注意以下几点:
-
确保在调用
setBluetoothScanMode
前已动态申请运行时权限,仅配置module.json5不够,还需使用abilityAccessCtrl.requestPermissionsFromUser
进行授权请求。 -
确认
DISCOVER_BLUETOOTH
权限的usedScene
字段是否完整配置,建议补充abilities和when条件,例如:{ "name": "ohos.permission.DISCOVER_BLUETOOTH", "usedScene": { "abilities": ["EntryAbility"], "when": "always" } }
-
检查系统蓝牙开关状态,虽然代码中有启用逻辑,但需确保
enableBluetooth()
成功完成后再执行后续操作,避免因状态延迟导致权限校验失败。
建议添加权限请求逻辑并验证授权结果后再调用蓝牙可见性设置接口。