main
1import 'dart:async';
2
3import 'package:flutter_blue_plus/flutter_blue_plus.dart';
4
5/// Wrapper for FlutterBluePlus in order to easily mock it
6/// Wraps all calls for testing purposes
7class FlutterBluePlusMockable {
8 LogLevel get logLevel => FlutterBluePlus.logLevel;
9
10 /// Checks whether the hardware supports Bluetooth
11 Future<bool> get isSupported => FlutterBluePlus.isSupported;
12
13 /// The current adapter state
14 BluetoothAdapterState get adapterStateNow => FlutterBluePlus.adapterStateNow;
15
16 /// Return the friendly Bluetooth name of the local Bluetooth adapter
17 Future<String> get adapterName => FlutterBluePlus.adapterName;
18
19 /// returns whether we are scanning as a stream
20 Stream<bool> get isScanning => FlutterBluePlus.isScanning;
21
22 /// are we scanning right now?
23 bool get isScanningNow => FlutterBluePlus.isScanningNow;
24
25 /// the most recent scan results
26 List<ScanResult> get lastScanResults => FlutterBluePlus.lastScanResults;
27
28 /// a stream of scan results
29 /// - if you re-listen to the stream it re-emits the previous results
30 /// - the list contains all the results since the scan started
31 /// - the returned stream is never closed.
32 Stream<List<ScanResult>> get scanResults => FlutterBluePlus.scanResults;
33
34 /// This is the same as scanResults, except:
35 /// - it *does not* re-emit previous results after scanning stops.
36 Stream<List<ScanResult>> get onScanResults => FlutterBluePlus.onScanResults;
37
38 /// Get access to all device event streams
39 BluetoothEvents get events => FlutterBluePlus.events;
40
41 /// Gets the current state of the Bluetooth module
42 Stream<BluetoothAdapterState> get adapterState =>
43 FlutterBluePlus.adapterState;
44
45 /// Retrieve a list of devices currently connected to your app
46 List<BluetoothDevice> get connectedDevices =>
47 FlutterBluePlus.connectedDevices;
48
49 /// Retrieve a list of devices currently connected to the system
50 /// - The list includes devices connected to by *any* app
51 /// - You must still call device.connect() to connect them to *your app*
52 Future<List<BluetoothDevice>> systemDevices(List<Guid> withServices) =>
53 FlutterBluePlus.systemDevices(withServices);
54
55 /// Retrieve a list of bonded devices (Android only)
56 Future<List<BluetoothDevice>> get bondedDevices =>
57 FlutterBluePlus.bondedDevices;
58
59 /// Set configurable options
60 /// - [showPowerAlert] Whether to show the power alert (iOS & MacOS only). i.e. CBCentralManagerOptionShowPowerAlertKey
61 /// To set this option you must call this method before any other method in this package.
62 /// See: https://developer.apple.com/documentation/corebluetooth/cbcentralmanageroptionshowpoweralertkey
63 /// This option has no effect on Android.
64 Future<void> setOptions({
65 bool showPowerAlert = true,
66 }) => FlutterBluePlus.setOptions(showPowerAlert: showPowerAlert);
67
68 /// Turn on Bluetooth (Android only),
69 Future<void> turnOn({int timeout = 60}) =>
70 FlutterBluePlus.turnOn(timeout: timeout);
71
72 /// Start a scan, and return a stream of results
73 /// Note: scan filters use an "or" behavior. i.e. if you set `withServices` & `withNames` we
74 /// return all the advertisments that match any of the specified services *or* any of the specified names.
75 /// - [withServices] filter by advertised services
76 /// - [withRemoteIds] filter for known remoteIds (iOS: 128-bit guid, android: 48-bit mac address)
77 /// - [withNames] filter by advertised names (exact match)
78 /// - [withKeywords] filter by advertised names (matches any substring)
79 /// - [withMsd] filter by manfacture specific data
80 /// - [withServiceData] filter by service data
81 /// - [timeout] calls stopScan after a specified duration
82 /// - [removeIfGone] if true, remove devices after they've stopped advertising for X duration
83 /// - [continuousUpdates] If `true`, we continually update 'lastSeen' & 'rssi' by processing
84 /// duplicate advertisements. This takes more power. You typically should not use this option.
85 /// - [continuousDivisor] Useful to help performance. If divisor is 3, then two-thirds of advertisements are
86 /// ignored, and one-third are processed. This reduces main-thread usage caused by the platform channel.
87 /// The scan counting is per-device so you always get the 1st advertisement from each device.
88 /// If divisor is 1, all advertisements are returned. This argument only matters for `continuousUpdates` mode.
89 /// - [oneByOne] if `true`, we will stream every advertistment one by one, possibly including duplicates.
90 /// If `false`, we deduplicate the advertisements, and return a list of devices.
91 /// - [androidScanMode] choose the android scan mode to use when scanning
92 /// - [androidUsesFineLocation] request `ACCESS_FINE_LOCATION` permission at runtime
93 Future<void> startScan({
94 List<Guid> withServices = const [],
95 List<String> withRemoteIds = const [],
96 List<String> withNames = const [],
97 List<String> withKeywords = const [],
98 List<MsdFilter> withMsd = const [],
99 List<ServiceDataFilter> withServiceData = const [],
100 Duration? timeout,
101 Duration? removeIfGone,
102 bool continuousUpdates = false,
103 int continuousDivisor = 1,
104 bool oneByOne = false,
105 AndroidScanMode androidScanMode = AndroidScanMode.lowLatency,
106 bool androidUsesFineLocation = false,
107 }) => FlutterBluePlus.startScan(
108 withServices: withServices,
109 withRemoteIds: withRemoteIds,
110 withNames: withNames,
111 withKeywords: withKeywords,
112 withMsd: withMsd,
113 withServiceData: withServiceData,
114 timeout: timeout,
115 removeIfGone: removeIfGone,
116 continuousUpdates: continuousUpdates,
117 continuousDivisor: continuousDivisor,
118 oneByOne: oneByOne,
119 androidScanMode: androidScanMode,
120 androidUsesFineLocation: androidUsesFineLocation,
121 );
122
123 /// Stops a scan for Bluetooth Low Energy devices
124 Future<void> stopScan() => FlutterBluePlus.stopScan();
125
126 /// Register a subscription to be canceled when scanning is complete.
127 /// This function simplifies cleanup, to prevent creating duplicate stream subscriptions.
128 /// - this is an optional convenience function
129 /// - prevents accidentally creating duplicate subscriptions before each scan
130 void cancelWhenScanComplete(StreamSubscription subscription) =>
131 FlutterBluePlus.cancelWhenScanComplete(subscription);
132
133 /// Sets the internal FlutterBlue log level
134 Future<void> setLogLevel(LogLevel level, {bool color = true}) =>
135 FlutterBluePlus.setLogLevel(level, color: color);
136
137 /// Request Bluetooth PHY support
138 Future<PhySupport> getPhySupport() => FlutterBluePlus.getPhySupport();
139}