使用WinRT+Bleak开发Python应用:首次自动配对报Error 19求助
解决WinRT+Bleak首次蓝牙配对Error 19(未知错误)问题
问题描述
使用Python结合Bleak和WinRT开发蓝牙配对功能,需求是输入MAC地址和PIN后自动完成Windows PC与蓝牙设备的配对连接。目前遇到的核心问题:
- 非首次配对(即使删除Windows注册表中的设备记录后重新配对)时连接正常
- 首次自动配对总会触发Error 19(未知错误)
已尝试的无效操作:
- 先通过
BleakClient连接设备再执行配对(在连接块内或断开回调中操作) - 配对前调用
BleakScanner主动扫描设备,尝试启停扫描机制
当前配对代码
async def do_pair(self) -> Tuple[bool, str]: """ Pair the device using WinRT, providing a PIN automatically. """ print(f"[BLEManagerThread] Pairing with {self._mac_address}...") address_uint64 = int(self._mac_address.replace(":", ""), 16) device = await BluetoothLEDevice.from_bluetooth_address_async(address_uint64) if device is None: print("[BLEManagerThread] Failed to access device.") return (False, "Failed to access device.") di = device.device_information custom_pairing = di.pairing.custom token = custom_pairing.add_pairing_requested(self.pairing_requested_handler) pairing_result = await custom_pairing.pair_async( DevicePairingKinds.PROVIDE_PIN, DevicePairingProtectionLevel.DEFAULT ) custom_pairing.remove_pairing_requested(token) device.close() if pairing_result.status in [DevicePairingResultStatus.PAIRED, DevicePairingResultStatus.ALREADY_PAIRED]: print("[BLEManagerThread] Device paired successfully.") MsgQueue().put("Paired".encode().hex()) return (True, "Paired") else: print(f"[BLEManagerThread] Pairing failed with status: {pairing_result.status}") return (False, pairing_result.status.name)
可能的解决方案
1. 确保设备完成系统扫描同步
首次配对时,仅通过MAC地址直接获取BluetoothLEDevice可能未完成系统层面的设备元数据同步,需先扫描并等待系统初始化:
async def do_pair(self) -> Tuple[bool, str]: print(f"[BLEManagerThread] Scanning for {self._mac_address}...") # 主动扫描设备 scanner = BleakScanner(scanning_mode="active") scanned_device = await scanner.find_device_by_address(self._mac_address, timeout=30) if not scanned_device: return (False, "Device not found in scan") # 给系统留足设备信息同步时间 await asyncio.sleep(2) # 后续配对逻辑保持不变 address_uint64 = int(self._mac_address.replace(":", ""), 16) device = await BluetoothLEDevice.from_bluetooth_address_async(address_uint64) if device is None: return (False, "Failed to access device.") di = device.device_information custom_pairing = di.pairing.custom token = custom_pairing.add_pairing_requested(self.pairing_requested_handler) pairing_result = await custom_pairing.pair_async( DevicePairingKinds.PROVIDE_PIN, DevicePairingProtectionLevel.DEFAULT ) custom_pairing.remove_pairing_requested(token) device.close() if pairing_result.status in [DevicePairingResultStatus.PAIRED, DevicePairingResultStatus.ALREADY_PAIRED]: print("[BLEManagerThread] Device paired successfully.") MsgQueue().put("Paired".encode().hex()) return (True, "Paired") else: print(f"[BLEManagerThread] Pairing failed with status: {pairing_result.status}") return (False, pairing_result.status.name)
2. 调整配对保护级别
DEFAULT保护级别可能无法匹配设备的安全要求,尝试指定加密级别的保护:
pairing_result = await custom_pairing.pair_async( DevicePairingKinds.PROVIDE_PIN, DevicePairingProtectionLevel.ENCRYPTED )
3. 检查PIN请求处理器逻辑
确保pairing_requested_handler能及时正确传递PIN码:
def pairing_requested_handler(self, sender, args): if args.pairing_kind == DevicePairingKinds.PROVIDE_PIN: args.accept(self._pin) # 确保self._pin为正确的字符串格式PIN码 else: args.reject()
4. 修正异步时序与线程上下文
WinRT的配对操作可能需要在主线程执行,若当前逻辑在子线程运行,可调整为在主线程发起配对请求,或使用asyncio.run_coroutine_threadsafe确保回调上下文正确。
5. 重置蓝牙服务(需管理员权限)
首次配对失败可能与蓝牙服务未完全初始化有关,可在配对前重启服务:
import subprocess def restart_bluetooth_service(): try: subprocess.run(["net", "stop", "bthserv"], check=True, shell=True) subprocess.run(["net", "start", "bthserv"], check=True, shell=True) return True except subprocess.CalledProcessError: return False
内容的提问来源于stack exchange,提问作者newuser
相关产品推荐
相关产品推荐

