react-native-ble-plx icon indicating copy to clipboard operation
react-native-ble-plx copied to clipboard

Question

Open anxheloo opened this issue 5 months ago • 0 comments

Prerequisites

  • [x] I checked the documentation and FAQ without finding a solution
  • [x] I checked to make sure that this issue has not already been filed
  • [x] I'm sure that question is related to the library itself and not Bluetooth Low Energy or Classic in general. If that so, please post your question on StackOverflow.
  • [x] I'm running the latest version

Question

I am working on a museum project where each room has a beacon device and based on rsi < 70 i navigate and show the content for that specific room. Till now im using macAddress for android and namespaceId for ios ( by parsing the data: const nameSpaceId = bytes.slice(2, 12).toString('hex')).

It seems to be working fine most of the cases but sometimes it stuck and doesnt recognize it anymore, seems like it is overwhelmed. And it keeps scanning every seconds multiple devices.

My first question is : Is this approach im using good? Second: Is there a timeout i should have or something im missing to make it optimize better?

This is more like a suggestion i need. Thanks in advance!

Question related code

This is my startScanning code:  

  const startScanning = useCallback(() => {
    const rooms = useAppStore.getState().rooms;

    if (specifiedModal === 'voice') {
      return;
    }

    bleManager.startDeviceScan(
      null,
      {allowDuplicates: false},
      (error, device) => {
        if (error) {
          console.error('BLE scan error:', error);
          return;
        }

        if (device && device.rssi! >= RSSI_THRESHOLD && device.serviceData) {
          // if (specifiedModal === 'voice') {
          //   return;
          // }

          // For IOS
          const namespaceId = parseIBeaconDataBuffer(
            Object.values(device.serviceData)[0],
          );
          // For Android
          const macAddress = device.id;

          // Check if the namespaceId or MAC address matches any of the rooms beacons array and return true or false
          const check = checkNamespaceOrMacAddressAgainstScannedDevices(
            Platform.OS === 'android' ? macAddress : namespaceId!,
          );

          // If we have a match we find that roomIndex that has that match and navigate to that room
          if (check) {
            // Find room index of the matched beacon stored in the room with namespaceId or macAddress we get from scanning
            const roomIndex = rooms.findIndex(room =>
              Platform.OS === 'android'
                ? room.beacon.some(
                    b =>
                      b.macAddress.toLowerCase() === macAddress.toLowerCase(),
                  )
                : room.beacon.some(
                    b =>
                      b.namespaceId.toLowerCase() ===
                      namespaceId?.toLowerCase(),
                  ),
            );

            // if (roomIndex !== -1 && roomIndex !== previousIndex.current) {
            if (roomIndex !== -1) {
              // Find the beacon to update location
              const beacon = rooms[roomIndex].beacon.find(b =>
                Platform.OS === 'android'
                  ? b.macAddress.toLowerCase() === macAddress.toLowerCase()
                  : b.namespaceId.toLowerCase() === namespaceId?.toLowerCase(),
              );

              if (beacon) {
                setBeaconPosition(beacon.position);
              }

              // updateVoiceSlice({isPlaying: false});
              setRoomIndex(roomIndex);
              // previousIndex.current = roomIndex;
            }
          }
        }
      },
    );
  }, [RSSI_THRESHOLD, bleManager, setBeaconPosition, specifiedModal]);


And this is the initialization of BLEManager:   const bleManager = useMemo(() => {
    return new BleManager();
  }, []); 


And inside useEffect im running it:   useEffect(() => {
    if (guideOption === 'automatic') {
      startScanning();
    } else {
      stopScan();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [guideOption]).


And destroying it on return :   useEffect(() => {
    return () => {
      bleManager.destroy();
    };
  }, [bleManager]). This is stopDeviceScan function :   const stopScan = useCallback(async () => {
    await bleManager.stopDeviceScan();
  }, [bleManager]);

anxheloo avatar Jul 15 '25 11:07 anxheloo