Android BLE特性getValue在API级别33中被弃用,并且在developer.androidBluetoothGattCharacteristic中表示我们可以使用BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)代替
但正如我用代码检查的那样,developer.android也提到它返回一个布尔值,而不是byteArray BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)
什么是正确的方法可以得到这个值?
2条答案
按热度按时间bq3bfh9z1#
API〈= 32时:
每个
BluetoothGattCharacteristic
对象都包含一个value
字段,该字段由应用程序(写入时)和蓝牙堆栈(阅读/接收通知时)更改。要写入特征值,首先设置
value
字段(通过使用setValue
setter方法),然后通过调用writeCharacteristic
执行实际写入。要读取特征值,请调用
readCharacteristic
(这会触发对远程设备的读取请求),并在响应到达时调用的onCharacteristicRead
回调中,通过获取value
字段(通过调用getValue
getter方法)来检索值。当使用
onCharacteristicChanged
接收到通知或指示时,以与读取回调相同的方式检索值。请注意,
getValue
只是返回存储在BluetoothGattCharacteristic
对象的本地value
字段中的任何当前值。它不会触发对远程设备的新读取请求。通常,getValue
不应该被调用,除非在onCharacteristicChanged
或onCharacteristicRead
回调中立即调用。API〉= 33时:
新的API不使用任何
value
字段。相反,该值作为参数传递。要写入特征值,只需调用
writeCharacteristic
并将值作为参数传递。要读取特征值,首先调用
readCharacteristic
。当响应从远程设备到达时,onCharacteristicRead
回调将以刚刚读取的值作为参数进行调用。当使用
onCharacteristicChanged
接收到通知或指示时,该值将作为参数传递给该方法。新旧设备兼容应用:
请注意,为新API编译的代码在旧设备上运行时将无法正常工作。您会注意到,根本不会调用新的回调重载。你基本上有两个选择:
1.坚持使用旧的API,忽略新的API。只要这个旧的API没有被完全删除,代码就会像以前一样工作,即使在新的设备上也是如此。
1.实现两个API,* 不 * 调用
super.onCharacteristicChanged(...)
等。对于旧设备,将(仅)调用旧API方法,对于新设备,将(仅)调用新API方法。我建议你有身体onCharacteristicChanged(gatt, characteristic, characteristic.getValue());
等。在旧的回调API方法中,手动将数据传递给新的回调,并将所有逻辑放在新的回调API方法中。为什么更新此API?
请考虑您具有允许通知和写入的特性的情况。如果Android应用在通知到达的确切时间写入特征,则会存在关于特征对象的
value
字段的竞争条件,这意味着您可能会写入刚刚通知的值,或者被通知您即将写入的值。新的API通过直接将值作为参数传递来解决这个问题。ws51t4hk2#
仅调用
BluetoothGatt.readCharacteristic()
是不够的,您还必须在管理BLE事务的任何地方实现BluetoothGattCallback
接口,以便从远程BLE设备获取值。假设您在名为MyBluetoothManager的类中管理事务。
BluetoothGatt.readCharacteristic()
函数不会立即返回值,而是启动蓝牙读取事务,远程设备将在稍后进行异步响应。它的工作原理类似于互联网连接,您向服务器发出请求以获取一些数据,然后服务器稍后异步响应,最后您在其响应回调中处理数据。调用
readCharacteristic
方法时返回的值是一个指示读取操作是否成功启动的值。编辑新增了
onCharacteristicRead
两种方法,支持API 33以下和API 33+。下面是MyBluetoothManager最小代码示例:
下面是一个从Activity调用
MyBluetoothManager.readCharacteristic
方法的示例: