I have an application that working well on Android 4.3 and 4.4.
The application will connect and communicate with a custom bluetooth device.
After I flashed my Nexus 5 to Lollipop suddenly the I can't connect to the device at all. The connection result always 133. This is the log :
D/BluetoothGatt﹕ connect() - device: 00:07:80:04:1A:5A, auto: true
D/BluetoothGatt﹕ registerApp()
D/BluetoothGatt﹕ registerApp() - UUID=xxxxxx-xxxx-xxxxx-xxxx-xxxxxxxx
D/BluetoothGatt﹕ onClientRegistered() - status=0 clientIf=6
D/BluetoothGatt﹕ onClientConnectionState() - status=133 clientIf=6 device=00:07:80:04:1A:5A
My code :
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
return false;
}
Handler handler = new Handler(Looper.getMainLooper());
// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null
&& address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
handler.post(new Runnable() {
@Override
public void run() {
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
}
}
});
if (mConnectionState == STATE_CONNECTING) {
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
return false;
}
handler.post(new Runnable() {
@Override
public void run() {
mBluetoothGatt = device.connectGatt(BluetoothConnectService.this, true, mGattCallback);
}
});
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
Anybody have any idea about this?
If your Bluetooth devices won't connect, it's likely because the devices are out of range, or aren't in pairing mode. If you're having persistent Bluetooth connection problems, try resetting your devices, or having your phone or tablet "forget" the connection.
Reset Bluetooth Settings 1: Go to Settings -> System and tap the Advanced drop-down button. 2: Select Reset options and then tap Reset Wi-Fi, mobile, & Bluetooth. 3: Tap the Reset settings button below and enter your phone's PIN when asked.
Sometimes, to fix Android Bluetooth not working, you might just need restarting it; especially if it's been left switched on for a while. Therefore, all you need to do is just simply off/on the Bluetooth connection. You'll see the Bluetooth icon, tap on it to switch it off. Now tap on it again to turn it on.
So I figured out that the problem is the Transport choice in Lollipop.
As you can see in here the change in the
BluetoothDevice.connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)
function is calling
BluetoothDevice.connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback, int transport)
with transport set to TRANSPORT_AUTO.
In my case because I will always use TRANSPORT_LE (The value is 2)
I tried to call the second method from my code and set the transport to TRANSPORT_LE.
For unknown reason I can't call it directly so I'm using reflection to call it.
Until now this works fine for me.
if(TTTUtilities.isLollipopOrAbove()) {
// Little hack with reflect to use the connect gatt with defined transport in Lollipop
Method connectGattMethod = null;
try {
connectGattMethod = device.getClass().getMethod("connectGatt", Context.class, boolean.class, BluetoothGattCallback.class, int.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
mBluetoothGatt = (BluetoothGatt) connectGattMethod.invoke(device, BluetoothConnectService.this, false, mGattCallback, TRANSPORT_LE);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} else {
mBluetoothGatt = device.connectGatt(BluetoothConnectService.this, true, mGattCallback);
}
If any of you have question about my answer feel free to ask in the comment.
Thank you.
For Xamarin users who have the same issue, here is a slightly different solution. I had the same issue with a Nexus 7 Android 6 using the Xamarin cross platform SDK. The use of TRANSPORT_LE fixed the issue. Rather than using Reflection to get the method by its signature (does not work), one can use Reflection to iterate through all the methods until you find a matching name. See code below:
BluetoothDevice bd = (BluetoothDevice)device.NativeDevice;
Java.Lang.Reflect.Method[] methods = bd.Class.GetDeclaredMethods();
foreach (Java.Lang.Reflect.Method possibleConnectGattMethod in methods)
{
// Find matching method name connectGatt and then invoke it with TRANSPORT_LE
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With