dotintent / react-native-ble-plx

React Native BLE library
Apache License 2.0
2.94k stars 492 forks source link

App crash on start NullPointerException "com.bleplx.adapter.BleAdapter.stopDeviceScan()"🐛 #1159

Open Philipp-gr4 opened 5 months ago

Philipp-gr4 commented 5 months ago

Prerequisites

Expected Behavior

App should start normal and start to scan for devices.

Current Behavior

App sometimes crashes on certain smartphones (Xiaomi Android 13) after allowing permissions at start. On my phone (Google Pixel 7 Pro Android 14) and on the Android Studio Emulator everything works as expected.

Library version

3.1.2

Device

Xiaomi Redmi Note 12 Pro+

Environment info

System:
  OS: Windows 10 10.0.19045
  CPU: "(16) x64 AMD Ryzen 7 5800X 8-Core Processor             "
  Memory: 19.93 GB / 31.92 GB
Binaries:
  Node:
    version: 18.17.0
    path: C:\Program Files\nodejs\node.EXE
  Yarn:
    version: 1.22.19
    path: C:\Program Files (x86)\Yarn\bin\yarn.CMD
  npm:
    version: 9.8.1
    path: C:\Program Files\nodejs\npm.CMD
  Watchman: Not Found
SDKs:
  Android SDK: Not Found
  Windows SDK:
    AllowDevelopmentWithoutDevLicense: Enabled
IDEs:
  Android Studio: Not Found
  Visual Studio: Not Found
Languages:
  Java: 11.0.20
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.72.3
    wanted: 0.72.3
  react-native-windows: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

Steps to reproduce

Formatted code sample or link to a repository

Zustand store

import { BleManager } from "react-native-ble-plx";
import { create } from "zustand";

export default useBleStore = create((set, get) => ({
  foundDevices: [],
  scanIsRunning: true,
  connectedDevice: null,
  serviceUUID: "sampleUUID",
  characteristicUUID: "sampleUUID",
  bleManager: new BleManager(),
  scanForDevices: async () => {
    get().bleManager.startDeviceScan([get().serviceUUID], null, (error, device) => {
      set({ scanIsRunning: true });
      if (device && device.id && device.name) {
        if (!deviceAlreadyFound(get().foundDevices, device)) {
          set({ foundDevices: [...get().foundDevices, device] });
        }
      }
    });
  },
  connectToDevice: async (device) => {
    var deviceConnection = await get().bleManager.connectToDevice(device.id);
    await deviceConnection.discoverAllServicesAndCharacteristics();
    set({ connectedDevice: deviceConnection });
  },
  writeCharacteristic: async (dataToWrite) => {
    const endChar = "/";
    const Buffer = require("buffer").Buffer;
    let base64String = Buffer.from(dataToWrite + endChar, 'utf-8').toString('base64');

    await get().bleManager.writeCharacteristicWithResponseForDevice(get().connectedDevice.id, get().serviceUUID, get().characteristicUUID, base64String);
  },
  disconnectDevice: async () => {
    if (get().connectedDevice != null) {
      await get().bleManager.cancelDeviceConnection(get().connectedDevice.id);
      set({ connectedDevice: null });
    }
  },
  stopScanning: () => {
    get().bleManager.stopDeviceScan();
    set({ scanIsRunning: false });
  },
}))

-----------------------------------------------
Component

async function handleDevicePress(device) {
    await connectToDevice(device);
    stopScanning();
    navigation.navigate('light-config')
  }

return (
<ScrollView style={styles.scrollView} showsVerticalScrollIndicator={false}>
        {foundDevices.map((foundDevice, index) => (
          <View style={[isLastDeviceInArray(index, foundDevices.length) && styles.lastDevice]} key={index}>
            <TextButton onPress={() => handleDevicePress(foundDevice)} name={foundDevice.name} />
            {setDevider(index, foundDevices.length)}
          </View>
        ))}
      </ScrollView>
)

Relevant log output

java.lang.NullPointerException: Attempt to invoke interface method'void
com.bleplx.adapter. BleAdapter.stop DeviceScan()' on a null object reference
at
com.bleplx.BlePlxModule.stopDeviceScan (BlePlxMod ule.java:222)
at java.lang.reflect. Method. invoke(Native Method) at
com.facebook.react. bridge. JavaMethodWrapper.invo ke(JavaMethodWrapper.java:372)
at
com.facebook.react. bridge. JavaModuleWrapper.invo ke(JavaModuleWrapper.java:1 88) at com.facebook.jni. NativeRunnable.run (Native Method)
at
android.os.Handler.handle Callback(Handler.java:942) at
android.os.Handler.dispatchMessage(Handlerjava:99 at
com.facebook.react.bridge.queue.MessageQueueThr eadHandler.dispatchMessage(MessageQueueThread Handler.java:27)
at android.os. Looper.loop Once(Looper.java:211) at android.os. Looper.loop(Looper.java:300) at
com.facebook.react. bridge.queue.MessageQueueThr eadimpl$4.run(MessageQueueThreadimpl,java:228) at java.lang.Thread.run(Thread.java:101 2)

Additional information

No response