Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- protected class ConnectBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(@NonNull Context context, @NonNull Intent intent) {
- logger.v(TAG + "------------------------ConnectBroadcastReceiver : onReceive " + intent.getAction());
- if ((intent.getAction().equals(BluetoothDevice.ACTION_ACL_CONNECTED))) {
- logger.v(TAG + "------------------------ConnectBroadcastReceiver : onReceive " + intent.getAction());
- logger.v(TAG + "PairingBroadcastReceiver : CONNECTED");
- } if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
- BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- if (bluetoothAdapter.isEnabled()) {
- bleDeviceManager.setApplicationContext(BluetoothLeService.this);
- bleDeviceManager.connectAll(bluetoothAdapter);
- }
- }
- }
- }
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
- filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
- filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
- filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
- filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
- registerReceiver(connectBroadcastReceiver, filter);
- @Override
- public void connectAll(final BluetoothAdapter bluetoothAdapter) {
- mainThreadHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- connectedGatt.clear();
- devicesList.clear();
- deviceHandlerMap.clear();
- logger.d(TAG + "connectAll");
- List<Sensor> sensors = databaseRepository.getConnectedSensors();
- for (Sensor sensor : sensors) {
- BluetoothDevice device = bluetoothAdapter.getRemoteDevice(sensor.getAddress());
- connectedGatt.add(new BleConnectionCompat(applicationContext, logger).connectGatt(device, true, callback));
- logger.d(TAG + "connect " + device.getName() + " " + device.getAddress());
- }
- }
- }, 10000);
- }
- public class BleConnectionCompat {
- private final Context context;
- private Logger logger;
- public BleConnectionCompat(Context context, Logger logger) {
- this.context = context;
- this.logger = logger;
- }
- public BluetoothGatt connectGatt(BluetoothDevice remoteDevice, boolean autoConnect, BluetoothGattCallback bluetoothGattCallback) {
- if (remoteDevice == null) {
- return null;
- }
- /**
- * Issue that caused a race condition mentioned below was fixed in 7.0.0_r1
- * https://android.googlesource.com/platform/frameworks/base/+/android-7.0.0_r1/core/java/android/bluetooth/BluetoothGatt.java#649
- * compared to
- * https://android.googlesource.com/platform/frameworks/base/+/android-6.0.1_r72/core/java/android/bluetooth/BluetoothGatt.java#739
- * issue: https://android.googlesource.com/platform/frameworks/base/+/d35167adcaa40cb54df8e392379dfdfe98bcdba2%5E%21/#F0
- */
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M || !autoConnect) {
- return connectGattCompat(bluetoothGattCallback, remoteDevice, autoConnect);
- }
- /**
- * Some implementations of Bluetooth Stack have a race condition where autoConnect flag
- * is not properly set before calling connectGatt. That's the reason for using reflection
- * to set the flag manually.
- */
- try {
- logger.v("Trying to connectGatt using reflection.");
- Object iBluetoothGatt = getIBluetoothGatt(getIBluetoothManager());
- if (iBluetoothGatt == null) {
- logger.w("Couldn't get iBluetoothGatt object");
- return connectGattCompat(bluetoothGattCallback, remoteDevice, true);
- }
- BluetoothGatt bluetoothGatt = createBluetoothGatt(iBluetoothGatt, remoteDevice);
- if (bluetoothGatt == null) {
- logger.w("Couldn't create BluetoothGatt object");
- return connectGattCompat(bluetoothGattCallback, remoteDevice, true);
- }
- boolean connectedSuccessfully = connectUsingReflection(bluetoothGatt, bluetoothGattCallback, true);
- if (!connectedSuccessfully) {
- logger.w("Connection using reflection failed, closing gatt");
- bluetoothGatt.close();
- }
- return bluetoothGatt;
- } catch (NoSuchMethodException
- | IllegalAccessException
- | IllegalArgumentException
- | InvocationTargetException
- | InstantiationException
- | NoSuchFieldException exception) {
- logger.w(exception + "Error during reflection");
- return connectGattCompat(bluetoothGattCallback, remoteDevice, true);
- }
- }
- private BluetoothGatt connectGattCompat(BluetoothGattCallback bluetoothGattCallback, BluetoothDevice device, boolean autoConnect) {
- logger.v("Connecting without reflection");
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- return device.connectGatt(context, autoConnect, bluetoothGattCallback, TRANSPORT_LE);
- } else {
- return device.connectGatt(context, autoConnect, bluetoothGattCallback);
- }
- }
- private boolean connectUsingReflection(BluetoothGatt bluetoothGatt, BluetoothGattCallback bluetoothGattCallback, boolean autoConnect)
- throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
- logger.v("Connecting using reflection");
- setAutoConnectValue(bluetoothGatt, autoConnect);
- Method connectMethod = bluetoothGatt.getClass().getDeclaredMethod("connect", Boolean.class, BluetoothGattCallback.class);
- connectMethod.setAccessible(true);
- return (Boolean) (connectMethod.invoke(bluetoothGatt, true, bluetoothGattCallback));
- }
- @TargetApi(Build.VERSION_CODES.M)
- private BluetoothGatt createBluetoothGatt(Object iBluetoothGatt, BluetoothDevice remoteDevice)
- throws IllegalAccessException, InvocationTargetException, InstantiationException {
- Constructor bluetoothGattConstructor = BluetoothGatt.class.getDeclaredConstructors()[0];
- bluetoothGattConstructor.setAccessible(true);
- logger.v("Found constructor with args count = " + bluetoothGattConstructor.getParameterTypes().length);
- if (bluetoothGattConstructor.getParameterTypes().length == 4) {
- return (BluetoothGatt) (bluetoothGattConstructor.newInstance(context, iBluetoothGatt, remoteDevice, TRANSPORT_LE));
- } else {
- return (BluetoothGatt) (bluetoothGattConstructor.newInstance(context, iBluetoothGatt, remoteDevice));
- }
- }
- private Object getIBluetoothGatt(Object iBluetoothManager)
- throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
- if (iBluetoothManager == null) {
- return null;
- }
- Method getBluetoothGattMethod = getMethodFromClass(iBluetoothManager.getClass(), "getBluetoothGatt");
- return getBluetoothGattMethod.invoke(iBluetoothManager);
- }
- private Object getIBluetoothManager() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
- BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- if (bluetoothAdapter == null) {
- return null;
- }
- Method getBluetoothManagerMethod = getMethodFromClass(bluetoothAdapter.getClass(), "getBluetoothManager");
- return getBluetoothManagerMethod.invoke(bluetoothAdapter);
- }
- private Method getMethodFromClass(Class<?> cls, String methodName) throws NoSuchMethodException {
- Method method = cls.getDeclaredMethod(methodName);
- method.setAccessible(true);
- return method;
- }
- private void setAutoConnectValue(BluetoothGatt bluetoothGatt, boolean autoConnect) throws NoSuchFieldException, IllegalAccessException {
- Field autoConnectField = bluetoothGatt.getClass().getDeclaredField("mAutoConnect");
- autoConnectField.setAccessible(true);
- autoConnectField.setBoolean(bluetoothGatt, autoConnect);
- }
- connectedGatt.add(device.connectGatt(applicationContext, true, callback));
- public void connectAll(final BluetoothAdapter btAdapter) {
- final BluetoothAdapter bluetoothAdapter;
- logger.d(TAG + "reconnectAll");
- mainThreadHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- for (BluetoothGatt gatt : connectedGatt) {
- gatt.connect();
- }
- }
- }, 1000);
- }
- 02-27 18:13:12.639 24192-24192/com.tel.btandroid.debug core::DevManager :: reconnectAll
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement