Vladimir Vladimir - 3 months ago 43
Android Question

Android set timeout on a bluetooth socket

On a bluetooth socket created with

device.createRfcommSocketToServiceRecord(MY_UUID)
I wish that after an certain amount of time when nothing arrives, to run some code, but still be able to process the bytes as soon as they arrive.

The description of
.setSoTimeout
explains exactly what I am willing to do:


With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid.


So it looks like the perfect opportunity to put my code in the
catch
statement.

But unfortunately
.setSoTimeout
does not work with Bluetooth sockets according to my Android Studio. How can I implement such functionality without such method?

Thread.sleep
is obviously also not a option, because I cannot lock the thread.

Answer

I solved it with Thread.sleep anyway, by using small intervals for the sleep and so trying to mimic the .setSoTimeout operation:

  • short sleep, check for incoming data, cycle until the timeout is reached then execute the timeout code.

I suppose there are better solutions, but this works for now.

The code given will execute the "timeout code" every second (set by the int timeOut), when no byte arrives on the input stream. If a byte arrives, then it resets the timer.

// this belongs to my "ConnectedThread" as in the Android Bluetooth-Chat example
public void run() {
    byte[] buffer = new byte[1024];
    int bytes = 0;
    int timeOut = 1000;
    int currTime = 0;
    int interval = 50;
    boolean letsSleep = false;
    // Keep listening to the InputStream
    while (true) {
        try {
            if (mmInStream.available() > 0) {               // something just arrived?
                buffer[bytes] = (byte) mmInStream.read();
                currTime = 0;                               // resets the timeout

                // .....
                // do something with the data
                // ...

            } else if (currTime < timeOut) {               // do we have to wait some more?
                try {
                    Thread.sleep(interval);
                    } catch (InterruptedException e) {
                        // ...
                        // exception handling code
                    }
                currTime += interval;
                } else {                                   // timeout detected
                // ....
                // timeout code
                // ...
                currTime = 0;                              // resets the timeout
            }
        } catch (IOException e) {
            // ...
            // exception handling code
        }
    }
}