Expo React Native应用使用react-native-ble-plx连接蓝牙报错排查
问题原因
这个错误的核心是react-native-ble-plx依赖iOS/Android原生代码实现蓝牙功能,但你用的是Expo默认的Managed Workflow(托管式工作流)——这种模式下Expo封装了原生环境,不允许直接引入需要原生配置的第三方库,导致NativeEventEmitter找不到对应的原生模块实例,从而抛出错误。
解决办法
有两种可行方案:
方案1:用Expo Dev Client(推荐,保留Expo大部分特性)
- 如果你愿意替换为Expo官方适配的蓝牙库,直接安装
expo-ble:
然后调整代码适配npx expo install expo-bleexpo-ble的API:import { BleClient } from 'expo-ble'; import { useEffect } from 'react'; useEffect(() => { let scanSubscription; const scanAndConnect = async () => { // 先请求蓝牙权限 const permissionResult = await BleClient.requestPermissionsAsync(); if (!permissionResult.granted) { console.error('蓝牙权限没拿到,没法继续'); return; } // 监听设备发现事件 scanSubscription = BleClient.addListener('BLEDeviceDiscovered', async (event) => { if (event.device.name === 'apa1') { await BleClient.stopDeviceScanAsync(); try { await BleClient.connectToDeviceAsync(event.device.id); console.log('连接成功'); // 后续可以做读取/写入特征值等操作 } catch (connectError) { console.error('连接失败:', connectError); } } }); // 启动扫描 await BleClient.startDeviceScanAsync(null, null, () => {}); }; scanAndConnect(); // 组件卸载时清理资源 return () => { scanSubscription?.remove(); BleClient.stopDeviceScanAsync(); BleClient.disconnectAllDevicesAsync(); }; }, []); - 如果你坚持要用
react-native-ble-plx,需要先配置Expo Dev Client:
然后生成自定义开发构建包:npx expo install expo-dev-client
构建完成后,就能在这个自定义客户端里正常使用npx expo run:ios # 或者针对Android运行 npx expo run:androidreact-native-ble-plx了。
方案2:切换到Bare Workflow(完全脱离Expo托管)
如果不需要Expo的托管特性,可以把项目转为原生裸项目:
- 执行命令生成原生代码目录:
npx expo prebuild - 配置
react-native-ble-plx的原生依赖:- iOS:进入
ios目录,执行pod install - Android:按照
react-native-ble-plx官方文档,配置android/build.gradle和android/app/build.gradle
- iOS:进入
- 重新运行项目:
npx react-native run-ios # 或者 npx react-native run-android
额外注意点
- 无论哪种方案,都要确保设备开了蓝牙,并且给应用授予蓝牙权限
- iOS需要在
Info.plist里添加NSBluetoothAlwaysUsageDescription和NSBluetoothPeripheralUsageDescription权限说明;Android要在AndroidManifest.xml里加BLUETOOTH、BLUETOOTH_ADMIN、ACCESS_FINE_LOCATION这些权限
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

