Android how to read multiple BLE characteristics with a PriorityQueue

穿精又带淫゛_ 提交于 2019-11-30 07:15:56

To anyone who might encounter the same problem, here is an easy solution using a List<> of characteristics.

public static final BluetoothGattCallback readGattCallback = new BluetoothGattCallback() {

    List<BluetoothGattCharacteristic> chars = new ArrayList<>();

    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

        if (newState == BluetoothProfile.STATE_CONNECTED) {
            Log.v(TAG, "Connected!");
            broadcastingInterval = 999;
            transmissionPower = 999;
            gatt.discoverServices();
        }
        if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            Log.v(TAG, "Disconnected...");

        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {

        List<BluetoothGattService> services = gatt.getServices();
        BluetoothGattService rightService = null;

        for (int i = 0; i < services.size(); i++) {
            if (services.get(i).getCharacteristics().size() > 8) {
                rightService = services.get(i);
            }
        }

        chars.add(rightService.getCharacteristics().get(4));
        chars.add(rightService.getCharacteristics().get(6));

        requestCharacteristics(gatt);

    }

    public void requestCharacteristics(BluetoothGatt gatt) {
        gatt.readCharacteristic(chars.get(chars.size()-1));
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        if (status == 0) {

            if (characteristic.getUuid().toString().substring(7, 8).equals("5")) {
                transmissionPower = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
                Log.v(TAG, "tPOWER READ");

            } else if (characteristic.getUuid().toString().substring(7,8).equals("7")) {
                broadcastingInterval = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
                Log.v(TAG, "INTERVAL READ");
            }

            chars.remove(chars.get(chars.size() - 1));

            if (chars.size() > 0) {
                requestCharacteristics(gatt);
            } else {
                gatt.disconnect();
            }
        }
    }

};
  1. Create a list of characteristics
  2. In onServicesDiscovered populate the list with characteristics you want to read/write
  3. Create a new method called requestCharacteristics(gatt) and pass the gatt object to it. Call this method from onServicesDiscovered after adding characteristics to the list.
  4. In requestCharacteristics() method call gatt.readCharacteristic(chars.get(chars.size()-1));
  5. In onCharacteristicRead check if size of your list is not zero, then read your characteristic, remove the last item of your list and call requestCharacteristic() again.
  6. That's all

Thanks a lot for your post, Robert K. I wanted my app to read all the characteristic values by itself and show the characteristic value in the ExpandableList instead of the UUID. Robert K's code worked for me but I have experienced an offset of the values that were being displayed. So I made some slight changes and want to share it: 1.

  1. This is how I modified onServicesDiscovered and OnCharacteristicRead:

        public List<BluetoothGattCharacteristic> chars = new ArrayList<>();
    
    public void requestCharacteristics(BluetoothGatt gatt) {
            gatt.readCharacteristic(chars.get(chars.size() - 1));
    }
    
    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
    
            List<BluetoothGattService> services = gatt.getServices();
            for(BluetoothGattService service:services){
                chars.addAll(service.getCharacteristics());
            }
            requestCharacteristics(gatt);
        } else {
            Log.w(TAG, "onServicesDiscovered received: " + status);
        }
    }
    
    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            chars.remove(chars.get(chars.size() - 1));
            if (chars.size() > 0) {
                requestCharacteristics(gatt);
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            } else {
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
                broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
            }
        }
    }
    
  2. the introduced List of characteristics is emptied after each disconnection.

  3. I introduced a list to save the characteristic values and an integer showing which index I am at (these need to be emptied / set to zero after each disconnection). I modified the displayData method, which is called after each characteristicRead:

public

public List<String> mCharValues = new ArrayList<>();
public int idx_charValues = 0;
private void displayData(String data) {
    if (data != null) { mCharValues.add(0, data); }
    else { mCharValues.add(0, "no Data"); }
}
  1. I want the characteristic values to be displayed on the ExpandableList as soon as services are discovered. The method displayGattServices fills the ExpandableList with the services' and characteristics' names and UUIDs.

Instead of filling the UUID, I fill the corresponding element of mCharValues

currentCharaData.put(LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
currentCharaData.put(LIST_UUID, mCharValues.get(idx_charValues));
idx_charValues = idx_charValues+1;
gattCharacteristicGroupData.add(currentCharaData);
  1. Finally, I commented out the content of the ExpandableListView.OnChildClickListener. Apart from what I introduced here I left the rest of the code pretty much the same.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!