Skip to content

Commit a80f98e

Browse files
bparrishMinesEgor
authored andcommitted
[wifi_info_flutter] Wifi plugin implementation (flutter#3143)
1 parent 43ec3ef commit a80f98e

File tree

19 files changed

+840
-169
lines changed

19 files changed

+840
-169
lines changed
Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,71 @@
11
# wifi_info_flutter
22

3-
A new flutter plugin project.
3+
This plugin retrieves information about a device's connection to wifi.
44

5-
## Getting Started
5+
> Note that on Android, this does not guarantee connection to Internet. For instance,
6+
the app might have wifi access but it might be a VPN or a hotel WiFi with no access.
7+
8+
## Usage
9+
10+
### Android
11+
12+
Sample usage to check current status:
13+
14+
To successfully get WiFi Name or Wi-Fi BSSID starting with Android O, ensure all of the following conditions are met:
15+
16+
* If your app is targeting Android 10 (API level 29) SDK or higher, your app has the ACCESS_FINE_LOCATION permission.
17+
18+
* If your app is targeting SDK lower than Android 10 (API level 29), your app has the ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.
19+
20+
* Location services are enabled on the device (under Settings > Location).
21+
22+
You can get wi-fi related information using:
23+
24+
```dart
25+
import 'package:wifi_info_flutter/wifi_info_flutter.dart';
26+
27+
var wifiBSSID = await WifiFlutter().getWifiBSSID();
28+
var wifiIP = await WifiFlutter().getWifiIP();
29+
var wifiName = await WifiFlutter().getWifiName();
30+
```
31+
32+
### iOS 12
33+
34+
To use `.getWifiBSSID()` and `.getWifiName()` on iOS >= 12, the `Access WiFi information capability` in XCode must be enabled. Otherwise, both methods will return null.
35+
36+
### iOS 13
637

7-
This project is a starting point for a Flutter
8-
[plug-in package](https://flutter.dev/developing-packages/),
9-
a specialized package that includes platform-specific implementation code for
10-
Android and/or iOS.
38+
The methods `.getWifiBSSID()` and `.getWifiName()` utilize the [`CNCopyCurrentNetworkInfo`](https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo) function on iOS.
39+
40+
As of iOS 13, Apple announced that these APIs will no longer return valid information.
41+
An app linked against iOS 12 or earlier receives pseudo-values such as:
42+
43+
* SSID: "Wi-Fi" or "WLAN" ("WLAN" will be returned for the China SKU).
44+
45+
* BSSID: "00:00:00:00:00:00"
46+
47+
An app linked against iOS 13 or later receives `null`.
48+
49+
The `CNCopyCurrentNetworkInfo` will work for Apps that:
50+
51+
* The app uses Core Location, and has the user’s authorization to use location information.
52+
53+
* The app uses the NEHotspotConfiguration API to configure the current Wi-Fi network.
54+
55+
* The app has active VPN configurations installed.
56+
57+
If your app falls into the last two categories, it will work as it is. If your app doesn't fall into the last two categories,
58+
and you still need to access the wifi information, you should request user's authorization to use location information.
59+
60+
There is a helper method provided in this plugin to request the location authorization: `requestLocationServiceAuthorization`.
61+
To request location authorization, make sure to add the following keys to your _Info.plist_ file, located in `<project root>/ios/Runner/Info.plist`:
62+
63+
* `NSLocationAlwaysAndWhenInUseUsageDescription` - describe why the app needs access to the user’s location information all the time (foreground and background). This is called _Privacy - Location Always and When In Use Usage Description_ in the visual editor.
64+
* `NSLocationWhenInUseUsageDescription` - describe why the app needs access to the user’s location information when the app is running in the foreground. This is called _Privacy - Location When In Use Usage Description_ in the visual editor.
65+
66+
## Getting Started
1167

12-
For help getting started with Flutter, view our
13-
[online documentation](https://flutter.dev/docs), which offers tutorials,
14-
samples, guidance on mobile development, and a full API reference.
68+
For help getting started with Flutter, view our online
69+
[documentation](http://flutter.io/).
1570

71+
For help on editing plugin code, view the [documentation](https://flutter.io/platform-plugins/#edit-code).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
22
package="io.flutter.plugins.wifi_info_flutter">
3+
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
34
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2020 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.wifi_info_flutter;
6+
7+
import android.net.wifi.WifiInfo;
8+
import android.net.wifi.WifiManager;
9+
10+
/** Reports wifi information. */
11+
class WifiInfoFlutter {
12+
private WifiManager wifiManager;
13+
14+
WifiInfoFlutter(WifiManager wifiManager) {
15+
this.wifiManager = wifiManager;
16+
}
17+
18+
String getWifiName() {
19+
final WifiInfo wifiInfo = getWifiInfo();
20+
String ssid = null;
21+
if (wifiInfo != null) ssid = wifiInfo.getSSID();
22+
if (ssid != null) ssid = ssid.replaceAll("\"", ""); // Android returns "SSID"
23+
if (ssid != null && ssid.equals("<unknown ssid>")) ssid = null;
24+
return ssid;
25+
}
26+
27+
String getWifiBSSID() {
28+
final WifiInfo wifiInfo = getWifiInfo();
29+
String bssid = null;
30+
if (wifiInfo != null) {
31+
bssid = wifiInfo.getBSSID();
32+
}
33+
return bssid;
34+
}
35+
36+
String getWifiIPAddress() {
37+
WifiInfo wifiInfo = null;
38+
if (wifiManager != null) wifiInfo = wifiManager.getConnectionInfo();
39+
40+
String ip = null;
41+
int i_ip = 0;
42+
if (wifiInfo != null) i_ip = wifiInfo.getIpAddress();
43+
44+
if (i_ip != 0)
45+
ip =
46+
String.format(
47+
"%d.%d.%d.%d",
48+
(i_ip & 0xff), (i_ip >> 8 & 0xff), (i_ip >> 16 & 0xff), (i_ip >> 24 & 0xff));
49+
50+
return ip;
51+
}
52+
53+
private WifiInfo getWifiInfo() {
54+
return wifiManager == null ? null : wifiManager.getConnectionInfo();
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2020 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.wifi_info_flutter;
6+
7+
import io.flutter.plugin.common.MethodCall;
8+
import io.flutter.plugin.common.MethodChannel;
9+
10+
/**
11+
* The handler receives {@link MethodCall}s from the UIThread, gets the related information from
12+
* a @{@link WifiInfoFlutter}, and then send the result back to the UIThread through the {@link
13+
* MethodChannel.Result}.
14+
*/
15+
class WifiInfoFlutterMethodChannelHandler implements MethodChannel.MethodCallHandler {
16+
private WifiInfoFlutter wifiInfoFlutter;
17+
18+
/**
19+
* Construct the WifiInfoFlutterMethodChannelHandler with a {@code wifiInfoFlutter}. The {@code
20+
* wifiInfoFlutter} must not be null.
21+
*/
22+
WifiInfoFlutterMethodChannelHandler(WifiInfoFlutter wifiInfoFlutter) {
23+
assert (wifiInfoFlutter != null);
24+
this.wifiInfoFlutter = wifiInfoFlutter;
25+
}
26+
27+
@Override
28+
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
29+
switch (call.method) {
30+
case "wifiName":
31+
result.success(wifiInfoFlutter.getWifiName());
32+
break;
33+
case "wifiBSSID":
34+
result.success(wifiInfoFlutter.getWifiBSSID());
35+
break;
36+
case "wifiIPAddress":
37+
result.success(wifiInfoFlutter.getWifiIPAddress());
38+
break;
39+
default:
40+
result.notImplemented();
41+
break;
42+
}
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,46 @@
1+
// Copyright 2020 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
15
package io.flutter.plugins.wifi_info_flutter;
26

3-
import androidx.annotation.NonNull;
7+
import android.content.Context;
8+
import android.net.wifi.WifiManager;
49
import io.flutter.embedding.engine.plugins.FlutterPlugin;
5-
import io.flutter.plugin.common.MethodCall;
10+
import io.flutter.plugin.common.BinaryMessenger;
611
import io.flutter.plugin.common.MethodChannel;
7-
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
8-
import io.flutter.plugin.common.MethodChannel.Result;
912

1013
/** WifiInfoFlutterPlugin */
11-
public class WifiInfoFlutterPlugin implements FlutterPlugin, MethodCallHandler {
12-
/// The MethodChannel that will the communication between Flutter and native Android
13-
///
14-
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
15-
/// when the Flutter Engine is detached from the Activity
16-
private MethodChannel channel;
14+
public class WifiInfoFlutterPlugin implements FlutterPlugin {
15+
private MethodChannel methodChannel;
1716

18-
@Override
19-
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
20-
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "wifi_info_flutter");
21-
channel.setMethodCallHandler(this);
17+
/** Plugin registration. */
18+
@SuppressWarnings("deprecation")
19+
public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) {
20+
WifiInfoFlutterPlugin plugin = new WifiInfoFlutterPlugin();
21+
plugin.setupChannels(registrar.messenger(), registrar.context());
2222
}
2323

2424
@Override
25-
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
26-
if (call.method.equals("getPlatformVersion")) {
27-
result.success("Android " + android.os.Build.VERSION.RELEASE);
28-
} else {
29-
result.notImplemented();
30-
}
25+
public void onAttachedToEngine(FlutterPluginBinding binding) {
26+
setupChannels(binding.getBinaryMessenger(), binding.getApplicationContext());
3127
}
3228

3329
@Override
34-
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
35-
channel.setMethodCallHandler(null);
30+
public void onDetachedFromEngine(FlutterPluginBinding binding) {
31+
methodChannel.setMethodCallHandler(null);
32+
methodChannel = null;
33+
}
34+
35+
private void setupChannels(BinaryMessenger messenger, Context context) {
36+
methodChannel = new MethodChannel(messenger, "plugins.flutter.io/wifi_flutter_info");
37+
final WifiManager wifiManager =
38+
(WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
39+
40+
final WifiInfoFlutter wifiInfoFlutter = new WifiInfoFlutter(wifiManager);
41+
42+
final WifiInfoFlutterMethodChannelHandler methodChannelHandler =
43+
new WifiInfoFlutterMethodChannelHandler(wifiInfoFlutter);
44+
methodChannel.setMethodCallHandler(methodChannelHandler);
3645
}
3746
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
org.gradle.jvmargs=-Xmx1536M
22
android.useAndroidX=true
33
android.enableJetifier=true
4+
android.enableR8=true

packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/Info.plist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,9 @@
4141
</array>
4242
<key>UIViewControllerBasedStatusBarAppearance</key>
4343
<false/>
44+
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
45+
<string>This app requires accessing your location information all the time to get wi-fi information.</string>
46+
<key>NSLocationWhenInUseUsageDescription</key>
47+
<string>This app requires accessing your location information when the app is in foreground to get wi-fi information.</string>
4448
</dict>
4549
</plist>

0 commit comments

Comments
 (0)