Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[wifi_info_flutter] Wifi plugin implementation #3143

Merged
merged 11 commits into from Oct 21, 2020
Merged
@@ -1,3 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.flutter.plugins.wifi_info_flutter">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @bparrishMines
To make the plugin work with Android 8.0 and Android 8.1 without additional steps, you can add that too: android.permission.CHANGE_WIFI_STATE .
https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-permissions
Thank you

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
</manifest>
@@ -0,0 +1,55 @@
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.wifi_info_flutter;

import android.net.wifi.WifiManager;

/** Reports connectivity related information such as wifi information. */
class WifiInfoFlutter {
private WifiManager wifiManager;

WifiInfoFlutter(WifiManager wifiManager) {
this.wifiManager = wifiManager;
}

String getWifiName() {
android.net.wifi.WifiInfo wifiInfo = getWifiInfo();
String ssid = null;
if (wifiInfo != null) ssid = wifiInfo.getSSID();
if (ssid != null) ssid = ssid.replaceAll("\"", ""); // Android returns "SSID"
if (ssid != null && ssid.equals("<unknown ssid>")) ssid = null;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return ssid;
}

String getWifiBSSID() {
android.net.wifi.WifiInfo wifiInfo = getWifiInfo();
String bssid = null;
if (wifiInfo != null) {
bssid = wifiInfo.getBSSID();
}
return bssid;
}

String getWifiIPAddress() {
android.net.wifi.WifiInfo wifiInfo = null;
if (wifiManager != null) wifiInfo = wifiManager.getConnectionInfo();

String ip = null;
int i_ip = 0;
if (wifiInfo != null) i_ip = wifiInfo.getIpAddress();

if (i_ip != 0)
ip =
String.format(
"%d.%d.%d.%d",
(i_ip & 0xff), (i_ip >> 8 & 0xff), (i_ip >> 16 & 0xff), (i_ip >> 24 & 0xff));

return ip;
}

private android.net.wifi.WifiInfo getWifiInfo() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bparrishMines Why not import android.net.wifi.WifiInfo ?

return wifiManager == null ? null : wifiManager.getConnectionInfo();
}
}
@@ -0,0 +1,44 @@
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.wifi_info_flutter;

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;

/**
* The handler receives {@link MethodCall}s from the UIThread, gets the related information from
* a @{@link WifiInfoFlutter}, and then send the result back to the UIThread through the {@link
* MethodChannel.Result}.
*/
class WifiInfoFlutterMethodChannelHandler implements MethodChannel.MethodCallHandler {
private WifiInfoFlutter wifiInfoFlutter;

/**
* Construct the ConnectivityMethodChannelHandler with a {@code connectivity}. The {@code
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bparrishMines It must be updated to Construct the WifiInfoFlutterMethodChannelHandle...

* connectivity} must not be null.
*/
WifiInfoFlutterMethodChannelHandler(WifiInfoFlutter wifiInfoFlutter) {
assert (wifiInfoFlutter != null);
this.wifiInfoFlutter = wifiInfoFlutter;
}

@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
switch (call.method) {
case "wifiName":
result.success(wifiInfoFlutter.getWifiName());
break;
case "wifiBSSID":
result.success(wifiInfoFlutter.getWifiBSSID());
break;
case "wifiIPAddress":
result.success(wifiInfoFlutter.getWifiIPAddress());
break;
default:
result.notImplemented();
break;
}
}
}
@@ -1,37 +1,46 @@
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.wifi_info_flutter;

import androidx.annotation.NonNull;
import android.content.Context;
import android.net.wifi.WifiManager;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

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

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

@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
public void onAttachedToEngine(FlutterPluginBinding binding) {
setupChannels(binding.getBinaryMessenger(), binding.getApplicationContext());
}

@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
public void onDetachedFromEngine(FlutterPluginBinding binding) {
methodChannel.setMethodCallHandler(null);
methodChannel = null;
}

private void setupChannels(BinaryMessenger messenger, Context context) {
methodChannel = new MethodChannel(messenger, "plugins.flutter.io/wifi_flutter_info");
final WifiManager wifiManager =
(WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);

final WifiInfoFlutter wifiInfoFlutter = new WifiInfoFlutter(wifiManager);

final WifiInfoFlutterMethodChannelHandler methodChannelHandler =
new WifiInfoFlutterMethodChannelHandler(wifiInfoFlutter);
methodChannel.setMethodCallHandler(methodChannelHandler);
}
}
@@ -1,3 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
android.enableR8=true
Expand Up @@ -41,5 +41,9 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app requires accessing your location information all the time to get wi-fi information.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app requires accessing your location information when the app is in foreground to get wi-fi information.</string>
</dict>
</plist>
159 changes: 136 additions & 23 deletions packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart
@@ -1,60 +1,173 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: public_member_api_docs

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';

