Android蓝牙LE - BluetoothGatt - onNotify停止接收数据

Phi*_* E. 5 android bluetooth bluetooth-lowenergy android-bluetooth

我正在连接蓝牙LE外设作为中心.我正在将数据写入特征,并通过20个字节的块中的通知接收数据.

通知订阅:

private void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w("BluetoothAdapter not initialized");
        return;
    }

    Log.d("Enabling Notifications");

    mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

    BluetoothGattDescriptor descriptor =
            characteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));

    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);

    mBluetoothGatt.writeDescriptor(descriptor);
}
Run Code Online (Sandbox Code Playgroud)

如果在写入之间只需要接收少量块,则这可以正常工作.蓝牙堆栈为每个块发送通知:

D/BluetoothGatt? onNotify() - Device=B0:EC:8F:00:07:AA UUID=06d1e5e7-79ad-4a71-8faa-373789f7d93c
Run Code Online (Sandbox Code Playgroud)

但是如果写入之间的块数大于10,则堆栈会停止通知,其余数据将丢失!该设备肯定会发送更多数据,因为我们可以在iOS设备上接收它.

收到的通知数量因Android设备而异.Galaxy S3(4.3)接收5,nexus 5(4.4.4)和htc one(4.4.2)接收12.

BT堆栈在最后一次通知后30秒关闭连接.

D/BluetoothGatt? onClientConnectionState() - status=0 clientIf=5 device=B0:EC:8F:00:00:88
Run Code Online (Sandbox Code Playgroud)

任何人都能重现这个问题吗?

由于蓝牙LE堆栈是基于轮询的,我想堆栈由于某种原因停止从外围设备轮询数据.目标设备不支持指示.

更新:Android L蓝牙堆栈提供的其他信息:

06-27 12:20:02.982 18909-18946/? D/BtGatt.GattService? onNotify() - address=B0:EC:8F:00:01:09, charUuid=06d1e5e7-79ad-4a71-8faa-373789f7d93c, length=20
Run Code Online (Sandbox Code Playgroud)

06-27 12:20:07.666 18909-18984 /?E/BTLD:############################################### ######################## 06-27 12:20:07.666 18909-18984 /?E/BTLD:#06-27 12:20:07.666 18909-18984 /?E/BTLD:#警告:BTU HCI(id = 0)命令超时.操作码= 0xfd55 06-27 12:20:07.666 18909-18984 /?E/BTLD:#06-27 12:20:07.666 18909-18984 /?E/BTLD:############################################### ######################## 06-27 12:20:07.670 18909-18984 /?E/bt-btm:无法解释IRK VSC cmpl回调06-27 12:20:07.670 18909-18984 /?W/bt-hci:HCI Cmd超时计数器1 06-27 12:20:34.315 18909-18984 /?E/bt-btm:btm_sec_disconnected - 清除待处理标志

小智 1

也许不是一个理想的解决方案,但我已经接受通知根本不起作用或停止工作作为在 Android 上执行 BLE 的不幸现实。考虑到这一点,我相信最好是通过在正常通知被破坏时进行读取轮询来设置自己的“伪通知”备份机制。例如,Handler#postDelayed()每秒循环一次。您甚至可以将其抽象到一个单独的类后面,该类存储最后读取的值,并且仅在最后读取的值不等于新值时通知您的 UI。