I'm developing an app that takes advantage of the new Bluetooth BLE API from Android 4.3.
I used the Samsung BLE Stack for Android 4.2 and it's working ok, even if the stability could be better.
Now with 4.3, for each client connection, we have an instance of the BluetoothGatt
class.
That is, I connect to a BLE device by calling
BluetoothGatt gatt = device.connectGatt(this, true, callbacks);
These BluetoothGatt
objects are the ones to use to actually interact with a device.
Since I want to connect to multiple devices and interact with those, I'm caching the BluetoothGatt
instances in a HashMap
defined as my service's private property :
private HashMap<String, BluetoothGatt> devicesGatts
= new HashMap<String, BluetoothGatt>();
The keys are device addresses.
Then whenever I want to connect to a device, I pull the BluetoothGatt
instance out of this HashMap
:
public BluetoothGatt connectGatt(final BluetoothDevice device){
if(device == null){
return null;
}
String adr = device.getAddress();
BluetoothGatt gatt = devicesGatts.get(adr);
if(gatt == null){
gatt = device.connectGatt(this, true, mGattCallbacks);
} else {
BluetoothDevice gattDevice = gatt.getDevice();
if(gattDevice != null && adr.equals(gattDevice.getAddress())){
gatt.connect(); // PROBLEM APPEARS HERE
} else {
gatt = device.connectGatt(this, true, mGattCallbacks);
}
}
devicesGatts.put(adr, gatt);
return gatt;
}
The problem is that sometimes, if a device is tried reconnecting via its cached BluetoothGatt
instance by calling gatt.connect()
, I get an error (not Fatal) called DeadObjectException
.
It happens when I pause the application and restart the Bluetooth chip, then resuming the application.
I'm not surprised that I can't use the cached instance after that happened, but I'd like to know how I could either catch that exception or detect it prior to it happening.
Here is the stack trace :
02-18 10:43:51.884: E/BluetoothGatt(23312): android.os.DeadObjectException
02-18 10:43:51.884: E/BluetoothGatt(23312): at android.os.BinderProxy.transact(Native Method)
02-18 10:43:51.884: E/BluetoothGatt(23312): at android.bluetooth.IBluetoothGatt$Stub$Proxy.clientConnect(IBluetoothGatt.java:841)
02-18 10:43:51.884: E/BluetoothGatt(23312): at android.bluetooth.BluetoothGatt.connect(BluetoothGatt.java:759)
02-18 10:43:51.884: E/BluetoothGatt(23312): at MYSERVICE.connectGatt(...)
The exception is raised by a native method but is not thrown by the Bluetooth stack classes.
How could I catch it?