接收有关Android中多个特征的通知

时间:2020-02-27 00:14:59

标签: android notifications bluetooth-lowenergy bluetooth-gatt characteristics

我想在Android应用程序中收到几个要通知的特征(全部在一项服务下)。当我为其中之一设置通知描述符时,它运行良好。我知道必须使用某种队列或延迟来接收多个通知,但是我不了解如何在我的代码中实现它。我也无法在此网站的Android文档中找到任何示例,否则将无法解释如何实现此示例。

这是我尝试创建的用于设置服务通知的代码:

@Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                for (BluetoothGattCharacteristic characteristic: gatt.getService(UUID.fromString("00001826-0000-1000-8000-00805f9b34fb")).getCharacteristics()) {
                    gatt.setCharacteristicNotification(characteristic, true);
                    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
                    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                    gatt.writeDescriptor(descriptor);
                }

            }
        }

这是我用于在应用程序中设置文本以匹配刚刚更改的特征的值的功能:

 @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            TextView instructionText = getView().findViewById(R.id.instructionText);
            if(showMeasurements) {
                instructionText.setText(characteristic.getStringValue(0));
            }
        }

我考虑尝试的另一种方法是创建列表List<BluetoothGattCharacteristic> chars = new ArrayList<>();并添加在此列表中找到的每个特征。然后,我可以尝试一个接一个地编写通知描述符,但是我似乎也无法实现。

我是一名大学生,不熟悉Android开发和此类功能。任何有关如何解决该问题的帮助将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:0)

由于this post,我能够将通知描述符异步地应用于我的每个特征。

尽管大多数代码是相同的,但仍需要进行一些细微的修改。出于这个原因,我想对代码中的内容进行更深入的说明,以便像我这样的未来新手开发人员可以利用它。

在我的gatCallback中,我创建了一个与我在问题中提到的清单类似的清单。我还定义了一些UUID,稍后将在我的代码中使用它们:

private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
        List<BluetoothGattCharacteristic> chars = new ArrayList<>();
        UUID pitchUUID = UUID.fromString("78c5307a-6715-4040-bd50-d64db33e2e9e");
        UUID rollUUID = UUID.fromString("78c5307b-6715-4040-bd50-d64db33e2e9e");

一旦我发现了服务,便会从我的特定服务中迭代所需的特性,然后将其添加到列表中。然后,我跳转到我创建的名为subscribeToCharacteristics的函数,并传入我的BluetoothGatt对象:

for (BluetoothGattCharacteristic characteristic: gatt.getService(UUID.fromString("00001826-0000-1000-8000-00805f9b34fb")).getCharacteristics()) {
                    chars.add(characteristic);
                }
                subscribeToCharacteristics(gatt);

在此功能中设置特征通知。我只在列表中有项目时才这样做。如果存在项目,则意味着仍然需要编写描述符!

private void subscribeToCharacteristics(BluetoothGatt gatt) {
            if(chars.size() == 0) return;
            BluetoothGattCharacteristic characteristic = chars.get(0);
            gatt.setCharacteristicNotification(characteristic, true);
            BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
            if(descriptor != null) {
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                gatt.writeDescriptor(descriptor);
            }
        }

当我覆盖onDescriptorWrite函数时,我只是删除列表中的第一个元素,然后再次调用subscribeToCharacteristics函数。

@Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            Log.i("DESCRIPTOR", "WROTE DESCRIPTOR FOR CHARACTERISTIC");
            super.onDescriptorWrite(gatt, descriptor, status);
            chars.remove(0);
            subscribeToCharacteristics(gatt);
        }

请注意,我没有使用GetCharacteristicsWithNotifications(gatt);,因为这不是标准功能,在另一篇文章中也没有很好地解释。

我也没有使用notifyCharacteristics.get(0);,因为以前没有对此进行解释或将其包含在帖子的代码中。

最后,我不使用characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);,因为我已经在Arduino代码中使用适当的属性定义了服务和特性。如果我不确定,则可以使用此代码。

我希望这个(详尽的)解释对任何未来的开发者都有价值!