11
votes

I've been having an issue with data integrity using an RFCOMM socket over Bluetooth in Android. I don't have any issues connecting, but the data I receive is garbled and not the same as the data that is sent. The data is sent by an RS232 device over a Bluetooth adapter, which the phone connects to. There isn't a problem with the adapter as the data is properly received if I connect with a laptop.

My Bluetooth connection is handled based off of the BluetoothChat sample application found at the Android developer site (http://developer.android.com/resources/samples/BluetoothChat/index.html), with no changes. The data being sent is plain text and control characters (which are stripped out before display to the user). The specific problem I have is that some of the text is missing, some of it is repeated, etc. The funny thing is if I connect to a computer with a terminal app and type in there, the data is transmitted fine. Additionally, if I connect to the device using the GetBlue app the data is received fine.

So I guess the issue is what does GetBlue possibly do different to handle its Bluetooth data transfer, or is there another way receive Bluetooth data over an RFCOMM socket on Android?

2
I think part of the issue has to do with threading, as the function that reads in the stream is on a separate thread. Also, the data is being sent quickly.clinejj

2 Answers

10
votes

The fix for the solution was to create the string in the connected thread, directly after calling read() on the InputStream, and then passing the string back to the main thread for display. For whatever reason, passing the byte array between threads led to significant repetition and data loss.

Modified run() code:

    public void run() {
        byte[] buffer = new byte[256];  // buffer store for the stream
        int bytes; // bytes returned from read()

        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);
                String readMessage = new String(buffer, 0, bytes);
                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(MESSAGE_READ, bytes, -1, readMessage)
                        .sendToTarget();
            } catch (IOException e) {
                break;
            }
        }
    }

And the handler reception:

        case MESSAGE_READ:
            // Read in string from message, display to mainText for user
            String readMessage = (String) msg.obj;
            if (msg.arg1 > 0) {
                mainText.append(readMessage);
            }
2
votes

This error is because the object reference is passed to the UI, If you copy the byte array(buffer) to another byte array it works.