Add name prefix filtering (#45)
* Add name filter * Change name filter to "prefix" * Implement namePrefix filtering * Update lib/src/universal_ble_platform_interface.dart * Update lib/src/universal_ble_platform_interface.dart --------- Co-authored-by: fotidim <foti@navideck.com>
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
## 0.9.11
|
||||
* Add device name prefix filtering
|
||||
|
||||
## 0.9.10
|
||||
* Fix Windows scan filter
|
||||
* Remove scan result caching on Windows
|
||||
* Improve service discovery on Linux
|
||||
* Use asynchronous callbacks for SetNotifiable
|
||||
* Remove dependency on `convert`
|
||||
|
||||
@@ -119,6 +119,13 @@ Use the `withManufacturerData` parameter to filter devices by manufacturer data.
|
||||
```dart
|
||||
List<ManufacturerDataFilter> withManufacturerData;
|
||||
```
|
||||
##### With namePrefix
|
||||
|
||||
Use the `withNamePrefix` parameter to filter devices by names (case sensitive). When you pass a list of names, the scan results will only include devices that have this name or start with the provided parameter.
|
||||
|
||||
```dart
|
||||
List<String> withNamePrefix;
|
||||
```
|
||||
|
||||
### Connecting
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:universal_ble/universal_ble.dart';
|
||||
import 'package:universal_ble_example/data/capabilities.dart';
|
||||
@@ -10,6 +11,11 @@ class ScannedItemWidget extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String? name = scanResult.name;
|
||||
Uint8List? rawManufacturerData = scanResult.manufacturerData;
|
||||
ManufacturerData? manufacturerData;
|
||||
if (rawManufacturerData != null && rawManufacturerData.isNotEmpty) {
|
||||
manufacturerData = ManufacturerData.fromData(rawManufacturerData);
|
||||
}
|
||||
if (name == null || name.isEmpty) name = 'NA';
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
@@ -23,12 +29,11 @@ class ScannedItemWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(scanResult.deviceId),
|
||||
Visibility(
|
||||
visible: scanResult.manufacturerData?.isNotEmpty == true,
|
||||
visible: manufacturerData != null,
|
||||
child: Text(
|
||||
Platform.isWeb || Platform.isDesktop
|
||||
? ManufacturerData.fromData(scanResult.manufacturerData!)
|
||||
.toString()
|
||||
: 'ManufacturerCompanyId: ${ManufacturerData.fromData(scanResult.manufacturerData!).companyIdRadix16}',
|
||||
? manufacturerData.toString()
|
||||
: 'ManufacturerCompanyId: ${manufacturerData?.companyIdRadix16}',
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
|
||||
@@ -3,10 +3,12 @@ import 'dart:typed_data';
|
||||
class ScanFilter {
|
||||
final List<String> withServices;
|
||||
final List<ManufacturerDataFilter> withManufacturerData;
|
||||
final List<String> withNamePrefix;
|
||||
|
||||
ScanFilter({
|
||||
this.withServices = const [],
|
||||
this.withManufacturerData = const [],
|
||||
this.withNamePrefix = const [],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ class UniversalBleLinux extends UniversalBlePlatform {
|
||||
ScanFilter? scanFilter,
|
||||
}) async {
|
||||
await _ensureInitialized();
|
||||
await super.startScan(scanFilter: scanFilter);
|
||||
if (_activeAdapter?.discovering != true) {
|
||||
// Add services filter
|
||||
_activeAdapter?.setDiscoveryFilter(
|
||||
@@ -399,7 +400,7 @@ class UniversalBleLinux extends UniversalBlePlatform {
|
||||
}
|
||||
|
||||
// Update scan results only if rssi is available
|
||||
if (device.rssi != 0) onScanResult?.call(device.toBleScanResult());
|
||||
if (device.rssi != 0) updateScanResult(device.toBleScanResult());
|
||||
|
||||
// Setup Cache
|
||||
_devices[device.address] = device;
|
||||
@@ -414,7 +415,7 @@ class UniversalBleLinux extends UniversalBlePlatform {
|
||||
for (final property in properties) {
|
||||
switch (property) {
|
||||
case BluezProperty.rssi:
|
||||
onScanResult?.call(device.toBleScanResult());
|
||||
updateScanResult(device.toBleScanResult());
|
||||
break;
|
||||
case BluezProperty.connected:
|
||||
onConnectionChanged?.call(
|
||||
@@ -425,7 +426,7 @@ class UniversalBleLinux extends UniversalBlePlatform {
|
||||
);
|
||||
break;
|
||||
case BluezProperty.manufacturerData:
|
||||
onScanResult?.call(device.toBleScanResult());
|
||||
updateScanResult(device.toBleScanResult());
|
||||
break;
|
||||
case BluezProperty.paired:
|
||||
onPairingStateChange?.call(device.address, device.paired, null);
|
||||
|
||||
@@ -31,6 +31,7 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
||||
Future<void> startScan({
|
||||
ScanFilter? scanFilter,
|
||||
}) async {
|
||||
await super.startScan(scanFilter: scanFilter);
|
||||
await _channel.startScan(
|
||||
scanFilter.toUniversalScanFilter(),
|
||||
);
|
||||
@@ -116,7 +117,7 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
||||
/// To set listeners
|
||||
void _setupListeners() {
|
||||
UniversalBleCallbackChannel.setUp(_UniversalBleCallbackHandler(
|
||||
scanResult: (BleScanResult scanResult) => onScanResult?.call(scanResult),
|
||||
scanResult: (BleScanResult scanResult) => updateScanResult(scanResult),
|
||||
availabilityChange: (AvailabilityState state) =>
|
||||
onAvailabilityChange?.call(state),
|
||||
connectionChanged: (String deviceId, BleConnectionState state) =>
|
||||
|
||||
@@ -3,13 +3,17 @@ import 'dart:typed_data';
|
||||
import 'package:universal_ble/universal_ble.dart';
|
||||
|
||||
abstract class UniversalBlePlatform {
|
||||
ScanFilter? _scanFilter;
|
||||
|
||||
Future<AvailabilityState> getBluetoothAvailabilityState();
|
||||
|
||||
Future<bool> enableBluetooth();
|
||||
|
||||
Future<void> startScan({
|
||||
ScanFilter? scanFilter,
|
||||
});
|
||||
}) async {
|
||||
_scanFilter = scanFilter;
|
||||
}
|
||||
|
||||
Future<void> stopScan();
|
||||
|
||||
@@ -44,6 +48,17 @@ abstract class UniversalBlePlatform {
|
||||
List<String>? withServices,
|
||||
);
|
||||
|
||||
void updateScanResult(BleScanResult scanResult) {
|
||||
// Filter by name
|
||||
ScanFilter? scanFilter = _scanFilter;
|
||||
if (scanFilter != null && scanFilter.withNamePrefix.isNotEmpty) {
|
||||
if (scanResult.name == null ||
|
||||
!scanFilter.withNamePrefix
|
||||
.any((e) => scanResult.name?.startsWith(e) == true)) return;
|
||||
}
|
||||
onScanResult?.call(scanResult);
|
||||
}
|
||||
|
||||
OnAvailabilityChange? onAvailabilityChange;
|
||||
OnScanResult? onScanResult;
|
||||
OnConnectionChanged? onConnectionChanged;
|
||||
|
||||
@@ -127,7 +127,7 @@ class UniversalBleWeb extends UniversalBlePlatform {
|
||||
_bluetoothDeviceList[device.id] = device;
|
||||
|
||||
// Update Scan Result
|
||||
onScanResult?.call(device.toBleScanResult());
|
||||
updateScanResult(device.toBleScanResult());
|
||||
|
||||
/// This will work only if `chrome://flags/#enable-experimental-web-platform-features` is enabled
|
||||
if (FlutterWebBluetooth.instance.hasRequestLEScan) {
|
||||
@@ -140,7 +140,7 @@ class UniversalBleWeb extends UniversalBlePlatform {
|
||||
|
||||
_deviceAdvertisementStreamList[device.id] =
|
||||
device.advertisements.listen((event) {
|
||||
onScanResult?.call(
|
||||
updateScanResult(
|
||||
device.toBleScanResult(
|
||||
rssi: event.rssi,
|
||||
manufacturerDataMap: event.manufacturerData,
|
||||
@@ -410,6 +410,13 @@ extension ScanFilterExtension on ScanFilter {
|
||||
);
|
||||
}
|
||||
|
||||
// Add name filter
|
||||
for (var name in withNamePrefix) {
|
||||
filters.add(
|
||||
RequestFilterBuilder(namePrefix: name),
|
||||
);
|
||||
}
|
||||
|
||||
if (filters.isEmpty) {
|
||||
return RequestOptionsBuilder.acceptAllDevices();
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
name: universal_ble
|
||||
description: A cross-platform (Android/iOS/macOS/Windows/Linux/Web) Bluetooth Low Energy (BLE) plugin for Flutter
|
||||
version: 0.9.10
|
||||
version: 0.9.11
|
||||
homepage: https://navideck.com
|
||||
repository: https://github.com/Navideck/universal_ble
|
||||
issue_tracker: https://github.com/Navideck/universal_ble/issues
|
||||
|
||||
Reference in New Issue
Block a user