react-native-ble-manager开启通知后监听器未触发、读写无响应的问题排查与跨库解决实践
react-native-ble-manager开启通知后监听器未触发、读写无响应的问题排查与跨库解决实践
最近在做React Native蓝牙外设对接的项目时,我踩了react-native-ble-manager的一个大坑:设备能正常连接,调用retrieveServices也能拿到完整的服务、特征列表,但开启通知后,BleManagerDidUpdateValueForCharacteristic监听器完全没触发,用bleManager.read()还返回空字符串。更诡异的是,每次发完命令后再调用一次retrieveServices,会发现fff1特征的解码值正好是我预期的响应——这显然不是正常的通信方式。
最初的排查尝试(无效)
我一开始严格按照文档要求,先调用retrieveServices再开启通知,还加了全局监听器,代码如下:
const setupAllBleListeners = async (deviceID : string) => { logMessage("📡 Setting up Bluetooth event listeners"); bleEmitter.addListener( "BleManagerDidUpdateValueForCharacteristic", (args) => { logMessage(`🌐 GLOBAL EVENT - value updates: ${JSON.stringify(args)}`); const data = args.value; logMessage(`📬 Decoded response: ${data ?? "null"}`); } ) // Start notifications try { await BleManager.retrieveServices(deviceID); // <- Always do this before startNotification logMessage( `Starting notifications on ${writeServiceUUID}/${readCharUUID}...` ); await BleManager.startNotification(deviceID, "fff0", "fff1"); logMessage("✅ Notifications started"); } catch (err) { logMessage( `❌ startNotification failed: ${err instanceof Error ? err.message : String(err)}` ); } };
但不管怎么调整顺序、重试,监听器就是没反应,发完命令也拿不到实时响应。
最终解决:混合使用两个蓝牙库
折腾了好久,我最终采用了混合react-native-ble-manager和react-native-ble-plx两个库的方案,完美解决了问题:
- 用react-native-ble-manager做设备连接:因为我需要用到它的bonding(配对绑定)功能;
- 用react-native-ble-plx做实际通信:用ble-manager连接成功的设备ID,创建一个ble-plx的设备实例,然后用ble-plx的通信方法就能正常拿到响应了。
对应的实现代码如下:
const getPlxDeviceFromConnection = async ( deviceId: string ): Promise<Device | null> => { try { logMessage("🔄 Creating BLE PLX device from connected device..."); // 兼容设备ID的大小写问题 const upperDeviceId = deviceId.toUpperCase(); const lowerDeviceId = deviceId.toLowerCase(); // 尝试用两种大小写查找设备 let plxDevices = await blePlxManager.devices([lowerDeviceId]); if (!plxDevices || plxDevices.length === 0) { plxDevices = await blePlxManager.devices([upperDeviceId]); } if (plxDevices && plxDevices.length > 0) { const device = plxDevices[0]; // 必须显式连接一次 logMessage(`Connecting to PLX device ${device.id}...`); const connectedDevice = await device.connect(); logMessage("✅ PLX device connected successfully"); // 发现所有服务和特征 logMessage("Discovering services for PLX device..."); const deviceWithServices = await connectedDevice.discoverAllServicesAndCharacteristics(); logMessage("✅ Services discovered for PLX device"); setPlxDevice(deviceWithServices); return deviceWithServices; } logMessage("❌ Device not found by BLE PLX"); return null; } catch (error) { logMessage( `❌ Error getting PLX device: ${error instanceof Error ? error.message : String(error)}` ); return null; } };
核心思路就是利用两个库的各自优势:ble-manager的配对绑定功能很实用,但通信部分可能存在兼容性问题;而ble-plx的通信API在我的场景下更可靠。通过共享设备ID,把两个库的能力结合起来,就解决了之前的通信无响应问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

