Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
405 views
Welcome To Ask or Share your Answers For Others

1 Answer

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...