From 4e712d68cedf1992a5c4aabd4c541aaa0f81f1ff Mon Sep 17 00:00:00 2001 From: Elias Lecomte Date: Wed, 8 Jan 2020 16:22:57 +0100 Subject: [PATCH] Use WifiNetworkSpecifier on AndroidQ and later. Set password for wpa2 (psk or eap). --- build.gradle | 8 +-- .../wifiutils/ConfigSecurities.java | 26 +++++++++ .../wifiutils/ConnectorUtils.java | 58 +++++++++++++++++++ 3 files changed, 88 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index f33a5f2..1417b54 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.1' + classpath 'com.android.tools.build:gradle:3.5.3' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' } @@ -25,10 +25,10 @@ task clean(type: Delete) { ext { - compileSdkVersion = 28 - buildToolsVersion = '28.0.3' + compileSdkVersion = 29 + buildToolsVersion = '29.0.0' minSdkVersion = 15 - targetSdkVersion = 28 + targetSdkVersion = 29 publishVersionName = '1.4.2' publishVersionCode = 14 diff --git a/wifiutils/src/main/java/com/thanosfisherman/wifiutils/ConfigSecurities.java b/wifiutils/src/main/java/com/thanosfisherman/wifiutils/ConfigSecurities.java index 9573ede..55c2db8 100644 --- a/wifiutils/src/main/java/com/thanosfisherman/wifiutils/ConfigSecurities.java +++ b/wifiutils/src/main/java/com/thanosfisherman/wifiutils/ConfigSecurities.java @@ -1,8 +1,12 @@ package com.thanosfisherman.wifiutils; +import android.annotation.TargetApi; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; +import android.net.wifi.WifiNetworkSpecifier; +import android.os.Build; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -96,6 +100,28 @@ static void setupSecurity(@NonNull WifiConfiguration config, String security, @N default: wifiLog("Invalid security type: " + security); + break; + } + } + + @TargetApi(Build.VERSION_CODES.Q) + static void setupWifiNetworkSpecifierSecurities(@NonNull WifiNetworkSpecifier.Builder wifiNetworkSpecifierBuilder, String security, @NonNull final String password) { + wifiLog("Setting up WifiNetworkSpecifier.Builder " + security); + switch (security) { + case SECURITY_NONE: + // nothing to do + break; + case SECURITY_WEP: + // no longer possible + break; + case SECURITY_PSK: + case SECURITY_EAP: + wifiNetworkSpecifierBuilder.setWpa2Passphrase(password); + break; + + default: + wifiLog("Invalid security type: " + security); + break; } } diff --git a/wifiutils/src/main/java/com/thanosfisherman/wifiutils/ConnectorUtils.java b/wifiutils/src/main/java/com/thanosfisherman/wifiutils/ConnectorUtils.java index e867d92..4da4907 100644 --- a/wifiutils/src/main/java/com/thanosfisherman/wifiutils/ConnectorUtils.java +++ b/wifiutils/src/main/java/com/thanosfisherman/wifiutils/ConnectorUtils.java @@ -4,9 +4,15 @@ import android.content.ContentResolver; import android.content.Context; import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.MacAddress; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; +import android.net.wifi.WifiNetworkSpecifier; import android.net.wifi.WpsInfo; import android.os.Build; import android.provider.Settings; @@ -166,6 +172,16 @@ static void unregisterReceiver(@NonNull Context context, @Nullable BroadcastRece static boolean connectToWifi(@NonNull Context context, @Nullable WifiManager wifiManager, @NonNull ScanResult scanResult, @NonNull String password) { if (wifiManager == null) return false; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + return connectAndroidQ(connectivityManager, scanResult, password); + } + + return connectPreAndroidQ(context, wifiManager, scanResult, password); + } + + private static boolean connectPreAndroidQ(@NonNull Context context, @Nullable WifiManager wifiManager, @NonNull ScanResult scanResult, @NonNull String password) { WifiConfiguration config = ConfigSecurities.getWifiConfiguration(wifiManager, scanResult); if (config != null && password.isEmpty()) { wifiLog("PASSWORD WAS EMPTY. TRYING TO CONNECT TO EXISTING NETWORK CONFIGURATION"); @@ -202,6 +218,7 @@ static boolean connectToWifi(@NonNull Context context, @Nullable WifiManager wif wifiLog("Error getting wifi config after save. (config == null)"); return false; } + return connectToConfiguredNetwork(wifiManager, config, true); } @@ -239,7 +256,48 @@ private static boolean connectToConfiguredNetwork(@Nullable WifiManager wifiMana // We have to retrieve the WifiConfiguration after save. config = ConfigSecurities.getWifiConfiguration(wifiManager, config); return config != null && disableAllButOne(wifiManager, config) && (reassociate ? wifiManager.reassociate() : wifiManager.reconnect()); + } + + @RequiresApi(Build.VERSION_CODES.Q) + private static boolean connectAndroidQ(@Nullable ConnectivityManager connectivityManager, @NonNull ScanResult scanResult, @NonNull String password) { + if (connectivityManager == null) { + return false; + } + + WifiNetworkSpecifier.Builder wifiNetworkSpecifierBuilder = new WifiNetworkSpecifier.Builder() + .setSsid(scanResult.SSID) + .setBssid(MacAddress.fromString(scanResult.BSSID)); + + final String security = ConfigSecurities.getSecurity(scanResult); + + ConfigSecurities.setupWifiNetworkSpecifierSecurities(wifiNetworkSpecifierBuilder, security , password); + + + NetworkRequest networkRequest = new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .setNetworkSpecifier(wifiNetworkSpecifierBuilder.build()) + .build(); + + connectivityManager.requestNetwork(networkRequest, new ConnectivityManager.NetworkCallback() { + @Override + public void onAvailable(@NonNull Network network) { + super.onAvailable(network); + + wifiLog("AndroidQ+ connected to wifi "); + + // bind so all api calls are performed over this new network + connectivityManager.bindProcessToNetwork(network); + } + + @Override + public void onUnavailable() { + super.onUnavailable(); + + wifiLog("AndroidQ+ could not connect to wifi"); + } + }); + return true; } private static boolean disableAllButOne(@Nullable final WifiManager wifiManager, @Nullable final WifiConfiguration config) {