I have a bluetooth headset which is paired with my Nexus 5X (running Android 7.1) and I would like to connect to a GATT Server of the headset. I tried it with the following code:
private BluetoothGattCallback btleGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.d(TAG, "onConnectionStateChange: " + status + ", " + newState);
if(newState == STATE_CONNECTED) {
Log.d(TAG, "Device connected");
boolean ans = gatt.discoverServices();
Log.d(TAG, "Discover Services started: " + ans);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
Log.d(TAG, "Number of Services: " + gatt.getServices().size());
}
};
public void onDeviceClicked(BluetoothDevice device) {
BluetoothGatt gatt = device.connectGatt(this, false, btleGattCallback);
Log.d(TAG, "Connected to GATT: " + gatt.connect());
}
If I click on the headset in my UI onDeviceClicked
is called and it comes to this Log output:
<!-- language: lang-none -->
Connected to GATT: true
onConnectionStateChange: 0, 2 // GATT_SUCCESS, STATE_CONNECTED
Device connected
Discover Services started: true
As you can see onServicesDiscovered
is never fired. I tried to call connectGatt
with TRANSPORT_LE
(ref) but then I get a onConnectionStateChange: 133, 0
. I also found this question which is why I added the gatt.connect()
method as mentioned in answer two.
Do you have any ideas why I don't get the onServicesDiscovered
callback?
In fact,I solve this problem by Execution the method mBluetoothGatt.discoverServices() several times(10 or more),
This may help
I will explain in two steps : connecting and discovering services
connecting: connect from mainthread
set auto reconnect to false
if Version greater than or equals to M , set Tranposrt type
else directly use reflection and handle it properly
disover services : in onGhattListener , if device is connected fire
discoverServices()
from main threadthis may solve your problem
call refresh method with reflection
Had the same problem, but waiting 600 ms wasn't enough. This is probably due to the BLE module used. I fixed the problem by calling my method
after calling
I'm basically just calling discoverServices every 5 seconds (this is arbitrarily chosen)
In the onServicesDiscovered(...) method of my gattCallback I make gattConnected true. This worked for me.
Something that has been really useful for me is to wait for about 600ms after the connection has been established and then start the service discovery.
BLE on Android can be a little finicky.
Make sure you are calling mBluetoothGatt.discoverServices() on the UI thread.
Also try making
BluetoothGatt gatt
a field variable instead of a local variable.If you are doing any significant work, try using a library that masks all of the idiosyncrasies so you can focus on the high level logic. https://github.com/Polidea/RxAndroidBle.
Here is an example of how to read a characteristic.
Or with Java 7 syntax