5

My application has issues when it comes to connecting to BluetoothGatt on certain devices.

All the BLE related code resides in an android Service and everything works fine except on Huawei CAM-L03. Some old Samsung Galaxy devices also have been reported to have issues.

I have discovered recently, that on some devices all the BLE communications must be performed on the UI thread. I wrote a quick test application and the Huawei problems are gone when everything runs on the UI thread.

I’ve tried creating a Handler in the Service with the main looper:

final Context context = getApplicationContext();
Handler handler = new Handler(context.getMainLooper());
handler.post(new Runnable(){
    @Override
    public void run() {
        BluetoothGatt gatt = device.connectGatt(context, false, callBackHandler);
        …
    } 
});

But that still gives me GATT_ERROR 133 in the connection callback, which I kind of suspected since the context is the service, not the UI app.

I only see two options here:

  1. List item Don’t support certain devices
  2. Move everything to the UI app to support all devices

I’m not content with either of these. Are there other options that I don’t know about?

unexplored
  • 1,414
  • 3
  • 18
  • 37
  • Try using runOnUiThread instead. YOu need an Activity instance though – Zoe Jul 31 '17 at 16:05
  • That's the thing, I don't have access to an Activity. – unexplored Jul 31 '17 at 16:59
  • There is nothing at all that differentiates how the Bluetooth calls work depending on which thread you run the call on. Android's Bluetooth API uses the "Binder" feature in Android to talk to the Bluetooth service. The error code 133 is just a general error code that means that it didn't succeed. One of the most common reasons the error code is 133 in the onConnectionChange callback is because the connection attempt timed out. – Emil Jul 31 '17 at 23:24
  • @Emil this old answer (https://stackoverflow.com/a/20507449/912094), and few others, suggests that the thread in which the gatt APIs are called matters. Anyhow, I found what the problem was. I'll post an answer now. – unexplored Aug 01 '17 at 13:37
  • Calling the connection on the main thread does help in certain cases with older devices, especially when they are – Roberto Betancourt Aug 01 '17 at 14:11

1 Answers1

7

I figured what the problem actually was and how to solve it. I'm adding my answer as another check for the generic gatt error (133) thrown on connection attempts because I didn't find one hinting to the same issue.

I have been led to a wrong conclusion by answers like this. I think that bug was long fixed on Android. The fact that I was getting connection failed callback is an indication that the thread issue was irrelevant since the callbacks were registered.

The problem I was facing was related to the fact that I kept the bluetooth adapter scanning while attempting to connect to the BLE device. It appears that some phones have a problem with that.

The requirements of my application dictate continuous scanning for the time the service is running and all the test phones I had around didn't have problems with it. This model of HUAWEI though, would refuse to connect.

TL;DR Stop scanning before attempting to connect, restart scanning if required after disconnect.

unexplored
  • 1,414
  • 3
  • 18
  • 37
  • 1
    Yes we have noticed this as well but only with one phone, namely Huawei P8 Lite. Which phone do you have where this issue happens? – Emil Aug 01 '17 at 16:08
  • @Emil I've mentioned it in the question - Huawei CAM-L03. I think we're having the same issues with some HTC devices, but I can't confirm since I don't have one around. – unexplored Aug 01 '17 at 16:18
  • 1
    Oh sorry I missed that. Anyway, if anybody is interested, the Bluetooth controller in Huawei P8 Lite is the source of the issue there. The host stack tells the controller to both scan and connect, and it replies with success status. However it still always fails to connect until you stop the scan. – Emil Aug 01 '17 at 17:41
  • @Emil are you aware of any other phones with that behavior? I'd say it's the same for Huawei P9 and P10. Your tip saved the day, I've been dealing with that issue for ages. – Maragues Apr 20 '18 at 15:47
  • Even with that workaround, it's still a very unreliable connection. Sometimes it works fine, others it takes ages to connect, others it never connects. I'm leaving them blacklisted in Google Play :( – Maragues Apr 20 '18 at 16:11
  • I am facing the same issue. I am using Huawei P8 lite with Android v6.0. I tried to stop scanning before calling *device.connectGatt(getApplicationContext(), false, mBluetoothGattCallback);* but no success. After few seconds, it gave 133 GATT_FAILURE error. – Aanal Shah Sep 07 '18 at 12:55
  • @AanalMehta try adding a small delay between stopping scanning and connect. The stack might take some time to actually stop disconnecting. Check the logcat output for BT related events to see how long it takes between you asking for disconnect and it actually disconnecting. – unexplored Sep 07 '18 at 14:36
  • I have called Stop Scanning first and after 2 seconds of delay *device.connectGatt(getApplicationContext()* will be called. Is anything required to change? – Aanal Shah Sep 09 '18 at 10:09
  • @AanalMehta were you able to see in logcat logs from the BT stack saying it stopped scanning? Does your code works as expected on other devices? Where you able to ever connect from this device? – unexplored Sep 10 '18 at 14:10
  • Yes, I can see the scanning is stopped. I tried the same code for Nexus 5, Nexus 5x, Samsung Galaxy S7, S8 and it's working fine for them. – Aanal Shah Sep 11 '18 at 04:46