gpt4 book ai didi

rxandroidble - 如何在 RxAndroidBle 中接收所有通知

转载 作者:行者123 更新时间:2023-12-01 00:24:19 27 4
gpt4 key购买 nike

我正在尝试使用在 Android 手机和使用 Android Things 的 Raspberry Pi 上运行的 rxBleAndroid 与 BLE 数据记录器/传感器进行通信。

但是,我目前遇到了一个问题,我的应用程序从未收到最多大约 5 个通知。

我已经验证 BLE 设备实际上已成功发送所有预期的通知。我已经通过 nRF Connect 应用程序做到了这一点,一切都按预期进行。

当我通过 nRF Connect 应用程序执行此操作时,这些是我采取的步骤:

  • 写入密码特征以解锁设备
  • 写入模式特性以将设备置于正确模式
  • 订阅通知(通知立即开始工作)

  • 通过 RxAndroidBle 执行此操作时,我怀疑可能是 .subscribe() 设置得不够快。

    有没有办法做setupNotification(),然后编写特征来告诉设备开始发送通知?

    这是我当前的代码:
    rxBleClient = RxBleClient.create(this);
    RxBleDevice device = rxBleClient.getBleDevice(mac_address);

    device.establishConnection(false)
    .flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(pword_uuid, pword)
    .flatMap(ignored1 -> rxBleConnection.writeCharacteristic(mode_uuid, mode))
    .flatMap(ignored2 -> rxBleConnection.setupNotification(log_uuid))
    )
    .flatMap(notificationObservable -> notificationObservable)
    .subscribe(
    bytes -> {
    System.out.println(">>> data from device " + bytesToHex(bytes));
    },
    throwable -> {
    System.out.println("error");
    System.out.println(throwable);
    });

    最佳答案

    可以通过 BLE 执行的大多数操作都是异步的,需要一些时间才能完成。设置通知也不异常(exception)——它是一个两步程序:

  • 设置本地通知
  • 编写一个客户端特征配置描述符,描述想要从
  • 获得通知的特征。

    如果您的外围设备在通知准备好被中央设备接收之前首先设置为发送通知,那么在通知设置过程中某些数据可能会丢失。

    Is there maybe some way to do setupNotification(), and then write the characteristics to tell the device to start sending notifications?



    当然(这是处理类似场景的通常方式)——有多种可能的实现方式。其中之一可能如下所示:
    device.establishConnection(false) // establish the connection
    .flatMap(rxBleConnection -> rxBleConnection.setupNotification(log_uuid) // once the connection is available setup the notification
    .flatMap(logDataObservable -> Observable.merge( // when the notification is setup start doing three things at once
    rxBleConnection.writeCharacteristic(pword_uuid, pword).ignoreElements(), // writing the `pword` but ignore the result so the output of this .merge() will contain only log data
    rxBleConnection.writeCharacteristic(mode_uuid, mode).ignoreElements(), // same as the line above but for `mode`
    logDataObservable // observing the log data notifications
    ))
    )
    .subscribe(
    bytes -> System.out.println(">>> data from device " + bytesToHex(bytes)),
    throwable -> {
    System.out.println("error");
    System.out.println(throwable);
    }
    );

    编辑:

    正如在下面的评论中提到的那样 - 在设置模式和写入密码之前,外设不允许任何 BLE 交互。正如我在上面写的那样,设置通知是一个两步程序,一个本地步骤和一个远程(在外围设备上执行)一个在上面的代码片段中的模式/密码之前执行。可以使用 NotificationSetupMode.COMPAT 将这两个步骤分开。模式并写入 Client Characteristic Configuration Descriptor稍后手动:
    UUID clientCharacteristicConfigDescriptorUuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
    device.establishConnection(false) // establish the connection
    .flatMap(
    RxBleConnection::discoverServices, // once the connection is available discover the services of the peripheral
    (rxBleConnection, rxBleDeviceServices) -> // and when we have the connection and services
    rxBleDeviceServices.getCharacteristic(log_uuid) // we get the log characteristic (on which we will setup the notification and write the descriptor)
    .flatMap(logDataCharacteristic -> // once the log characteristic is retrieved
    rxBleConnection.setupNotification(logDataCharacteristic, NotificationSetupMode.COMPAT) // we setup the notification on it in the COMPAT mode (without writing the CCC descriptor)
    .flatMap(logDataObservable -> Observable.merge( // when the notification is setup start doing four things at once
    rxBleConnection.writeCharacteristic(pword_uuid, pword).ignoreElements(), // writing the `pword` but ignore the result so the output of this .merge() will contain only log data
    rxBleConnection.writeCharacteristic(mode_uuid, mode).ignoreElements(), // same as the line above but for `mode`
    rxBleConnection.writeDescriptor(logDataCharacteristic.getDescriptor(clientCharacteristicConfigDescriptorUuid), BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE).ignoreElements(), // and we write the CCC descriptor manually
    logDataObservable // observing the log data notifications
    ))
    )
    )
    .flatMap(observable -> observable) // flatMap to get the raw byte[]
    .subscribe(
    bytes -> System.out.println(">>> data from device " + bytesToHex(bytes)),
    throwable -> {
    System.out.println("error");
    System.out.println(throwable);
    }
    );
    rxBleConnection.discoverServices()如果我们知道日志特征服务 UUID 可以省略调用并使用 rxBleConnection.writeDescriptor(UUID serviceUuid, UUID characteristicUuid, UUID descriptorUuid功能。
    UUID clientCharacteristicConfigDescriptorUuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
    device.establishConnection(false) // establish the connection
    .flatMap(rxBleConnection -> rxBleConnection.setupNotification(log_uuid, NotificationSetupMode.COMPAT) // once the connection is available setup the notification w/o setting Client Characteristic Config Descriptor
    .flatMap(logDataObservable -> Observable.merge( // when the notification is setup start doing three things at once
    rxBleConnection.writeCharacteristic(pword_uuid, pword).ignoreElements(), // writing the `pword` but ignore the result so the output of this .merge() will contain only log data
    rxBleConnection.writeCharacteristic(mode_uuid, mode).ignoreElements(), // same as the line above but for `mode`
    rxBleConnection.writeDescriptor(log_service_uuid, log_uuid, clientCharacteristicConfigDescriptorUuid).ignoreElements(), // same as the above line but for writing the CCC descriptor
    logDataObservable // observing the log data notifications
    ))
    )
    .subscribe(
    bytes -> System.out.println(">>> data from device " + bytesToHex(bytes)),
    throwable -> {
    System.out.println("error");
    System.out.println(throwable);
    }
    );

    编辑2:

    自版本 1.8.0有一个新的 NotificationSetupMode.QUICK_SETUP它首先打开内部通知,然后写入 CCC 描述符值。
    rxBleConnection.setupNotification(log_uuid, NotificationSetupMode.QUICK_SETUP)

    优点:
  • Observable<byte[]>在写入描述符之前发出,允许从头开始观察通知(如果开始写入描述符)

  • 缺点:
  • 无法确定描述符何时被写入。
  • 关于rxandroidble - 如何在 RxAndroidBle 中接收所有通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46192575/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com