为啥 onCharacteristicRead 读取设置为 readCharacteristic 的不同特征

Posted

技术标签:

【中文标题】为啥 onCharacteristicRead 读取设置为 readCharacteristic 的不同特征【英文标题】:Why does onCharacteristicRead read different characteristic that is set to readCharacteristic为什么 onCharacteristicRead 读取设置为 readCharacteristic 的不同特征 【发布时间】:2021-05-25 13:29:26 【问题描述】:

我是 Java 和 OOP 的新手。但是,我正在使用 notify 读取一个特征,然后使用 read 在回调中读取多个特征。

我想知道,为什么我在使用 readCharacteristic(my characteristic) 时只能从单个特征(除了通知的特征之外)获取值。蓝牙 gatt 回调声明如下:

公共布尔读取特性

(BluetoothGattCharacteristic特性) 从关联的远程设备读取请求的特征。

这是一个异步操作。读取操作的结果由 BluetoothGattCallback#onCharacteristicRead 回调报告。"

我为每个特征按顺序调用 readCharacteristic 并始终在请求执行 onCrahacteristicRead 回调的下一个特征之前等待。但在 onCrahacteristicRead 内部,最终被读取的特征每次都相同(不一定是我在 readCharacteristic 上请求的特征)。

我在某处读到我应该为特征制作优先队列。为什么是这样?为什么首先在 readCharacteristic 中有请求的特征输入,gatt 参考如何说明这一点。

谢谢

编辑

经过进一步测试,我现在认为这是由于某种原因而发生的

onCharacteristicRead()

回调在读取第一个请求(读取)特性后卡住,但通知特性继续触发,导致

onCharacteristicChanged 回调重启 -> 再次读取第一个特征并卡住 -> 新通知等等。

我在 onCharacteristicChanged 回调期间禁用了通知,导致程序在第一次读取后卡住

onCharacteristicRead()

所以程序永远不会离开 onCharacteristicRead() 回调。我尝试使用优先级队列,它最终读取了两个(读取)特征,但再次卡住并且永远不会离开 onCharacteristicRead 回调。令人沮丧。有什么想法吗?

【问题讨论】:

【参考方案1】:

我的简单方法是使用 CountDownLatch。我调用了一个值为 1 的 countdownlatch(倒计时)。然后我称之为读取特性。然后我等待倒计时(await() 方法)。在 BluetoothGattCallback onCharacteristicRead 中执行倒计时,等待函数将返回。然后你就可以阅读结果了。

一个接一个地完成这个特性。我发现在尝试再次读取之前,我必须等待回调发出信号。

类似这样的:

 countDownLatch = new CountDownLatch(1)
 BluetoothGatt.readCharacteristic(your characteristic)
 if (countDownLatch.await(3, TimeUnit.SECONDS))  this blocks for at least 3 seconds
    // if true no timeout
     the characteristic value now has the read value.

在回调中

 onCharacteristicRead()
 countDownLatch.count(); // Counts down 1 - this will cause the await method to return.

这只是记忆中的草图。显然,两个线程之间必须知道 CountDownLatch 对象。您将需要处理“await()”方法的中断异常。

【讨论】:

以上是关于为啥 onCharacteristicRead 读取设置为 readCharacteristic 的不同特征的主要内容,如果未能解决你的问题,请参考以下文章

Android BLE:onCharacteristicRead 仅在第一次工作

为啥这个 plist 读/写失败?

JasperReports xlsx 导出错误 - 内容不可读 - 为啥?

为啥使用 AWS DynamoDb“Hello world”会产生读/写警报?

为啥这样写还是读不出来500数值,芯片是 24c02?

为啥 NSObject 必须在其 .class-property 可读之前进行初始化