react-native-ble-plx: bleManager.isDeviceConnected() always returns false, irrespective of it's actually connected or not

Expected Behavior

According to the docs isDeviceConnected should return either true or false depending on whether the BLE device is connected to the mobile/app

Current Behavior

Despite of running isDeviceConnected on a device that it’s actually connected it always returns false.

Context

I need to check by using the built-in RN AppState component whether a device the user was using before switching of apps (or after coming back from background) it’s still connected…

  • Library version: 2.0.0

Every time I call isDeviceConnected with a connected device Id, I always get Device AA:BB:CC:DD:EE:FF is NOT connected!

const isBleDeviceConnected = async (deviceId = null) => {
    if (!deviceId) return false;
    const isConnected = await bleManager.isDeviceConnected(deviceId);
    if (isConnected) {
      console.log(`Device ${deviceId} is connected!`);
    } else {
      console.log(`Device ${deviceId} is NOT connected!`);
    }
    return isConnected;
  };

Is there any fix in progress or a workaround available?

Thanks in advance!

Federico

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 27

Most upvoted comments

I have the Same issue, App is connected to device. isDeviceConnected() always show the device is disconnected but I can see the ble device is connected. After I connect it and perform some operation. In the next write characterstic cycle it again show the ble is disconnected and I have to connect back again.

I am also facing issue with disconnect. Neither device.cancelConnection() work or bleManager.cancelDeviceConnection() work.

Update:

After lot of Efforts, I was able to work it. How?

Make sure new BleManager() is call only once in entire life cycle of your code or the instance is destroy before you leave it. Basically no Multiple Instance.

–I was using

const [manager, setManager] = useState(new BleManager());

Instead of this you can directly declare it as a

const manager = new BleManager()

–Make sure the constant is out of your UI component Instead of doing this

export default function HomeScreen() {
    const [manager, setManager] = useState(new BleManager());
    // etc.
}

go for this

import { BleManager } from 'react-native-ble-plx'

// Where to instantiate the BleManager
const manager = new BleManager()

//Ui Component
const BluetoothTest = () => {
}
export default BluetoothTest 

I think this will help both the issue. disconnect and is deviceConnected.

I think that your example is working because you call the isConnected() function before you assign the connected device with setConnectedDevice() function.
Can you try to call the isConnected() function with your connectedDevice outside this listener ? It should return only false. I remark that the device._manager._uniqueId is not the same before and after you call the setConnecteDevice() function. You should log the device object in each case to notice that.

Here is an example.

const [connectedDevice, setConnectedDevice] = useState(null);

const scan = () => {
manager.startDeviceScan(
  null,
  null,
  (error, device) => {
    if (error) {
      console.log('error', JSON.stringify(error));
    } else if (device) {
      if (device.localName === 'MyTestDevice') {
        manager.stopDeviceScan();
        localScanChange(false);
        device
          .isConnected()
          .then(bool => console.log('isConnected0', bool, device));
        manager
          .isDeviceConnected(device.id)
          .then(bool => console.log('isConnectedM0', bool, device));
        device
          .connect()
          .then(() => {
            device
              .isConnected()
              .then(bool => console.log('isConnected1', bool, device));
            manager
              .isDeviceConnected(device.id)
              .then(bool => console.log('isConnectedM1', bool, device));
            return device.discoverAllServicesAndCharacteristics();
          })
          .then(() => {
            setConnectedDevice(device);
            console.log('connected');
          });
        const sub = device.onDisconnected((error, device) => {
          console.log('disconnected');
          setConnectedDevice(null);
          sub.remove();
        });
      }
    }
  },
);
}

const checkIfDeviceConnected = () => {
     // RETURN FALSE EACH TIME EVEN IF THE DEVICE IS CONNECTED !
     connectedDevice.isConnected().then(bool => console.log('isConnected', bool, device));
}

My guess is that you are misusing React Hooks. Could you edit to contain information according to the issue template? I am especially interested in native logs.