标签: rxandroidble

RxAndroidBle保持持久连接+写入/通知处理

我正在构建一个对蓝牙低功耗有特定要求的Android应用程序.

我需要写一个只写特性并在单独的通知特性上接收响应,我需要在很多很多活动中完成它.是否有Rx方式在第一个特征上发送请求,等待第二个请求的答案,然后继续另一个请求?

另外,为了分享我的RxAndroidBle实例,我想做一些BleManager Singleton,我会公开Observables,所以我可以在我的Presenter中轻松订阅它们.我只是想避免为每个活动复制连接逻辑并且(理想情况下)具有持久连接.这样我只能公开connectionObservable并订阅它,所以我可以轻松发送Write Requests并获取Notifications,但我相信有更好的方法可以做到.

这就是我现在所拥有的:

@Singleton
public class BleManager {

  private PublishSubject<Void> disconnectTriggerSubject = PublishSubject.create();
  private Observable<RxBleConnection> connectionObservable;
  private boolean isConnected;

  private final UUID CTRL_FROM_BRIDGE_UUID = UUID.fromString("someUUID");
  private final UUID BLE_WRITE_CHARACTERISTIC_UUID = UUID.fromString("someOtherUUID");

  private final RxBleClient bleClient;
  private String mMacAddress;
  private final Context context;
  private RxBleDevice bleDevice;

  @Inject
  public BleManager(Context context, RxBleClient client) {
    Timber.d("Constructing BleManager and injecting members");
    this.context = context;
    this.bleClient = client;
  }

  public void setMacAddress(String mMacAddress) {
    this.mMacAddress = mMacAddress;

    // Set the associated device …
Run Code Online (Sandbox Code Playgroud)

android bluetooth-lowenergy rx-java rx-android rxandroidble

9
推荐指数
1
解决办法
3137
查看次数

Android BLE:“扫描失败,原因是应用程序注册UUID失败”

我正在使用该RxAndroidBle库开发一个应用程序,该库大约每30秒定期执行BLE扫描,每分钟左右执行一些BLE操作。几个小时后(通常在5到24小时之间),扫描将停止工作。每次应该开始扫描时,我都会得到:

09-05 09:08:37.160 8160-8160/myapp D/BluetoothAdapter: startLeScan(): null
09-05 09:08:37.165 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.165 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.165 8160-8160/myapp D/BluetoothLeScanner: Start Scan
09-05 09:08:37.165 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.165 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.170 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.170 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.210 8160-12850/myapp D/BluetoothLeScanner: onClientRegistered() - status=133 clientIf=0
09-05 09:08:37.210 8160-12850/myapp D/BluetoothLeScanner: Registration failed, unregister clientIf = 0
09-05 09:08:37.215 8160-8160/myapp D/BluetoothLeScanner: Scan failed, reason app registration failed for UUID = 4c321920-a2b7-449a-bc24-ea4361f7a255
09-05 09:08:44.150 8160-8160/myapp …
Run Code Online (Sandbox Code Playgroud)

android bluetooth bluetooth-lowenergy android-bluetooth rxandroidble

6
推荐指数
2
解决办法
3185
查看次数

读取和写入操作时,Rxble发生129错误和133错误

BleGattException - 在第一次读写操作期间发生,有时它读取和写入正确但在重新连接ble设备后得到此异常...

 if (bleManager.getMacAddress() != null && checkIsSameMac(peripheralModel.address) && bleManager.getConnectionSubscription() != null) {
        bleManager.getConnectionSubscription().flatMap(RxBleConnection::discoverServices)
                .observeOn(AndroidSchedulers.mainThread())
                .first() // Disconnect automatically after discovery
                .subscribe(swapScanResult -> {
                    Log.e("write and read", "discover success");
                    firstWriteCharacteristic(peripheralModel);
                }, this::onConnectionFailure);
Run Code Online (Sandbox Code Playgroud)

java android bluetooth-lowenergy rxandroidble

5
推荐指数
0
解决办法
222
查看次数

将timeout()与retryWhen()组合

我正在创建一个简单的应用程序,用于使用RxAndroidBle库与蓝牙设备进行连接(干得好!)。我有时遇到的情况是,当我连接到设备时,收到状态为133的Gatt错误。我知道它可能会发生,所以我想做的就是在发生该错误时重试所有内容。没问题,我可以使用retryWhen()运算符轻松地做到这一点,但是我还有另一个要求-如果连接失败,流必须在30秒后终止。我曾经timeout()这样做,但是问题是当我重试时,计时器再次启动。

因此,问题是如何将timeout()运算符与retryWhen()结合使用,以便我可以重试某些特定错误,但保持计数器继续运行。

我对合并可观察变量有一些想法,或者有一些单独的可观察变量,它们将在超时期限后检查连接状态,但是我想知道是否可以在单个可观察变量中进行此操作。

到目前为止,我的代码如下所示:

public Observable<ConnectingViewState> connectToDevice(String macAddress) {
        final RxBleDevice rxBleDevice = rxBleClient.getBleDevice(macAddress);
        return rxBleDevice.establishConnection(false)
                .subscribeOn(Schedulers.io())
                .map(rxBleConnection -> new ConnectingViewState.ConnectedViewState(rxBleConnection))
                .cast(ConnectingViewState.class)
                .timeout(40, TimeUnit.SECONDS)
                .startWith(new ConnectingViewState.ConnectingInProgressViewState())
                .retryWhen(errors -> errors.flatMap(error -> {
                            if (isDefaultGattError(error)) {
                                return Observable.just(new Object());
                            } else {
                                return Observable.error(error);
                            }
                        }
                ))
                .onErrorReturn(throwable -> new ConnectingViewState.ErrorState(throwable));
    }
Run Code Online (Sandbox Code Playgroud)

android rx-java rxandroidble

5
推荐指数
1
解决办法
1458
查看次数

BLE 通知订阅获得 133

一部 Android 手机 (N5X 6.0.1) 正在运行 BLE 服务器,另一部 (N5X O) 正在订阅。可以启用特征通知,但是,在写入描述符部分,我始终得到 133。

Server.java

private void createServer() {
    bluetoothGattServer = bluetoothManager.openGattServer(this, serverCallback);
    BluetoothGattService service = new BluetoothGattService(Constants.SERVICE,
        BluetoothGattService.SERVICE_TYPE_PRIMARY);

    characteristic =
        new BluetoothGattCharacteristic(Constants.CHARACTERISTIC,
                BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);

    // public static UUID DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
    characteristic.addDescriptor(new BluetoothGattDescriptor(Constants.DESCRIPTOR,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE));

    characteristic.setWriteType(
        BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);

    service.addCharacteristic(characteristic);
    bluetoothGattServer.addService(service);
}

private BluetoothGattServerCallback serverCallback = new BluetoothGattServerCallback() {
    @Override
    public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
        super.onConnectionStateChange(device, status, newState);
        Log.d(TAG, "onConnectionStateChange " + device.getName() + " " …
Run Code Online (Sandbox Code Playgroud)

android bluetooth-lowenergy rxandroidble

5
推荐指数
1
解决办法
897
查看次数

如何在 RxAndroidBle 中接收所有通知

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

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

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

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

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

通过 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);
                });
Run Code Online (Sandbox Code Playgroud)

rxandroidble

5
推荐指数
1
解决办法
1407
查看次数

如何正确使用UUID.fromString方法?

我正在尝试读/写这些特征:

在此输入图像描述

现在,我正在尝试阅读AA01*

我正在使用这个库来做到这一点.

这是我的代码:

private void connectToSensorTag(RxBleDevice rxBleDevice) {
    rxBleDevice.establishConnection(getApplicationContext(), false)
            .doOnError(new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    int i = 0;
                }
            })
            .flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(UUID.fromString("AA01*")))
            .subscribe(new Subscriber<byte[]>() {
                @Override
                public void onCompleted() {
                    int i = 0;
                }

                @Override
                public void onError(Throwable e) {
                    int i = 0;
                }

                @Override
                public void onNext(byte[] bytes) {
                    int i = 0;
                }
            });
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

