theman theman - 1 year ago 186
Android Question

Error in reading data from InputStream in Bluetooth on Android

I'm working on an Android app, which uses bluetooth connection to transfer data between my android smartphone and a non-android bluetooth module, using SPP profile. I've used Bluetooth Chat Example from Android Developer site as reference.

I've successfully made two devices connect to each other and sent simple strings from the smart phone to the bluetooth module. But I've got some error in reading data sent back from the module. I've used the following code, which is exactly the same as in Bluetooth Chat Example, to read data from InputStream

while (true)
try {
// Read from the InputStream
bytes =;
String str = new String(buffer);
Log.i(TAG, "mmInStream - " + str);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
} catch (IOException e) {
Log.e(TAG, "disconnected", e);

When my bluetooth module send a simple string to the phone, that string is not received correctly. It is splited into several pieces in random ways. For example, if I send "1234567890abcdef1234567890abcdef0123456789" for three times to the phone, the Logcat on Eclipse will log these:

mmInstream - 12345678910abcdef��������(continuing null)
mmInstream - 1��������(continuing null)
mmInstream - 2345678910abcdef0123456789��������(continuing null)

for the first time. In the second and the third time data is transmitted, it is received in a difference pieces:

mmInstream - 1234567891�������(continuing null)
mmInstream - 0abcdef012�������(continuing null)
mmInstream - 3456789���������(continuing null)

mmInstream - 1234567891����������������(continuing null)
mmInstream - 0abcdef0123456789������������(continuing null)

I don't know why this happen and how to solve this problem. If data is received in a arbitrary way like this, I can't get necessary data to process. How can I get it in one pieces?

Any help would be appreciated.

Many Thanks.

Answer Source

Two things I noticed with your code:

  • First of all sending further down to your app a reference to the buffer in which you read is not always a good solution: What if in the meantime the buffer gets overridden? See this bug on stackoverflow for example You can bypass this by making a copy of the data (for example use buffer.clone()) which you have read from Bluetooth, or if you don't like using too much memory you can make your read buffer a circular one.

  • You should be able to recompile your data even if it is received in separate packets (but packets are received in a short time span). You can make start/stop flags for instance. Ofc it still depends on the type of object you send over Bluetooth...

And now a possible solution if the 2 previous warnings are of no use is this:

Instead of an infinite loop which calls .read - a blocking call - you can do something like this:

while(true) {
     if mmInStream.getAvailable()>0 { 
          -your read code here-
     else SystemClock.sleep(100);

It's a hack and it might still sometimes read only some part of the message - but it will be very rare!

Pls vote up/correct if useful!