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

James Whong
  • 231
  • 5
  • 5

4 Answers4

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.

AAnkit
  • 27,299
  • 12
  • 60
  • 71
  • 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. – James Whong Nov 24 '15 at 23:27
  • @JamesWhong you were precise enough. You can upvote or accept the answer if it helps you. :) – AAnkit Nov 24 '15 at 23:30
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.

Dan Hulme
  • 14,779
  • 3
  • 46
  • 95
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();
Trip
  • 13
  • 6
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.