Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android BLE multiple connections

I am trying to create an application that connects and receives notifications from multiple bluetooth low energy devices. I am wondering how this can be achieved. Do I need a separate thread for each connection? How can I make sure the services get discovered and notifications get set in an order that works given the asynchronous nature of the API. I am currently using the same structure provided here: https://developer.android.com/guide/topics/connectivity/bluetooth-le.html. This is setup for a single connection only. Would I be able to keep this structure i.e. extending the Service class in the BluetoothLeService class and binding to the service. I have recently discovered that The Service class is a singleton so how would I go about creating different instances of my BluetootLeService class and receiving broadcast and registering the Broadcast Receiver/Receivers to handle changes from the appropriate devices.

like image 437
IceManStan Avatar asked Nov 21 '17 01:11

IceManStan


People also ask

Is it possible to connect to multiple BLE devices on Android?

Have a look at this question regarding multiple BLE connections on Android. YES, it is possible to connect from one application to multiple BLE devices

How does a BLE device connect to the device?

If Bluetooth is available, the device will scan for nearby BLE devices. Once a device is found, the capabilities of the BLE device are discovered by connecting to the GATT server on the BLE device. Once a connection is made, data can be transferred with the connected device based on the available services and characteristics.

How many devices can connect to BLE central mode at once?

As what I learnt from BLE4.x protocol SPEC, when the iPhone/Android phone play as role of BLE central mode, the limitation to have active connection at the same time is up to 8 devices. But from what we observed, iPhone 8 can connect and collect data from our module up to 10 units at the same time!

How many Bluetooth devices can I connect to my Android device?

Most Android devices can connect to two or five Bluetooth devices simultaneously, while others support up to seven devices. The number of supported connections depends on the Bluetooth module your device is equipped with. Obviously, the newer the hardware, the more Bluetooth devices you can connect to.


1 Answers

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.

like image 83
Abu Yousuf Avatar answered Sep 27 '22 17:09

Abu Yousuf