Search code examples
javaandroidbluetooth-lowenergydelaywait

Wait statement that are sequential


I have an issue leading to the requirement of needing to wait sequentially from going from one thing into the next. I presently do this by setting 3 runnables with different delays to allow for a sequential flow of data to appear on my bluetooth connection. However, whilst this does work I feel there must be a better / cleaner implementation of this. My present code is below.

My code works like this:

  • Write command 1
  • Wait till command is written
  • Write command 2
  • Wait till command is written
  • Write command 3
  • Wait till command is written

Please could you give me some suggestions as to how I can perform my write functions one after another in a better manner.

Handler h =new Handler() ;
h.postDelayed(new Runnable() {
    public void run() {
        Log.d(TAG, "Write 1");
        mBluetoothLeService.writeCharacteristic(10);
    }
}, 1000);

Handler h1 =new Handler() ;
final int Command_to_run = value;
h1.postDelayed(new Runnable() {
    public void run() {
        Log.d(TAG, "Write 2");
        mBluetoothLeService.writeCharacteristic(Command_to_run);
    }
}, 2000);

Handler h2 =new Handler() ;
h2.postDelayed(new Runnable() {
    public void run() {
        Log.d(TAG, "Write 3");
        mBluetoothLeService.writeCharacteristic(20);
    }
}, 3000);

Write code

 public void writeCharacteristic(int Data) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }

        byte[] value = intToByteArray(Data);

        BluetoothGattService mCustomService = 
        mBluetoothGatt.getService(UUID.fromString("f3641400-00b0-4240-ba50- 
        05ca45bf8abc"));
        if(mCustomService == null){
            Log.w(TAG, "Custom BLE Service not found");
            return;
        }
        /*get the read characteristic from the service*/
        BluetoothGattCharacteristic characteristic = 
        mCustomService.getCharacteristic(UUID.fromString("f3641401-00b0-4240- 
        ba50-05ca45bf8abc"));
        characteristic.setValue(value);
        mBluetoothGatt.writeCharacteristic(characteristic);
    }

Solution

  • I think mBluetoothLeService.writeCharacteristic(10); calls like these already blocks the thread so using them in order without the need of handlers can be your solution. I don't think that function is asynchronous, so if it returns true, you can write the next one. They are boolean functions so if it returns true you can switch to next one.

    I've examined the source code and if it throws an exception inside it, it returns false. Otherwise, it returns if it was successful or not.

    Side note: This behavior might differ on different API versions, the source code I've looked into was for API 29. Though, I believe the behavior would be the same, except you might need to wrap the mBluetoothLeService.writeCharacteristic(10); calls to a try-catch block.

    I have to edit this since the answer is wrong, the boolean return value is not enough to determine whether the operation was successful. The operation is indeed asynchronous but there is a callback that you can use (this callback) to see if the write operation was successful, and then move on to the next one.

    Check this answer for more information, and, if possible, remove the tick from this one please.