Android Question BLE2 java.lang.RuntimeException: Error writing data to:

wes58

Active Member
Licensed User
Longtime User
I have the following error due to the problem with writing data to BLE device - due to the issue with the BLE device for example:
B4X:
retries: 4
retries: 3
retries: 2
retries: 1
java.lang.RuntimeException: Error writing data to: 00001f1f-0000-1000-8000-00805f9b34fb
    at anywheresoftware.b4a.objects.BleManager2.WriteData(BleManager2.java:426)
    at b4a.ble3.starter._writedata(starter.java:829)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1082)
    at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:1037)
    at b4a.ble3.main._bgetname_click(main.java:1356)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:197)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)

After 4 retries application crasshes.
I had a look at the BLE2 code:
Java:
    /**
     * Writes the data to the specified characteristic.
     */
    public void WriteData(String Service, String Characteristic, byte[] Data) throws InterruptedException {
        BluetoothGattCharacteristic chr = getChar(getService(Service), Characteristic);
        chr.setValue(Data);
        int retries = 5;
        while (true) {
            if (!gatt.writeCharacteristic(chr)) {
                if (--retries <= 0)
                    throw new RuntimeException("Error writing data to: " + Characteristic);
            }
            else
                break;
            BA.Log("retries: " + retries);
            Thread.sleep(150 * (5 - retries));
        }
    }
I thought that it would be better way of handling of writing error than throwing RuntimeException and crashing the app after number of retries!

Edit:
I noticed that there is an event raised in callback function onCharacteristicWrite(), with the status of the write process:
Java:
        public void onCharacteristicWrite(BluetoothGatt gatt,
                BluetoothGattCharacteristic characteristic, int status) {
            if (characteristic == null || characteristic.getUuid() == null)
                return;
            ba.raiseEventFromDifferentThread(BleManager2.this, null, 0, eventName + "_writecomplete", false,
                    new Object[] {characteristic.getUuid().toString(), status});
        }
So do we need to have a RuntimeException?
 
Last edited:

wes58

Active Member
Licensed User
Longtime User
Catch the error with Try / Catch.
Sorry, I am a beginner with Java, but I can't understand why would you want to use Try/Catch? You know what the issue is - you retried 5 times and can't write to the device - so why not raise an event and notify the user about "writing error to ble device". Application can continue to run.

The same thing I noticed in your connect() function.
Java:
    /**
     * Similar to Connect. Allows you to disable auto connection.
     */
    public void Connect2(String DeviceId, boolean AutoConnect) {
        charsToReadQueue.clear();
        BluetoothDevice bd = this.devices.get(DeviceId);
        if (bd == null) 
            throw new RuntimeException("MacAddress not found. Make sure to call Scan before trying to connect.")
        else {
            bd.connectGatt(BA.applicationContext, AutoConnect, new GattCallback());
        }
    }
You have "throw new RuntimeException("MacAddress not found. Make sure to call Scan before trying to connect.")".
Why not handling this error and notify the user that he has to scan before trying to connect, instead of crashing the app?
An easy way to do it, would be, to return boolean from this function , and return FALSE if bd=null, which would mean that mac address was not found.
That's only my suggestion, you are a Java expert, so you know better what to do.
 
Upvote 0

wes58

Active Member
Licensed User
Longtime User
It has nothing to do with Java.

There are many cases where a failed operation throws exceptions.
It was only my understanding of exceptions.
And here is what others think about RuntimeExceptions:
In the examples I mentioned, it is not a programmer's error. And the program could deal with this error!

Or another one:
That's why I thought, that in the examples I mentioned there was no need of throwing RuntimeExceptions.
Obviously, you have a different opinion about it, and that's OK.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…