Search code examples
androidmultithreadingsocketsbluetoothsocket-timeout-exception

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.


Solution

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