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:
Device is paired successfully.
Device transmits to Android for somewhere between 1-7 minutes (varies by device or possibly Android version).
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.
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.
Hi everyone I have a question for you. I have a project that is using xamarin forms and in this project we are using the signalr client. Whenever I switch from Wi-Fi to cellular data my signal are times out. However the weird thing is that no statechanged events ever fire on a client side not even the disconnect, and I can still send messages with the proxy to other clients but it doesn't receive messages from the other clients. I had a question last week where servicestack was timing out when I switched from Wi-Fi to mobile and the solution was to put a connection header in the request that was set to close. I tried that with the signalr connection but it doesn't work. I've also tried to use the project modernhttpclient and that doesn't work either. On the server side I've even tried saying the keepalive to know so that way it only uses the connection timeout and the disconnect timeout.
Some other weird information about this problem is that it doesn't happen on all Android devices. It seems to work on the Samsung and a different Android device possibly a Nexus device. The reason I know this is that my coworkers have these phones and it works perfectly fine for them. However my device, which is a samsung galaxy s6 edge comma does not work with the code that was implemented for reconnecting when did not work changes
I'm making an application which has to talk to a BLE devices on Android.
I am running into issues establishing the connection to the BLE device.
Case 1) Scan:
During a scan after a device has been discovered and reported via
BluetoothLEScanCallback.onScanResult(...)
I am attempting the connect via:
result.getDevice().connectGatt(...)
Problem is on some devices I test this (namely HTC One M8 running Android 5.0.1 and HTC Desire 516 running Android 4.3) the connection process seems to fail, i.e. the callback
BluetoothGattCallback.onConnectionStateChange(....)
is simply not called most of the time.
Now this is not a consistent behavior, sometimes it is sometimes it is not.
The second problem is that often if the connection is established
the
BluetoothGatt.discoverServices()
call fails, i.e. the
BluetoothGattCallback.onServicesDiscovered(...)
is also not called. I tried retrying the call a couple of times spaced by X number of milliseconds but it seems to consistently fail regardless of the number of attempts or spacing between them.
Case 2 Listening
The pretty much same thing happens when I attempt to simply "listen" for a device, again calling
BluetoothDevice device = BluetoothManager.getAdapter().getRemoteDevice(macAddress);
device.connectGatt(...)
results often in the same situation.
In both cases I am having issue with Android most of the time, I have a Nexus 5 device on which that same code seems to work for the most part (sometimes the BT stack seems to fail to do its job)
A bit more disturbing that the iOS application we have has none of these problems.
Has anyone encountered these issues?
Any ideas how to address them?
EDIT:
We did "solve" this one. Just in case somebody stumbles on such situation, the issue in my case is that ymmv a lot from device to device or even from connection to connection.
Sometimes the process happens in a second or so other times it takes 5, in my tests it can climb up to like 15 on the devices I test with.
As for why this is I can't tell.
I encounter the same problem. I connect to a Bluegigga BLE113 bluetooth 4.0 module. My app is based on the BluetoothLeGatt Sample source. My Samsung phone connects great, with no problems. My LG V10 can't connect. Except sometimes, when it will connect. Mostly, it won't connect. onConnectionStateChange never gets called. It is very frustrating, and I haven't been able to figure out the problem.
But I can connect my LG phone if I use NRF Connect, which seems to prove there is a programming solution. But they don't release the source for NRF-Connect.
If anyone can expand of how to fix this, I would appreciate it.
Together with a sub-company we try to develop an android app which simulates an automotive HMI system. There is a functionality to changes the color-theme in case of connected mobile-phone (via Bluetooth). In general this is working: If a known paired phone is in range the theme switches... if the phone loses connection the theme switches back...
Problem: Currently the app polls the paired bluetooth devices for every second and checks if a known phone is paired.
After ~1h and 20min (+/- 5min) the app freezes (reproducible).
Our sub-company told us, that the reason is a problem in android bluetooth device - A timer overflows and android refuses the requests of the app after this time. Thats the reason, that the app freezes.
I´m not familiar with android development and I have to believe in this statements.
Could you tell me if there are other possibilities?
Is it necessary to poll the bluetooth device? Is there nothing like an system event which could be used?
Is this problem (refused bluetooth pooling after defined time) known?
Hint: The problem occurs only with power supply. In battery usage the app runs till battery is empty (longer than 80min).
Samsung Galaxy Tab Pro with android 4.4 (same problem with android 4.3)
It would be nice if anybody is able to help.
Many thanks
I am currently developing an application that will use Bluetooth Low Energy (testing on the Nexus 4). After getting started with the official BLE APIs in Android 4.3, I have noticed that after I connect a device for the first time I am rarely able to successfully connect to / communicate with that device or any other device again.
Following the guide here, I can successfully connect to a device, scan services and characteristics, and read/write/receive notifications without any issues. However, after disconnecting and re-connecting, I am often unable to either scan services/characteristics or unable to complete a read/write. I can't find anything in the logs to indicate why this is happening.
Once this happens I have to uninstall the application, disable Bluetooth, and restart the phone before it will start working again.
Whenever a device is disconnected I make sure to call close() on the BluetoothGatt object and set it to null. Any insights?
EDIT:
Log dumps: For these logs I rooted my phone and upped the trace levels of related items in /etc/bluetooth/bt_stack.conf
Successful connection - First attempt after rebooting the phone and installing the app. I am able to connect, discover all services/characteristics, and read/write.
Failed Attempt 1 - This is the next attempt after disconnecting from the successful connection above. It seems I was able to discover characteristics, but the first attempt to read returned a null value and disconnected soon thereafter.
Failed Attempt 2 - An example where I am not even able to discover services/characteristics.
EDIT 2:
The device to which I am trying to connect is based on TI's CC2541 chip. I obtained a TI SensorTag (also based on the CC2541) to play around with and discovered that TI released an android app for the SensorTag yesterday. However, this app has the same problem. I tested this on two other Nexus 4s with the same result: Connection to the SensorTag is successful the first or second time, but (according to the logs) fails to discover services thereafter, causing all sorts of crashes. I'm starting to wonder if it's an issue with this specific chip?
Important implementation hints
(Perhaps some of those hints aren't necessary anymore due to Android OS updates.)
Some devices like Nexus 4 with Android 4.3 take 45+ seconds to connect using an existing gatt instance. Work around: Always close gatt instances on disconnect and create a fresh instance of gatt on each connect.
Don't forget to call android.bluetooth.BluetoothGatt#close()
Start a new thread inside onLeScan(..) and then connect. Reason: BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback) always fails, if called inside LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) in the same thread on Samsung Galaxy S3 with Android 4.3 (at least for build JSS15J.I9300XXUGMK6)
Most devices filter advertising
Better not use android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback) with the parameter to filter for certain service UUIDs because this is broken completely in Samsung Galaxy S3 with Android 4.3 and doesn't work for 128bit UUIDs in general.
Gatt always can process one command at a time. If several commands get called short after another, the first one gets cancelled due to the synchronous nature of the gatt implementation.
I often see even on modern devices with Android 5, that Wifi interferes withs bluetooth and vice versa. As a last resort, turn off wifi to stabilize bluetooth.
Tutorial for beginners
A pretty OK entry point for newcomers could be this video tutorial: Developing Bluetooth Smart Applications for Android http://youtu.be/x1y4tEHDwk0
The issue and work around described below is probably fixed now by OS updates
Work around: I could "stabilize" my app doing that...
I provide the user a setting "Restart Bluetooth". If that setting is enabled, I restart Bluetooth at some points that indicate the begin of BLE stack becoming unstable. E.g. if startScan returns false. A good point may also be if serviceDiscovery failes. I just turn Bluetooth off and on.
I provide another setting "Turn off WiFi". If that setting is enabled, my app turns off Wifi when the app is running (and turns it back on afterwards)
This work around is based on follwoing experiences...
Restarting Bluetooth helps to fix problems with BLE in most cases
If you turn off Wifi, the BLE stack gets much more stable. However, it also works fine on most devices with wifi turned on.
If you turn off Wifi, restarting Bluetooth fully recovers the BLE stack without the need to reboot the device in most cases.
Turning WIFI OFF:
I can confirm too, that turning WIFI OFF makes Bluetooth 4.0 more stable especially on Google Nexus (I have a Nexus 7).
The problem
is that the application I am developing needs both WIFI and continous Bluetooth LE scanning. So turning WIFI OFF was no option for me.
Moreover I have realised is that continous Bluetooth LE scanning can actually kill WIFI connection and make the WIFI adapter unable to re-connect to any WIFI network until BLE scan is ON. (I'm not sure about mobile networks and mobile internet).
This definitely happened on the following devices:
Nexus 7
Motorola Moto G
However BLE scanning with WIFI on seemed pretty stable on:
Samsung S4
HTC One
My workaround
I scan BLE for a short period of time 3-4 seconds then I turn scan OFF for 3-4 seconds. Then ON again.
Obviously I always turn BLE scan OFF when I'm connecting to a BLE device.
When I disconnect from a device I restart BLE (turn adapter OFF and then ON) to reset the stack before starting scan again.
I also reset BLE when discovering services or characteristics fails.
When I get advertisement data from a device that the app should connect to (lets say 500 times without being able to connect - thats about 5-10 seconds of advertising) I reset BLE again.
Make sure your Nexus is paired to the device. I can't verify whether or not the communication works properly, but you will be able to connect more than once without a reboot. It seems the first connect is not requiring pairing but all subsequent attempts do.
I will update this answer in a couple of days when I test service discovery and gatt read and write requests without a reboot.
EDIT:
It turns out I was testing on a development firmware version (our sensor) that was causing issues if not paired. Our latest production firmware build works fine on the 2540s and 2541s.
EDIT:
I did notice that on the Nexus 7 2013, connections are more stable when WiFi is turned off. I'd like to know if this helps anyone else.
EDIT:
I seem to have had it backwards with pairing. Everything works fine when not paired. After pairing, I am experiencing the exact same symptoms as the OP. It's just not known yet if this is related to our firmware or the Android BLE API. Be careful if testing this because once paired, you may not be able to unpair due to a bug explained in 3b of this post.
In some models there is a defect:
https://code.google.com/p/android/issues/detail?id=180440
On the other hand in my case the problem was, that my connection was not properly closed in onDestroy method. After correct closing, problem for me is not existing, not matter that wifi is turned on or off.
btGatt.disconnect();
btGatt.close();
I was facing a similar issue. My fix was
if (Build.VERSION.SDK_INT >= 23) {
mBluetoothGatt = device.connectGatt(this, false, mGattCallback, BluetoothDevice.TRANSPORT_LE);
} else {
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
}
& calling close after disconnect.