Disconnecting a BluetoothDevice without BluetoothGATT
Asked Answered
F

4

7

My app talks to a BLE peripheral. Sometimes the app is started with that peripheral already connected. I can retrieve the device by calling:

BluetoothManager manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
List<BluetoothDevice> connectedDevices = manager.getConnectedDevices(BluetoothProfile.GATT);

I can then filter connectedDevices based on address or UUID. However, BluetoothDevice has no disconnect method. To disconnect, I need a BluetoothGATT instance. But the only way I can see to get a BluetoothGATT instance is to call

connectedDevice.connectGatt(Context, boolean, BluetoothGattCallback)

Which takes a very long time. On top of this, the BluetoothGatt instance I get back after calling connectGatt doesn't seem to actually disconnect the peripheral when I call disconnect().

So my questions are:

  • Is there a way to disconnect a connected BluetoothDevice without calling connectGatt?
  • Why does connectGatt take so long for a device that's already connected?
  • Is it even valid to call connectGatt on a connected BluetoothDevice?

Thank you

Falsity answered 20/11, 2015 at 22:54 Comment(2)
I'm still trying to figure this out too.Sadick
Any solution found for this so far?Hendon
T
7

Here are my 2 cents for your queries.

  • Is there a way to disconnect a connected BluetoothDevice without
    calling connectGatt?

    you need to call bluetoothGatt.disconnect(); why do you need to call connectGatt for disconnection? If it is because you need gatt instance, then save it when the device is connected already. Do not call connectGatt on connectedDevice.

  • Why does connectGatt take so long for a device that's already
    connected?

    Cause to make a connection both device needs to be in connectable mode(there are modes like advertisement, connectable, non-connectable). Once the connection is made, the device is no longer in connectable mode. Thats the reason for its taking longer. Dont call it, or disconnect before connecting again.

  • Is it even valid to call connectGatt on a connected
    BluetoothDevice?

    Everything in coding is valid and legal, but read my answer of second point.

Tinea answered 23/11, 2015 at 22:17 Comment(2)
Thanks AAnkit - I will try to be more concise. My entire problem is that I can't call BluetoothGatt.disconnect() because I don't have a BluetoothGatt object, I only have a BluetoothDevice object. The only way I can see to get a BluetoothGatt object is to call BluetoothDevice.connectGatt(), which I don't want to do for all the reasons I listed.Falsity
@JamesWhong you were precise enough. You can upvote or accept the answer if it helps you. :)Tinea
H
1

Sometimes the app is started with that peripheral already connected.

This implies that some other app is connected to the peripheral. Of course you can't disconnect some other app's connection. The app that connects the peripheral also has to disconnect it.

Honorine answered 23/3, 2017 at 12:59 Comment(0)
C
0

For my project i found this workaround, don't know if it's the best solution, but maybe it could help someone.

Declare a BluetoothGatt List:

List<BluetoothGatt> gattList = new ArrayList<>();

In OnConnectionStateChange, every time a new device is connected, add his gatt object to the list:

public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
    super.onConnectionStateChange(gatt, status, newState);
    if (newState == BluetoothProfile.STATE_CONNECTED) {                  
        gattList.add(gatt) ;
    }       
}

Get your gatt object using a BluetoothDevice address (that is easier to retrive) using a function like this one:

public BluetoothGatt getGattFromAddress(String address) {
    BluetoothGatt gatt = null ;
    for(int i=0; i<gattList.size(); i++)    {
        if(address.equals(gattList.get(i).getDevice().getAddress()))
            gatt = gattList.get(i);
    }
    return gatt ;
}

Perform gatt actions:

getGattFromAddress(bleDeviceAddress).disconnect();
Couturier answered 12/5, 2021 at 10:5 Comment(0)
D
0

In the mentioned case of using an arraylist to keep connected gatt devices, the device will never be removed from the list after it has been disconnected.

And if you remove the device on STATE_DISCONNECTED, any iteration with that arraylist might crash with a ConcurrentModificationException, as a disconnection of the device might occur at any time.

Dunseath answered 29/3, 2023 at 6:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.