Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 startDeviceScan errors with "BleManager was destroyed" on android API level 33 (android 13) when published (works fine when running with metro) #1238

Open
2 tasks done
ArthurRuxton-DY opened this issue Aug 31, 2024 · 2 comments
Labels

Comments

@ArthurRuxton-DY
Copy link

Prerequisites

  • I checked the documentation and FAQ without finding a solution
  • I checked to make sure that this issue has not already been filed

Expected Behavior

startDeviceScan should work as normal

Current Behavior

My app works on ios, android 11, android 14.
It also works on android 14 when running with metro (npx react-native run-android)
When running the published app, startDeviceScan always errors with "BleManger was destroyed".
I've even tried conditionally reinitialising bleManager imediately before device scan:
if(!bleManager) bleManager = new BleManager()

Library version

3.2.1

Device

all android 13 (api level 33) devices

Environment info

react-native 0.74.0

Steps to reproduce

attempt startDeviceScan in published app on android 13 (api 33)

Formatted code sample or link to a repository

const callBleScanner = async () => {
    // if no bleManager: reinitialise 
    if(!bleManager){
      bleManager = new BleManager();
      // verify that the ble manager is created. 
      logger(`BLE Manager reinitialized? ${bleManager}`)
    } 

    // to ensure useEffect is triggered by errors: reset 'scanError' state
    setScanError(false);

    // Use a try catch for more robust error catching
    try{
      // Attempt scanning 
      logger("Attempt startDeviceScan:")
      bleManager.startDeviceScan(
        null, 
        // use low latency scan on android for quicker discovery. 
        Platform.OS === "android" ? {scanMode: ScanMode.LowLatency} : null,
        // handle scan error.  
        (error, scannedDevice) => {
          if (error) {
            // stringify the ble error to get all available information. 
            setScanError(true);
            logger(`Bluetooth scanning error: ${JSON.stringify(error)}`)
          }
          
          if (!scannedDevice) return
          if(!scannedDevice.name) return 
          let nameContainsKeyChars = /(ES-|IS-)/.test(scannedDevice.name)
          if(!nameContainsKeyChars) return
          logger(`DEVICE FOUND: ${scannedDevice.name}`)
          // conditionally update state with new device. 
          setDevicesFound((prevState: Device[]) => {
            if (isOriginalDevice(prevState, scannedDevice)) {
              return [...prevState, scannedDevice];
            } 
            return prevState;
          });
        }
      );
    } catch (error) {
      // this catch always runs on android 13 (api 33) in the published app (not in dev)
      logger(`Failed Bluetooth-state check & scan-start: ${error}`)
      setScanError(true)
    }

  }

Relevant log output

"Failed Bluetooth-state check & scan-start: BleManagerWasDestroyed"

Additional information

No response

@intent-kacper-cyranowski
Copy link
Collaborator

Hi @ArthurRuxton-DY

Where do you store your bleManager? According to the documentation it should be initialized once, outside of React.

Aside from that, your code looks fine, so I would need more context to determine what's causing the error.

@ArthurRuxton-DY
Copy link
Author

ArthurRuxton-DY commented Sep 5, 2024

Hi @intent-kacper-cyranowski thanks for your response.
I have a custom hook where all blw methods live. Originally my bleManager was initialised at the top of that file, so outside of React. I think Android 13 did not agree with some other aspect of my set up.

In the end the only way to get my implementation to work on all api levels was to initialise the bleManager after permissions had been granted rather than before. This solution actually caused the same bug in IOS, so now I conditionally initialise the bleManger before / after permissions are granted.

for IOS: initialise bleManager > request permissions > check permissions granted > start scanning
for Android: request permissions > check permissions granted > initialise bleManager > start scanning

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants