react-native-ble-manager 12.1.2 → 12.1.4

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.
package/README.md CHANGED
@@ -17,7 +17,7 @@ The library is a simple connection with the OS APIs, the BLE stack should be sta
17
17
 
18
18
  RN 0.76+ only the new architecture is supported
19
19
 
20
- RN 0.60-0.75 supported until 11.5.X
20
+ RN 0.60-0.75 supported until 11.X
21
21
  RN 0.40-0.59 supported until 6.7.X
22
22
  RN 0.30-0.39 supported until 2.4.3
23
23
 
@@ -72,6 +72,16 @@ npm run build
72
72
 
73
73
  > if you are modifying the typescript files of the library (in `src/`) on the fly, you can run `npm run watch` instead. If you are modifying files from the native counterparts, you'll need to rebuild the whole app for your target environnement (`npm run android/ios`).
74
74
 
75
+ ### Updating documentation
76
+
77
+ Edit files in `docs/`, then test locally with:
78
+ ```shell
79
+ cd docs
80
+ bundle install
81
+ bundle exec jekyll serve --watch --baseurl /
82
+ ```
83
+ Then open http://localhost:4000/
84
+
75
85
  ## Generate the native code from specs
76
86
  A react-native project is needed to generate the code via *codegen*.
77
87
 
@@ -69,7 +69,7 @@ android {
69
69
  }
70
70
 
71
71
  defaultConfig {
72
- minSdkVersion safeExtGet("minSdkVersion", 21)
72
+ minSdkVersion safeExtGet("minSdkVersion", 24)
73
73
  targetSdk safeExtGet("targetSdk", 34)
74
74
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
75
75
  }
@@ -129,4 +129,4 @@ if (isNewArchitectureEnabled()) {
129
129
  libraryName = "BleManager"
130
130
  codegenJavaPackageName = "it.innove"
131
131
  }
132
- }
132
+ }
@@ -767,6 +767,8 @@ class BleManager extends NativeBleManagerSpec {
767
767
  if (peripheral.isConnected()) {
768
768
  peripheral.disconnect(null, true);
769
769
  }
770
+ peripheral.errorAndClearAllCallbacks("disconnected by BleManager");
771
+ peripheral.resetQueuesAndBuffers();
770
772
  }
771
773
  }
772
774
  }
