I am wondering how this can be achieved
To achieve multiple BLE connection you have to store multiple BluetoothGatt
object and use those object for different device. To store multiple connection object of BluetoothGatt
you can use Map<>
private Map<String, BluetoothGatt> connectedDeviceMap;
On Service onCreate
initialize the Map
connectedDeviceMap = new HashMap<String, BluetoothGatt>();
Then before calling device.connectGatt(this, false, mGattCallbacks);
to connect to GATT Server check that device is already connected.
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(deviceAddress);
int connectionState = mBluetoothManager.getConnectionState(device, BluetoothProfile.GATT);
if(connectionState == BluetoothProfile.STATE_DISCONNECTED ){
// connect your device
device.connectGatt(this, false, mGattCallbacks);
}else if( connectionState == BluetoothProfile.STATE_CONNECTED ){
// already connected . send Broadcast if needed
}
On BluetoothGattCallback
if connection state is CONNECTED then store BluetoothGatt
object on Map
and if connection state is DISCONNECTED then remove it form Map
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
BluetoothDevice device = gatt.getDevice();
String address = device.getAddress();
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.i(TAG, "Connected to GATT server.");
if (!connectedDeviceMap.containsKey(address)) {
connectedDeviceMap.put(address, gatt);
}
// Broadcast if needed
Log.i(TAG, "Attempting to start service discovery:" +
gatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.i(TAG, "Disconnected from GATT server.");
if (connectedDeviceMap.containsKey(address)){
BluetoothGatt bluetoothGatt = connectedDeviceMap.get(address);
if( bluetoothGatt != null ){
bluetoothGatt.close();
bluetoothGatt = null;
}
connectedDeviceMap.remove(address);
}
// Broadcast if needed
}
}
Similarly onServicesDiscovered(BluetoothGatt gatt, int status)
method you have BluetoothGatt
connection object on parameter and you can get device from that BluetoothGatt
. And other callback method like public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
you will get the device form gatt
.
When you need to writeCharacteristic or writeDescriptor, get BluetoothGatt
object from Map
and use that BluetoothGatt
object to call gatt.writeCharacteristic(characteristic)
gatt.writeDescriptor(descriptor)
for different connection.
Do I need a separate thread for each connection?
I think you don't need to use separate Thread for each connection. Just run the Service
on a Background Thread.
Hope this help you.