Android InputStream dropping first two bytes (modified BluetoothChat)

11,478

Solution 1

I have seen people run into this sort of problem before when using the Bluetooth Chat example. The problem with the example code is that the message object that is sent to the Handler simply contains a reference to the actual byte[] array that is used for each subsequent read() operation. This means that as soon as the Handler obtains the message and starts inspecting the array, the subsequent read() operation on the Bluetooth socket has already had the opportunity to write newer data to that array.

In this line of code:

mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget()

The array is not being copied; but rather the message is simply conveying an object reference to the same array.

The only reason why the Bluetooth Chat example works for its original purpose is because its purpose is to convey short bunches of characters at human typing speed. If you send anything faster than that, what the Handler reads from that array turns to garbage.

The answer is to send a copy of the array (e.g. System.arraycopy()) or use a simple circular buffer, which is what my own Bluetooth application uses.

The fact that the first two bytes are being mangled is a strange one, but it could just be down to the specific implementation of the underlying read operation in the Bluetooth stack on your particular device. The simple fact is that once you have called read() with that buffer, you should not be touching that buffer in the meantime or caring what's in it. Perhaps the particular Bluetooth socket read implementation on your device does something with those first few bytes in the buffer because of something to do with its internal operation. But you should not care what kind of funny intermediate state the buffer is in while read() is blocking, because no other thread should be trying to make sense of it at that time. All you care about is that the buffer is in a valid state with valid data when read() returns.

The reason why using the sleep() operation apparently partly "cures" the problem is because it's a crude way of giving your Handler time to look at the array before the subsequent read() operation gets its hands on the array. This is not a good solution though.

The second issue you have is due to the fact that in Java, byte is signed. That's why the debugger shows you the bytes as signed values. In your application, if you need to work with a given byte as an int and the byte is originally unsigned, you do something like:

int someValue = myByteArray[someIndex] & 0xff;

Solution 2

I think the issue you are seeing with e.g. the 198 turning into -58 is because Java uses signed bytes, so anything over 127 is a negative number. So 198 binary is seen as -(256 - 198) = -58.
The solution is to convert it to an int using some code like the following:

private int UByte(byte b){
        if(b<0) // if negative
            return (int)( (b&0x7F) + 128 );
        else
            return (int)b;
    }

Solution 3

As said before the data is not guaranteed, bluetooth is an open stream of data like UDP.

I suppose some understanding of rs232 is needed to know when bytes will be packaged together, or sent individually.

with a microcontroller project, imagine something like:

if (data_ready) echo read_byte();

with PIC microchips, the resulting data is something like:

0 0 0 0 0 0 0 h 0 0 0 0 e 0 0 0 0 0 0 l 0 0 0 0 0 0 l 0 0 0 0 0 0 o ...

With the Android to microcontroller project I'm working on at the moment I'm doing something like:

do {instream.read()} while (!DELIMETER)

I've found that you need to be efficient with your code when reading a bluetooth data stream. Using inputstream methods other than read(), I would almost always miss the first byte.

I've just started with bluetooth smart, which I guess is quite different since data is only sent when it's available.

Share:
11,478

Related videos on Youtube

Adrian Wreyford
Author by

Adrian Wreyford

Updated on September 15, 2022