@@ -970,6 +972,11 @@ class BleManager extends NativeBleManagerSpec {
970
972
 
971
973
  @Override
972
974
  public void invalidate() {
975
+ try {
976
+ context.unregisterReceiver(mReceiver);
977
+ } catch (Exception e) {
978
+ Log.e(LOG_TAG, "Receiver not registered or already unregistered", e);
979
+ }
973
980
  try {
974
981
  // Disconnect all known peripherals, otherwise android system will think we are still connected
975
982
  // while we have lost the gatt instance
@@ -7,6 +7,8 @@ import android.Manifest;
7
7
  import android.annotation.SuppressLint;
8
8
  import android.bluetooth.BluetoothAdapter;
9
9
  import android.bluetooth.BluetoothDevice;
10
+ import android.bluetooth.BluetoothDevice;
11
+ import android.bluetooth.le.BluetoothLeScanner;
10
12
  import android.bluetooth.le.ScanCallback;
11
13
  import android.bluetooth.le.ScanFilter;
12
14
  import android.bluetooth.le.ScanRecord;
@@ -45,7 +47,9 @@ public class DefaultScanManager extends ScanManager {
45
47
  // update scanSessionId to prevent stopping next scan by running timeout thread
46
48
  scanSessionId.incrementAndGet();
47
49
 
48
- getBluetoothAdapter().getBluetoothLeScanner().stopScan(mScanCallback);
50
+ final BluetoothLeScanner scanner = getBluetoothAdapter().getBluetoothLeScanner();
51
+ if (scanner != null)
52
+ scanner.stopScan(mScanCallback);
49
53
  isScanning = false;
50
54
  callback.invoke();
51
55
  }
@@ -173,7 +177,8 @@ public class DefaultScanManager extends ScanManager {
173
177
  // check current scan session was not stopped
174
178
  if (scanSessionId.intValue() == currentScanSession) {
175
179
  if (btAdapter.getState() == BluetoothAdapter.STATE_ON) {
176
- btAdapter.getBluetoothLeScanner().stopScan(mScanCallback);
180
+ final BluetoothLeScanner scanner = btAdapter.getBluetoothLeScanner();
181
+ if (scanner != null) scanner.stopScan(mScanCallback);
177
182
  isScanning = false;
178
183
  }
179
184
 
@@ -12,6 +12,7 @@ import android.bluetooth.BluetoothGattDescriptor;
12
12
  import android.bluetooth.BluetoothGattService;
13
13
  import android.bluetooth.BluetoothProfile;
14
14
  import android.bluetooth.BluetoothStatusCodes;
15
+
15
16
  import android.content.Context;
16
17
  import android.os.Build;
17
18
  import android.os.Handler;
@@ -160,14 +161,9 @@ public class Peripheral extends BluetoothGattCallback {
160
161
 
161
162
  public void disconnect(final Callback callback, final boolean force) {
162
163
  mainHandler.post(() -> {
163
- for (Callback connectCallback : connectCallbacks) {
164
- connectCallback.invoke("Disconnect called before connect callback invoked");
165
- }
166
- connectCallbacks.clear();
164
+ errorAndClearAllCallbacks("Disconnect called before the command completed");
165
+ resetQueuesAndBuffers();
167
166
  connected = false;
168
- clearBuffers();
169
- commandQueue.clear();
170
- commandQueueBusy = false;
171
167
 
172
168
  if (gatt != null) {
173
169
  try {
@@ -297,15 +293,83 @@ public class Peripheral extends BluetoothGattCallback {
297
293
  public void onServicesDiscovered(BluetoothGatt gatt, int status) {
298
294
  super.onServicesDiscovered(gatt, status);
299
295
  mainHandler.post(() -> {
300
- for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
301
- WritableMap map = this.asWritableMap(gatt);
302
- retrieveServicesCallback.invoke(null, map);
296
+ if (gatt == null) {
297
+ for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
298
+ retrieveServicesCallback.invoke("Error during service retrieval: gatt is null");
299
+ }
300
+ }
301
+ else if (status == BluetoothGatt.GATT_SUCCESS)
302
+ {
303
+ for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
304
+ WritableMap map = this.asWritableMap(gatt);
305
+ retrieveServicesCallback.invoke(null, map);
306
+ }
307
+ }
308
+ else {
309
+ for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
310
+ retrieveServicesCallback.invoke("Error during service retrieval.");
311
+ }
303
312
  }
304
313
  retrieveServicesCallbacks.clear();
305
314
  completedCommand();
306
315
  });
307
316
  }
308
317
 
318
+ public void errorAndClearAllCallbacks(final String errorMessage) {
319
+
320
+ for (Callback writeCallback : writeCallbacks) {
321
+ writeCallback.invoke(errorMessage);
322
+ }
323
+ writeCallbacks.clear();
324
+
325
+ for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
326
+ retrieveServicesCallback.invoke(errorMessage);
327
+ }
328
+ retrieveServicesCallbacks.clear();
329
+
330
+ for (Callback readRSSICallback : readRSSICallbacks) {
331
+ readRSSICallback.invoke(errorMessage);
332
+ }
333
+ readRSSICallbacks.clear();
334
+
335
+ for (Callback registerNotifyCallback : registerNotifyCallbacks) {
336
+ registerNotifyCallback.invoke(errorMessage);
337
+ }
338
+ registerNotifyCallbacks.clear();
339
+
340
+ for (Callback requestMTUCallback : requestMTUCallbacks) {
341
+ requestMTUCallback.invoke(errorMessage);
342
+ }
343
+ requestMTUCallbacks.clear();
344
+
345
+ for (Callback readCallback : readCallbacks) {
346
+ readCallback.invoke(errorMessage);
347
+ }
348
+ readCallbacks.clear();
349
+
350
+ for (Callback readDescriptorCallback : readDescriptorCallbacks) {
351
+ readDescriptorCallback.invoke(errorMessage);
352
+ }
353
+ readDescriptorCallbacks.clear();
354
+
355
+ for (Callback callback : writeDescriptorCallbacks) {
356
+ callback.invoke(errorMessage);
357
+ }
358
+ writeDescriptorCallbacks.clear();
359
+
360
+ for (Callback connectCallback : connectCallbacks) {
361
+ connectCallback.invoke(errorMessage);
362
+ }
363
+ connectCallbacks.clear();
364
+ }
365
+
366
+ public void resetQueuesAndBuffers() {
367
+ writeQueue.clear();
368
+ commandQueue.clear();
369
+ commandQueueBusy = false;
370
+ connected = false;
371
+ clearBuffers();
372
+ }
309
373
  @Override
310
374
  public void onConnectionStateChange(BluetoothGatt gatta, int status, final int newState) {
311
375
 
@@ -315,7 +379,7 @@ public class Peripheral extends BluetoothGattCallback {
315
379
  mainHandler.post(() -> {
316
380
  gatt = gatta;
317
381
 
318
- if (status != BluetoothGatt.GATT_SUCCESS) {
382
+ if (gatt != null && status != BluetoothGatt.GATT_SUCCESS) {
319
383
  gatt.close();
320
384
  }
321
385
 
@@ -333,59 +397,13 @@ public class Peripheral extends BluetoothGattCallback {
333
397
 
334
398
  } else if (newState == BluetoothProfile.STATE_DISCONNECTED || status != BluetoothGatt.GATT_SUCCESS) {
335
399
 
336
- for (Callback writeCallback : writeCallbacks) {
337
- writeCallback.invoke("Device disconnected");
338
- }
339
- writeCallbacks.clear();
340
-
341
- for (Callback retrieveServicesCallback : retrieveServicesCallbacks) {
342
- retrieveServicesCallback.invoke("Device disconnected");
343
- }
344
- retrieveServicesCallbacks.clear();
345
-
346
- for (Callback readRSSICallback : readRSSICallbacks) {
347
- readRSSICallback.invoke("Device disconnected");
348
- }
349
- readRSSICallbacks.clear();
350
-
351
- for (Callback registerNotifyCallback : registerNotifyCallbacks) {
352
- registerNotifyCallback.invoke("Device disconnected");
353
- }
354
- registerNotifyCallbacks.clear();
355
-
356
- for (Callback requestMTUCallback : requestMTUCallbacks) {
357
- requestMTUCallback.invoke("Device disconnected");
358
- }
359
- requestMTUCallbacks.clear();
360
-
361
- for (Callback readCallback : readCallbacks) {
362
- readCallback.invoke("Device disconnected");
363
- }
364
- readCallbacks.clear();
365
-
366
- for (Callback readDescriptorCallback : readDescriptorCallbacks) {
367
- readDescriptorCallback.invoke("Device disconnected");
368
- }
369
- readDescriptorCallbacks.clear();
370
-
371
- for (Callback callback : writeDescriptorCallbacks) {
372
- callback.invoke("Device disconnected");
373
- }
374
- writeDescriptorCallbacks.clear();
375
-
376
- for (Callback connectCallback : connectCallbacks) {
377
- connectCallback.invoke("Connection error");
400
+ errorAndClearAllCallbacks("Device disconnected");
401
+ resetQueuesAndBuffers();
402
+ if (gatt != null) {
403
+ gatt.disconnect();
404
+ gatt.close();
378
405
  }
379
- connectCallbacks.clear();
380
406
 
381
- writeQueue.clear();
382
- commandQueue.clear();
383
- commandQueueBusy = false;
384
- connected = false;
385
- clearBuffers();
386
-
387
- gatt.disconnect();
388
- gatt.close();
389
407
  gatt = null;
390
408
  sendDisconnectionEvent(device, BluetoothGatt.GATT_SUCCESS);
391
409
  }
@@ -891,7 +909,9 @@ public class Peripheral extends BluetoothGattCallback {
891
909
  }
892
910
 
893
911
  private boolean enqueue(Runnable command) {
912
+
894
913
  final boolean result = commandQueue.add(command);
914
+
895
915
  if (result) {
896
916
  nextCommand();
897
917
  } else {
@@ -921,9 +941,9 @@ public class Peripheral extends BluetoothGattCallback {
921
941
 
922
942
  // Check if we still have a valid gatt object
923
943
  if (gatt == null) {
924
- Log.d(BleManager.LOG_TAG, "Error, gatt is null");
925
- commandQueue.clear();
926
- commandQueueBusy = false;
944
+ Log.d(BleManager.LOG_TAG, "Error, gatt is null. Fill all callbacks with an error");
945
+ errorAndClearAllCallbacks("Gatt is null");
946
+ resetQueuesAndBuffers();
927
947
  return;
928
948
  }
929
949
 
@@ -971,6 +991,10 @@ public class Peripheral extends BluetoothGattCallback {
971
991
  public void refreshCache(Callback callback) {
972
992
  enqueue(() -> {
973
993
  try {
994
+ if (gatt == null) {
995
+ throw new Exception("gatt is null");
996
+ }
997
+
974
998
  Method localMethod = gatt.getClass().getMethod("refresh", new Class[0]);
975
999
  boolean res = (Boolean) localMethod.invoke(gatt, new Object[0]);
976
1000
  callback.invoke(null, res);
@@ -1218,6 +1242,9 @@ public class Peripheral extends BluetoothGattCallback {
1218
1242
  writeProperty = BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE;
1219
1243
  }
1220
1244
 
1245
+ if (service == null) {
1246
+ throw new Exception("Service is null.");
1247
+ }
1221
1248
  List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
1222
1249
  for (BluetoothGattCharacteristic characteristic : characteristics) {
1223
1250
  if ((characteristic.getProperties() & writeProperty) != 0
package/ios/BleManager.h CHANGED
@@ -4,6 +4,7 @@
4
4
  #ifdef RCT_NEW_ARCH_ENABLED
5
5
 
6
6
  #import <BleManagerSpec/BleManagerSpec.h>
7
+ @class SwiftBleManager;
7
8
 
8
9
  @interface BleManager : NativeBleManagerSpecBase <NativeBleManagerSpec>
9
10
  - (void)emitOnDiscoverPeripheral:(NSDictionary *)value;
@@ -17,6 +18,8 @@
17
18
  - (void)emitOnDidUpdateNotificationStateFor:(NSDictionary *)value;
18
19
  - (void)emitOnCompanionPeripheral:(NSDictionary *)value;
19
20
  - (void)emitOnCompanionFailure:(NSDictionary *)value;
21
+ + (nullable CBCentralManager *)getCentralManager;
22
+ + (nullable SwiftBleManager *)getInstance;
20
23
  @end
21
24
 
22
25
  #else
package/ios/BleManager.mm CHANGED
@@ -290,4 +290,12 @@ RCT_EXPORT_MODULE()
290
290
  callback:callback];
291
291
  }
292
292
 
293
+ + (nullable CBCentralManager *)getCentralManager {
294
+ return [SwiftBleManager getCentralManager];
295
+ }
296
+
297
+ + (nullable SwiftBleManager *)getInstance {
298
+ return [SwiftBleManager getInstance];
299
+ }
300
+
293
301
  @end
@@ -1178,11 +1178,11 @@ import CoreBluetooth
1178
1178
  }
1179
1179
 
1180
1180
 
1181
- static func getCentralManager() -> CBCentralManager? {
1181
+ @objc public static func getCentralManager() -> CBCentralManager? {
1182
1182
  return sharedManager
1183
1183
  }
1184
1184
 
1185
- static func getInstance() -> SwiftBleManager? {
1185
+ @objc public static func getInstance() -> SwiftBleManager? {
1186
1186
  return shared
1187
1187
  }
1188
1188
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-ble-manager",
3
- "version": "12.1.2",
3
+ "version": "12.1.4",
4
4
  "description": "A BLE module for react native.",
5
5
  "homepage": "https://innoveit.github.io/react-native-ble-manager/",
6
6
  "repository": {