使用gatt与ble设备进行通信时,我有点不太喜欢。根据这个:https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback)
BluetoothGatt gatt = device.connectGatt(context,true,new BluetoothGattCallback(){....})
我可以连接到ble设备并给它一个回调对象,以便在onCharacteristicRead和onCharacteristicWrite等内容上得到通知
我没有得到的是哪个写对应哪个读回调?
这种方法的签名是:
public void onCharacteristicRead (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
public void onCharacteristicWrite (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
所以,如果我这样做:
BluetoothGattCharacteristic char = gatt.getService(UART_SERVICE_UUID).getCharacteristic(UART_TX_CHARACTERISTIC_UUID);
char1.setValue("command1");
gatt.writeCharacteristic(char);
char1.setValue("command2");
gatt.writeCharacteristic(char);
在onCharacteristicRead回调中,我怎么知道characteristic.getStringValue()是用于command1还是command2?
谢谢!
使用BluetoothGatt.writeCharacteristic()
和相关的BluetoothGatt
方法时,有几个重要的事情需要了解。
writeCharacteristic()
(以及BluetoothGatt
的许多其他方法)返回一个布尔值。如果结果为false,则表示操作未成功启动。什么时候发生?请参阅下一个项目。BluetoothGatt
对象,无法同时启动两个操作。启动第二个的调用将失败并返回false。在调用writeCharacteristic()
之后,代码必须等待回调响应(onCharacteristicWrite
)才能发出另一个写入。在这个问题的示例代码中,第二次调用writeCharacteristic()
几乎肯定会因此而返回false。这样,如果每个BluetoothGatt操作等待先前发出的命令的回调,您可以成功配对命令启动和回调 - 实际上您是被迫的。
在此实现中,您应该在第一次写入之后等待onCharacteristicWrite
,然后再发出下一个写操作。但是,如果您没有使用setWriteType (int writeType)
从默认的WRITE_TYPE_DEFAULT
更改写入类型,这会回调写操作。您可能需要为这些操作保持状态。
另一种选择是在响应中使用命令代码(例如1个字节),以便将其映射到命令。
private String heartRate;
private String temperature;
...
char.setValue("command1");
gatt.writeCharacteristic(char);
...
然后在onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
检查heartRate
变量是否为空。如果是,则获取特征的值并将其分配给heartRate
变量。然后做characteristic.setValue("command2");
gatt.writeCharacteristic(characteristic);
,它将再次打电话给onCharacteristicWrite(...)
。
如果heartRate
变量不为null,则获取该值并将其分配给温度变量。您还可以使用传递的特征的UUID来区分值的用途。
额外奖励:单个特征可以包含多个描述符。您可以拥有两个描述符,其中包含用于该特征的UUID。然后你可以打电话给characteristic.getDescriptor(UUIDDescriptor).getValue()
。
一次不能打两个写。应该有延迟。更好的选择是与处理程序,对我来说它工作正常。
// call 1st write here
char1.setValue("command1");
gatt.writeCharacteristic(char);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// call your 2nd write here
char1.setValue("command1");
gatt.writeCharacteristic(char1);
}
}, 2000);