Skip to content

Commit 4fe564b

Browse files
authored
revert(wifi_scan)!: added back "can" APIs (#288)
- reverting #246 pull [most of it]
1 parent 1cd174d commit 4fe564b

File tree

8 files changed

+438
-454
lines changed

8 files changed

+438
-454
lines changed

packages/wifi_scan/README.md

Lines changed: 45 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -33,79 +33,71 @@ This plugin allows Flutter apps to scan for nearby visible WiFi access points.
3333
## Usage
3434
The entry point for the plugin is the singleton instance `WiFiScan.instance`.
3535

36-
### Check support
37-
You can check if the platform has Wi-Fi scan capabilities with `WiFiScan.hasCapability` API, as shown below:
38-
```dart
39-
void _scan() async {
40-
if(await WiFiScan.instance.hasCapability()){
41-
// can safely call scan related functionalities
42-
} else {
43-
// fallback mechanism, like - show user that "scan" is not possible
44-
}
45-
}
46-
```
47-
48-
For more details, you can read documentation of [`WiFiScan.hasCapability`][doc_hasCapability].
49-
5036
### Start scan
5137
You can trigger full WiFi scan with `WiFiScan.startScan` API, as shown below:
5238
```dart
5339
void _startScan() async {
54-
// start full scan async-ly
55-
final error = await WiFiScan.instance.startScan(askPermissions: true);
56-
if (error != null) {
57-
switch(error) {
58-
// handle error for values of StartScanErrors
59-
}
40+
// check platform support and necessary requirements
41+
final can = await WiFiScan.instance.canStartScan(askPermissions: true);
42+
switch(can) {
43+
case CanStartScan.yes:
44+
// start full scan async-ly
45+
final isScanning = await WiFiScan.instance.startScan();
46+
//...
47+
break;
48+
// ... handle other cases of CanStartScan values
6049
}
6150
}
6251
```
6352

6453
For more details, you can read documentation of [`WiFiScan.startScan`][doc_startScan],
65-
[`StartScanErrors`][doc_StartScanErrors] and [`Result<ValueType, ErrorType>`][doc_Result].
54+
[`WiFiScan.canStartScan`][doc_canStartScan] and [`CanStartScan`][doc_enum_CanStartScan].
6655

6756
### Get scanned results
6857
You can get scanned results with `WiFiScan.getScannedResults` API, as shown below:
6958
```dart
7059
void _getScannedResults() async {
71-
// get scanned results
72-
final result = await WiFiScan.instance.getScannedResults(askPermissions: true);
73-
if (result.hasError){
74-
switch (error){
75-
// handle error for values of GetScannedResultErrors
76-
}
77-
} else {
78-
final accessPoints = result.value;
79-
// ...
60+
// check platform support and necessary requirements
61+
final can = await WiFiScan.instance.canGetScannedResults(askPermissions: true);
62+
switch(can) {
63+
case CanGetScannedResults.yes:
64+
// get scanned results
65+
final accessPoints = await WiFiScan.instance.getScannedResults();
66+
// ...
67+
break;
68+
// ... handle other cases of CanGetScannedResults values
8069
}
8170
}
8271
```
8372

8473
> **NOTE:** `getScannedResults` API can be used independently of `startScan` API. This returns the latest available scanned results.
8574
86-
For more details, you can read documentation of [`WiFiScan.getScannedResults`][doc_getScannedResults],
87-
[`WiFiAccessPoint`][doc_WiFiAccessPoint], [`GetScannedResultsErrors`][doc_GetScannedResultsErrors] and
88-
[`Result<ValueType, ErrorType>`][doc_Result].
75+
For more details, you can read documentation of [`WiFiScan.getScannedResults`][doc_getScannedResults],
76+
[`WiFiAccessPoint`][doc_WiFiAccessPoint],
77+
[`WiFiScan.canGetScannedResults`][doc_canGetScannedResults] and
78+
[`CanGetScannedResults`][doc_enum_CanGetScannedResults].
8979

9080
### Get notified when scanned results available
9181
You can get notified when new scanned results are available with `WiFiScan.onScannedResultsAvailable` API, as shown below:
9282
```dart
9383
// initialize accessPoints and subscription
9484
List<WiFiAccessPoint> accessPoints = [];
95-
StreamSubscription<Result<List<WiFiAccessPoint>, GetScannedResultErrors>>? subscription;
85+
StreamSubscription<List<WiFiAccessPoint>>? subscription;
9686
9787
void _startListeningToScannedResults() async {
98-
// listen to onScannedResultsAvailable stream
99-
subscription = WiFiScan.instance.onScannedResultsAvailable.listen((result) {
100-
if (result.hasError){
101-
switch (error){
102-
// handle error for values of GetScannedResultErrors
103-
}
104-
} else {
105-
// update accessPoints
106-
setState(() => accessPoints = result.value);
107-
}
108-
});
88+
// check platform support and necessary requirements
89+
final can = await WiFiScan.instance.canGetScannedResults(askPermissions: true);
90+
switch(can) {
91+
case CanGetScannedResults.yes:
92+
// listen to onScannedResultsAvailable stream
93+
subscription = WiFiScan.instance.onScannedResultsAvailable.listen((results) {
94+
// update accessPoints
95+
setState(() => accessPoints = results);
96+
});
97+
// ...
98+
break;
99+
// ... handle other cases of CanGetScannedResults values
100+
}
109101
}
110102
111103
// make sure to cancel subscription after you are done
@@ -122,9 +114,10 @@ Additionally, `WiFiScan.onScannedResultsAvailable` API can also be used with Flu
122114
> **NOTE:** `onScannedResultsAvailable` API can be used independently of `startScan` API. The notification can also be result of a full scan performed by platform or other app.
123115
124116
For more details, you can read documentation of
125-
[`WiFiScan.onScannedResultsAvailable`][doc_onScannedResultsAvailable],
126-
[`WiFiAccessPoint`][doc_WiFiAccessPoint], [`GetScannedResultsErrors`][doc_GetScannedResultsErrors] and
127-
[`Result<ValueType, ErrorType>`][doc_Result].
117+
[`WiFiScan.onScannedResultsAvailable`][doc_onScannedResultsAvailable],
118+
[`WiFiAccessPoint`][doc_WiFiAccessPoint],
119+
[`WiFiScan.canGetScannedResults`][doc_canGetScannedResults] and
120+
[`CanGetScannedResults`][doc_enum_CanGetScannedResults].
128121

129122
## Resources
130123
- 📖[API docs][docs]
@@ -155,13 +148,13 @@ This project follows the [all-contributors][all_contributors] specification. Con
155148
[docs]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/wifi_scan-library.html
156149
[example]: https://github.com/flutternetwork/WiFiFlutter/tree/master/packages/wifi_scan/example
157150

158-
[doc_hasCapability]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/WiFiScan/hasCapability.html
159151
[doc_startScan]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/WiFiScan/startScan.html
160-
[doc_StartScanErrors]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/StartScanErrors.html
161-
[doc_Result]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/Result-class.html
152+
[doc_canStartScan]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/WiFiScan/canStartScan.html
153+
[doc_enum_CanStartScan]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/CanStartScan.html
162154
[doc_getScannedResults]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/WiFiScan/getScannedResults.html
163155
[doc_WiFiAccessPoint]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/WiFiAccessPoint-class.html
164-
[doc_GetScannedResultsErrors]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/GetScannedResultsErrors.html
156+
[doc_canGetScannedResults]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/WiFiScan/canGetScannedResults.html
157+
[doc_enum_CanGetScannedResults]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/CanGetScannedResults.html
165158
[doc_onScannedResultsAvailable]: https://pub.dev/documentation/wifi_scan/latest/wifi_scan/WiFiScan/onScannedResultsAvailable.html
166159

167160
[flutter_StreamBuilder]: https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html

packages/wifi_scan/android/src/main/kotlin/dev/flutternetwork/wifi/wifi_scan/WifiScanPlugin.kt

Lines changed: 74 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,21 @@ import kotlin.random.Random
3131
private const val ERROR_INVALID_ARGS = "InvalidArgs"
3232
private const val ERROR_NULL_ACTIVITY = "NullActivity"
3333

34-
/** StartScanError codes */
35-
private const val ERROR_START_SCAN_NOT_SUPPORTED = 0
36-
private const val ERROR_START_SCAN_NO_LOC_PERM_REQUIRED = 1
37-
private const val ERROR_START_SCAN_NO_LOC_PERM_DENIED = 2
38-
private const val ERROR_START_SCAN_NO_LOC_PERM_UPGRADE_ACCURACY = 3
39-
private const val ERROR_START_SCAN_NO_LOC_DISABLED = 4
40-
private const val ERROR_START_SCAN_FAILED = 5
41-
42-
/** GetScannedResultsError codes */
43-
private const val ERROR_GET_RESULTS_NOT_SUPPORTED = 0
44-
private const val ERROR_GET_RESULTS_NO_LOC_PERM_REQUIRED = 1
45-
private const val ERROR_GET_RESULTS_NO_LOC_PERM_DENIED = 2
46-
private const val ERROR_GET_RESULTS_NO_LOC_PERM_UPGRADE_ACCURACY = 3
47-
private const val ERROR_GET_RESULTS_NO_LOC_DISABLED = 4
34+
/** CanStartScan codes */
35+
private const val CAN_START_SCAN_NOT_SUPPORTED = 0
36+
private const val CAN_START_SCAN_YES = 1
37+
private const val CAN_START_SCAN_NO_LOC_PERM_REQUIRED = 2
38+
private const val CAN_START_SCAN_NO_LOC_PERM_DENIED = 3
39+
private const val CAN_START_SCAN_NO_LOC_PERM_UPGRADE_ACCURACY = 4
40+
private const val CAN_START_SCAN_NO_LOC_DISABLED = 5
41+
42+
/** CanGetScannedResults codes */
43+
private const val CAN_GET_RESULTS_NOT_SUPPORTED = 0
44+
private const val CAN_GET_RESULTS_YES = 1
45+
private const val CAN_GET_RESULTS_NO_LOC_PERM_REQUIRED = 2
46+
private const val CAN_GET_RESULTS_NO_LOC_PERM_DENIED = 3
47+
private const val CAN_GET_RESULTS_NO_LOC_PERM_UPGRADE_ACCURACY = 4
48+
private const val CAN_GET_RESULTS_NO_LOC_DISABLED = 5
4849

4950
/** Magic codes */
5051
private const val ASK_FOR_LOC_PERM = -1
@@ -141,31 +142,38 @@ class WifiScanPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
141142
eventSink = null
142143
}
143144

145+
override fun onRequestPermissionsResult(
146+
requestCode: Int, permissions: Array<out String>, grantResults: IntArray
147+
): Boolean {
148+
Log.d(
149+
logTag,
150+
"onRequestPermissionsResult: arguments ($requestCode, $permissions, $grantResults)"
151+
)
152+
Log.d(logTag, "requestPermissionCookie: $requestPermissionCookie")
153+
return requestPermissionCookie[requestCode]?.invoke(grantResults) ?: false
154+
}
155+
144156
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
145157
when (call.method) {
146-
"hasCapability" -> result.success(true)
147-
"startScan" -> {
158+
"canStartScan" -> {
148159
val askPermission = call.argument<Boolean>("askPermissions") ?: return result.error(
149160
ERROR_INVALID_ARGS,
150161
"askPermissions argument is null",
151162
null
152163
)
153-
val errorCode = startScan(askPermission)
154164
// if not ASK_FOR_LOC_PERM, send result
155165
// else ask for permission - wait for user action - return result based on it
156-
if (errorCode != ASK_FOR_LOC_PERM) {
157-
result.success(errorCode)
158-
} else {
159-
askForLocationPermission { askResult ->
166+
when (val canCode = canStartScan(askPermission)) {
167+
ASK_FOR_LOC_PERM -> askForLocationPermission { askResult ->
160168
when (askResult) {
161169
AskLocPermResult.GRANTED -> {
162-
result.success(startScan(askPermission = false))
170+
result.success(canStartScan(askPermission = false))
163171
}
164172
AskLocPermResult.UPGRADE_TO_FINE -> {
165-
result.success(ERROR_START_SCAN_NO_LOC_PERM_UPGRADE_ACCURACY)
173+
result.success(CAN_START_SCAN_NO_LOC_PERM_UPGRADE_ACCURACY)
166174
}
167175
AskLocPermResult.DENIED -> {
168-
result.success(ERROR_START_SCAN_NO_LOC_PERM_DENIED)
176+
result.success(CAN_START_SCAN_NO_LOC_PERM_DENIED)
169177
}
170178
AskLocPermResult.ERROR_NO_ACTIVITY -> {
171179
result.error(
@@ -176,30 +184,27 @@ class WifiScanPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
176184
}
177185
}
178186
}
187+
else -> result.success(canCode)
179188
}
180189
}
181-
"getScannedResults" -> {
190+
"startScan" -> result.success(startScan())
191+
"canGetScannedResults" -> {
182192
val askPermission = call.argument<Boolean>("askPermissions") ?: return result.error(
183193
ERROR_INVALID_ARGS,
184194
"askPermissions argument is null",
185195
null
186196
)
187-
val mResult = getScannedResults(askPermission)
188-
// if error != ASK_FOR_LOC_PERM, send result
189-
// else ask for permission - wait for user action - return result based on it
190-
if (mResult["error"] != ASK_FOR_LOC_PERM) {
191-
result.success(mResult)
192-
} else {
193-
askForLocationPermission { askResult ->
197+
when(val canCode = canGetScannedResults(askPermission)){
198+
ASK_FOR_LOC_PERM -> askForLocationPermission { askResult ->
194199
when (askResult) {
195200
AskLocPermResult.GRANTED -> {
196-
result.success(getScannedResults(askPermission = false))
201+
result.success(canGetScannedResults(askPermission = false))
197202
}
198203
AskLocPermResult.UPGRADE_TO_FINE -> {
199-
result.success(errorResult(ERROR_GET_RESULTS_NO_LOC_PERM_UPGRADE_ACCURACY))
204+
result.success(CAN_GET_RESULTS_NO_LOC_PERM_UPGRADE_ACCURACY)
200205
}
201206
AskLocPermResult.DENIED -> {
202-
result.success(errorResult(ERROR_GET_RESULTS_NO_LOC_PERM_DENIED))
207+
result.success(CAN_GET_RESULTS_NO_LOC_PERM_DENIED)
203208
}
204209
AskLocPermResult.ERROR_NO_ACTIVITY -> {
205210
result.error(
@@ -210,81 +215,64 @@ class WifiScanPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
210215
}
211216
}
212217
}
218+
else -> result.success(canCode)
213219
}
214220
}
221+
"getScannedResults" -> result.success(getScannedResults())
215222
else -> result.notImplemented()
216223
}
217224
}
218225

219-
override fun onRequestPermissionsResult(
220-
requestCode: Int, permissions: Array<out String>, grantResults: IntArray
221-
): Boolean {
222-
Log.d(
223-
logTag,
224-
"onRequestPermissionsResult: arguments ($requestCode, $permissions, $grantResults)"
225-
)
226-
Log.d(logTag, "requestPermissionCookie: $requestPermissionCookie")
227-
return requestPermissionCookie[requestCode]?.invoke(grantResults) ?: false
228-
}
229-
230-
private fun startScan(askPermission: Boolean): Int? {
226+
private fun canStartScan(askPermission: Boolean): Int {
231227
val hasLocPerm = hasLocationPermission()
232228
val isLocEnabled = isLocationEnabled()
233-
// check all prerequisite conditions for startScan
234-
val errorCode = when {
229+
return when {
235230
// for SDK < P[28] : Not in guide, should not require any additional permissions
236-
Build.VERSION.SDK_INT < Build.VERSION_CODES.P -> null
231+
Build.VERSION.SDK_INT < Build.VERSION_CODES.P -> CAN_START_SCAN_YES
237232
// for SDK >= Q[29]: CHANGE_WIFI_STATE & ACCESS_x_LOCATION & "Location enabled"
238-
hasLocPerm && isLocEnabled -> null
239-
hasLocPerm -> ERROR_START_SCAN_NO_LOC_DISABLED
233+
hasLocPerm && isLocEnabled -> CAN_START_SCAN_YES
234+
hasLocPerm -> CAN_START_SCAN_NO_LOC_DISABLED
240235
askPermission -> ASK_FOR_LOC_PERM
241-
else -> ERROR_START_SCAN_NO_LOC_PERM_REQUIRED
236+
else -> CAN_START_SCAN_NO_LOC_PERM_REQUIRED
242237
}
243-
// if any errorCode then return it
244-
if (errorCode != null) return errorCode
245-
246-
// call startScan API - if failed then return ERROR_START_SCAN_FAILED
247-
return if (wifi!!.startScan()) null else ERROR_START_SCAN_FAILED
248238
}
249239

250-
private fun getScannedResults(askPermission: Boolean): Map<String, Any?> {
240+
private fun startScan(): Boolean = wifi!!.startScan()
241+
242+
private fun canGetScannedResults(askPermission: Boolean): Int {
251243
// check all prerequisite conditions
252244
// ACCESS_WIFI_STATE & ACCESS_x_LOCATION & "Location enabled"
253245
val hasLocPerm = hasLocationPermission()
254246
val isLocEnabled = isLocationEnabled()
255-
val errorCode = when {
256-
hasLocPerm && isLocEnabled -> null
257-
hasLocPerm -> ERROR_GET_RESULTS_NO_LOC_DISABLED
247+
return when {
248+
hasLocPerm && isLocEnabled -> CAN_GET_RESULTS_YES
249+
hasLocPerm -> CAN_GET_RESULTS_NO_LOC_DISABLED
258250
askPermission -> ASK_FOR_LOC_PERM
259-
else -> ERROR_GET_RESULTS_NO_LOC_PERM_REQUIRED
251+
else -> CAN_GET_RESULTS_NO_LOC_PERM_REQUIRED
260252
}
253+
}
261254

262-
// if any errorCode then return it
263-
if (errorCode != null) return errorResult(errorCode)
264-
265-
// return scannedResults
266-
return mapOf("value" to wifi!!.scanResults.map { ap ->
267-
mapOf(
268-
"ssid" to ap.SSID,
269-
"bssid" to ap.BSSID,
270-
"capabilities" to ap.capabilities,
271-
"frequency" to ap.frequency,
272-
"level" to ap.level,
273-
"timestamp" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) ap.timestamp else null,
274-
"standard" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) ap.wifiStandard else null,
275-
"centerFrequency0" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.centerFreq0 else null,
276-
"centerFrequency1" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.centerFreq1 else null,
277-
"channelWidth" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.channelWidth else null,
278-
"isPasspoint" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.isPasspointNetwork else null,
279-
"operatorFriendlyName" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.operatorFriendlyName else null,
280-
"venueName" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.venueName else null,
281-
"is80211mcResponder" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.is80211mcResponder else null
282-
)
283-
})
255+
private fun getScannedResults(): List<Map<String, Any?>> = wifi!!.scanResults.map { ap ->
256+
mapOf(
257+
"ssid" to ap.SSID,
258+
"bssid" to ap.BSSID,
259+
"capabilities" to ap.capabilities,
260+
"frequency" to ap.frequency,
261+
"level" to ap.level,
262+
"timestamp" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) ap.timestamp else null,
263+
"standard" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) ap.wifiStandard else null,
264+
"centerFrequency0" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.centerFreq0 else null,
265+
"centerFrequency1" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.centerFreq1 else null,
266+
"channelWidth" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.channelWidth else null,
267+
"isPasspoint" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.isPasspointNetwork else null,
268+
"operatorFriendlyName" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.operatorFriendlyName else null,
269+
"venueName" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.venueName else null,
270+
"is80211mcResponder" to if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ap.is80211mcResponder else null
271+
)
284272
}
285273

286274
private fun onScannedResultsAvailable() {
287-
eventSink?.success(getScannedResults(askPermission = false))
275+
eventSink?.success(getScannedResults())
288276
}
289277

290278
/**
@@ -349,6 +337,4 @@ class WifiScanPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
349337
LocationManagerCompat.isLocationEnabled(
350338
context.applicationContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
351339
)
352-
353-
private fun errorResult(code: Int): Map<String, Int> = mapOf("error" to code)
354340
}

0 commit comments

Comments
 (0)