chipweinberger / flutter_blue_plus

Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android, iOS, macOS
Other
791 stars 478 forks source link

[Bug]: Android randomly tries to reconnect to device after spontaneous disconnect() call, with autoConnect on #793

Closed William-Geng closed 9 months ago

William-Geng commented 9 months ago

Requirements

Have you checked this problem on the example app?

No

FlutterBluePlus Version

1.31.13

Flutter Version

3.16.8

What OS?

Android

OS Version

13

Bluetooth Module

nRF52832

What is your problem?

I have an app that tries to connect to a bunch of BLE devices periodically, 3 at a time, read some data then disconnect. The process will run for a bit but eventually I would start seeing these random I/flutter (16417): [FBP] <connect> args: {remote_id: E7: AB: 37:5F: 77:3B, auto_connect: 1} logs right after a successful disconnect that is initiated by the app. After that that particular device will stay connected and stop advertising and become invisible to my app. so eventually my app will stop seeing any available devices to read data from.

After disconnect() I use BluetoothDevice.isAutoConnectEnabled to check whether autoConnect is still on and it does say false. I am not sure what is triggering these random connect attempts. I also found https://stackoverflow.com/questions/24763204/android-ble-automatic-re-connect-after-spontaneous-disconnect this dated thread that seems to be having the same issue. Has anyone seen similar behavior before? Any help would be much appreciated!

logs attached

Screenshot 2024-02-13 at 9 34 55 PM

here E7:AB:37:5F:77:3B is showing this behavior.

Logs

Log.debug:
D/[FBP-Android](10127): [FBP] onMethodCall: disconnect
D/BluetoothGatt(10127): cancelOpen() - device: DA17CE_6
D/BluetoothGatt(10127): onClientConnectionState() - status=0 clientIf=5 device=DA17CE_6
D/[FBP-Android](10127): [FBP] onConnectionStateChange:disconnected
D/[FBP-Android](10127): [FBP]   status: SUCCESS
D/BluetoothGatt(10127): close()
D/BluetoothGatt(10127): unregisterApp() - mClientIf=5
I/flutter (10127): 2024-02-13T11:30:10.001152   D   BleService:  BluetoothConnectionState.disconnected
I/flutter (10127): 2024-02-13T11:30:10.002050   D   BleService:  ----disconnected! DA:17:CE:A1:6E:A6
I/flutter (10127): 2024-02-13T11:30:10.002774   D   BleService:  ----autoConnect is disabled, cleaning up
I/flutter (10127): 2024-02-13T11:30:10.003492   D   BleService:  ----clean up after disconnection DA:17:CE:A1:6E:A6
I/flutter (10127): 2024-02-13T11:30:10.004361   I   BleService:  ----disconnected DA:17:CE:A1:6E:A6
I/flutter (10127): 2024-02-13T11:30:10.005268   D   BleService:  ----clean up after disconnection DA:17:CE:A1:6E:A6
D/BluetoothGatt(10127): connect() - device: DA17CE_6, auto: true
D/BluetoothGatt(10127): registerApp()
D/BluetoothGatt(10127): registerApp() - UUID=cdca240c-f9a4-4c97-abfb-edadaeddb18d
D/BluetoothGatt(10127): onClientRegistered() - status=0 clientIf=5
chipweinberger commented 9 months ago

this log

I/flutter (16417): [FBP] <connect> args: {remote_id: E7: AB: 37:5F: 77:3B, auto_connect: 1}

seems like it is coming from this code

    // keep track of connection states
    if (call.method == "OnConnectionStateChanged") {
      var r = BmConnectionStateResponse.fromMap(call.arguments);
      _connectionStates[r.remoteId] = r;
      if (r.connectionState == BmConnectionStateEnum.disconnected) {

        ........

        // autoconnect
        for (DeviceIdentifier d in _autoConnect) {
          if (_adapterStateNow == BmAdapterStateEnum.on) {
            BluetoothDevice(remoteId: d).connect(autoConnect: true, mtu: null);
          }
        }
      }
    }

but if you call disconnect it is supposed to remove the device from _autoConnect

chipweinberger commented 9 months ago

you'll need to study the FBP code more closely and debug the issue further. possibly add print statements. see debugging in the README

chipweinberger commented 9 months ago

ahh, i think I know this issue. I'm looping through every device.

       // autoconnect
        for (DeviceIdentifier d in _autoConnect) {
          if (_adapterStateNow == BmAdapterStateEnum.on) {
            BluetoothDevice(remoteId: d).connect(autoConnect: true, mtu: null);
          }
        }

but really I should just do the device that disconnected

chipweinberger commented 9 months ago

pushed https://github.com/boskokg/flutter_blue_plus/commit/95869c0684038e76b327be0dcc552f5731f6cf64

try master branch

William-Geng commented 9 months ago

Testing right now, looks promising so far! Will leave it running for a bit and get back to you. Thank you so much for such prompt response!

William-Geng commented 9 months ago

Issue is fixed in master, thanks @chipweinberger !

chipweinberger commented 9 months ago

fixed 1.31.14