Search code examples
androidreact-nativebluetoothbluetooth-lowenergyreact-native-ble-manager

react native - crash the app when I call scan function with react-native-ble-manager


I used for the first time react-native-ble-manager. The app has all the permissions, however when I run the BleManager.scan() the app is closing without any error or logs. I know the code is a little ugly but it's just for testing, the first second I run the bluetooth manager start and after 5 seconds I run the scan. But the crash happen immediately after 5 seconds. Any idea why?


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(() => {
});
 

the manifest is like:


   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" />

Solution

  • The problem has been solved. The new android 12 (I think from this one), needs a different permission that it hasn't been updated in react-native-ble-manager webpage. In the manifest you need to add

        <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
        <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
    

    Also, In the app.js you need to call once requestPermissions(); that it can be like

     
     const requestPermissions = async () => {
      if (Platform.OS === 'android') {
        const apiLevel = await DeviceInfo.getApiLevel();
    
        if (apiLevel < 31) {
          const granted = await PermissionsAndroid.request(
            PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
            {
              title: 'Location Permission',
              message: 'Bluetooth Low Energy requires Location',
              buttonNeutral: 'Ask Later',
              buttonNegative: 'Cancel',
              buttonPositive: 'OK',
            },
          );
        } else {
          const result = await requestMultiple([
            PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
            PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
            PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
          ]);
    
          const isGranted =
            result['android.permission.BLUETOOTH_CONNECT'] ===
            PermissionsAndroid.RESULTS.GRANTED &&
            result['android.permission.BLUETOOTH_SCAN'] ===
            PermissionsAndroid.RESULTS.GRANTED &&
            result['android.permission.ACCESS_FINE_LOCATION'] ===
            PermissionsAndroid.RESULTS.GRANTED;
    
        }
      } else {
      }
    };