Kotlin BlegatCharacteristicException:试图指示->;时的GATT异常状态129;写入->;通知BLE血糖仪
我正在尝试使用rxAndroidBle库读取血糖仪中存储的所有记录。根据我发现的一些资源,配对/连接和连接到设备后,该过程包括三个主要步骤:Kotlin BlegatCharacteristicException:试图指示->;时的GATT异常状态129;写入->;通知BLE血糖仪,kotlin,rx-java2,rxandroidble,Kotlin,Rx Java2,Rxandroidble,我正在尝试使用rxAndroidBle库读取血糖仪中存储的所有记录。根据我发现的一些资源,配对/连接和连接到设备后,该过程包括三个主要步骤: 记录访问控制点特性(RACP)中的设置指示 关于葡萄糖测量特性的设置通知 在RACP特征上写入两个字节0x01、0x01 然后,如果有任何记录,通知应该是流动的 现在,这个流程在装有安卓7.0的LG G5上运行得很好,但在我能访问的其他手机上就不行了。它将抛出一个可怕的关贸总协定内部错误(状态129),这有点模棱两可。我发现它描述了我可能面临的情况 我担心
fun loadRecords(rxBleDevice: RxBleDevice){
...
...
rxBleDevice.establishConnection(false)
.flatMap { rxBleConnection: RxBleConnection ->
rxBleConnection.setupIndication(racpUUID)
.flatMapSingle {
Single.just(rxBleConnection)
}
}
.flatMap { rxBleConnection ->
writeAndReadOnNotification(racpUUID,
glucoseUUID,
byteArrayOf(0x01, 0x01),
false,
rxBleConnection)
}
.subscribe(
{ it:ByteArray ->
decodeReading(it)
},Logger::logException)
}
private fun writeAndReadOnNotification(writeTo: UUID, readOn: UUID,
bytes: ByteArray,
isIndication: Boolean,
rxBleConnection:RxBleConnection)
: Observable<ByteArray> {
val notifObservable = if (isIndication)
rxBleConnection.setupIndication(readOn)
else
rxBleConnection.setupNotification(readOn)
return notifObservable.flatMap { notificationObservable ->
Observable.combineLatest(
notificationObservable,
rxBleConnection.writeCharacteristic(writeTo, bytes).toObservable(),
BiFunction { readBytes: ByteArray, writeBytes: ByteArray -> readBytes })
}
}
fun loadRecords(rxBleDevice: RxBleDevice){
...
//Do stuff
...
rxBleDevice.establishConnection(false)
.flatMap { rxBleConnection: RxBleConnection ->
rxBleConnection.setupNotification(glucoseUUID,
NotificationSetupMode.QUICK_SETUP)
.flatMapSingle {
Single.just(Pair(it, rxBleConnection))
}
}
.flatMap { (observable, rxBleConnection) ->
writeAndReadOnNotification(racpUUID,
racpUUID,
byteArrayOf(0x01, 0x01),
true,
rxBleConnection).subscribe()
observable
}
.subscribe(
{
decodeReading(it)
},Logger::logException)
}
我的代码中有什么遗漏吗?为什么它能在一些手机上工作?我自己设法解决了这个问题。通过查看我之前发布的日志,我发现在设置指示和通知之后,指示和通知都被禁用,因此我对库进行了深入的探索,以了解它为什么这样做。我发现,在以任何特征设置通知之前,都不应该设置指示(即使它们是两个不同的特征)。因此,阅读本文的主要步骤应按以下顺序进行:
/*
*注意:由于特征的状态性质,如果在setupNotification()之前将setupIndication()设置为
*将不会设置通知,并将发出其他类型ReadySetException的BleCharacteristicNotification
*/
这导致我将通知部分移到指示部分之前。
下面是它现在的样子:
fun loadRecords(rxBleDevice: RxBleDevice){
...
...
rxBleDevice.establishConnection(false)
.flatMap { rxBleConnection: RxBleConnection ->
rxBleConnection.setupIndication(racpUUID)
.flatMapSingle {
Single.just(rxBleConnection)
}
}
.flatMap { rxBleConnection ->
writeAndReadOnNotification(racpUUID,
glucoseUUID,
byteArrayOf(0x01, 0x01),
false,
rxBleConnection)
}
.subscribe(
{ it:ByteArray ->
decodeReading(it)
},Logger::logException)
}
private fun writeAndReadOnNotification(writeTo: UUID, readOn: UUID,
bytes: ByteArray,
isIndication: Boolean,
rxBleConnection:RxBleConnection)
: Observable<ByteArray> {
val notifObservable = if (isIndication)
rxBleConnection.setupIndication(readOn)
else
rxBleConnection.setupNotification(readOn)
return notifObservable.flatMap { notificationObservable ->
Observable.combineLatest(
notificationObservable,
rxBleConnection.writeCharacteristic(writeTo, bytes).toObservable(),
BiFunction { readBytes: ByteArray, writeBytes: ByteArray -> readBytes })
}
}
fun loadRecords(rxBleDevice: RxBleDevice){
...
//Do stuff
...
rxBleDevice.establishConnection(false)
.flatMap { rxBleConnection: RxBleConnection ->
rxBleConnection.setupNotification(glucoseUUID,
NotificationSetupMode.QUICK_SETUP)
.flatMapSingle {
Single.just(Pair(it, rxBleConnection))
}
}
.flatMap { (observable, rxBleConnection) ->
writeAndReadOnNotification(racpUUID,
racpUUID,
byteArrayOf(0x01, 0x01),
true,
rxBleConnection).subscribe()
observable
}
.subscribe(
{
decodeReading(it)
},Logger::logException)
}
我知道它看起来很难看,需要抛光。我自己解决了这个问题。通过查看我之前发布的日志,我发现在设置指示和通知之后,指示和通知都被禁用,因此我对库进行了深入的探索,以了解它为什么这样做。我发现,在以任何特征设置通知之前,都不应该设置指示(即使它们是两个不同的特征)。因此,阅读本文的主要步骤应按以下顺序进行:
/*
*注意:由于特征的状态性质,如果在setupNotification()之前将setupIndication()设置为
*将不会设置通知,并将发出其他类型ReadySetException的BleCharacteristicNotification
*/
这导致我将通知部分移到指示部分之前。
下面是它现在的样子:
fun loadRecords(rxBleDevice: RxBleDevice){
...
...
rxBleDevice.establishConnection(false)
.flatMap { rxBleConnection: RxBleConnection ->
rxBleConnection.setupIndication(racpUUID)
.flatMapSingle {
Single.just(rxBleConnection)
}
}
.flatMap { rxBleConnection ->
writeAndReadOnNotification(racpUUID,
glucoseUUID,
byteArrayOf(0x01, 0x01),
false,
rxBleConnection)
}
.subscribe(
{ it:ByteArray ->
decodeReading(it)
},Logger::logException)
}
private fun writeAndReadOnNotification(writeTo: UUID, readOn: UUID,
bytes: ByteArray,
isIndication: Boolean,
rxBleConnection:RxBleConnection)
: Observable<ByteArray> {
val notifObservable = if (isIndication)
rxBleConnection.setupIndication(readOn)
else
rxBleConnection.setupNotification(readOn)
return notifObservable.flatMap { notificationObservable ->
Observable.combineLatest(
notificationObservable,
rxBleConnection.writeCharacteristic(writeTo, bytes).toObservable(),
BiFunction { readBytes: ByteArray, writeBytes: ByteArray -> readBytes })
}
}
fun loadRecords(rxBleDevice: RxBleDevice){
...
//Do stuff
...
rxBleDevice.establishConnection(false)
.flatMap { rxBleConnection: RxBleConnection ->
rxBleConnection.setupNotification(glucoseUUID,
NotificationSetupMode.QUICK_SETUP)
.flatMapSingle {
Single.just(Pair(it, rxBleConnection))
}
}
.flatMap { (observable, rxBleConnection) ->
writeAndReadOnNotification(racpUUID,
racpUUID,
byteArrayOf(0x01, 0x01),
true,
rxBleConnection).subscribe()
observable
}
.subscribe(
{
decodeReading(it)
},Logger::logException)
}
我知道它看起来很丑,需要擦亮