我不太习惯使用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?
谢谢!
答案 0 :(得分:4)
使用BluetoothGatt.writeCharacteristic()
和相关BluetoothGatt
方法时,需要了解一些重要事项。
请注意writeCharacteristic()
(以及BluetoothGatt
的许多其他方法)返回布尔值。如果结果为false,则表示操作未成功启动。什么时候发生?请参阅下一个项目。
使用BluetoothGatt
对象,无法同时启动两个操作。启动第二个的调用将失败并返回false。在调用writeCharacteristic()
之后,代码必须等待回调响应(onCharacteristicWrite
)才能发出另一个写入。在此问题的示例代码中,对writeCharacteristic()
的第二次调用几乎肯定会因此而返回false。
通过这种方式,如果每个BluetoothGatt操作等待先前发出的命令的回调,您可以成功配对命令启动和回调 - 实际上您是被迫的。
答案 1 :(得分:0)
在此实现中,您应该在发出下一个写操作之前等待第一次写入后的onCharacteristicWrite
。但是,如果您没有使用默认setWriteType (int writeType)
中的WRITE_TYPE_DEFAULT
更改写入类型,则会执行此操作,后者会回写写入操作。您可能需要保留这些操作的状态。
另一种选择是在响应中使用命令代码(例如1个字节),以便将其映射到命令。
答案 2 :(得分:0)
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()
。
答案 3 :(得分:0)
正如我已经解释过的那样 here,当我开始“玩”GATT BLE 时,我会给出我想要的答案。
为了创建一种 API(带有参数的请求 => 响应,正如本问题标题中所说的那样),请按照下列步骤操作:
具体来说,如何使用 FreeRTOS 做到这一点?
按如下方式创建您的 GATT 服务:
static const BTAttribute_t pxAttributeTable[] =
{
{
.xServiceUUID =
{
.uu.uu128 = GATT_SERVICE_UUID,
.ucType = eBTuuidType128
}
},
{
.xAttributeType = eBTDbCharacteristic,
.xCharacteristic =
{
.xUuid =
{
.uu.uu128 = GATT_CHARACTERISTIC_REQUEST_UUID,
.ucType = eBTuuidType128
},
.xPermissions = (IOT_BLE_CHAR_WRITE_PERM),
.xProperties = (eBTPropWrite)
}
},
{
.xAttributeType = eBTDbCharacteristic,
.xCharacteristic =
{
.xUuid =
{
.uu.uu128 = GATT_CHARACTERISTIC_RESPONSE_UUID,
.ucType = eBTuuidType128
},
.xPermissions = (IOT_BLE_CHAR_READ_PERM),
.xProperties = (eBTPropRead | eBTPropNotify)
}
},
{
.xAttributeType = eBTDbDescriptor,
.xCharacteristicDescr =
{
.xUuid =
{
.uu.uu16 = 0x2902,
.ucType = eBTuuidType16
},
.xPermissions = (IOT_BLE_CHAR_READ_PERM | IOT_BLE_CHAR_WRITE_PERM)
}
}
};
答案 4 :(得分:-1)
一次不能调用两次写入。 应该有延迟。 更好的选择是与处理程序一起使用,对我来说它工作正常。
// 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);