dotintent / FlutterBleLib

Bluetooth Low Energy library for Flutter with support for simulating peripherals
Apache License 2.0
536 stars 197 forks source link

Specify other ScanFilter filters on Android #471

Open isaiahtaylorhh opened 4 years ago

isaiahtaylorhh commented 4 years ago

Hello, we can currently specify service UUIDs which gets built into a ScanFilter on Android, but Android supports several other ScanFilter filters like name, MAC address, etc. (https://developer.android.com/reference/android/bluetooth/le/ScanFilter). I'd like to specify those filters as well for Android.

I believe this request is dependent on the my open issue for the underlying library:

https://github.com/Polidea/MultiPlatformBleAdapter/issues/59

If the above were to be implemented, could we have that functionality also supported in this higher level library?

And same as before, if there is no bandwidth for this, would a PR be appreciated?

mikolak commented 4 years ago

Hi!

Thanks for the issues.

Wouldn't filtering them in Flutter better suit your needs? Like this: startScan().filter((scanResult) { /* do whatever you want*/ }.listen()

The library mostly exposes the common ground between the two platforms - filtering by services is working on both iOS and Android.

I haven't found any details on Android's ScanFilter, but since BLE works over radio I guess the device receives and parses all the advertisement packets and only limits the output to client application. The upside would be a lesser workload for the bridge between Dart VM and ART, but I'm not aware of any performance issues there as of now.

Filtering scan results in Dart would work more or less the same for both platforms (since some information is platform–specific) and requires pretty much the same work from the user of the library, but is more flexible.

isaiahtaylorhh commented 4 years ago

@mikolak Android requires that you have some non-null, non-empty ScanFilter in order to scan in the background. The library can currently use Service UUIDs to accomplish this, but ScanFilter has a broader range. For instance, background scanning with a MAC filter when service UUID is unavailable. My proposal here is to support that quirk of Android’s background policy.

mikolak commented 4 years ago

Ah, didn't know that. Yeah, it makes sense! I'm not sure if it wouldn't force you to use isolates in Flutter, but that's the user's concerns, plugin can't do anything about it.

A PR to both libraries would be greatly appreciated.

I think it'd have to be marked in Dart as Android-only, so perhaps something along the lines of:

Stream<ScanResult> startPeripheralScan({
    int scanMode = ScanMode.lowPower,
    int callbackType = CallbackType.allMatches,
    List<String> uuids = const [],
    bool allowDuplicates = false,
    AndroidFilters optionalFilters,
  });

class AndroidFilters {
   List<String> macAddresses;
   List<String> manufacturersDatas;
   List<String> names;
   List<String> serviceDatas;
}