Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用RxAndroidBLE从GATT服务器读取BLE GATT字符块_Android_Bluetooth Lowenergy_Rx Java_Rxandroidble_Bluetooth Gatt - Fatal编程技术网

如何使用RxAndroidBLE从GATT服务器读取BLE GATT字符块

如何使用RxAndroidBLE从GATT服务器读取BLE GATT字符块,android,bluetooth-lowenergy,rx-java,rxandroidble,bluetooth-gatt,Android,Bluetooth Lowenergy,Rx Java,Rxandroidble,Bluetooth Gatt,我正在使用RxAndroidBle库处理从我的android GATT客户端应用程序到GATT服务器的BLE连接和读/写。我遵循了提供的示例应用程序 我面临的问题是,我的GATT服务器运行在Intel Edison上,它只支持80大小的MTU。它以块的形式发送数据,我应该多次读取字符值,直到遇到一个特殊字符,如“/END”。我尝试过自定义读取操作示例,该示例应该每250毫秒读取5次 private static class CustomReadOperation implements RxBle

我正在使用RxAndroidBle库处理从我的android GATT客户端应用程序到GATT服务器的BLE连接和读/写。我遵循了提供的示例应用程序

我面临的问题是,我的GATT服务器运行在Intel Edison上,它只支持80大小的MTU。它以块的形式发送数据,我应该多次读取字符值,直到遇到一个特殊字符,如“/END”。我尝试过自定义读取操作示例,该示例应该每250毫秒读取5次

private static class CustomReadOperation implements RxBleRadioOperationCustom<byte[]> {

    private RxBleConnection connection;
    private UUID characteristicUuid;

    CustomReadOperation(RxBleConnection connection, UUID characteristicUuid) {
        this.connection = connection;
        this.characteristicUuid = characteristicUuid;
    }

    /**
     * Reads a characteristic 5 times with a 250ms delay between each. This is easily achieve without
     * a custom operation. The gain here is that only one operation goes into the RxBleRadio queue
     * eliminating the overhead of going on & out of the operation queue.
     */
    @NonNull
    @Override
    public Observable<byte[]> asObservable(BluetoothGatt bluetoothGatt,
                                           RxBleGattCallback rxBleGattCallback,
                                           Scheduler scheduler) throws Throwable {
        return connection.getCharacteristic(characteristicUuid)
                .flatMap(characteristic -> readAndObserve(characteristic, bluetoothGatt, rxBleGattCallback))
                .subscribeOn(scheduler)
                .takeFirst(readResponseForMatchingCharacteristic())
                .map(byteAssociation -> byteAssociation.second)
                .repeatWhen(notificationHandler -> notificationHandler.take(5).delay(250, TimeUnit.MILLISECONDS));
    }

    @NonNull
    private Observable<ByteAssociation<UUID>> readAndObserve(BluetoothGattCharacteristic characteristic,
                                                             BluetoothGatt bluetoothGatt,
                                                             RxBleGattCallback rxBleGattCallback) {
        Observable<ByteAssociation<UUID>> onCharacteristicRead = rxBleGattCallback.getOnCharacteristicRead();

        return Observable.create(emitter -> {
            Subscription subscription = onCharacteristicRead.subscribe(emitter);
            emitter.setCancellation(subscription::unsubscribe);

            try {
                final boolean success = bluetoothGatt.readCharacteristic(characteristic);
                if (!success) {
                    throw new BleGattCannotStartException(bluetoothGatt, BleGattOperationType.CHARACTERISTIC_READ);
                }
            } catch (Throwable throwable) {
                emitter.onError(throwable);
            }
        }, Emitter.BackpressureMode.BUFFER);
    }

    private Func1<ByteAssociation<UUID>, Boolean> readResponseForMatchingCharacteristic() {
        return uuidByteAssociation -> uuidByteAssociation.first.equals(characteristicUuid);
    }
}
我没有使用此代码从服务器获取任何数据。 但是,如果我尝试像这样的简单读取操作

public void customRead()
{
    if (isConnected()) {
        connectionObservable
                .flatMap(rxBleConnection -> rxBleConnection.queue(new CustomReadOperation(rxBleConnection, UUID_READ_CHARACTERISTIC)))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(bytes -> {
                    configureMvpView.showList(bytes);
                }, this::onRunCustomFailure);
    }
}
public void readInfo() {

    if (isConnected()) {
        connectionObservable
                .flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(UUID_READ_CHARACTERISTIC))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(bytes -> {
                    // parse data
                    configureMvpView.showWifiList(bytes);

                }, this::onReadFailure);
    }

}
我得到第一块数据,但我需要读取其余数据。
我不是很精通RxJava。因此,可能有一个简单的方法来做到这一点,但任何建议或帮助都会很好

