diff --git a/packages/network_info_plus/network_info_plus/CHANGELOG.md b/packages/network_info_plus/network_info_plus/CHANGELOG.md index ee8a0cd587..adc2c1ea1e 100644 --- a/packages/network_info_plus/network_info_plus/CHANGELOG.md +++ b/packages/network_info_plus/network_info_plus/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.2.0 + +- Android: Migrate to Kotlin +- Android: Bump targetSDK to 33 (Android 13) +- Android: Update dependencies, build config updates +- Android: Fixed getWifiBroadcast to not add redundant `/` symbol +- Update Flutter dependencies + ## 2.1.4+1 - Add issue_tracker link. diff --git a/packages/network_info_plus/network_info_plus/android/build.gradle b/packages/network_info_plus/network_info_plus/android/build.gradle index d9230ae67b..59c7eb4d92 100644 --- a/packages/network_info_plus/network_info_plus/android/build.gradle +++ b/packages/network_info_plus/network_info_plus/android/build.gradle @@ -2,13 +2,15 @@ group 'dev.fluttercommunity.plus.network_info' version '1.0-SNAPSHOT' buildscript { + ext.kotlin_version = '1.7.10' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.4' + classpath 'com.android.tools.build:gradle:7.3.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -20,9 +22,10 @@ rootProject.allprojects { } apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' android { - compileSdkVersion 31 + compileSdkVersion 33 defaultConfig { minSdkVersion 16 @@ -31,4 +34,8 @@ android { lintOptions { disable 'InvalidPackage' } + + dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + } } diff --git a/packages/network_info_plus/network_info_plus/android/settings.gradle b/packages/network_info_plus/network_info_plus/android/settings.gradle index aa218d55a1..835a425131 100644 --- a/packages/network_info_plus/network_info_plus/android/settings.gradle +++ b/packages/network_info_plus/network_info_plus/android/settings.gradle @@ -1 +1 @@ -rootProject.name = 'network_info' +rootProject.name = 'network_info_plus' diff --git a/packages/network_info_plus/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfo.java b/packages/network_info_plus/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfo.java deleted file mode 100644 index 7f32489577..0000000000 --- a/packages/network_info_plus/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfo.java +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2019 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 dev.fluttercommunity.plus.network_info; - -import android.annotation.SuppressLint; -import android.net.DhcpInfo; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InterfaceAddress; -import java.net.NetworkInterface; -import java.util.List; - -/** Reports network info such as wifi name and address. */ -class NetworkInfo { - private final WifiManager wifiManager; - - NetworkInfo(WifiManager wifiManager) { - this.wifiManager = wifiManager; - } - - String getWifiName() { - WifiInfo wifiInfo = getWifiInfo(); - String ssid = null; - if (wifiInfo != null) ssid = wifiInfo.getSSID(); - return ssid; - } - - String getWifiBSSID() { - WifiInfo wifiInfo = getWifiInfo(); - String bssid = null; - if (wifiInfo != null) { - bssid = wifiInfo.getBSSID(); - } - return bssid; - } - - @SuppressLint("DefaultLocale") - String getWifiIPAddress() { - 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; - } - - String getWifiSubnetMask() { - String ip = this.getWifiIPAddress(); - String subnet = ""; - try { - InetAddress inetAddress = InetAddress.getByName(ip); - subnet = getIPv4Subnet(inetAddress); - } catch (Exception ignored) { - } - return subnet; - } - - String getBroadcast() { - String broadcastIP = null; - String ip = this.getWifiIPAddress(); - try { - NetworkInterface ni = NetworkInterface.getByInetAddress(InetAddress.getByName(ip)); - for (InterfaceAddress address : ni.getInterfaceAddresses()) { - if (!address.getAddress().isLoopbackAddress()) { - InetAddress broadCast = address.getBroadcast(); - if (broadCast != null) { - broadcastIP = broadCast.toString(); - } - } - } - } catch (Exception ignored) { - } - return broadcastIP; - } - - public String getIpV6() { - try { - String ip = this.getWifiIPAddress(); - NetworkInterface ni = NetworkInterface.getByInetAddress(InetAddress.getByName(ip)); - for (InterfaceAddress interfaceAddress : ni.getInterfaceAddresses()) { - InetAddress address = interfaceAddress.getAddress(); - if (!address.isLoopbackAddress() && address instanceof Inet6Address) { - String ipaddress = address.getHostAddress(); - if (ipaddress != null) { - return ipaddress.split("%")[0]; - } - } - } - } catch (Exception ignored) { - } - return null; - } - - String getGatewayIpAdress() { - DhcpInfo dhcpInfo = this.wifiManager.getDhcpInfo(); - int gatewayIPInt = dhcpInfo.gateway; - @SuppressLint("DefaultLocale") - String gatewayIP = - String.format( - "%d.%d.%d.%d", - ((gatewayIPInt) & 0xFF), - ((gatewayIPInt >> 8) & 0xFF), - ((gatewayIPInt >> 16) & 0xFF), - ((gatewayIPInt >> 24) & 0xFF)); - return gatewayIP; - } - - private WifiInfo getWifiInfo() { - return wifiManager == null ? null : wifiManager.getConnectionInfo(); - } - - private String getIPv4Subnet(InetAddress inetAddress) { - try { - NetworkInterface ni = NetworkInterface.getByInetAddress(inetAddress); - List intAddrs = ni.getInterfaceAddresses(); - for (InterfaceAddress ia : intAddrs) { - if (!ia.getAddress().isLoopbackAddress() && ia.getAddress() instanceof Inet4Address) { - final InetAddress networkPrefix = - getIPv4SubnetFromNetPrefixLength(ia.getNetworkPrefixLength()); - if (networkPrefix != null) { - return networkPrefix.getHostAddress(); - } - } - } - } catch (Exception ignored) { - } - return ""; - } - - private InetAddress getIPv4SubnetFromNetPrefixLength(int netPrefixLength) { - try { - int shift = (1 << 31); - for (int i = netPrefixLength - 1; i > 0; i--) { - shift = (shift >> 1); - } - String subnet = - ((shift >> 24) & 255) - + "." - + ((shift >> 16) & 255) - + "." - + ((shift >> 8) & 255) - + "." - + (shift & 255); - return InetAddress.getByName(subnet); - } catch (Exception ignored) { - } - return null; - } -} diff --git a/packages/network_info_plus/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoMethodChannelHandler.java b/packages/network_info_plus/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoMethodChannelHandler.java deleted file mode 100644 index ae4cc9ad39..0000000000 --- a/packages/network_info_plus/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoMethodChannelHandler.java +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2019 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 dev.fluttercommunity.plus.network_info; - -import androidx.annotation.NonNull; -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 NetworkInfo}, and then send the result back to the UIThread through the {@link - * MethodChannel.Result}. - */ -class NetworkInfoMethodChannelHandler implements MethodChannel.MethodCallHandler { - - private final NetworkInfo networkInfo; - - /** - * Construct the NetworkInfoMethodChannelHandler with a {@code networkInfo}. The {@code - * networkInfo} must not be null. - */ - NetworkInfoMethodChannelHandler(NetworkInfo networkInfo) { - assert (networkInfo != null); - this.networkInfo = networkInfo; - } - - @Override - public void onMethodCall(MethodCall call, @NonNull MethodChannel.Result result) { - switch (call.method) { - case "wifiName": - result.success(networkInfo.getWifiName()); - break; - case "wifiBSSID": - result.success(networkInfo.getWifiBSSID()); - break; - case "wifiIPAddress": - result.success(networkInfo.getWifiIPAddress()); - break; - case "wifiBroadcast": - result.success(networkInfo.getBroadcast()); - break; - case "wifiSubmask": - result.success(networkInfo.getWifiSubnetMask()); - break; - case "wifiGatewayAddress": - result.success(networkInfo.getGatewayIpAdress()); - break; - case "wifiIPv6Address": - result.success(networkInfo.getIpV6()); - break; - default: - result.notImplemented(); - break; - } - } -} diff --git a/packages/network_info_plus/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoPlusPlugin.java b/packages/network_info_plus/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoPlusPlugin.java deleted file mode 100644 index 7f8750b369..0000000000 --- a/packages/network_info_plus/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoPlusPlugin.java +++ /dev/null @@ -1,46 +0,0 @@ -// 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. - -package dev.fluttercommunity.plus.network_info; - -import android.content.Context; -import android.net.wifi.WifiManager; -import androidx.annotation.NonNull; -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodChannel; - -/** NetworkInfoPlusPlugin */ -public class NetworkInfoPlusPlugin implements FlutterPlugin { - - private MethodChannel methodChannel; - - @Override - public void onAttachedToEngine(FlutterPluginBinding binding) { - setupChannels(binding.getBinaryMessenger(), binding.getApplicationContext()); - } - - @Override - public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { - teardownChannels(); - } - - private void setupChannels(BinaryMessenger messenger, Context context) { - methodChannel = new MethodChannel(messenger, "dev.fluttercommunity.plus/network_info"); - WifiManager wifiManager = - (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); - - NetworkInfo networkInfo = new NetworkInfo(wifiManager); - - NetworkInfoMethodChannelHandler methodChannelHandler = - new NetworkInfoMethodChannelHandler(networkInfo); - - methodChannel.setMethodCallHandler(methodChannelHandler); - } - - private void teardownChannels() { - methodChannel.setMethodCallHandler(null); - methodChannel = null; - } -} diff --git a/packages/network_info_plus/network_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/network_info/NetworkInfo.kt b/packages/network_info_plus/network_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/network_info/NetworkInfo.kt new file mode 100644 index 0000000000..b0a75ff0a5 --- /dev/null +++ b/packages/network_info_plus/network_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/network_info/NetworkInfo.kt @@ -0,0 +1,138 @@ +package dev.fluttercommunity.plus.network_info + +import android.net.wifi.WifiInfo +import android.net.wifi.WifiManager +import java.net.* + +/** Reports network info such as wifi name and address. */ +internal class NetworkInfo(private val wifiManager: WifiManager?) { + + private val wifiInfo: WifiInfo? + get() = wifiManager?.connectionInfo + + // Android returns "SSID" + fun getWifiName(): String? { + var ssid: String? = null + if (wifiInfo != null) ssid = wifiInfo!!.ssid + return ssid + } + + fun getWifiBSSID(): String? { + return if (wifiInfo != null) { + wifiInfo!!.bssid + } else { + null + } + } + + fun getWifiIPAddress(): String? { + var wifiInfo: WifiInfo? = null + if (wifiManager != null) wifiInfo = wifiManager.connectionInfo + var ip: String? = null + var interfaceIp = 0 + if (wifiInfo != null) interfaceIp = wifiInfo.ipAddress + if (interfaceIp != 0) ip = formatIPAddress(interfaceIp) + return ip + } + + fun getWifiSubnetMask(): String { + val ip = getWifiIPAddress() + var subnet = "" + try { + val inetAddress = InetAddress.getByName(ip) + subnet = getIPv4Subnet(inetAddress) + } catch (ignored: Exception) { + } + return subnet + } + + fun getBroadcastIP(): String? { + var broadcastIP: String? = null + val currentWifiIpAddress = getWifiIPAddress() + val inetAddress = InetAddress.getByName(currentWifiIpAddress) + try { + val networkInterface = NetworkInterface.getByInetAddress(inetAddress) + networkInterface.interfaceAddresses.forEach { interfaceAddress -> + if (!interfaceAddress.address.isLoopbackAddress) { + if (interfaceAddress.broadcast != null) { + broadcastIP = interfaceAddress.broadcast.hostAddress + } + } + } + } catch (ignored: Exception) { + + } + return broadcastIP + } + + fun getIpV6(): String? { + try { + val ip = getWifiIPAddress() + val ni = NetworkInterface.getByInetAddress(InetAddress.getByName(ip)) + for (interfaceAddress in ni.interfaceAddresses) { + val address = interfaceAddress.address + if (!address.isLoopbackAddress && address is Inet6Address) { + val ipaddress = address.getHostAddress() + if (ipaddress != null) { + return ipaddress.split("%").toTypedArray()[0] + } + } + } + } catch (socketException: SocketException) { + + } + return null + } + + fun getGatewayIPAddress(): String { + val dhcpInfo = wifiManager!!.dhcpInfo + val gatewayIPInt = dhcpInfo.gateway + return formatIPAddress(gatewayIPInt) + } + + private fun formatIPAddress(intIP: Int): String = + String.format( + "%d.%d.%d.%d", + intIP and 0xFF, + intIP shr 8 and 0xFF, + intIP shr 16 and 0xFF, + intIP shr 24 and 0xFF + ) + + private fun getIPv4Subnet(inetAddress: InetAddress): String { + try { + val ni = NetworkInterface.getByInetAddress(inetAddress) + val intAddresses = ni.interfaceAddresses + for (ia in intAddresses) { + if (!ia.address.isLoopbackAddress && ia.address is Inet4Address) { + val networkPrefix = + getIPv4SubnetFromNetPrefixLength(ia.networkPrefixLength.toInt()) + if (networkPrefix != null) { + return networkPrefix.hostAddress!! + } + } + } + } catch (ignored: Exception) { + } + return "" + } + + private fun getIPv4SubnetFromNetPrefixLength(netPrefixLength: Int): InetAddress? { + try { + var shift = 1 shl 31 + for (i in netPrefixLength - 1 downTo 1) { + shift = shift shr 1 + } + val subnet = ((shift shr 24 and 255) + .toString() + "." + + (shift shr 16 and 255) + + "." + + (shift shr 8 and 255) + + "." + + (shift and 255)) + return InetAddress.getByName(subnet) + } catch (ignored: Exception) { + } + return null + } +} diff --git a/packages/network_info_plus/network_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/network_info/NetworkInfoMethodChannelHandler.kt b/packages/network_info_plus/network_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/network_info/NetworkInfoMethodChannelHandler.kt new file mode 100644 index 0000000000..88d1408db8 --- /dev/null +++ b/packages/network_info_plus/network_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/network_info/NetworkInfoMethodChannelHandler.kt @@ -0,0 +1,26 @@ +package dev.fluttercommunity.plus.network_info + +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.MethodCallHandler + +/** + * The handler receives [MethodCall]s from the UIThread, gets the related information from + * a [NetworkInfo], and then send the result back to the UIThread through the [MethodChannel.Result]. + */ +internal class NetworkInfoMethodChannelHandler(private val networkInfo: NetworkInfo) : + MethodCallHandler { + + override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { + when (call.method) { + "wifiName" -> result.success(networkInfo.getWifiName()) + "wifiBSSID" -> result.success(networkInfo.getWifiBSSID()) + "wifiIPAddress" -> result.success(networkInfo.getWifiIPAddress()) + "wifiBroadcast" -> result.success(networkInfo.getBroadcastIP()) + "wifiSubmask" -> result.success(networkInfo.getWifiSubnetMask()) + "wifiGatewayAddress" -> result.success(networkInfo.getGatewayIPAddress()) + "wifiIPv6Address" -> result.success(networkInfo.getIpV6()) + else -> result.notImplemented() + } + } +} diff --git a/packages/network_info_plus/network_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/network_info/NetworkInfoPlusPlugin.kt b/packages/network_info_plus/network_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/network_info/NetworkInfoPlusPlugin.kt new file mode 100644 index 0000000000..1c768759cd --- /dev/null +++ b/packages/network_info_plus/network_info_plus/android/src/main/kotlin/dev/fluttercommunity/plus/network_info/NetworkInfoPlusPlugin.kt @@ -0,0 +1,35 @@ +package dev.fluttercommunity.plus.network_info + +import android.content.Context +import android.net.wifi.WifiManager +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MethodChannel + +/** NetworkInfoPlusPlugin */ +class NetworkInfoPlusPlugin : FlutterPlugin { + + private lateinit var methodChannel: MethodChannel + + override fun onAttachedToEngine(binding: FlutterPluginBinding) { + setupChannels(binding.binaryMessenger, binding.applicationContext) + } + + override fun onDetachedFromEngine(binding: FlutterPluginBinding) { + methodChannel.setMethodCallHandler(null) + } + + private fun setupChannels(messenger: BinaryMessenger, context: Context) { + methodChannel = MethodChannel(messenger, CHANNEL) + val wifiManager = + context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager + val networkInfo = NetworkInfo(wifiManager) + val methodChannelHandler = NetworkInfoMethodChannelHandler(networkInfo) + methodChannel.setMethodCallHandler(methodChannelHandler) + } + + companion object { + private const val CHANNEL = "dev.fluttercommunity.plus/network_info" + } +} diff --git a/packages/network_info_plus/network_info_plus/example/android/app/build.gradle b/packages/network_info_plus/network_info_plus/example/android/app/build.gradle index a97a22f29e..fc49aa2c4c 100644 --- a/packages/network_info_plus/network_info_plus/example/android/app/build.gradle +++ b/packages/network_info_plus/network_info_plus/example/android/app/build.gradle @@ -25,7 +25,7 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 31 + compileSdkVersion 33 lintOptions { disable 'InvalidPackage' @@ -34,7 +34,7 @@ android { defaultConfig { applicationId "dev.fluttercommunity.plus.network_info_plus_example" minSdkVersion 16 - targetSdkVersion 31 + targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/network_info_plus/network_info_plus/example/android/build.gradle b/packages/network_info_plus/network_info_plus/example/android/build.gradle index 3865eb4c22..3ecc2576de 100644 --- a/packages/network_info_plus/network_info_plus/example/android/build.gradle +++ b/packages/network_info_plus/network_info_plus/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.1.1' + classpath 'com.android.tools.build:gradle:7.3.0' } } diff --git a/packages/network_info_plus/network_info_plus/example/android/gradle.properties b/packages/network_info_plus/network_info_plus/example/android/gradle.properties index 94adc3a3f9..d9cf55df7c 100644 --- a/packages/network_info_plus/network_info_plus/example/android/gradle.properties +++ b/packages/network_info_plus/network_info_plus/example/android/gradle.properties @@ -1,3 +1,2 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true -android.enableJetifier=true diff --git a/packages/network_info_plus/network_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/network_info_plus/network_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties index 57d967396f..3c80641873 100644 --- a/packages/network_info_plus/network_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/network_info_plus/network_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Tue Oct 05 15:29:21 CEST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/packages/network_info_plus/network_info_plus/pubspec.yaml b/packages/network_info_plus/network_info_plus/pubspec.yaml index 374e1c60fa..4a37cefb28 100644 --- a/packages/network_info_plus/network_info_plus/pubspec.yaml +++ b/packages/network_info_plus/network_info_plus/pubspec.yaml @@ -1,6 +1,6 @@ name: network_info_plus description: Flutter plugin for discovering information (e.g. WiFi details) of the network. -version: 2.1.4+1 +version: 2.2.0 homepage: https://plus.fluttercommunity.dev/ repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/ issue_tracker: https://github.com/fluttercommunity/plus_plugins/labels/network_info_plus @@ -29,17 +29,16 @@ flutter: dependencies: flutter: sdk: flutter - meta: ^1.3.0 + meta: ^1.8.0 network_info_plus_platform_interface: ^1.1.2 network_info_plus_linux: ^1.1.2 network_info_plus_macos: ^1.3.0 - network_info_plus_windows: ^1.0.0 + network_info_plus_windows: ^1.0.2 network_info_plus_web: ^1.0.1 dev_dependencies: flutter_test: sdk: flutter - test: ^1.16.4 - mockito: ^5.0.0 - plugin_platform_interface: ^2.0.0 - flutter_lints: ^1.0.4 + mockito: ^5.3.2 + plugin_platform_interface: ^2.1.3 + flutter_lints: ^2.0.1