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:
Rohit Sangwan
2024-05-17 19:19:30 +05:30
committed by GitHub
parent 77b8658f72
commit 5847bbffc5
9 changed files with 54 additions and 12 deletions
+4
View File
@@ -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`
+7
View File
@@ -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(
+2
View File
@@ -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) =>
+16 -1
View File
@@ -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
View File
@@ -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