当BluetoothGattCallback#onCharacteristicChanged具有回调时,RxBleConnection#writeCharacteristic失败

时间:2018-07-29 15:13:42

标签: android rxandroidble

我用两个不同的命令进行了测试: 命令A:writeCharacteristic和设备响应什么都没有 命令B:使用onCharacteristicChanged的writeCharacteristic和设备响应

命令A可以正常工作,每个writeCharacteristic都可以成功 命令B不能正常工作,只有第一个writeCharacteristic可以成功,并且之后经常失败。

奇怪的是,当我在writeCharacteristic之前添加Thread.sleep(100)时,情况会稍好一些,延迟时间越长,失败的可能性就越低。我不知道这个问题的原因。

带有setupNotification的代码:

@Override
protected Observable<?> rxPrepare(final RxBleConnection connection) {
    return connection
            .discoverServices()
            .flatMap(new Function<RxBleDeviceServices, SingleSource<BluetoothGattService>>() {
                @Override
                public SingleSource<BluetoothGattService> apply(RxBleDeviceServices rxBleDeviceServices) throws Exception {
                    return rxBleDeviceServices.getService(SERVICE_UUID);
                }
            })
            .toObservable()
            .flatMap(new Function<BluetoothGattService, ObservableSource<?>>() {
                @Override
                public ObservableSource<?> apply(BluetoothGattService bluetoothGattService) throws Exception {
                    mWriteCharacteristic = bluetoothGattService.getCharacteristic(WRITE_CHARACTERISTIC_UUID);
                    if (mWriteCharacteristic == null) {
                        throw new BleCharacteristicNotFoundException(WRITE_CHARACTERISTIC_UUID);
                    }
                    final BluetoothGattCharacteristic notifyCharacteristic = bluetoothGattService.getCharacteristic(NOTIFY_CHARACTERISTIC_UUID);
                    if (notifyCharacteristic == null) {
                        throw new BleCharacteristicNotFoundException(NOTIFY_CHARACTERISTIC_UUID);
                    }
                    return connection.setupNotification(notifyCharacteristic, NotificationSetupMode.DEFAULT)
                            .doOnNext(new Consumer<Observable<byte[]>>() {
                                @Override
                                public void accept(Observable<byte[]> observable) throws Exception {
                                    doListenCharacteristicChanged(observable);
                                }
                            });
                }
            })
            .retryWhen(new RetryWithDelay(1000, 3, new Predicate<Throwable>() {
                @Override
                public boolean test(Throwable throwable) throws Exception {
                    return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled();
                }
            }));
}

@SuppressLint("CheckResult")
private void doListenCharacteristicChanged(Observable<byte[]> observable) {
    observable
            .subscribe(new Consumer<byte[]>() {
                @Override
                public void accept(byte[] bytes) throws Exception {
                    onReceiveData(bytes);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    Log.e(TAG, "throwable:" + throwable + " Thread:" + Thread.currentThread().getName());
                }
            });
}

带有发送命令的代码:

public boolean sendDataSync(@NonNull byte[] data) {
    RxBleConnection connection = getRxBleConnection();
    if (!isConnected() || connection == null || mWriteCharacteristic == null) {
        return false;
    } else {
        if (WristbandApplication.isDebugEnable())
            Log.e(TAG, "Send Data :" + BytesUtil.byte2HexStr(data));
        boolean success = true;
        try {
            //Thread.sleep(100); 
            if (data.length <= MTU_SIZE) {
                connection.writeCharacteristic(mWriteCharacteristic, data).blockingGet();
            } else {
                RxBleConnection.LongWriteOperationBuilder builder = connection.createNewLongWriteBuilder();
                builder.setBytes(data);
                builder.setCharacteristic(mWriteCharacteristic);
                builder.setMaxBatchSize(MTU_SIZE);
                builder.build().blockingSubscribe();
            }
        } catch (Exception e) {
            e.printStackTrace();
            success = false;
        }
        return success;
    }
}

测试代码:

public void set_user_info() {
    boolean success = mWristManager.sendDataSync(datas);
    Log.e(TAG, "sendDataSync result:" + success);

    success = mWristManager.sendDataSync(datas);
    Log.e(TAG, "sendDataSync result:" + success);

    success = mWristManager.sendDataSync(datas);
    Log.e(TAG, "sendDataSync result:" + success);

    success = mWristManager.sendDataSync(datas);
    Log.e(TAG, "sendDataSync result:" + success);

    success = mWristManager.sendDataSync(datas);
    Log.e(TAG, "sendDataSync result:" + success);
}

错误:

com.polidea.rxandroidble2.exceptions.BleGattCannotStartException: GATT exception from MAC address 10:00:A1:12:09:AC, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation.writeData(CharacteristicLongWriteOperation.java:177)
at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation.access$200(CharacteristicLongWriteOperation.java:44)
at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation$2.subscribe(CharacteristicLongWriteOperation.java:155)
at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
at io.reactivex.Observable.subscribe(Observable.java:12051)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:762)

0 个答案:

没有答案