From 9b992b4800c4eedb9b7abf40b932839835519b19 Mon Sep 17 00:00:00 2001 From: Eugene Kuleshov Date: Wed, 4 Dec 2024 22:11:48 -0500 Subject: [PATCH] force TRANSPORT_LE for connectGatt on Android 5 (#111) --- .../MyCentralManager.kt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/hebei/bluetooth_low_energy_android/MyCentralManager.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/hebei/bluetooth_low_energy_android/MyCentralManager.kt index 7afa156..6b750d3 100644 --- a/bluetooth_low_energy_android/android/src/main/kotlin/dev/hebei/bluetooth_low_energy_android/MyCentralManager.kt +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/hebei/bluetooth_low_energy_android/MyCentralManager.kt @@ -26,6 +26,7 @@ import androidx.core.app.ActivityCompat import androidx.core.app.ActivityOptionsCompat import androidx.core.content.ContextCompat import io.flutter.plugin.common.BinaryMessenger +import java.lang.reflect.Method import java.util.concurrent.Executor class MyCentralManager(context: Context, binaryMessenger: BinaryMessenger) : MyBluetoothLowEnergyManager(context), MyCentralManagerHostAPI { @@ -174,7 +175,23 @@ class MyCentralManager(context: Context, binaryMessenger: BinaryMessenger) : MyB val transport = BluetoothDevice.TRANSPORT_LE device.connectGatt(context, autoConnect, mBluetoothGattCallback, transport) } else { - device.connectGatt(context, autoConnect, mBluetoothGattCallback) + try { + // From Android LOLLIPOP (21) the transport types exists, but it is private + // have to use reflection to call it for TRANSPORT_LE + val connectGattMethod: Method = device.javaClass.getDeclaredMethod( + "connectGatt", + Context::class.java, + Boolean::class.javaPrimitiveType, + BluetoothGattCallback::class.java, + Int::class.javaPrimitiveType + ) + connectGattMethod.isAccessible = true + connectGattMethod.invoke( + device, context, autoConnect, mBluetoothGattCallback, 2 /* TRANSPORT_LE */) as BluetoothGatt + } catch (ex: Exception) { + // fall back to default method if reflection fails + device.connectGatt(context, autoConnect, mBluetoothGattCallback) + } } mConnectCallbacks[addressArgs] = callback } catch (e: Throwable) {