java.lang.IllegalArgumentException:无效的UUID:AA01*

我也尝试过这个类似问题的解决方案,但没有任何效果.同样的错误.

java android bluetooth-lowenergy android-ble rxandroidble

2
推荐指数
1
解决办法
4885
查看次数

RxAndroidBle:定期广告扫描

我需要ble在未连接到我的设备时永久扫描广告以找到它并知道何时连接到它(特定产品)。此扫描在前台服务中实现以匹配 8.0 先决条件。

为了节省一些电池,我想定期扫描(同时尊重 Android 7 的启动量/时间限制)。我看到 2 个不同的实现:

  • 每 X 秒开始扫描,Y 秒后可以停止,等待时间为 XY。

    ?? ?? ?? ?? ?? 扫描???? ?? ?? ?? ?? 等待???? ?? ?? ?? ??扫描???? ?? ?? ?? ?? 等待
    |--------------|------|--------------|------|---
    | ---------X-------->|---------X-------->|---
    |------你----->?? ?? ?? ?? ?? ?? ?? ?? |-----Y----->?? ?? ?? ?? ?? ?? ?? ?? |---


  • 开始扫描 X 秒,等待 Y 秒,开始扫描 X 秒等等。

    ?? ?? ?? ?? ?? 扫描???? ?? ?? ?? ?? 等待???? ?? ?? ?? ??扫描???? ?? ?? …

android bluetooth-lowenergy android-bluetooth rxandroidble

1
推荐指数
1
解决办法
1136
查看次数

使用库RxAndroidBle从Android设备读取多个特征

我正在使用RxAndroidBle库来扫描设备,然后连接到一个特定的设备并读取4 GATT特征。

我可以通过以下代码读取一个特性(电池电量):

scanSubscription = rxBleClient.scanBleDevices(
            new ScanSettings.Builder()
                    .build()
    )
            .observeOn(AndroidSchedulers.mainThread())
            .doOnNext(
                    scanResult -> {
                        if(scanResult.getBleDevice().getName() != null){
                            if(scanResult.getBleDevice().getName().equals("NODE 1")){
                                Log.e("BLE SCAN", "SUCCESS");
                                Log.e("BLE SCAN", scanResult.getBleDevice().getName());
                                Log.e("BLE SCAN", scanResult.getBleDevice().getMacAddress());
                                scanSubscription.unsubscribe();

                                RxBleDevice device = scanResult.getBleDevice();
                                subscription = device.establishConnection(false) // <-- autoConnect flag
                                        .flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb")))
                                        .subscribe(
                                                characteristicValue -> {
                                                    Log.e("Characteristic", characteristicValue[0]+"");
                                                },
                                                throwable -> {
                                                    Log.e("Error", throwable.getMessage());
                                                }
                                        );
                            }
                        }
                    }
            )
            .subscribe();
Run Code Online (Sandbox Code Playgroud)

我可以使用来阅读两个:

.flatMap(rxBleConnection -> Observable.combineLatest( // use the same connection and combine latest emissions
                rxBleConnection.readCharacteristic(aUUID),
                rxBleConnection.readCharacteristic(bUUID),
                Pair::new
        )) …
Run Code Online (Sandbox Code Playgroud)

bluetooth-lowenergy android-bluetooth rxandroidble

0
推荐指数
1
解决办法
657
查看次数