react-native-ble-manager 11.5.7 → 12.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +16 -3
  2. package/RNBleManager.podspec +24 -0
  3. package/android/build.gradle +116 -43
  4. package/android/gradle.properties +1 -0
  5. package/android/src/main/java/it/innove/BleManager.java +174 -148
  6. package/android/src/main/java/it/innove/BleManagerPackage.java +15 -14
  7. package/android/src/main/java/it/innove/CompanionScanner.java +13 -3
  8. package/android/src/main/java/it/innove/DefaultPeripheral.java +4 -4
  9. package/android/src/main/java/it/innove/DefaultScanManager.java +16 -16
  10. package/android/src/main/java/it/innove/Peripheral.java +20 -17
  11. package/dist/cjs/NativeBleManager.d.ts +241 -0
  12. package/dist/cjs/NativeBleManager.js +5 -0
  13. package/dist/cjs/NativeBleManager.js.map +1 -0
  14. package/dist/cjs/index.d.ts +15 -3
  15. package/dist/cjs/index.js +89 -38
  16. package/dist/cjs/index.js.map +1 -1
  17. package/dist/cjs/types.d.ts +11 -11
  18. package/dist/esm/NativeBleManager.d.ts +241 -0
  19. package/dist/esm/NativeBleManager.js +3 -0
  20. package/dist/esm/NativeBleManager.js.map +1 -0
  21. package/dist/esm/index.d.ts +15 -3
  22. package/dist/esm/index.js +92 -41
  23. package/dist/esm/index.js.map +1 -1
  24. package/dist/esm/types.d.ts +11 -11
  25. package/ios/BleManager-Bridging-Header.h +7 -1
  26. package/ios/BleManager.h +39 -2
  27. package/ios/BleManager.mm +277 -0
  28. package/ios/Helper.swift +6 -6
  29. package/ios/RNBleManager.h +7 -0
  30. package/ios/{BleManager.swift → SwiftBleManager.swift} +322 -355
  31. package/package.json +107 -56
  32. package/src/NativeBleManager.ts +409 -0
  33. package/src/index.ts +162 -77
  34. package/src/types.ts +31 -31
  35. package/android/src/main/java/it/innove/LegacyScanManager.java +0 -112
  36. package/ios/BleManager.m +0 -153
  37. package/ios/BleManager.xcodeproj/project.pbxproj +0 -324
  38. package/ios/BleManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  39. package/ios/BleManager.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  40. package/react-native-ble-manager.podspec +0 -17
@@ -2,6 +2,7 @@ package it.innove;
2
2
 
3
3
  import static android.app.Activity.RESULT_OK;
4
4
  import static android.bluetooth.BluetoothProfile.GATT;
5
+
5
6
  import android.annotation.SuppressLint;
6
7
  import android.app.Activity;
7
8
  import android.bluetooth.BluetoothAdapter;
@@ -17,6 +18,7 @@ import android.content.pm.PackageManager;
17
18
  import android.os.Build;
18
19
  import android.util.Log;
19
20
 
21
+ import androidx.annotation.NonNull;
20
22
  import androidx.annotation.Nullable;
21
23
  import androidx.annotation.RequiresApi;
22
24
 
@@ -25,13 +27,11 @@ import com.facebook.react.bridge.Arguments;
25
27
  import com.facebook.react.bridge.BaseActivityEventListener;
26
28
  import com.facebook.react.bridge.Callback;
27
29
  import com.facebook.react.bridge.ReactApplicationContext;
28
- import com.facebook.react.bridge.ReactContextBaseJavaModule;
29
30
  import com.facebook.react.bridge.ReactMethod;
30
31
  import com.facebook.react.bridge.ReadableArray;
31
32
  import com.facebook.react.bridge.ReadableMap;
32
33
  import com.facebook.react.bridge.WritableArray;
33
34
  import com.facebook.react.bridge.WritableMap;
34
- import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
35
35
 
36
36
  import java.lang.reflect.Method;
37
37
  import java.util.Iterator;
