4

I am only trying to write and read across a Bluetooth Socket but i my readBytes call is not completing. I think that this is very simple but maybe i am just using the wrong type of stream or something. As of right now my code is just sending a small amount of text as bytes. This is placeholder code that will be replaced with code that writes and reads a file over the stream. Here is my Receive Thread:

class ReceiveThread(val inStream:BufferedInputStream):Thread() {

var bytes:ByteArray? = null


override fun run() {
    BluetoothService.log("Begin ${BTS_Constants.THREAD_RECEIVE}")
    BluetoothService.log("preparing to read data")
    name = BTS_Constants.THREAD_RECEIVE

//here is my new code
    inStream.use {
        do{
            count++
            BluetoothService.log("read loop round $count")
            byteList.add(it.read() as Byte)
        }while (it.available()>0)
     }
    BluetoothService.log("data read: ${byteList.get(0) as Char}")
}
}

and here is my Send Thread:

class SendThread(val outStream:BufferedOutputStream, val file:File? = null):Thread(){

var bytes:ByteArray? = null

override fun run() {
    BluetoothService.log("Begin : ${BTS_Constants.THREAD_SEND}")
    name = BTS_Constants.THREAD_SEND

    bytes = "hello testing".toByteArray()
    try{
        outStream.use {
            it.write(bytes)
            it.flush()
        }
    }catch (ioe:IOException){

    }

    BluetoothService.log("data sent")
}

}

the data is successfully sent, and the BluetoothService.log("data sent") call is reached and displayed in the logcat for the device that is running a Send Thread. For the device running the Receive Thread logs the "Preparing to read data" message, but never logs the data read: "$bytes message".

How can i make this call to inStream.readBytes() complete?

Edit: new Error message that i am receiving:

11-27 23:45:29.298 16253-16413/com.example.zemcd.fileblue E/AndroidRuntime: FATAL EXCEPTION: RECEIVE
                                                                        Process: com.example.zemcd.fileblue, PID: 16253
                                                                        java.io.IOException: bt socket closed, read return: -1
                  at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:588)
                  at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96)
                  at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
                  at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
                  at com.example.zemcd.fileblue.ReceiveThread.run(BluetoothService.kt:230)
Mox_z
  • 501
  • 7
  • 30

1 Answers1

2

If you look on source of Kotlin extension function readBytes you see that it starts loop while InputStream.read(buffer) > 0. According to documentation:

This method blocks until input data is available, end of file is detected, or an exception is thrown.

Second iteration of this loop freeze your program. So don't use method readBytes. Just read(buffer). For example - https://developer.android.com/guide/topics/connectivity/bluetooth.html#ManagingAConnection

Update:

Now ReceiveThread can receive one message from stream. But your bluetooth socket is close. So your problem is in setup bluetooth connection and inStream's initialization. Maybe you have wrong send part too.

Dmitrii Nechepurenko
  • 1,414
  • 1
  • 11
  • 13
  • thanks. this answer is very infomative, but i made the changes to the code and it is still blockiing. maybe i am misunderstanding. I changed `bytes = it.readBytes()` to `byteSize = it.read(buffer)` and added a byteSize variable to my code. as an Int field of my Receive Thread. am i needing to do something more? i am not seeing any more in the documentation and because i am using kotlin i can't do the`while((byteSize = it.read(buffer))!=-1)` loop. – Mox_z Nov 28 '17 at 07:14
  • @Mox_z Are you sure that ReceiveThread call method read before SendThread call method write ? – Dmitrii Nechepurenko Nov 28 '17 at 07:30
  • Yes, the write side is completing the send. but could this have something to do with it being a BufferedInputStream? is there a different technique used there? – Mox_z Nov 28 '17 at 07:34
  • see above comment – Mox_z Nov 28 '17 at 07:34
  • @Mox_z why you can't use `while`? And can it be a bluetooth connect problem? – Dmitrii Nechepurenko Nov 28 '17 at 07:40
  • i guess in kotlin the example that i showed you is an assignment and cannot be used in place of the expression that while(expression) expects as an argument. maybe there is a work around? i will try taking a look at my send code. maybe im just missing something there. also, i am going to post an edit to this question showing the updated code and new error message i am receiving. I think this is helping to clarifiy my problem. – Mox_z Nov 28 '17 at 07:49
  • i posted an edit. maybe you were right about the problem being with my send code and not my receive code? – Mox_z Nov 28 '17 at 07:53
  • @Mox_z I've updated my answer. You have a close bt socket on receive side so you don't have bluetooth connection between programs on your devices. Therefore you can't read any of bytes and have an exception. – Dmitrii Nechepurenko Nov 28 '17 at 08:21
  • could this be something to do with me not correctly synchronizing my threads? my outStream and inStream references are passed in as args but the streams originally come from a BluetoothSocket aquired by a singleton object: BluetoothService. could passing the socket into an unsynchronized thread be part of the problem? – Mox_z Nov 29 '17 at 02:54
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/160046/discussion-between-mox-z-and-dmitrii-nechepurenko). – Mox_z Nov 29 '17 at 05:50