Difference between close() and disconnect()?
Android Bluetooth Low Energy API implements 1 method to connect to the device connectGatt()
but 2 methods to close the connection disconnect()
and close()
.
Documentation says:
disconnect()
: Disconnects an established connection, or cancels a connection attempt currently in progress.close()
: Application should call this method as early as possible after it is done with this GATT client.
The source code of BluetoothGatt.java shows that close() unregisters the application and disconnect() disconnect the client. However it does not say what that actually means. I mean, if there is only 1 way to connect to the client, why there are 2 ways to close/disconnect the connection?
Solution 1:
With disconnect()
you can later call connect()
and continue with that cycle.
Once you call close()
you are done. If you want to connect again you will have to call connectGatt()
on the BluetoothDevice
again; close()
will release any resources held by BluetoothGatt
.
Solution 2:
Here is some food for thought:
As long as you have not called close on the Gatt, you can still try to connect to it, or discover. So when I try to discover services for a machine, I will usually run a thread or runnable that makes the request to connect to the machine for a certain period of time.
The first attempt with a machine connection, will return a BluetoothGatt object that you can later use to try to discover the services for the BluetoothDevice object. It seems pretty easy to connect, but much harder to discover the machine servces.
mBluetoothGatt = machine.getDevice().connectGatt(this, false, mGattCallback);
So in my thread / runnable, I will check to see if the BluetoothGatt is null. If it is, I will call the above line of code again, else I will attempt to discover the BluetoothGatt services as such.
mBluetoothGatt.discoverServices();
Oh, and I ALWAYS make sure to call BluetoothAdapter.cancelDiscovery() before any attempt at connecting of discovering the service.
mBluetoothAdapter.cancelDiscovery();
Here is a method is use to connect in my runnable etc:
public void connectToMachineService(BLEMachine machine) {
Log.i(SERVICE_NAME, "ATTEMPTING TO CONNECT TO machine.getDevice().getName());
mBluetoothAdapter.cancelDiscovery();
if(mBluetoothGatt == null)
mBluetoothGatt = machine.getDevice().connectGatt(this, false, mGattCallback);
else
mBluetoothGatt.discoverServices();
}
Lastly, make sure that you close out any BluetoothGatt objects that you have connected to. It appears that Android can handle five BluetoothGatt objects before it starts saying "unable to connect to Gatt server" or other something like that.
On every BluetoothGatt that I create, I will call close on it then broadcast an update stating the connection is closed. It seems that there are a lot of times where the BluetootGatt will not respond with a state change when it becomes disconnected. My method of closing the BluetoothGatt goes something like this. I leave the method open up for the Activity to call the service and disconnect if a machine becomes non - responsive and the disconnect state is not called.
public void disconnectGatt(BluetoothGatt gatt) {
if(gatt != null) {
gatt.close();
gatt = null;
}
broadcastUpdate(ACTION_STATE_CLOSED);
}