import 'package:connectivity/connectivity.dart'
show Connectivity, ConnectivityResult;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:wifi_info_flutter/wifi_info_flutter.dart';

// Sets a platform override for desktop to avoid exceptions. See
// https://flutter.dev/desktop#target-platform-override for more info.
void _enablePlatformOverrideForDesktop() {
if (!kIsWeb && (Platform.isWindows || Platform.isLinux)) {
debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
}
}

void main() {
_enablePlatformOverrideForDesktop();
runApp(MyApp());
}

class MyApp extends StatefulWidget {
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyAppState createState() => _MyAppState();
_MyHomePageState createState() => _MyHomePageState();
}

class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
class _MyHomePageState extends State<MyHomePage> {
String _connectionStatus = 'Unknown';
final Connectivity _connectivity = Connectivity();
final WifiInfo _wifiInfo = WifiInfo();
StreamSubscription<ConnectivityResult> _connectivitySubscription;

@override
void initState() {
super.initState();
initPlatformState();
initConnectivity();
_connectivitySubscription =
_connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
}

@override
void dispose() {
_connectivitySubscription.cancel();
super.dispose();
}

// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
Future<void> initConnectivity() async {
ConnectivityResult result;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
platformVersion = await WifiInfoFlutter.platformVersion;
} on PlatformException {
platformVersion = 'Failed to get platform version.';
result = await _connectivity.checkConnectivity();
} on PlatformException catch (e) {
print(e.toString());
}

// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
if (!mounted) {
return Future.value(null);
}

setState(() {
_platformVersion = platformVersion;
});
return _updateConnectionStatus(result);
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text('Running on: $_platformVersion\n'),
),
return Scaffold(
appBar: AppBar(
title: const Text('Connectivity example app'),
),
body: Center(child: Text('Connection Status: $_connectionStatus')),
);
}

Future<void> _updateConnectionStatus(ConnectivityResult result) async {
switch (result) {
case ConnectivityResult.wifi:
String wifiName, wifiBSSID, wifiIP;

try {
if (!kIsWeb && Platform.isIOS) {
LocationAuthorizationStatus status =
await _wifiInfo.getLocationServiceAuthorization();
if (status == LocationAuthorizationStatus.notDetermined) {
status = await _wifiInfo.requestLocationServiceAuthorization();
}
if (status == LocationAuthorizationStatus.authorizedAlways ||
status == LocationAuthorizationStatus.authorizedWhenInUse) {
wifiName = await _connectivity.getWifiName();
} else {
wifiName = await _connectivity.getWifiName();
}
} else {
wifiName = await _connectivity.getWifiName();
}
} on PlatformException catch (e) {
print(e.toString());
wifiName = "Failed to get Wifi Name";
}

try {
if (!kIsWeb && Platform.isIOS) {
LocationAuthorizationStatus status =
await _wifiInfo.getLocationServiceAuthorization();
if (status == LocationAuthorizationStatus.notDetermined) {
status = await _wifiInfo.requestLocationServiceAuthorization();
}
if (status == LocationAuthorizationStatus.authorizedAlways ||
status == LocationAuthorizationStatus.authorizedWhenInUse) {
wifiBSSID = await _connectivity.getWifiBSSID();
} else {
wifiBSSID = await _connectivity.getWifiBSSID();
}
} else {
wifiBSSID = await _connectivity.getWifiBSSID();
}
} on PlatformException catch (e) {
print(e.toString());
wifiBSSID = "Failed to get Wifi BSSID";
}

try {
wifiIP = await _connectivity.getWifiIP();
} on PlatformException catch (e) {
print(e.toString());
wifiIP = "Failed to get Wifi IP";
}

setState(() {
_connectionStatus = '$result\n'
'Wifi Name: $wifiName\n'
'Wifi BSSID: $wifiBSSID\n'
'Wifi IP: $wifiIP\n';
});
break;
case ConnectivityResult.mobile:
case ConnectivityResult.none:
setState(() => _connectionStatus = result.toString());
break;
default:
setState(() => _connectionStatus = 'Failed to get connectivity.');
break;
}
}
}