You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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两个库的方案,完美解决了问题:

  1. 用react-native-ble-manager做设备连接:因为我需要用到它的bonding(配对绑定)功能;
  2. 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 09:38:06