@@ -40,7 +40,7 @@ import java.util.List;
40
40
  import java.util.Map;
41
41
  import java.util.Set;
42
42
 
43
- class BleManager extends ReactContextBaseJavaModule {
43
+ class BleManager extends NativeBleManagerSpec {
44
44
 
45
45
  public static final String LOG_TAG = "RNBleManager";
46
46
  private static final int ENABLE_REQUEST = 539;
@@ -98,6 +98,116 @@ class BleManager extends ReactContextBaseJavaModule {
98
98
 
99
99
  };
100
100
 
101
+ private class MyBroadcastReceiver extends BroadcastReceiver {
102
+ private final BleManager bleManager;
103
+
104
+ public MyBroadcastReceiver(BleManager bleManager) {
105
+ this.bleManager = bleManager;
106
+ }
107
+
108
+ @SuppressLint("MissingPermission")
109
+ @Override
110
+ public void onReceive(Context context, Intent intent) {
111
+ Log.d(LOG_TAG, "onReceive");
112
+ final String action = intent.getAction();
113
+
114
+ if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
115
+ final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
116
+ String stringState = "";
117
+
118
+ switch (state) {
119
+ case BluetoothAdapter.STATE_OFF:
120
+ stringState = "off";
121
+ clearPeripherals();
122
+ break;
123
+ case BluetoothAdapter.STATE_TURNING_OFF:
124
+ stringState = "turning_off";
125
+ disconnectPeripherals();
126
+ break;
127
+ case BluetoothAdapter.STATE_ON:
128
+ stringState = "on";
129
+ break;
130
+ case BluetoothAdapter.STATE_TURNING_ON:
131
+ stringState = "turning_on";
132
+ break;
133
+ default:
134
+ // should not happen as per https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#EXTRA_STATE
135
+ stringState = "off";
136
+ break;
137
+ }
138
+
139
+ WritableMap map = Arguments.createMap();
140
+ map.putString("state", stringState);
141
+ Log.d(LOG_TAG, "state: " + stringState);
142
+ emitOnDidUpdateState(map);
143
+
144
+ } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
145
+ final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
146
+ final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
147
+ BluetoothDevice.ERROR);
148
+ BluetoothDevice device;
149
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
150
+ device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class);
151
+ } else {
152
+ device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
153
+ }
154
+
155
+ String bondStateStr = "UNKNOWN";
156
+ switch (bondState) {
157
+ case BluetoothDevice.BOND_BONDED:
158
+ bondStateStr = "BOND_BONDED";
159
+ break;
160
+ case BluetoothDevice.BOND_BONDING:
161
+ bondStateStr = "BOND_BONDING";
162
+ break;
163
+ case BluetoothDevice.BOND_NONE:
164
+ bondStateStr = "BOND_NONE";
165
+ break;
166
+ }
167
+ Log.d(LOG_TAG, "bond state: " + bondStateStr);
168
+
169
+ if (bondRequest != null && bondRequest.uuid.equals(device.getAddress())) {
170
+ if (bondState == BluetoothDevice.BOND_BONDED) {
171
+ bondRequest.callback.invoke();
172
+ bondRequest = null;
173
+ } else if (bondState == BluetoothDevice.BOND_NONE || bondState == BluetoothDevice.ERROR) {
174
+ bondRequest.callback.invoke("Bond request has been denied");
175
+ bondRequest = null;
176
+ }
177
+ }
178
+
179
+ if (bondState == BluetoothDevice.BOND_BONDED) {
180
+ Peripheral peripheral;
181
+ if (!forceLegacy) {
182
+ peripheral = new DefaultPeripheral(device, bleManager);
183
+ } else {
184
+ peripheral = new Peripheral(device, bleManager);
185
+ }
186
+ WritableMap map = peripheral.asWritableMap();
187
+ emitOnPeripheralDidBond(map);
188
+ }
189
+
190
+ if (removeBondRequest != null && removeBondRequest.uuid.equals(device.getAddress())
191
+ && bondState == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED) {
192
+ removeBondRequest.callback.invoke();
193
+ removeBondRequest = null;
194
+ }
195
+ } else if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
196
+ BluetoothDevice bluetoothDevice;
197
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
198
+ bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class);
199
+ } else {
200
+ bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
201
+ }
202
+ if (bondRequest != null && bondRequest.uuid.equals(bluetoothDevice.getAddress()) && bondRequest.pin != null) {
203
+ bluetoothDevice.setPin(bondRequest.pin.getBytes());
204
+ bluetoothDevice.createBond();
205
+ }
206
+ }
207
+
208
+ }
209
+ }
210
+
101
211
  // key is the MAC Address
