Web Bluetooth API:如何检测Mac权限弹窗取消/连接已配对设备?
Web Bluetooth API 问题解决:权限拒绝检测与已连接设备连接
一、检测用户是否拒绝蓝牙权限弹窗
在Mac系统中,Web Bluetooth的二次权限弹窗属于系统级操作,API没有直接提供弹窗取消的回调,但可以通过后续连接验证步骤间接判断用户是否拒绝了权限:
- 检查GATT服务器连接状态:调用
device.gatt.connect()后,立即校验server.connected属性,若为false则判定连接未授权。 - 尝试读取特征值:权限被拒时,读取蓝牙特征值会抛出错误,可通过捕获该错误确认权限被拒绝。
- 监听连接断开事件:用户取消权限后,设备会快速触发
ongattserverdisconnected事件,可通过标记状态识别该场景。
修改你的连接代码如下:
const connectMicrobit = async () => { try { const device = await navigator?.bluetooth?.requestDevice(bluetoothSearchOptions); if (!device) { throw new Error("无法获取设备信息,可能浏览器不支持Web Bluetooth"); } let connectionRejected = false; // 临时绑定断开事件,用于检测权限取消 device.ongattserverdisconnected = () => { connectionRejected = true; disconnectMicrobit(); }; const server = await device.gatt.connect(); // 验证服务器真实连接状态 if (!server.connected || connectionRejected) { throw new Error("用户拒绝了蓝牙连接权限"); } // 获取服务,权限被拒时此处会抛出错误 const service = await server.getPrimaryService(MBIT_UART_SERVICE); const rxCharacteristic = await service.getCharacteristic(MBIT_UART_RX_CHARACTERISTIC); // 尝试读取特征值,验证权限有效性 try { await rxCharacteristic.readValue(); } catch (readErr) { throw new Error("权限被拒绝,无法访问设备特征"); } const txCharacteristic = await service.getCharacteristic(MBIT_UART_TX_CHARACTERISTIC); const uart = new MicroBitUART(rxCharacteristic, txCharacteristic); microbitUARTRef.current = uart; // 重置断开事件为正常业务逻辑 device.ongattserverdisconnected = () => { console.log("Microbit 已断开连接"); disconnectMicrobit(); }; } catch (error) { console.error("连接Microbit时出错:", error); disconnectMicrobit(); } };
二、连接已配对的蓝牙设备
要连接用户电脑上已配对/之前授权过的设备,可通过以下两种方式实现:
方式1:直接获取已授权设备连接
使用navigator.bluetooth.getDevices()获取用户之前通过Web Bluetooth授权过的设备,无需再次弹出选择窗口:
const connectPairedMicrobit = async () => { try { const devices = await navigator.bluetooth.getDevices(); // 根据设备名称筛选micro:bit const microbitDevice = devices.find(dev => dev.name?.includes("micro:bit")); if (!microbitDevice) { throw new Error("未找到已授权的micro:bit设备"); } const server = await microbitDevice.gatt.connect(); // 后续步骤与正常连接一致 const service = await server.getPrimaryService(MBIT_UART_SERVICE); const rxCharacteristic = await service.getCharacteristic(MBIT_UART_RX_CHARACTERISTIC); const txCharacteristic = await service.getCharacteristic(MBIT_UART_TX_CHARACTERISTIC); const uart = new MicroBitUART(rxCharacteristic, txCharacteristic); microbitUARTRef.current = uart; microbitDevice.ongattserverdisconnected = () => { console.log("Microbit 已断开连接"); disconnectMicrobit(); }; } catch (error) { console.error("连接已配对设备失败:", error); disconnectMicrobit(); } };
方式2:在设备选择器中包含已配对设备
调用requestDevice时,确保optionalServices包含你需要访问的服务UUID,这样已配对且支持该服务的设备会出现在选择列表中:
const bluetoothSearchOptions = { filters: [{ namePrefix: "micro:bit" }], optionalServices: [MBIT_UART_SERVICE] // 必须指定需要访问的服务UUID };
注意:Web Bluetooth无法访问系统中所有已配对设备,只能获取用户之前授权过的设备,或通过选择器让用户重新选择已配对设备。
内容的提问来源于stack exchange,提问作者ktt
相关产品推荐
相关产品推荐

