BluetoothGattCallBack 函数 onCharacteristicRead 仅调用一次

BluetoothGattCallBack function onCharacteristicRead called only once

我正在尝试开发一个 BT 应用程序以连接到 BLE 设备并从中读取一些数据。 对于设备信息部分,我循环遍历设备的所有特征,读取特征并从 BluetoothGattCallback 的 onCharacteristicRead 方法收集返回的数据。

问题是对于循环,onCharacteristicRead 方法只被调用一次。请参考下面的代码和logcat。

 @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            String value = characteristic.getStringValue(0);
            Log.e("TAG", "onCharacteristicRead: " + value + " UUID " + characteristic.getUuid().toString() );

        }

特征循环为

private void getDeviceInformation() {
    BluetoothGattService deviceInfoService = bluetoothGatt.getService(UUIDs.DEVICE_INFORMATION_SERVICE);
    BluetoothGattCharacteristic deviceSerialNumber, deviceHardwareRevision, deviceSoftwareRevision;


    for (BluetoothGattCharacteristic characteristic : bluetoothGatt.getService(UUIDs.DEVICE_INFORMATION_SERVICE).getCharacteristics()) {
        bluetoothGatt.setCharacteristicNotification(characteristic, true);
        bluetoothGatt.readCharacteristic(characteristic);
    }
}

Logcat -

D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a25-0000-1000-8000-00805f9b34fb enable: true
D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a27-0000-1000-8000-00805f9b34fb enable: true
D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a28-0000-1000-8000-00805f9b34fb enable: true
D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a23-0000-1000-8000-00805f9b34fb enable: true
D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a50-0000-1000-8000-00805f9b34fb enable: true
W/BluetoothGatt: onCharacteristicRead() - Device=F6:8B:C2:F3:EB:EE handle=14 Status=0
E/TAG: onCharacteristicRead: 86a691595263 UUID 00002a25-0000-1000-8000-00805f9b34fb

您应该同步进行所有操作。所以之后:

bluetoothGatt.readCharacteristic(characteristic);

你应该等待回调

public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)

所以如果你想做你描述的事情,就做这样的事情:

List<BluetoothGattCharacteristic> characteristics = new ArrayList<>();
boolean isGettingDeviceInformation;
int count = 0;

@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    String value = characteristic.getStringValue(0);
    Log.e("TAG", "onCharacteristicRead: " + value + " UUID " + characteristic.getUuid().toString() );
    if(isGettingDeviceInformation) {
        if(count < characteristics.size()) {
            count++;
            bluetoothGatt.setCharacteristicNotification(characteristics.get(count), true);
            bluetoothGatt.readCharacteristic(characteristics.get(count));
        } else {
            isGettingDeviceInformation = false;
        }
    }
}

private void getDeviceInformation() {
    BluetoothGattService deviceInfoService = bluetoothGatt.getService(UUIDs.DEVICE_INFORMATION_SERVICE);
    BluetoothGattCharacteristic deviceSerialNumber, deviceHardwareRevision, deviceSoftwareRevision;
    characteristics = bluetoothGatt.getService(UUIDs.DEVICE_INFORMATION_SERVICE).getCharacteristics();
    bluetoothGatt.setCharacteristicNotification(characteristics.get(count), true);
    bluetoothGatt.readCharacteristic(characteristics.get(count));
}

更新

不要忘记在蓝牙中你的操作可以消失,所以你可以循环堆栈,等待回调。所以为了避免它,你需要让操作超时,所以如果没有得到回调,你就取消当前操作,然后继续。