Search code examples
androidbluetoothunreliable-connection

Why does Android Bluetooth stop receiving bytes after a few minutes?


I'm having trouble maintaining a Bluetooth connection (from Android to a device I'm developing) for longer than a few minutes.

The scenario is:

  1. Device is paired successfully.
  2. Device transmits to Android for somewhere between 1-7 minutes (varies by device or possibly Android version).
  3. Android stops receiving bytes although device is still transmitting.

So: why does Android BT stop receiving?

This is very similar to the issue/observation described in bboydflo's answer to this question: Application using bluetooth SPP profile not working after update from Android 4.2 to Android 4.3

Some more background:

  • The BT device I'm working with continually emits measurement packets containing ~200 characters, once per second. I am certain that the device-side is still transmitting when the issue occurs.
  • This sympom happens in my app on two Android devices: an Android 5.0.1 Acer tablet, and an Android 7.1.1 Moto Play X
  • I've tested with an app called Serial Bluetooth Terminal. This app does not experience the same issue; the connection is stable for as long as I've tested. Therefore, this issue is probably caused by something in my application code.
  • I've seen various responses to Android BT questions directing the user to use asynchronous streams rather than polling for received bytes. This seems to be a red herring; if you feel that the threading model is causing a probelm in this case, please clearly describe why switching to async would resolve this issue.

I would like to pre-emptively address reasons that this question may be closed:

  • This is not a duplicate. There are other questions on SO about BT connections dropping (i.e. Real-time Bluetooth SPP data streaming on Android only works for 5 seconds) but this is not the same issue. I have already added a keep-alive outgoing char transmitted every 1s, and my issue remains.
  • I'm not asking about an issue specific to my application; at least one other user on SO has encountered this problem.
  • I've reviewed the Android Bluetooth documentation in detail, and I can't see any obvious reason for this to happen.
  • I'm not asking for an opinion; I'm asking for an objective answer as to why the bytes stop being received.

Solution

  • Ok, I have a partial answer for this one. First, a bit more background:

    • I was running the BT stream polling on a thread which executed a runnable every 2s
    • The buffer being used to read the stream was 1024 elements long

    I had a suspicious that this might be some background buffer running out of space. So, I changed the 2s to 500ms and the 1024-length to 10024. Now, I've had about 20 minutes of connectivity without any trouble (and still going).

    It would be nice to find the smoking gun for this. I initially thought that stream.Available() would be sufficient to tell if a buffer was getting filled up, but in this scenario, stream.Available() is actually returning 0 when the Android device stops receiving. So I'm not really sure which queue to check to prove that this issue is related to a buffer becoming filled.