Android Bluetooth Low Energy获取特定请求的响应

时间:2015-06-24 11:17:01

标签: android bluetooth bluetooth-lowenergy gatt

我不太习惯使用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?

谢谢!

5 个答案:

答案 0 :(得分:4)

使用BluetoothGatt.writeCharacteristic()和相关BluetoothGatt方法时,需要了解一些重要事项。

  1. 请注意writeCharacteristic()(以及BluetoothGatt的许多其他方法)返回布尔值。如果结果为false,则表示操作未成功启动。什么时候发生?请参阅下一个项目。

  2. 使用BluetoothGatt对象,无法同时启动两个操作。启动第二个的调用将失败并返回false。在调用writeCharacteristic()之后,代码必须等待回调响应(onCharacteristicWrite)才能发出另一个写入。在此问题的示例代码中,对writeCharacteristic()的第二次调用几乎肯定会因此而返回false。

  3. 通过这种方式,如果每个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(带有参数的请求 => 响应,正如本问题标题中所说的那样),请按照下列步骤操作:

  • 使用以下命令创建 GATT 服务:
    • 一个写特性(不同于读特性,写一个接收数据)来管理请求(通过数据负载带参数)
    • 将响应作为通知管理的读取特性
    • 用于读取特性的客户端特性配置描述符以启用通知(标准 16 位 CCCD UUID:0x2902)。
  • 客户端写入客户端特征配置描述符以启用通知/指示(在 ble 连接后一次)
  • 客户端写请求特性(请求)
  • GATT 服务器发送响应“状态”OK 写入特性(请求)
  • GATT 服务器使用读取特性中的“数据”发送指示(不等待来自客户端的确认)

具体来说,如何使用 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);