So I\'m able to connect to a BLE device just fine under normal circumstances. What I want to do is handle abnormal circumstances, like when the connection to a device fails or a
This answer aligns with the answer from Emil.
I coded up a test App with a single Activity running on Moto G4 Play Android 6.0.1 (Marshmellow: API23) and a Peripheral based on a Laird BL600
I was going to post some logs - but they don't format so well - so I'll just describe the results.
As usual, the Peripheral advertised and the Central scanned, and obtained a device instance.
The question does not state exactly how the first connection is made, but let's assume it is with 'autoconnect' false, of the form
mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback);
(this is the only style of connection used in the test App)
This gives an instance of BluetoothGatt
and, as noted in the question, events are then reported asynchronously through the call back,
but there is also an instance of BluetoothGatt
on which to call disconnect()
even before any connection events have occurred.
The API documentation for disconnect() states - especially the part after the ','
BluetoothGatt.disconnect()
Disconnects an established connection, or cancels a connection attempt currently in progress.
To free up GATT resources, after disconnecting, the test App also then always calls
mBluetoothGatt.close();
Here are some different scenarios
device.connectGatt() -- Peripheral advertising - connection made -- followed by mBluetoothGatt.disconnect() and close().
Result: this is a normal successful connection, followed by Central device closing the connection in code. Call back events are received as expected. When the Central disconnects in the code, the underlying Bluetooth Service disconnects and the Peripheral gets a Disconnection event.
.
device.connectGatt() -- Peripheral advertising - connection made - followed by Peripheral switched off.
Result: this is a normal successful connection, call back events as expected, followed by connection broken by Peripheral. The Peripheral indicates preferred connection supervision timeout in BleGapSvcInit and this is confirmed by Central in a Connection Parameters Update. After Peripheral drops the connection a Disconnection event occurs in Central just after the connection supervision timeout. (Repeated with 8 seconds and 4 seconds supervision timeouts).
.
device.connectGatt() -- but Peripheral has stopped advertising, connection attempt allowed to time out.
Result: (This is a specific scenario of the question) After 30 seconds, probably the connection timeout of the Bluetooth Service on the phone,
there is a an onConnectionStateChange
event indicating the new connection state is Disconnected - with (error) status 133.
Must still remember to call mBluetoothGatt.close()
else an interface leak occurs and subsequent connection is made on the next client interface.
.
device.connectGatt() -- Peripheral still advertising but connection cancelled after 200ms using mBluetoothGatt.disconnect() and close().
Result: (I found this case the most interesting, if also the most unlikely to happen in a real application) Sometimes, (about 1 in 10) the underlying Bluetooth Service actually did connect to the Peripheral; which saw a connect, followed by a disconnect; even though the App doesn't see these events in the call back. Sometimes, even though, as far as the App is concerned, the App is disconnected, the underlying Bluetooth phone service connected to the Peripheral - and remained connected in my test for a few minutes until I timed out! - and turned the BT service, or the Peripheral, off.