Scenario:
Given, a device which is always turned on, and does a Bluetooth Low Energy advertising every second.
I have to implement an application for Android tablets which connects to this device via Bluetooth Low Energy, sends some commands and then disconnects from it.
Minimum Android version: the one which works best, I'm free to decide.
I started with API 21 (Android 5.0, Lollipop)
Issue:
The issues the BLE stack has, caused trouble also for me: I'd like to issue a successful direct connection using the object retrieved by BluetoothAdapter#getRemoteDevice(MACAddress: String) method, and it always fails.
Results of my research:
Below are the questions / answers / posts that I've found and seems useful (maybe these will help someone):
- Bluetooth / BLE development is miserable on Android. Anyone know any special tricks?
- android ble connect slowly
- an implementation of GattManager, which has workarounds - implementation by a company in Norway: Nordic Semiconductor
- RxAndroidBle - "RxAndroidBle is a powerful painkiller for Android's Bluetooth Low Energy headaches. It is backed by RxJava, implementing complicated APIs as handy reactive observables."
- workaround for re/connecting
Questions:
Beside these, I looked into the BluetoothDevice's source code, and I've found out that the Context parameter of the connectGatt() method is not used at all:
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothDevice.java#1899
Wondering if can this be one of the reasons of the flaws the BLE stack has?
Also, I don't understand what is the difference between a BluetoothDevice object retrieved by the scanner vs the one retrieved by BluetoothAdapter#getRemoteDevice(MACAddress: String) method.
If I issue a direct connection (autoconnect parameter is set to false when calling connectGatt()) on the device got via scanning, the connection usually succeeds. But, a direct connection always fails (status = 133, timeout) when using the object retrieved by getRemoteDevice().
As the device I want to connect to advertises itself every second, I expect the direct connection to always / most of the time work, like in the case of scanning.
Because the background connection (autoconnect parameter set to true) is very slow, I cannot rely on that.
Also, because the scanning is unreliable and slow, I cannot force the user to wait every time the application starts.
To summarize my questions:
- The Context parameter of the connectGatt() method is not used at all - can this be one of the reasons of the flaws the BLE stack has? I suppose someone put it there for a good reason.
- What is the difference between a BluetoothDevice object retrieved by the scanner vs the one retrieved by BluetoothAdapter#getRemoteDevice(MACAddress: String) method?