From 25dba1334735ded0f7b71d5b55c9b6f58ca25d9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20JEAN?= Date: Fri, 18 Feb 2022 17:53:40 +0100 Subject: [PATCH] feat: `avoidDuplicates` option on `startScanning` method --- README.md | 4 ++++ src/bluetooth.android.ts | 21 +++++++++++++++++++-- src/bluetooth.common.ts | 6 ++++++ src/bluetooth.ios.ts | 7 ++++++- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8977e7e..d895162 100755 --- a/README.md +++ b/README.md @@ -119,6 +119,10 @@ A few of the optional params require a bit of explanation: #### seconds Scanning for peripherals drains the battery quickly, so you better not scan any longer than necessary. If a peripheral is in range and not engaged in another connection it usually pops up in under a second. If you don't pass in a number of seconds you will need to manually call `stopScanning`. +#### avoidDuplicates +Set this to true if you don't want duplicates with the same serviceUUID reported in "onDiscovered" callback. +If true, only the first discovered peripheral with the same serviceUUID will be reported. + #### skipPermissionCheck Set this to true if you don't want the plugin to check (and request) the required Bluetooth permissions. Particularly useful if you're running this function on a non-UI thread (ie. a Worker). diff --git a/src/bluetooth.android.ts b/src/bluetooth.android.ts index b7134ea..0719e1c 100644 --- a/src/bluetooth.android.ts +++ b/src/bluetooth.android.ts @@ -1506,6 +1506,23 @@ export class Bluetooth extends BluetoothCommon { // } // } + let onPeripheralDiscovered; + + if (args.onDiscovered) { + if (args.avoidDuplicates) { + const discoveredUUIDs = []; + onPeripheralDiscovered = (data: Peripheral) => { + const hasBeenDiscovered = discoveredUUIDs.includes(data.UUID); + if (!hasBeenDiscovered) { + discoveredUUIDs.push(data.UUID); + args.onDiscovered(data); + } + }; + } else { + onPeripheralDiscovered = args.onDiscovered; + } + } + const filters = args.filters || []; if (this.scanningReferTimer) { @@ -1519,7 +1536,7 @@ export class Bluetooth extends BluetoothCommon { uuids.push(stringToUuid(f.serviceUUID)); } }); - this.LeScanCallback.onPeripheralDiscovered = args.onDiscovered; + this.LeScanCallback.onPeripheralDiscovered = onPeripheralDiscovered; const didStart = uuids.length === 0 ? this.adapter.startLeScan(this.LeScanCallback) : this.adapter.startLeScan(uuids, this.LeScanCallback); if (Trace.isEnabled()) { CLog(CLogTypes.info, methodName, '---- PreLollipop ---- didStart scanning:', didStart, JSON.stringify(uuids)); @@ -1577,7 +1594,7 @@ export class Bluetooth extends BluetoothCommon { scanSettings.setCallbackType(androidCallbackType(callbackType)); } - this.scanCallback.onPeripheralDiscovered = args.onDiscovered; + this.scanCallback.onPeripheralDiscovered = onPeripheralDiscovered; this.adapter.getBluetoothLeScanner().startScan(scanFilters, scanSettings.build(), this.scanCallback); if (Trace.isEnabled()) { CLog(CLogTypes.info, methodName, ' ---- PostLollipop ---- didStart scanning:', JSON.stringify(filters)); diff --git a/src/bluetooth.common.ts b/src/bluetooth.common.ts index 4f80cc9..c920d16 100755 --- a/src/bluetooth.common.ts +++ b/src/bluetooth.common.ts @@ -220,6 +220,12 @@ export interface StartScanningOptions { */ seconds?: number; + /** + * Avoid duplicates with the same serviceUUID in "onDiscovered" callback. + * If true, only the first discovered peripheral with the same serviceUUID will be reported. + */ + avoidDuplicates?: boolean; + /** * This callback is invoked when a peripheral is found. */ diff --git a/src/bluetooth.ios.ts b/src/bluetooth.ios.ts index 4fca082..2b69a45 100644 --- a/src/bluetooth.ios.ts +++ b/src/bluetooth.ios.ts @@ -823,8 +823,13 @@ export class Bluetooth extends BluetoothCommon { CLog(CLogTypes.info, methodName, '---- services:', services); } + const options: NSMutableDictionary = new (NSMutableDictionary as any)(); + if (!args.avoidDuplicates) { + options.setObjectForKey(true, CBCentralManagerScanOptionAllowDuplicatesKey); + } + // TODO: check on the services as any casting - this.centralManager.scanForPeripheralsWithServicesOptions(services as any, null); + this.centralManager.scanForPeripheralsWithServicesOptions(services as any, options); if (this.scanningReferTimer) { clearTimeout(this.scanningReferTimer.timer); this.scanningReferTimer.resolve();