102
212
  private final Map<String, Peripheral> peripherals = new LinkedHashMap<>();
103
213
  // scan session id
@@ -117,6 +227,7 @@ class BleManager extends ReactContextBaseJavaModule {
117
227
  Log.d(LOG_TAG, "BleManager created");
118
228
  }
119
229
 
230
+ @NonNull
120
231
  @Override
121
232
  public String getName() {
122
233
  return "BleManager";
@@ -137,10 +248,6 @@ class BleManager extends ReactContextBaseJavaModule {
137
248
  return bluetoothManager;
138
249
  }
139
250
 
140
- public void sendEvent(String eventName, @Nullable WritableMap params) {
141
- getReactApplicationContext().getJSModule(RCTNativeAppEventEmitter.class).emit(eventName, params);
142
- }
143
-
144
251
  @ReactMethod
145
252
  public void start(ReadableMap options, Callback callback) {
146
253
  Log.d(LOG_TAG, "start");
@@ -155,17 +262,13 @@ class BleManager extends ReactContextBaseJavaModule {
155
262
  forceLegacy = options.getBoolean("forceLegacy");
156
263
  }
157
264
 
158
- if (!forceLegacy) {
159
- scanManager = new DefaultScanManager(reactContext, this);
160
- } else {
161
- scanManager = new LegacyScanManager(reactContext, this);
162
- }
265
+ scanManager = new DefaultScanManager(reactContext, this);
163
266
 
164
267
  IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
165
268
  filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
166
269
  IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
167
270
  intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
168
- if (Build.VERSION.SDK_INT >= 34){
271
+ if (Build.VERSION.SDK_INT >= 34) {
169
272
  // Google in 2023 decides that flag RECEIVER_NOT_EXPORTED or RECEIVER_EXPORTED should be explicit set SDK 34(UPSIDE_DOWN_CAKE) on registering receivers.
170
273
  // Also the export flags are available on Android 8 and higher, should be used with caution so that don't break compability with that devices.
171
274
  context.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED);
@@ -192,22 +295,21 @@ class BleManager extends ReactContextBaseJavaModule {
192
295
  Intent intentEnable = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
193
296
  if (getCurrentActivity() == null)
194
297
  callback.invoke("Current activity not available");
195
- else
196
- {
197
- try{
198
- getCurrentActivity().startActivityForResult(intentEnable, ENABLE_REQUEST);
199
- }catch(Exception e){
200
- callback.invoke("Current activity not available");
201
- }
202
-
298
+ else {
299
+ try {
300
+ getCurrentActivity().startActivityForResult(intentEnable, ENABLE_REQUEST);
301
+ } catch (Exception e) {
302
+ callback.invoke("Current activity not available");
203
303
  }
204
304
 
305
+ }
306
+
205
307
  } else
206
308
  callback.invoke();
207
309
  }
208
310
 
209
311
  @ReactMethod
210
- public void scan(ReadableArray serviceUUIDs, final int scanSeconds, boolean allowDuplicates, ReadableMap options,
312
+ public void scan(ReadableArray serviceUUIDs, double timeoutSeconds, boolean allowDuplicates, ReadableMap scanningOptions,
211
313
  Callback callback) {
212
314
  Log.d(LOG_TAG, "scan");
213
315
  if (getBluetoothAdapter() == null) {
@@ -230,12 +332,12 @@ class BleManager extends ReactContextBaseJavaModule {
230
332
  }
231
333
 
232
334
  if (scanManager != null)
233
- scanManager.scan(serviceUUIDs, scanSeconds, options, callback);
335
+ scanManager.scan(serviceUUIDs, (int) timeoutSeconds, scanningOptions, callback);
234
336
  }
235
337
 
236
338
  @SuppressLint("NewApi") // NOTE: constructor checks the API version.
237
339
  @ReactMethod
238
- public void companionScan(ReadableArray serviceUUIDs, ReadableMap options, Callback callback) {
340
+ public void companionScan(ReadableArray serviceUUIDs, ReadableMap options, Callback callback) {
239
341
  if (this.companionScanner == null) {
240
342
  callback.invoke("not supported");
241
343
  } else {
@@ -264,7 +366,7 @@ class BleManager extends ReactContextBaseJavaModule {
264
366
  scanManager.stopScan(callback);
265
367
  WritableMap map = Arguments.createMap();
266
368
  map.putInt("status", 0);
267
- sendEvent("BleManagerStopScan", map);
369
+ emitOnStopScan(map);
268
370
  }
269
371
  }
270
372
 
@@ -299,7 +401,7 @@ class BleManager extends ReactContextBaseJavaModule {
299
401
  }
300
402
 
301
403
  @ReactMethod
302
- private void removeBond(String peripheralUUID, Callback callback) {
404
+ public void removeBond(String peripheralUUID, Callback callback) {
303
405
  Log.d(LOG_TAG, "Remove bond to: " + peripheralUUID);
304
406
 
305
407
  Peripheral peripheral = retrieveOrCreatePeripheral(peripheralUUID);
@@ -345,7 +447,7 @@ class BleManager extends ReactContextBaseJavaModule {
345
447
 
346
448
  @ReactMethod
347
449
  public void startNotificationUseBuffer(String deviceUUID, String serviceUUID, String characteristicUUID,
348
- Integer buffer, Callback callback) {
450
+ double buffer, Callback callback) {
349
451
  Log.d(LOG_TAG, "startNotification");
350
452
  if (serviceUUID == null || characteristicUUID == null) {
351
453
  callback.invoke("ServiceUUID and characteristicUUID required.");
@@ -354,7 +456,7 @@ class BleManager extends ReactContextBaseJavaModule {
354
456
  Peripheral peripheral = peripherals.get(deviceUUID);
355
457
  if (peripheral != null) {
356
458
  peripheral.registerNotify(UUIDHelper.uuidFromString(serviceUUID),
357
- UUIDHelper.uuidFromString(characteristicUUID), buffer, callback);
459
+ UUIDHelper.uuidFromString(characteristicUUID), (int) buffer, callback);
358
460
  } else
359
461
  callback.invoke("Peripheral not found");
360
462
  }
@@ -391,7 +493,7 @@ class BleManager extends ReactContextBaseJavaModule {
391
493
 
392
494
  @ReactMethod
393
495
  public void write(String deviceUUID, String serviceUUID, String characteristicUUID, ReadableArray message,
394
- Integer maxByteSize, Callback callback) {
496
+ double maxByteSize, Callback callback) {
395
497
  Log.d(LOG_TAG, "Write to: " + deviceUUID);
396
498
  if (serviceUUID == null || characteristicUUID == null) {
397
499
  callback.invoke("ServiceUUID and characteristicUUID required.");
@@ -405,14 +507,14 @@ class BleManager extends ReactContextBaseJavaModule {
405
507
  }
406
508
  Log.d(LOG_TAG, "Message(" + decoded.length + "): " + bytesToHex(decoded));
407
509
  peripheral.write(UUIDHelper.uuidFromString(serviceUUID), UUIDHelper.uuidFromString(characteristicUUID),
408
- decoded, maxByteSize, null, callback, BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
510
+ decoded, (int) maxByteSize, null, callback, BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
409
511
  } else
410
512
  callback.invoke("Peripheral not found");
411
513
  }
412
514
 
413
515
  @ReactMethod
414
516
  public void writeWithoutResponse(String deviceUUID, String serviceUUID, String characteristicUUID,
415
- ReadableArray message, Integer maxByteSize, Integer queueSleepTime, Callback callback) {
517
+ ReadableArray message, double maxByteSize, double queueSleepTime, Callback callback) {
416
518
  Log.d(LOG_TAG, "Write without response to: " + deviceUUID);
417
519
  if (serviceUUID == null || characteristicUUID == null) {
418
520
  callback.invoke("ServiceUUID and characteristicUUID required.");
@@ -422,11 +524,11 @@ class BleManager extends ReactContextBaseJavaModule {
422
524
  if (peripheral != null) {
423
525
  byte[] decoded = new byte[message.size()];
424
526
  for (int i = 0; i < message.size(); i++) {
425
- decoded[i] = Integer.valueOf(message.getInt(i)).byteValue();
527
+ decoded[i] = Integer.valueOf(message.getInt(i)).byteValue();
426
528
  }
427
529
  Log.d(LOG_TAG, "Message(" + decoded.length + "): " + bytesToHex(decoded));
428
530
  peripheral.write(UUIDHelper.uuidFromString(serviceUUID), UUIDHelper.uuidFromString(characteristicUUID),
429
- decoded, maxByteSize, queueSleepTime, callback, BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
531
+ decoded, (int) maxByteSize, (int) queueSleepTime, callback, BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
430
532
  } else
431
533
  callback.invoke("Peripheral not found");
432
534
  }
@@ -523,9 +625,9 @@ class BleManager extends ReactContextBaseJavaModule {
523
625
  if (!peripherals.containsKey(address)) {
524
626
  Peripheral peripheral;
525
627
  if (!forceLegacy) {
526
- peripheral = new DefaultPeripheral(device, reactContext);
628
+ peripheral = new DefaultPeripheral(device, this);
527
629
  } else {
528
- peripheral = new Peripheral(device, reactContext);
630
+ peripheral = new Peripheral(device, this);
529
631
  }
530
632
  peripherals.put(device.getAddress(), peripheral);
531
633
  }
@@ -581,7 +683,7 @@ class BleManager extends ReactContextBaseJavaModule {
581
683
  WritableMap map = Arguments.createMap();
582
684
  map.putString("state", state);
583
685
  Log.d(LOG_TAG, "state:" + state);
584
- sendEvent("BleManagerDidUpdateState", map);
686
+ emitOnDidUpdateState(map);
585
687
  callback.invoke(state);
586
688
  }
587
689
 
@@ -594,6 +696,16 @@ class BleManager extends ReactContextBaseJavaModule {
594
696
  }
595
697
  }
596
698
 
699
+ @Override
700
+ public void getMaximumWriteValueLengthForWithoutResponse(String peripheralUUID, Callback callback) {
701
+ callback.invoke("Not implemented");
702
+ }
703
+
704
+ @Override
705
+ public void getMaximumWriteValueLengthForWithResponse(String deviceUUID, Callback callback) {
706
+ callback.invoke("Not implemented");
707
+ }
708
+
597
709
  @ReactMethod
598
710
  @SuppressLint("MissingPermission")
599
711
  public void setName(String name) {
@@ -601,108 +713,7 @@ class BleManager extends ReactContextBaseJavaModule {
601
713
  adapter.setName(name);
602
714
  }
603
715
 
604
- @SuppressLint("MissingPermission")
605
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
606
- @Override
607
- public void onReceive(Context context, Intent intent) {
608
- Log.d(LOG_TAG, "onReceive");
609
- final String action = intent.getAction();
610
-
611
- if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
612
- final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
613
- String stringState = "";
614
-
615
- switch (state) {
616
- case BluetoothAdapter.STATE_OFF:
617
- stringState = "off";
618
- clearPeripherals();
619
- break;
620
- case BluetoothAdapter.STATE_TURNING_OFF:
621
- stringState = "turning_off";
622
- disconnectPeripherals();
623
- break;
624
- case BluetoothAdapter.STATE_ON:
625
- stringState = "on";
626
- break;
627
- case BluetoothAdapter.STATE_TURNING_ON:
628
- stringState = "turning_on";
629
- break;
630
- default:
631
- // should not happen as per https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#EXTRA_STATE
632
- stringState = "off";
633
- break;
634
- }
635
-
636
- WritableMap map = Arguments.createMap();
637
- map.putString("state", stringState);
638
- Log.d(LOG_TAG, "state: " + stringState);
639
- sendEvent("BleManagerDidUpdateState", map);
640
-
641
- } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
642
- final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
643
- final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
644
- BluetoothDevice.ERROR);
645
- BluetoothDevice device;
646
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
647
- device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class);
648
- } else {
649
- device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
650
- }
651
-
652
- String bondStateStr = "UNKNOWN";
653
- switch (bondState) {
654
- case BluetoothDevice.BOND_BONDED:
655
- bondStateStr = "BOND_BONDED";
656
- break;
657
- case BluetoothDevice.BOND_BONDING:
658
- bondStateStr = "BOND_BONDING";
659
- break;
660
- case BluetoothDevice.BOND_NONE:
661
- bondStateStr = "BOND_NONE";
662
- break;
663
- }
664
- Log.d(LOG_TAG, "bond state: " + bondStateStr);
665
-
666
- if (bondRequest != null && bondRequest.uuid.equals(device.getAddress())) {
667
- if (bondState == BluetoothDevice.BOND_BONDED) {
668
- bondRequest.callback.invoke();
669
- bondRequest = null;
670
- } else if (bondState == BluetoothDevice.BOND_NONE || bondState == BluetoothDevice.ERROR) {
671
- bondRequest.callback.invoke("Bond request has been denied");
672
- bondRequest = null;
673
- }
674
- }
675
-
676
- if (bondState == BluetoothDevice.BOND_BONDED) {
677
- Peripheral peripheral;
678
- if (!forceLegacy) {
679
- peripheral = new DefaultPeripheral(device, reactContext);
680
- } else {
681
- peripheral = new Peripheral(device, reactContext);
682
- }
683
- WritableMap map = peripheral.asWritableMap();
684
- sendEvent("BleManagerPeripheralDidBond", map);
685
- }
686
-
687
- if (removeBondRequest != null && removeBondRequest.uuid.equals(device.getAddress())
688
- && bondState == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED) {
689
- removeBondRequest.callback.invoke();
690
- removeBondRequest = null;
691
- }
692
- } else if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
693
- BluetoothDevice bluetoothDevice;
694
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
695
- bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class);
696
- } else {
697
- bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
698
- }
699
- if (bondRequest != null && bondRequest.uuid.equals(bluetoothDevice.getAddress()) && bondRequest.pin != null) {
700
- bluetoothDevice.setPin(bondRequest.pin.getBytes());
701
- bluetoothDevice.createBond();
702
- }
703
- }
704
-
705
- }
716
+ private final BroadcastReceiver mReceiver = new MyBroadcastReceiver(this) {
706
717
  };
707
718
 
708
719
  private void clearPeripherals() {
@@ -760,6 +771,16 @@ class BleManager extends ReactContextBaseJavaModule {
760
771
  callback.invoke(null, map);
761
772
  }
762
773
 
774
+ @Override
775
+ public void isPeripheralConnected(String deviceUUID, Callback callback) {
776
+ Log.d(LOG_TAG, "Checking connection state for: " + deviceUUID);
777
+ Peripheral peripheral = peripherals.get(deviceUUID);
778
+ if (peripheral != null) {
779
+ callback.invoke(null, peripheral.isConnected());
780
+ } else
781
+ callback.invoke("Peripheral not found");
782
+ }
783
+
763
784
  @SuppressLint("MissingPermission")
764
785
  @ReactMethod
765
786
  public void getBondedPeripherals(Callback callback) {
@@ -769,9 +790,9 @@ class BleManager extends ReactContextBaseJavaModule {
769
790
  for (BluetoothDevice device : deviceSet) {
770
791
  Peripheral peripheral;
771
792
  if (!forceLegacy) {
772
- peripheral = new DefaultPeripheral(device, reactContext);
793
+ peripheral = new DefaultPeripheral(device, this);
773
794
  } else {
774
- peripheral = new Peripheral(device, reactContext);
795
+ peripheral = new Peripheral(device, this);
775
796
  }
776
797
  WritableMap jsonBundle = peripheral.asWritableMap();
777
798
  map.pushMap(jsonBundle);
@@ -797,22 +818,22 @@ class BleManager extends ReactContextBaseJavaModule {
797
818
  }
798
819
 
799
820
  @ReactMethod
800
- public void requestConnectionPriority(String deviceUUID, int connectionPriority, Callback callback) {
821
+ public void requestConnectionPriority(String deviceUUID, double connectionPriority, Callback callback) {
801
822
  Log.d(LOG_TAG, "Request connection priority of " + connectionPriority + " from: " + deviceUUID);
802
823
  Peripheral peripheral = peripherals.get(deviceUUID);
803
824
  if (peripheral != null) {
804
- peripheral.requestConnectionPriority(connectionPriority, callback);
825
+ peripheral.requestConnectionPriority((int) connectionPriority, callback);
805
826
  } else {
806
827
  callback.invoke("Peripheral not found", null);
807
828
  }
808
829
  }
809
830
 
810
831
  @ReactMethod
811
- public void requestMTU(String deviceUUID, int mtu, Callback callback) {
832
+ public void requestMTU(String deviceUUID, double mtu, Callback callback) {
812
833
  Log.d(LOG_TAG, "Request MTU of " + mtu + " bytes from: " + deviceUUID);
813
834
  Peripheral peripheral = peripherals.get(deviceUUID);
814
835
  if (peripheral != null) {
815
- peripheral.requestMTU(mtu, callback);
836
+ peripheral.requestMTU((int) mtu, callback);
816
837
  } else {
817
838
  callback.invoke("Peripheral not found", null);
818
839
  }
@@ -890,9 +911,9 @@ class BleManager extends ReactContextBaseJavaModule {
890
911
  if (BluetoothAdapter.checkBluetoothAddress(peripheralUUID)) {
891
912
  BluetoothDevice device = bluetoothAdapter.getRemoteDevice(peripheralUUID);
892
913
  if (!forceLegacy) {
893
- peripheral = new DefaultPeripheral(device, reactContext);
914
+ peripheral = new DefaultPeripheral(device, this);
894
915
  } else {
895
- peripheral = new Peripheral(device, reactContext);
916
+ peripheral = new Peripheral(device, this);
896
917
  }
897
918
  peripherals.put(peripheralUUID, peripheral);
898
919
  }
@@ -907,12 +928,12 @@ class BleManager extends ReactContextBaseJavaModule {
907
928
  }
908
929
 
909
930
  @ReactMethod
910
- public void removeListeners(Integer count) {
931
+ public void removeListeners(double count) {
911
932
  // Keep: Required for RN built in Event Emitter Calls.
912
933
  }
913
934
 
914
935
  @Override
915
- public void onCatalystInstanceDestroy() {
936
+ public void invalidate() {
916
937
  try {
917
938
  // Disconnect all known peripherals, otherwise android system will think we are still connected
918
939
  // while we have lost the gatt instance
@@ -927,4 +948,9 @@ class BleManager extends ReactContextBaseJavaModule {
927
948
  });
928
949
  }
929
950
  }
951
+
952
+ @Override
953
+ public void onCatalystInstanceDestroy() {
954
+ invalidate();
955
+ }
930
956
  }
@@ -13,22 +13,23 @@ import java.util.List;
13
13
 
14
14
  public class BleManagerPackage implements ReactPackage {
15
15
 
16
- public BleManagerPackage() {}
16
+ public BleManagerPackage() {
17
+ }
17
18
 
18
- @Override
19
- public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
20
- List<NativeModule> modules = new ArrayList<>();
19
+ @Override
20
+ public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
21
+ List<NativeModule> modules = new ArrayList<>();
21
22
 
22
- modules.add(new BleManager(reactApplicationContext));
23
- return modules;
24
- }
23
+ modules.add(new BleManager(reactApplicationContext));
24
+ return modules;
25
+ }
25
26
 
26
- public List<Class<? extends JavaScriptModule>> createJSModules() {
27
- return new ArrayList<>();
28
- }
27
+ public List<Class<? extends JavaScriptModule>> createJSModules() {
28
+ return new ArrayList<>();
29
+ }
29
30
 
30
- @Override
31
- public List<ViewManager> createViewManagers(ReactApplicationContext reactApplicationContext) {
32
- return Collections.emptyList();
33
- }
31
+ @Override
32
+ public List<ViewManager> createViewManagers(ReactApplicationContext reactApplicationContext) {
33
+ return Collections.emptyList();
34
+ }
34
35
  }
@@ -67,6 +67,16 @@ public class CompanionScanner {
67
67
  } else {
68
68
  Log.wtf(LOG_TAG, "Unexpected AssociationInfo device!");
69
69
  }
70
+
71
+ if (peripheral != null && scanCallback != null) {
72
+ scanCallback.invoke(null, peripheral.asWritableMap());
73
+ scanCallback = null;
74
+ bleManager.emitOnCompanionPeripheral(peripheral.asWritableMap());
75
+ }
76
+ } else {
77
+ scanCallback.invoke(null, null);
78
+ scanCallback = null;
79
+ bleManager.emitOnCompanionPeripheral(null);
70
80
  }
71
81
  } else {
72
82
  // No device, user cancelled?
@@ -78,7 +88,7 @@ public class CompanionScanner {
78
88
  scanCallback.invoke(null, peripheral != null ? peripheral.asWritableMap() : null);
79
89
  scanCallback = null;
80
90
  }
81
- bleManager.sendEvent("BleManagerCompanionPeripheral", peripheral != null ? peripheral.asWritableMap() : null);
91
+ bleManager.emitOnCompanionPeripheral(peripheral != null ? peripheral.asWritableMap() : null);
82
92
  }
83
93
  };
84
94
 
@@ -135,7 +145,7 @@ public class CompanionScanner {
135
145
 
136
146
  WritableMap map = Arguments.createMap();
137
147
  map.putString("error", charSequence.toString());
138
- bleManager.sendEvent("BleManagerCompanionFailure", map);
148
+ bleManager.emitOnCompanionFailure(map);
139
149
  }
140
150
 
141
151
  @Override
@@ -156,7 +166,7 @@ public class CompanionScanner {
156
166
 
157
167
  WritableMap map = Arguments.createMap();
158
168
  map.putString("error", msg);
159
- bleManager.sendEvent("BleManagerCompanionFailure", map);
169
+ bleManager.emitOnCompanionFailure(map);
160
170
  }
161
171
  }
162
172
  }, null);
@@ -24,14 +24,14 @@ public class DefaultPeripheral extends Peripheral {
24
24
  private ScanRecord advertisingData;
25
25
  private ScanResult scanResult;
26
26
 
27
- public DefaultPeripheral(ReactContext reactContext, ScanResult result) {
28
- super(result.getDevice(), result.getRssi(), result.getScanRecord().getBytes(), reactContext);
27
+ public DefaultPeripheral(BleManager bleManager, ScanResult result) {
28
+ super(result.getDevice(), result.getRssi(), result.getScanRecord().getBytes(), bleManager);
29
29
  this.advertisingData = result.getScanRecord();
30
30
  this.scanResult = result;
31
31
  }
32
32
 
33
- public DefaultPeripheral(BluetoothDevice device, ReactApplicationContext reactContext) {
34
- super(device, reactContext);
33
+ public DefaultPeripheral(BluetoothDevice device, BleManager bleManager) {
34
+ super(device, bleManager);
35
35
  }
36
36
 
37
37
  @Override