Implement a timeout in BluetoothSocket inputstream.read() in Android

前端 未结 2 1663
我寻月下人不归
我寻月下人不归 2020-12-15 11:04

Is it possible to implement a timeout in an inputstream.read() function from a BluetoothSocket in Android?

I\'ve tried using Thread.sleep() but this only pauses my a

相关标签:
2条回答
  • 2020-12-15 11:12

    You could do something like this:

    InputStream in = someBluetoothSocket.getInputStream();
    int timeout = 0;
    int maxTimeout = 8; // leads to a timeout of 2 seconds
    int available = 0;
    
    while((available = in.available()) == 0 && timeout < maxTimeout) {
        timeout++;
        // throws interrupted exception
        Thread.sleep(250);
    }
    
    byte[] read = new byte[available];
    in.read(read);
    

    This way you are able to initially read from a stream with a specific timeout. If u want to implement a timeout at any time of reading you can try something like this:

    Thread readThread = new ReadThread(); // being a thread you use to read from an InputStream
    try {
       synchronized (readThread) {
          // edit: start readThread here
          readThread.start();
          readThread.wait(timeOutInMilliSeconds);
       }
    catch (InterruptedException e) {}
    

    using this you may need some kind of event handler to notify your application if the thread actually read something from the input stream.

    I hope that helps!

    ----edit:

    I implemented an example without using any handlers.

    Socket s = new Socket("localhost", 8080);
        final InputStream in = s.getInputStream();
    
        Thread readThread = new Thread(new Runnable() {
            public void run() {
                int read = 0;
                try {
                    while((read = in.read()) >= 0) {
                        System.out.println(new String(new byte[]{ (byte) read }));
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    
        synchronized (readThread) {
            readThread.start();
            try {
                readThread.wait(2000);
    
                if(readThread.isAlive()) {
                                        // probably really not good practice!
                    in.close();
                    System.out.println("Timeout exceeded!");
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
    0 讨论(0)
  • 2020-12-15 11:26

    A Kotlin extension function for socket read with timeout:

    fun InputStream.read(
      buffer: ByteArray,
      offset: Int,
      length: Int,
      timeout: Long
    ): Int = runBlocking {
        val readAsync = async {
            if (available() > 0) read(buffer, offset, length) else 0
        }
        var byteCount = 0
        var retries = 3
        while (byteCount == 0 && retries > 0) {
            withTimeout(timeout) {
                byteCount = readAsync.await()
            }
            delay(timeout)
            retries--
        }
        byteCount
    }
    
    0 讨论(0)
提交回复
热议问题