这是我的预备连接可观察

private Observable<RxBleConnection> prepareConnectionObservable() {
    return bleDevice
            .establishConnection(false)
            .takeUntil(disconnectTriggerSubject)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnUnsubscribe(this::clearSubscription)
            .compose(this.bindToLifecycle())
            .compose(new ConnectionSharingAdapter());


}

一旦收到连接,我就呼叫CustomRead

您没有显示如何创建
连接observable
,在执行上述代码之前,我不知道是否对该连接执行了其他操作

我的猜测是,如果您查看应用程序的日志,您将看到无线电处理队列开始执行您的
CustomReadOperation
,这是连接后的第一个操作。在您的自定义操作中,您正在调用
rxbeconnection.getCharacteristic(UUID)
,它试图执行
.discoverServices()
(在无线电队列上安排一个
rxbeleradiooperationdiscoverservices
)。问题在于,无线电队列已经在执行您的
CustomReadOperation
,并且在完成之前不会发现服务

有一个原因是,
rxbeconnection
没有传递给
rxbeleradiooperationcustom.asObservable()
-此时大多数功能将无法工作

您可以做的是在计划
CustomReadOperation
之前执行
RxBleConnection.discoverServices()
,并传递从构造函数中的
rxbledevices
检索到的
BluetoothGattCharacteristic
。因此,与其这样:

public void customRead()
{
    if (isConnected()) {
        connectionObservable
                .flatMap(rxBleConnection -> rxBleConnection.queue(new CustomReadOperation(rxBleConnection, UUID_READ_CHARACTERISTIC)))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(bytes -> {
                    configureMvpView.showList(bytes);
                }, this::onRunCustomFailure);
    }
}
你会有这样的想法:

public void customRead()
{
    if (isConnected()) {
        connectionObservable
                .flatMap(RxBleConnection::discoverServices, (rxBleConnection, services) -> 
                    services.getCharacteristic(UUID_READ_CHARACTERISTIC)
                        .flatMap(characteristic -> rxBleConnection.queue(new CustomReadOperation(characteristic)))
                )
                .flatMap(observable -> observable)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(bytes -> {
                    configureMvpView.showList(bytes);
                }, this::onRunCustomFailure);
    }
}
编辑(澄清):

CustomReadOperation
的构造函数应该如下所示:

CustomReadOperation(BluetoothGattCharacteristic characteristic) {
    this.characteristic = characteristic;
}
因此,您不必在
CustomReadOperation
中使用
this.rxbeconnection.getCharacteristic(UUID)
,而直接使用
bluetoothGatt.readCharacteristic(this.characteristic)

编辑2: 更改这两行:

    return connection.getCharacteristic(characteristicUuid)
            .flatMap(characteristic -> readAndObserve(characteristic, bluetoothGatt, rxBleGattCallback))
对此(其余内容相同):


谢谢你的回复。关于RxBleRadioOperationDiscoverServices,您是对的,它会被卡住。您可以发布需要在CustomereAdoOperation类上完成的更改吗。我在更改asObservable函数时遇到问题。添加了一个说明。谢谢,我确实更改了CustomReadOperation的构造函数,但是我在public Observable asObservable中遇到了问题(BluetoothGatt BluetoothGatt,RXBLAGETCALLBACK RXBLAGETCALLBACK,调度程序)抛出Throwable Puting BluetoothGatt.readCharacteristic由于CustomRead是一个静态类,因此在非静态上下文中出现错误。请发布更新后的asObservable函数。我已编辑了说明。当然,您需要调用传递给
CustomReadOperation
->`BluetoothGatt.readCha的对象分形的(这个特征)。问题是CustomRead类中的asObservable返回一个Observable,而bluetoothGatt.readCharacteristic返回一个boolean,我认为这需要Observable。这可能是RxJava的问题,我可能会遗漏它。如果您有时间,请发布更新的CustomRead类,主要是asObservable函数。
    return connection.getCharacteristic(characteristicUuid)
            .flatMap(characteristic -> readAndObserve(characteristic, bluetoothGatt, rxBleGattCallback))
    return readAndObserve(this.characteristic, bluetoothGatt, rxBleGattCallback)