question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

connection.writeCharacteristic failed when onCharacteristicChanged has callback

See original GitHub issue

I have test with two diffrent command: command A : writeCharacteristic and device response nothing command B : writeCharacteristic and device response something with onCharacteristicChanged

Command A can work properly, every writeCharacteristic can succeed Command B does not work properly, only the first writeCharacteristic can succeed, and often fails afterwards.

And the strange thing is that when I added a Thread.sleep(100) before the writeCharacteristic, the situation will be slightly better, the longer the delay, the lower the probability of failure. I don’t know the cause of this problem.

code with 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());
                }
            });
}

code with send command:

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;
    }
}

test code:

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);
}

error:

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)

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
dariuszseweryncommented, Jul 29, 2018

Hello!

Thank you for using the library.

This is a general usage question and as such should be posted on stackoverflow with rxandroidble tag—it will be easier to find by other users.

Best Regards

0reactions
Kilnncommented, Aug 4, 2018

Great, thanks for you help.

Read more comments on GitHub >

github_iconTop Results From Across the Web

connection.writeCharacteristic failed when ... - GitHub
I have test with two diffrent command: command A : writeCharacteristic and device response nothing command B : writeCharacteristic and ...
Read more >
java - Android BLE: onDescriptorWrite, onCharacteristicWrite ...
I am calling them one at a time. The test code I've built does nothing but call writeCharacteristic after the connection is made,...
Read more >
BluetoothGattCallback - Android Developers
Use BluetoothGattCallback#onCharacteristicChanged(BluetoothGatt, ... Callback indicating the MTU for a given device connection has changed.
Read more >
Making Android BLE work — part 3 - Medium
This means that the command you issue will return immediately and you will receive the data a bit later via a callback function....
Read more >
Bluetooth LE not triggering OnCharacteristicWrite - MSDN
My BluetoothGattCallback is as follows: ... As such, subsequent calls to WriteCharacteristic fail. Below is a list of what I have tried (and ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found