Comments

  • Adrian Wreyford
    Adrian Wreyford about 1 year

    I've used code from BluetoothChat example to send and receive byte data from a Bluetooth Scale. The scale receives the command from the device, then sends back a byte array. {2,198,48,48,48,48,199,3} The 2 = STX, and the 198 = packet start, and 199 = packet end, and 3 = ETX in our comms protocol.

    All works just fine, except that the following code in the BluetoothChatService.java reacts strangely in that it drops the first two bytes.

    /**
         * This thread runs during a connection with a remote device.
         * It handles all incoming and outgoing transmissions.
         */
        private class ConnectedThread extends Thread {
            private final BluetoothSocket mmSocket;
            private final InputStream mmInStream;
            private final OutputStream mmOutStream;
    
            public ConnectedThread(BluetoothSocket socket, String socketType) {
                Log.d(TAG, "create ConnectedThread: " + socketType);
                mmSocket = socket;
                InputStream tmpIn = null;
                OutputStream tmpOut = null;
    
                // Get the BluetoothSocket input and output streams
                try {
                    tmpIn = socket.getInputStream();
                    tmpOut = socket.getOutputStream();
                } catch (IOException e) {
                    Log.e(TAG, "temp sockets not created", e);
                }
    
                mmInStream = tmpIn;
                mmOutStream = tmpOut;
            }
    
            public void run() {
                Log.i(TAG, "BEGIN mConnectedThread");
                final byte[] buffer = new byte[1024];
                int bytes;
    
                // Keep listening to the InputStream while connected
                while (true) {
                    try {
                        // Read from the InputStream
                        bytes = mmInStream.read(buffer);
    
                        // Send the obtained bytes to the UI Activity
                        mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                                .sendToTarget();
                    } catch (IOException e) {
                        Log.e(TAG, "disconnected", e);
                        connectionLost();
                        // Start the service over to restart listening mode
                        BluetoothChatService.this.start();
                        break;
                    }
                }
            }
    

    I have a problem specifically with the following section of code:

     bytes = mmInStream.read(buffer);
    
                        // Send the obtained bytes to the UI Activity
                        mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                                .sendToTarget();
    

    When debugging, and looking at the content of buffer in mmInStream.read(buffer) before it is executed, the buffer contains the correct data that was sent back by the scale device ie:

    {2,198,48,48,48,48,48,199,3}
    

    but once the code has been stepped, the first two bytes of the buffer are stripped off, and it now erroneously contains:

    {48,48,48,48,48,199,3}
    

    and it is this that the message handler then finally passes on to the activity.

    For more clarity, I must add, that the stream of bytes being sent by the scale are Hex characters in the range 00 to FF. For some strange reason the string actually looks like this in the debugger:

    {2,-58,48,48,48,48,48,-57,3}
    

    and then the 2,-58 are dropped.

    I noticed that when I send a byte array over a socket, I need to do the following:

    byte[] sendBytes = {2,(byte)198,48,48,48,48,48,(byte)199,3}
    

    When the content of this array is debugged it will give {2,-58,48,48,48,48,48,-57,3}

    Please understand that I am new to Android - java, and have a lot to learn. All help will be appreciated. Thanks Adrian

    I have added log.i entries to better understand what is happening based on Radu's advice. It appears that after I write data to my device over Bluetooth, it responds, and we read for some reason only first two bytes, then send these to the message handler, then read the rest of the packet sent from the device, and then send this off to the message handler, but before the handler has even responded the first time, the buffer has already been overwritten, thus by the time the handler tries to read the first two bytes, it is reading the 3rd and 4th bytes of the response packet, then immediately responds again and reads the entire packet from 3-17th position. So if I can put it simply .. the message handler only responds to the sent buffer after it has been overwritten. See the log below:

    09-05 13:16:52.093: V/BluetoothSocket.cpp(11279): writeNative
    09-05 13:16:52.118: I/IN_BUFFER(11279): The entire buffer after read stream into buffer: 2 
    09-05 13:16:52.118: I/IN_BUF_AFTER(11279): 2 
    09-05 13:16:52.118: I/IN_BUF_AFTER(11279): -58 
    09-05 13:16:52.118: I/IN_BUF_AFTER(11279): 0 
    09-05 13:16:52.118: I/IN_BUF_AFTER(11279): 0 
    ...truncated to save space ... 
    09-05 13:16:52.163: I/IN_BUF_AFTER(11279): 0 
    09-05 13:16:52.163: I/IN_BUFFER(11279): We now send to handler.
    09-05 13:16:52.168: I/IN_BUFFER(11279): Read Stream into Buffer:
    09-05 13:16:52.168: V/BluetoothSocket.cpp(11279): readNative
    09-05 13:16:52.168: I/IN_BUFFER(11279): The entire buffer after read stream into buffer: 17 
    09-05 13:16:52.168: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:52.168: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:52.168: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:52.173: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:52.173: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:52.173: I/IN_BUF_AFTER(11279): 44 
    09-05 13:16:52.173: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:52.178: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:52.178: I/IN_BUF_AFTER(11279): 49 
    09-05 13:16:52.178: I/IN_BUF_AFTER(11279): 50 
    09-05 13:16:52.188: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:52.188: I/IN_BUF_AFTER(11279): 44 
    09-05 13:16:52.188: I/IN_BUF_AFTER(11279): 85 
    09-05 13:16:52.188: I/IN_BUF_AFTER(11279): 13 
    09-05 13:16:52.188: I/IN_BUF_AFTER(11279): -57 
    09-05 13:16:52.188: I/IN_BUF_AFTER(11279): 3 
    09-05 13:16:52.188: I/IN_BUF_AFTER(11279): 6 
    09-05 13:16:52.188: I/IN_BUF_AFTER(11279): 0 
    ...truncated to save space ... 
    09-05 13:16:52.188: I/IN_BUF_AFTER(11279): 0 
    09-05 13:16:52.188: I/IN_BUFFER(11279): We now send to handler.
    09-05 13:16:52.193: I/IN_BUFFER(11279): Read Stream into Buffer:
    09-05 13:16:52.208: V/BluetoothSocket.cpp(11279): readNative
    09-05 13:16:52.208: I/MESSAGE_READ(11279): I am reading 2 bytes
    09-05 13:16:52.208: I/Content(11279): The entire array:
    09-05 13:16:52.208: I/some hardcoded tag(11279): 0 
    09-05 13:16:52.208: I/some hardcoded tag(11279): 0 
    09-05 13:16:52.273: I/MESSAGE_READ(11279): I am reading 17 bytes
    09-05 13:16:52.273: I/Content(11279): The entire array:
    09-05 13:16:52.273: I/some hardcoded tag(11279): 0 
    ...truncated to save space ... 
    09-05 13:16:52.283: I/some hardcoded tag(11279): 0 
    09-05 13:16:52.283: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.528: V/BluetoothSocket.cpp(11279): writeNative
    09-05 13:16:54.553: I/IN_BUFFER(11279): The entire buffer after read stream into buffer: 2 
    09-05 13:16:54.553: I/IN_BUF_AFTER(11279): 2 
    09-05 13:16:54.553: I/IN_BUF_AFTER(11279): -58 
    09-05 13:16:54.558: I/IN_BUF_AFTER(11279): 0 
    09-05 13:16:54.558: I/IN_BUF_AFTER(11279): 0 
    ...truncated to save space ... 
    09-05 13:16:54.618: I/IN_BUF_AFTER(11279): 0 
    09-05 13:16:54.618: I/IN_BUF_AFTER(11279): 0 
    09-05 13:16:54.618: I/IN_BUFFER(11279): We now send to handler.
    09-05 13:16:54.618: I/IN_BUFFER(11279): Read Stream into Buffer:
    09-05 13:16:54.618: V/BluetoothSocket.cpp(11279): readNative
    09-05 13:16:54.623: I/IN_BUFFER(11279): The entire buffer after read stream into buffer: 17 
    09-05 13:16:54.623: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:54.623: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:54.623: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:54.623: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:54.628: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:54.628: I/IN_BUF_AFTER(11279): 44 
    09-05 13:16:54.628: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:54.628: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:54.633: I/IN_BUF_AFTER(11279): 49 
    09-05 13:16:54.633: I/IN_BUF_AFTER(11279): 50 
    09-05 13:16:54.638: I/IN_BUF_AFTER(11279): 48 
    09-05 13:16:54.638: I/IN_BUF_AFTER(11279): 44 
    09-05 13:16:54.638: I/IN_BUF_AFTER(11279): 85 
    09-05 13:16:54.638: I/IN_BUF_AFTER(11279): 13 
    09-05 13:16:54.638: I/IN_BUF_AFTER(11279): -57 
    09-05 13:16:54.648: I/IN_BUF_AFTER(11279): 3 
    09-05 13:16:54.648: I/IN_BUF_AFTER(11279): 6 
    09-05 13:16:54.648: I/IN_BUF_AFTER(11279): 0 
    09-05 13:16:54.648: I/IN_BUF_AFTER(11279): 0 
    ...truncated to save space ... 
    09-05 13:16:54.653: I/IN_BUF_AFTER(11279): 0 
    09-05 13:16:54.653: I/IN_BUF_AFTER(11279): 0 
    09-05 13:16:54.653: I/IN_BUFFER(11279): We now send to handler.
    09-05 13:16:54.653: I/IN_BUFFER(11279): Read Stream into Buffer:
    09-05 13:16:54.653: V/BluetoothSocket.cpp(11279): readNative
    09-05 13:16:54.658: I/MESSAGE_READ(11279): I am reading 2 bytes
    09-05 13:16:54.658: I/Content(11279): The entire array:
    09-05 13:16:54.658: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.663: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/MESSAGE_READ(11279): I am reading 17 bytes
    09-05 13:16:54.723: I/Content(11279): The entire array:
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.723: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.728: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.728: I/some hardcoded tag(11279): 0 
    09-05 13:16:54.728: I/some hardcoded tag(11279): 0 
    

    My new code also resets the buffer to 0 before reading in the latest stream, thus the message handler only seeing 0, before I did this the log appeared as follows:

    09-05 13:06:20.508: V/BluetoothSocket.cpp(10176): writeNative
    09-05 13:06:20.533: I/IN_BUFFER(10176): The entire buffer after read stream into buffer: 2 
    09-05 13:06:20.533: I/IN_BUF_AFTER(10176): 2 
    09-05 13:06:20.533: I/IN_BUF_AFTER(10176): -58 
    09-05 13:06:20.533: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.533: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.538: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.538: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.548: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.548: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.548: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.553: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.553: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.568: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.573: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.573: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.573: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.573: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.573: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.578: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.578: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.578: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.578: I/IN_BUFFER(10176): We now send to handler.
    09-05 13:06:20.578: I/IN_BUFFER(10176): Read Stream into Buffer:
    09-05 13:06:20.578: V/BluetoothSocket.cpp(10176): readNative
    09-05 13:06:20.578: I/IN_BUFFER(10176): The entire buffer after read stream into buffer: 17 
    09-05 13:06:20.578: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:20.578: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:20.583: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:20.583: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:20.583: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:20.593: I/IN_BUF_AFTER(10176): 44 
    09-05 13:06:20.593: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:20.593: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:20.593: I/IN_BUF_AFTER(10176): 49 
    09-05 13:06:20.593: I/IN_BUF_AFTER(10176): 51 
    09-05 13:06:20.593: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:20.593: I/IN_BUF_AFTER(10176): 44 
    09-05 13:06:20.593: I/IN_BUF_AFTER(10176): 85 
    09-05 13:06:20.593: I/IN_BUF_AFTER(10176): 13 
    09-05 13:06:20.598: I/IN_BUF_AFTER(10176): -57 
    09-05 13:06:20.598: I/IN_BUF_AFTER(10176): 3 
    09-05 13:06:20.613: I/IN_BUF_AFTER(10176): 6 
    09-05 13:06:20.613: I/IN_BUF_AFTER(10176): 0 
    ...truncated to save space ... 
    09-05 13:06:20.623: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:20.623: I/IN_BUFFER(10176): We now send to handler.
    09-05 13:06:20.623: I/IN_BUFFER(10176): Read Stream into Buffer:
    09-05 13:06:20.623: V/BluetoothSocket.cpp(10176): readNative
    09-05 13:06:20.628: I/MESSAGE_READ(10176): I am reading 2 bytes
    09-05 13:06:20.628: I/Content(10176): The entire array:
    09-05 13:06:20.628: I/some hardcoded tag(10176): 48 
    09-05 13:06:20.628: I/some hardcoded tag(10176): 48 
    09-05 13:06:20.688: I/MESSAGE_READ(10176): I am reading 17 bytes
    09-05 13:06:20.688: I/Content(10176): The entire array:
    09-05 13:06:20.688: I/some hardcoded tag(10176): 48 
    09-05 13:06:20.688: I/some hardcoded tag(10176): 48 
    09-05 13:06:20.688: I/some hardcoded tag(10176): 48 
    09-05 13:06:20.688: I/some hardcoded tag(10176): 48 
    09-05 13:06:20.688: I/some hardcoded tag(10176): 48 
    09-05 13:06:20.688: I/some hardcoded tag(10176): 44 
    09-05 13:06:20.688: I/some hardcoded tag(10176): 48 
    09-05 13:06:20.693: I/some hardcoded tag(10176): 48 
    09-05 13:06:20.693: I/some hardcoded tag(10176): 49 
    09-05 13:06:20.693: I/some hardcoded tag(10176): 51 
    09-05 13:06:20.693: I/some hardcoded tag(10176): 48 
    09-05 13:06:20.693: I/some hardcoded tag(10176): 44 
    09-05 13:06:20.693: I/some hardcoded tag(10176): 85 
    09-05 13:06:20.693: I/some hardcoded tag(10176): 13 
    09-05 13:06:20.693: I/some hardcoded tag(10176): -57 
    09-05 13:06:20.693: I/some hardcoded tag(10176): 3 
    09-05 13:06:20.693: I/some hardcoded tag(10176): 6 
    09-05 13:06:21.788: V/BluetoothSocket.cpp(10176): writeNative
    09-05 13:06:21.803: I/IN_BUFFER(10176): The entire buffer after read stream into buffer: 2 
    09-05 13:06:21.803: I/IN_BUF_AFTER(10176): 2 
    09-05 13:06:21.803: I/IN_BUF_AFTER(10176): -58 
    09-05 13:06:21.803: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.803: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.808: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.808: I/IN_BUF_AFTER(10176): 44 
    09-05 13:06:21.818: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.818: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.818: I/IN_BUF_AFTER(10176): 49 
    09-05 13:06:21.823: I/IN_BUF_AFTER(10176): 51 
    09-05 13:06:21.823: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.828: I/IN_BUF_AFTER(10176): 44 
    09-05 13:06:21.828: I/IN_BUF_AFTER(10176): 85 
    09-05 13:06:21.833: I/IN_BUF_AFTER(10176): 13 
    09-05 13:06:21.848: I/IN_BUF_AFTER(10176): -57 
    09-05 13:06:21.848: I/IN_BUF_AFTER(10176): 3 
    09-05 13:06:21.848: I/IN_BUF_AFTER(10176): 6 
    09-05 13:06:21.853: I/IN_BUF_AFTER(10176): 0 
    ...truncated to save space ... 
    09-05 13:06:21.853: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:21.853: I/IN_BUFFER(10176): We now send to handler.
    09-05 13:06:21.858: I/IN_BUFFER(10176): Read Stream into Buffer:
    09-05 13:06:21.858: V/BluetoothSocket.cpp(10176): readNative
    09-05 13:06:21.858: I/IN_BUFFER(10176): The entire buffer after read stream into buffer: 17 
    09-05 13:06:21.858: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.863: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.863: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.863: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.863: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.863: I/IN_BUF_AFTER(10176): 44 
    09-05 13:06:21.868: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.868: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.868: I/IN_BUF_AFTER(10176): 49 
    09-05 13:06:21.868: I/IN_BUF_AFTER(10176): 51 
    09-05 13:06:21.868: I/IN_BUF_AFTER(10176): 48 
    09-05 13:06:21.868: I/IN_BUF_AFTER(10176): 44 
    09-05 13:06:21.868: I/IN_BUF_AFTER(10176): 85 
    09-05 13:06:21.868: I/IN_BUF_AFTER(10176): 13 
    09-05 13:06:21.868: I/IN_BUF_AFTER(10176): -57 
    09-05 13:06:21.868: I/IN_BUF_AFTER(10176): 3 
    09-05 13:06:21.873: I/IN_BUF_AFTER(10176): 6 
    09-05 13:06:21.873: I/IN_BUF_AFTER(10176): 0 
    ...truncated to save space ...
    09-05 13:06:21.893: I/IN_BUF_AFTER(10176): 0 
    09-05 13:06:21.893: I/IN_BUFFER(10176): We now send to handler.
    09-05 13:06:21.893: I/IN_BUFFER(10176): Read Stream into Buffer:
    09-05 13:06:21.898: V/BluetoothSocket.cpp(10176): readNative
    09-05 13:06:21.903: I/MESSAGE_READ(10176): I am reading 2 bytes
    09-05 13:06:21.903: I/Content(10176): The entire array:
    09-05 13:06:21.903: I/some hardcoded tag(10176): 48 
    09-05 13:06:21.903: I/some hardcoded tag(10176): 48 
    09-05 13:06:21.958: I/MESSAGE_READ(10176): I am reading 17 bytes
    09-05 13:06:21.958: I/Content(10176): The entire array:
    09-05 13:06:21.958: I/some hardcoded tag(10176): 48 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 48 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 48 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 48 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 48 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 44 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 48 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 48 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 49 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 51 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 48 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 44 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 85 
    09-05 13:06:21.958: I/some hardcoded tag(10176): 13 
    09-05 13:06:21.958: I/some hardcoded tag(10176): -57 
    09-05 13:06:21.963: I/some hardcoded tag(10176): 3 
    09-05 13:06:21.963: I/some hardcoded tag(10176): 6 
    

    I hope that hasn't confused the matter, but actually demonstrates the problem so many people appear to be having with the BluetoothChat demonstration code, when addapted for their own use. Somehow we need to keep the buffer from being overwritten until the message handler has read it?? Regards

    Adrian Wreyford

    Updated code working better because of Sleep!

    public void run() {
                Log.i(TAG, "BEGIN  IN mConnectedThread");
                byte[] buffer = new byte[1024];
                int bytes;
    
                // Keep listening to the InputStream while connected
                while (true) {
                    try {
                          try {
                            sleep(100);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        bytes = mmInStream.available();
                        Log.i("IN_BUFFER", "mmInStream-available bytes: " + Integer.toString(bytes)+ " ");
                        if (bytes>0){ 
                        for(int i=0; i<30; i++){ 
                           buffer[i] = 0;}
                        // Read from the InputStream
                        Log.i("IN_BUFFER", "Read Stream into Buffer:");
                        bytes = mmInStream.read(buffer);
    
                        Log.i("IN_BUFFER", "The entire buffer after read stream into buffer: " + Integer.toString(bytes)+ " "); 
                        for(int i=0; i<30; i++) 
                             Log.i("IN_BUF_AFTER", buffer[i] + " ");
                        // Send the obtained bytes to the UI Activity
                        Log.i("IN_BUFFER", "We now send to handler.");
                        mHandler.obtainMessage(BluetoothScale.MESSAGE_READ, bytes, -1, buffer)
                                .sendToTarget();}
                    } catch (IOException e) {
                        Log.e(TAG, "disconnected", e);
                        connectionLost();
                        // Start the service over to restart listening mode
                        BluetoothScaleService.this.start();
                        break;
                    }
                }
            }
    

    Now the logs look as follows:

    09-05 20:57:15.833: V/BluetoothSocket.cpp(25368): availableNative
    09-05 20:57:15.838: I/IN_BUFFER(25368): mmInStream-available bytes: 0 
    09-05 20:57:15.888: V/BluetoothSocket.cpp(25368): availableNative
    09-05 20:57:15.888: I/IN_BUFFER(25368): mmInStream-available bytes: 0 
    09-05 20:57:15.943: V/BluetoothSocket.cpp(25368): availableNative
    09-05 20:57:15.943: I/IN_BUFFER(25368): mmInStream-available bytes: 0 
    09-05 20:57:15.958: V/BluetoothSocket.cpp(25368): writeNative
    09-05 20:57:15.988: V/BluetoothSocket.cpp(25368): availableNative
    09-05 20:57:15.993: I/IN_BUFFER(25368): mmInStream-available bytes: 2 
    09-05 20:57:15.993: I/IN_BUFFER(25368): Read Stream into Buffer:
    09-05 20:57:15.993: V/BluetoothSocket.cpp(25368): readNative
    09-05 20:57:15.998: I/IN_BUFFER(25368): The entire buffer after read stream into buffer: 19 
    09-05 20:57:15.998: I/IN_BUF_AFTER(25368): 2 
    09-05 20:57:15.998: I/IN_BUF_AFTER(25368): -58 
    09-05 20:57:16.003: I/IN_BUF_AFTER(25368): 48 
    ...truncated to save space ... 
    09-05 20:57:16.033: I/IN_BUF_AFTER(25368): 85 
    09-05 20:57:16.033: I/IN_BUF_AFTER(25368): 13 
    09-05 20:57:16.033: I/IN_BUF_AFTER(25368): -57 
    09-05 20:57:16.033: I/IN_BUF_AFTER(25368): 3 
    09-05 20:57:16.038: I/IN_BUF_AFTER(25368): 6 
    09-05 20:57:16.038: I/IN_BUF_AFTER(25368): 0 
    ...truncated to save space ... 
    09-05 20:57:16.043: I/IN_BUF_AFTER(25368): 0 
    09-05 20:57:16.043: I/IN_BUFFER(25368): We now send to handler.
    09-05 20:57:16.058: I/MESSAGE_READ(25368): I am reading 19 bytes
    09-05 20:57:16.058: I/Content(25368): The entire array:
    09-05 20:57:16.058: I/some hardcoded tag(25368): 2 
    09-05 20:57:16.058: I/some hardcoded tag(25368): -58 
    09-05 20:57:16.058: I/some hardcoded tag(25368): 48 
    ...truncated to save space ...
    09-05 20:57:16.063: I/some hardcoded tag(25368): 13 
    09-05 20:57:16.063: I/some hardcoded tag(25368): -57 
    09-05 20:57:16.063: I/some hardcoded tag(25368): 3 
    09-05 20:57:16.063: I/some hardcoded tag(25368): 6 
    09-05 20:57:16.093: V/BluetoothSocket.cpp(25368): availableNative
    09-05 20:57:16.093: I/IN_BUFFER(25368): mmInStream-available bytes: 0
    

    Notice that the mmInStream.available() returns 2 bytes, then on the next line of code when we read the buffer, 19 bytes are read .. really strange, how it fills up between these two supposedly immediate steps. The sleep appears to allow enough time for the handler to read the message from passed buffer, before the buffer is rewritten to.

    I would have expected the handler.obtainmessage... to send a unique buffer, but appears to send the reference to the thread buffer, thus the hassle. How can I send a unique buffer each time? Thx Adrian

  • Adrian Wreyford
    Adrian Wreyford about 11 years
    Thx Radu, I took your advice and set up a few log.i's and it appears I'm closer to finding the real cause of the problem. Please se my original Question .. I'm adding the logs to try and show what is going on.
  • Radu
    Radu about 11 years
    Hi Adrian, I read your logs - although you have not update your code sample to be in-sync with the logs... You need to re-read my answer: So maybe you read the first 2 bytes, then a subsequent iteration you read the input buffer again without the first 2 bytes (the debugger shows you the wrong picture in this case). Why are you doing this? It is because your 'read' loop is executed way too many times - too fast!
  • Radu
    Radu about 11 years
    You should look at the code I posted and especially the first 2 lines! Read only when there is something to read! bytes = mmInStream.getAvailable(); if (bytes>0)
  • Radu
    Radu about 11 years
    If previous mentioned fix still does not work - copy the buffer into a new object - send the new object every time to the target. Don't worry about spamming too many new objects - you have garbage collection! Recompile your array there!
  • Adrian Wreyford
    Adrian Wreyford about 11 years
    I now have implemented your suggestion - only when bytes>0 mmInStream.Available(); with some improvement, but still overwriting the buffer before message handler getting to the buffer. I then put a sleep into my code, and suddenly it worked better, but still not faultlessly. Updated code above in main question.
  • Adrian Wreyford
    Adrian Wreyford about 11 years
    Thx Trevor, I have in the meentime figured using the copy of the array. What is a circular buffer?
  • Trevor
    Trevor about 11 years
    There is nothing wrong with constantly calling read(). It's a blocking socket call, which will return when there is data. Until the call returns (unblocks), the thread is essentially waiting on a semaphore; it is not "busy-waiting". Furthermore, the API documentation gives caution about making use of .available().
  • Trevor
    Trevor about 11 years
    You'd be best Googling it as it's a very common buffer structure. For now, you're probably fine performing an array copy. I've only used a circular buffer in my application because I'm dealing with large amounts of streaming data. In your situation I believe you're dealing with small amounts of data, so I don't think you'll benefit from an elaborate buffering scheme.
  • Radu
    Radu about 11 years
    You are probably right Trevor. It worked for me, so I wanted Adrian to move towards my code :). So the problem was in fact that he transmitted a reference to the buffer which is subject to change.
  • user1213202
    user1213202 almost 10 years
    can you please show run method code how you have send copy of the array or use a simple circular buffer