Advertisement
Guest User

Untitled

a guest
Feb 28th, 2017
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.32 KB | None | 0 0
  1. protected class ConnectBroadcastReceiver extends BroadcastReceiver {
  2.  
  3. @Override
  4. public void onReceive(@NonNull Context context, @NonNull Intent intent) {
  5. logger.v(TAG + "------------------------ConnectBroadcastReceiver : onReceive " + intent.getAction());
  6. if ((intent.getAction().equals(BluetoothDevice.ACTION_ACL_CONNECTED))) {
  7. logger.v(TAG + "------------------------ConnectBroadcastReceiver : onReceive " + intent.getAction());
  8. logger.v(TAG + "PairingBroadcastReceiver : CONNECTED");
  9. } if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
  10. BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  11. if (bluetoothAdapter.isEnabled()) {
  12. bleDeviceManager.setApplicationContext(BluetoothLeService.this);
  13. bleDeviceManager.connectAll(bluetoothAdapter);
  14. }
  15. }
  16. }
  17. }
  18.  
  19. IntentFilter filter = new IntentFilter();
  20. filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
  21. filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
  22. filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
  23. filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
  24. filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
  25. registerReceiver(connectBroadcastReceiver, filter);
  26.  
  27. @Override
  28. public void connectAll(final BluetoothAdapter bluetoothAdapter) {
  29. mainThreadHandler.postDelayed(new Runnable() {
  30. @Override
  31. public void run() {
  32. connectedGatt.clear();
  33. devicesList.clear();
  34. deviceHandlerMap.clear();
  35. logger.d(TAG + "connectAll");
  36. List<Sensor> sensors = databaseRepository.getConnectedSensors();
  37. for (Sensor sensor : sensors) {
  38. BluetoothDevice device = bluetoothAdapter.getRemoteDevice(sensor.getAddress());
  39. connectedGatt.add(new BleConnectionCompat(applicationContext, logger).connectGatt(device, true, callback));
  40. logger.d(TAG + "connect " + device.getName() + " " + device.getAddress());
  41. }
  42.  
  43. }
  44. }, 10000);
  45.  
  46. }
  47.  
  48. public class BleConnectionCompat {
  49.  
  50. private final Context context;
  51. private Logger logger;
  52.  
  53. public BleConnectionCompat(Context context, Logger logger) {
  54. this.context = context;
  55. this.logger = logger;
  56. }
  57.  
  58. public BluetoothGatt connectGatt(BluetoothDevice remoteDevice, boolean autoConnect, BluetoothGattCallback bluetoothGattCallback) {
  59.  
  60. if (remoteDevice == null) {
  61. return null;
  62. }
  63.  
  64. /**
  65. * Issue that caused a race condition mentioned below was fixed in 7.0.0_r1
  66. * https://android.googlesource.com/platform/frameworks/base/+/android-7.0.0_r1/core/java/android/bluetooth/BluetoothGatt.java#649
  67. * compared to
  68. * https://android.googlesource.com/platform/frameworks/base/+/android-6.0.1_r72/core/java/android/bluetooth/BluetoothGatt.java#739
  69. * issue: https://android.googlesource.com/platform/frameworks/base/+/d35167adcaa40cb54df8e392379dfdfe98bcdba2%5E%21/#F0
  70. */
  71. if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M || !autoConnect) {
  72. return connectGattCompat(bluetoothGattCallback, remoteDevice, autoConnect);
  73. }
  74.  
  75. /**
  76. * Some implementations of Bluetooth Stack have a race condition where autoConnect flag
  77. * is not properly set before calling connectGatt. That's the reason for using reflection
  78. * to set the flag manually.
  79. */
  80.  
  81. try {
  82. logger.v("Trying to connectGatt using reflection.");
  83. Object iBluetoothGatt = getIBluetoothGatt(getIBluetoothManager());
  84.  
  85. if (iBluetoothGatt == null) {
  86. logger.w("Couldn't get iBluetoothGatt object");
  87. return connectGattCompat(bluetoothGattCallback, remoteDevice, true);
  88. }
  89.  
  90. BluetoothGatt bluetoothGatt = createBluetoothGatt(iBluetoothGatt, remoteDevice);
  91.  
  92. if (bluetoothGatt == null) {
  93. logger.w("Couldn't create BluetoothGatt object");
  94. return connectGattCompat(bluetoothGattCallback, remoteDevice, true);
  95. }
  96.  
  97. boolean connectedSuccessfully = connectUsingReflection(bluetoothGatt, bluetoothGattCallback, true);
  98.  
  99. if (!connectedSuccessfully) {
  100. logger.w("Connection using reflection failed, closing gatt");
  101. bluetoothGatt.close();
  102. }
  103.  
  104. return bluetoothGatt;
  105. } catch (NoSuchMethodException
  106. | IllegalAccessException
  107. | IllegalArgumentException
  108. | InvocationTargetException
  109. | InstantiationException
  110. | NoSuchFieldException exception) {
  111. logger.w(exception + "Error during reflection");
  112. return connectGattCompat(bluetoothGattCallback, remoteDevice, true);
  113. }
  114. }
  115.  
  116. private BluetoothGatt connectGattCompat(BluetoothGattCallback bluetoothGattCallback, BluetoothDevice device, boolean autoConnect) {
  117. logger.v("Connecting without reflection");
  118.  
  119. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  120. return device.connectGatt(context, autoConnect, bluetoothGattCallback, TRANSPORT_LE);
  121. } else {
  122. return device.connectGatt(context, autoConnect, bluetoothGattCallback);
  123. }
  124. }
  125.  
  126. private boolean connectUsingReflection(BluetoothGatt bluetoothGatt, BluetoothGattCallback bluetoothGattCallback, boolean autoConnect)
  127. throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
  128. logger.v("Connecting using reflection");
  129. setAutoConnectValue(bluetoothGatt, autoConnect);
  130. Method connectMethod = bluetoothGatt.getClass().getDeclaredMethod("connect", Boolean.class, BluetoothGattCallback.class);
  131. connectMethod.setAccessible(true);
  132. return (Boolean) (connectMethod.invoke(bluetoothGatt, true, bluetoothGattCallback));
  133. }
  134.  
  135. @TargetApi(Build.VERSION_CODES.M)
  136. private BluetoothGatt createBluetoothGatt(Object iBluetoothGatt, BluetoothDevice remoteDevice)
  137. throws IllegalAccessException, InvocationTargetException, InstantiationException {
  138. Constructor bluetoothGattConstructor = BluetoothGatt.class.getDeclaredConstructors()[0];
  139. bluetoothGattConstructor.setAccessible(true);
  140. logger.v("Found constructor with args count = " + bluetoothGattConstructor.getParameterTypes().length);
  141.  
  142. if (bluetoothGattConstructor.getParameterTypes().length == 4) {
  143. return (BluetoothGatt) (bluetoothGattConstructor.newInstance(context, iBluetoothGatt, remoteDevice, TRANSPORT_LE));
  144. } else {
  145. return (BluetoothGatt) (bluetoothGattConstructor.newInstance(context, iBluetoothGatt, remoteDevice));
  146. }
  147. }
  148.  
  149. private Object getIBluetoothGatt(Object iBluetoothManager)
  150. throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
  151.  
  152. if (iBluetoothManager == null) {
  153. return null;
  154. }
  155.  
  156. Method getBluetoothGattMethod = getMethodFromClass(iBluetoothManager.getClass(), "getBluetoothGatt");
  157. return getBluetoothGattMethod.invoke(iBluetoothManager);
  158. }
  159.  
  160. private Object getIBluetoothManager() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
  161.  
  162. BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  163.  
  164. if (bluetoothAdapter == null) {
  165. return null;
  166. }
  167.  
  168. Method getBluetoothManagerMethod = getMethodFromClass(bluetoothAdapter.getClass(), "getBluetoothManager");
  169. return getBluetoothManagerMethod.invoke(bluetoothAdapter);
  170. }
  171.  
  172. private Method getMethodFromClass(Class<?> cls, String methodName) throws NoSuchMethodException {
  173. Method method = cls.getDeclaredMethod(methodName);
  174. method.setAccessible(true);
  175. return method;
  176. }
  177.  
  178. private void setAutoConnectValue(BluetoothGatt bluetoothGatt, boolean autoConnect) throws NoSuchFieldException, IllegalAccessException {
  179. Field autoConnectField = bluetoothGatt.getClass().getDeclaredField("mAutoConnect");
  180. autoConnectField.setAccessible(true);
  181. autoConnectField.setBoolean(bluetoothGatt, autoConnect);
  182. }
  183.  
  184. connectedGatt.add(device.connectGatt(applicationContext, true, callback));
  185.  
  186. public void connectAll(final BluetoothAdapter btAdapter) {
  187. final BluetoothAdapter bluetoothAdapter;
  188. logger.d(TAG + "reconnectAll");
  189. mainThreadHandler.postDelayed(new Runnable() {
  190. @Override
  191. public void run() {
  192. for (BluetoothGatt gatt : connectedGatt) {
  193. gatt.connect();
  194. }
  195. }
  196. }, 1000);
  197. }
  198.  
  199. 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