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

首次使用react-native-ble-manager调用scan()致APP崩溃求助

React Native BleManager调用scan()时APP直接闪退问题排查

首次使用react-native-ble-manager进行开发,APP已配置所需全部权限,但调用BleManager.scan()时,APP无任何错误日志直接闪退。

测试代码(结构较粗糙,仅作测试用)

import BleManager from 'react-native-ble-manager';
const BleManagerModule = NativeModules.BleManager;
const bleManagerEmitter = new NativeEventEmitter(BleManagerModule);

const handleDiscoverPeripheral = (peripheral) => {
  console.log('Got ble peripheral', peripheral);
  if (!peripheral.name) {
    peripheral.name = 'NO NAME';
  }
  peripherals.set(peripheral.id, peripheral);
  setList(Array.from(peripherals.values()));
}
const handleStopScan = () => {
  console.log('Scan is stopped');
}


let interval;
let gImageShow = true;
let gTime = 0;



BleManager.enableBluetooth()
.then(() => {
  // Success code
  console.log("The bluetooth is already enabled or the user confirm");
})
.catch((error) => {
  // Failure code
  console.log("The user refuse to enable bluetooth");
});
function App(props) {

const [shouldShow, setShouldShow] = useState(gImageShow);

  useEffect(() => {
    interval = setInterval(() => {

      if (gTime == 1)
      {
        BleManager.start({showAlert: true});
        bleManagerEmitter.addListener('BleManagerDiscoverPeripheral', handleDiscoverPeripheral);
        bleManagerEmitter.addListener('BleManagerStopScan', handleStopScan );
        PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION).then((result) => {
        if (result) {
          console.log("Permission is OK");
        }
      });
      }

      if (gTime == 5)
      {  
        BleManager.scan([], 10, true);
      }

      gImageShow = !gImageShow;
      setShouldShow(gImageShow);  
      gTime = gTime + 1;

   },1000);
   return () => clearInterval(interval);
 }, []);
 useEffect(() => {
});

AndroidManifest配置

xmlns:tools="http://schemas.android.com/tools"
package="com.diagnostic_ble">

  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />

  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="28"/>
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" tools:targetApi="Q"/>
     <!-- Needed only if your app looks for Bluetooth devices. -->
  <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
  
  <uses-permission-sdk-23 android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

  <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />

代码逻辑:启动后先开启蓝牙,1秒时初始化蓝牙管理器并添加监听,5秒时执行扫描操作,但APP在5秒时立即崩溃,以下是可能的原因:

  • 权限配置不完整:Android 12+的BLUETOOTH_SCAN权限需要额外声明属性。如果你的扫描不需要位置信息,需给BLUETOOTH_SCAN添加android:usesPermissionFlags="neverForLocation";如果需要位置关联,要确保已动态获取ACCESS_FINE_LOCATION权限,当前配置缺少该属性可能触发权限验证崩溃。
  • 全局变量引发状态冲突:代码中用全局变量gTime、gImageShow管理状态,在setInterval中直接修改并更新React状态,容易导致组件状态不一致,触发扫描时引发内存或状态异常。应改用useState管理这些变量,避免全局副作用。
  • 蓝牙初始化时机错误:BleManager.enableBluetooth()在组件外部调用,此时组件尚未挂载,蓝牙初始化流程与组件生命周期冲突,可能导致扫描时蓝牙服务未正确初始化。需将蓝牙启用逻辑移到组件内部的useEffect中。
  • 监听器重复添加风险:gTime == 1分支中每次执行都会添加监听器,若setInterval逻辑异常导致分支重复执行,会引发监听器重复绑定,造成内存泄漏或事件处理冲突,最终导致崩溃。应将监听器添加逻辑移到单独的useEffect中,确保只绑定一次。
  • 未捕获扫描异常:BleManager.scan()返回Promise但未添加.catch()处理,扫描过程中的错误无法被捕获,直接导致APP闪退。需补充错误捕获:
    BleManager.scan([], 10, true)
    .then(() => console.log('Scan started'))
    .catch(err => console.error('Scan error:', err));
    

内容的提问来源于stack exchange,提问作者damooo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 11:45:37