2

Actually I make an update through Bluetooth. In first time I erase the memory bank and then I write an hexa File on it.

But half the time an update will don't work correctly, for every data I transfer the first writeCharacteristic will return false. It happen on an entire update half the time.

I try in debug mode but the method never return false in that case, of course it's probably a delay problem, but I can't increase the time.

This is my code for send my data :

public void sendTX(final byte[] sMessage) {
        BluetoothGattService service = mBluetoothGatt.getService(UUID_SERVICE_SERIAL);
        if (service != null && sMessage != null) {
            Log.d(TAG,"sMessage : " + sMessage);

            final BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID_TX);
            if (characteristic != null) {

                Thread thread = new Thread() {
                    public void run() {

                        if (sMessage.length > 20) {

                            for (int i = 0; i < sMessage.length; i += 20) {
                                byte[] byteArraySplit = Arrays.copyOfRange(sMessage, i, i + 20 < sMessage.length ? i + 20 : sMessage.length);
                                characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
                                characteristic.setValue(byteArraySplit);
                                while(!mBluetoothGatt.writeCharacteristic(characteristic)) {
                                    try {
                                        TimeUnit.MILLISECONDS.sleep(15);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                 }
                            }
                        } else {
                            characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
                            characteristic.setValue(sMessage);
                            while(!mBluetoothGatt.writeCharacteristic(characteristic)){

                            try {
                                 TimeUnit.MILLISECONDS.sleep(15);
                               } catch (InterruptedException e) {
                                 e.printStackTrace();
                              }

                            }

                        }

                    }
                };
                thread.start();
            } else {
                Log.d(TAG, "UUID TX null");

            }
        } else {
            Log.d(TAG, "Service BLE null");
        }
    }

And this is the code of the native writeCharacteristic method :

public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
            && (characteristic.getProperties() &
                BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false;

        if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
        if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false;

        BluetoothGattService service = characteristic.getService();
        if (service == null) return false;

        BluetoothDevice device = service.getDevice();
        if (device == null) return false;

        synchronized(mDeviceBusy) {
            if (mDeviceBusy) return false;
            mDeviceBusy = true;
        }

        try {
            mService.writeCharacteristic(mClientIf, device.getAddress(),
                characteristic.getInstanceId(), characteristic.getWriteType(),
                AUTHENTICATION_NONE, characteristic.getValue());
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            mDeviceBusy = false;
            return false;
        }

        return true;
    }
KotC
  • 53
  • 2
  • 10

1 Answers1

1

Never use timeouts to try to workaround this issue. The proper way is to wait for the callback and then perform the next request. See Android BLE BluetoothGatt.writeDescriptor() return sometimes false.

Emil
  • 16,784
  • 2
  • 41
  • 52
  • Yes it's right, I've modfied my code and it work a little better. Thanks for the help. – KotC Nov 15 '18 at 11:02