2

As we know Google has updated their policies that New apps will need to must target Android 11 (API level 30) or higher link. My app is working as expected if I am using the lower targeted SDK but When am I using targeted SDK 30 then It is not working as Expected.

There are the following main functionality in the App:

  • Available WiFi should be visible on list for Android 6 to 11 (with latest Android version)
  • After clicking on any list item user should connect with their respected WiFi. It can be OPEN or other.
  • After connected with respective WiFi, It will redirect to captive page if any. Captive page will be WebView into the app.

Now coming to the point, I am facing the following issue with the targeted 30 SDK.

  • When I am using the latest suggestion wifi connection code [1] then it's working partially.There is one issue, Suppose we are already connected to another WiFi connection and I am trying to connect with new WiFi then It's not connecting to new WiFi but I need to connect with the New Wifi.

Code which is using in the App with targeted SDK 30 (Which is not connecting with New Wifi)-

 val suggestion = WifiNetworkSuggestion.Builder() .setSsid(SSID) // SSID of network .setWpa2Passphrase(wifiPassword) // password is network is not open //.setIsAppInteractionRequired(true) // Optional (Needs location permission) .build() val suggestionsList = listOf(suggestion) val wifiManager = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) { // do error handling here Log.e("NETWORK", "Error") } // Optional (Wait for post connection broadcast to one of your suggestions) val intentFilter = IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION); val broadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Log.e("NETWORK", "broadcastReceiver") if (!intent.action.equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) { return; } // do post connect processing here Log.e("NETWORK", "post connect") } }; registerReceiver(broadcastReceiver, intentFilter) 
  • Whenever my targeted SDK was 29 then I am using the WifiNetworkSpecifier [2] approach for connecting WiFi in Android 10 and 11. It was also working.

Code which is using in the App with targeted SDK 29 (Which is working as expected but targeted SDK must be 28 or 29 otherwise Internet will not work out of the Application)-

 private fun android10andMoreVersionsWithoutOuterInternet( scanResult: ScanResult, wifiSSID: String, wifiPassword: String, capabilities: String ) { // Android 10 (API level 29) -- Android Q (Android 10) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { val wifiManager = this.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder() .setSsid(wifiSSID) //.setSsidPattern(PatternMatcher(wifiSSID, PatternMatcher.PATTERN_PREFIX)) .setWpa2Passphrase(wifiPassword) .build() val networkRequest = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) //.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) .setNetworkSpecifier(wifiNetworkSpecifier) .build() val connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { Log.d("NETWORK", "Network available") super.onAvailable(network) // To make sure that requests don't go over mobile data connectivityManager.bindProcessToNetwork(network) //unregister network callback //connectivityManager.unregisterNetworkCallback(this) // connectivityManager.bindProcessToNetwork(null) gotoNextScreen(scanResult, wifiManager) } override fun onUnavailable() { Log.d("NETWORK", "Network unavailable") super.onUnavailable() } override fun onLosing(network: Network, maxMsToLive: Int) { Log.d("NETWORK", "onLosing") super.onLosing(network, maxMsToLive) } override fun onLost(network: Network) { Log.d("NETWORK", "onLost") super.onLost(network) //connectivityManager.bindProcessToNetwork(null) //connectivityManager.unregisterNetworkCallback(this) } } connectivityManager.requestNetwork(networkRequest, networkCallback) val builder = NetworkRequest.Builder() builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI) connectivityManager.registerNetworkCallback(builder.build(), networkCallback) //connectivityManager.registerNetworkCallback(networkRequest, networkCallback) // For listen } } 
  • Everything is working as expected with old depreciated code with Android 9..

    Code which is using in Android 9 abd below (Which is working as expected and It is not impacting with any targeted SDK)-

     private fun android9AndPreviousVersion( scanResult: ScanResult, wifiSSID: String, wifiPassword: String, capabilities: String ) { val conf = WifiConfiguration() conf.SSID = "\"" + wifiSSID + "\"" // Please note the quotes. String should contain ssid in quotes conf.status = WifiConfiguration.Status.ENABLED conf.priority = 40 if (Common.checkWifiType(capabilities) == "WEP") { Log.e("NETWORK", "Configuring WEP") conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE) conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN) conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA) conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN) conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED) conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP) conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP) conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40) conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104) if (wifiPassword.matches(Regex("^[0-9a-fA-F]+$"))) { conf.wepKeys[0] = wifiPassword } else { conf.wepKeys[0] = "\"" + wifiPassword + "\"" } conf.wepTxKeyIndex = 0 } else if (Common.checkWifiType(capabilities) == "WPA") { Log.e("NETWORK", "Configuring WPA") conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN) conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA) conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK) conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP) conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP) conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40) conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104) conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP) conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP) conf.preSharedKey = "\"" + wifiPassword + "\"" } else { Log.e("NETWORK", "Configuring OPEN network") conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE) } val wifiManager = this.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager val networkId = wifiManager.addNetwork(conf) Log.e("NETWORK", "Add result $networkId") if (ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) { return } val list = wifiManager.configuredNetworks for (i in list) { if (i.SSID != null && i.SSID == "\"" + wifiSSID + "\"") { Log.e("NETWORK", "WifiConfiguration SSID " + i.SSID) val isDisconnected = wifiManager.disconnect() Log.e("NETWORK", "isDisconnected : $isDisconnected") val isEnabled = wifiManager.enableNetwork(i.networkId, true) Log.e("NETWORK", "isEnabled : $isEnabled") val isReconnected = wifiManager.reconnect() Log.e("NETWORK", "isReconnected : $isReconnected") break } } //val connectionInfo: WifiInfo = wifiManager.getConnectionInfo() gotoNextScreen(scanResult, wifiManager) 

    }

Conclude: When am I using WifiNetworkSpecifier for connecting to Available WiFi with targeted SDK 30 then I am able to connect but My Internet is only working in the App. When am I using latest Suggestion wifi for connecting to Available WiFi with targeted SDK 30 then I am unable to connect with the New WiFi. I am facing this issue in Android 10 and Android 11 devices.

Please suggest me for the solution. Please check my POC code [here]

2 Answers 2

1

The only way to have internet with wifi is :

In Android 10, you should implement wifiConfiguration to connect/disconnect

connect function :

val wifiConfiguration = WifiConfiguration() wifiConfiguration.SSID = "\"${configuration.ssid}\"" wifiConfiguration.preSharedKey = "\"${configuration.password}\"" var netId = wifiManager.addNetwork(wifiConfiguration) if (netId == -1) { // If the network configuration with the same SSID already exists, we need to retrieve the configured networks and get the network id of the network corresponding to the given SSID. netId = configuredNetworkForSSID(configuration.ssid)?.networkId ?: -1 } wifiManager.enableNetwork(netId, true) 

disconnect function :

wifiManager.removeNetwork(it.networkId) wifiManager.disconnect() 

In Android 11

You should use : WifiSuggestion

final WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder() .setSsid("test111111") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); final IntentFilter intentFilter = new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION); final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!intent.getAction().equals( WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) { return; } // do post connect processing here... } }; context.registerReceiver(broadcastReceiver, intentFilter); 

to disconnect from Android 11, it's really weird, Google use a stupid solution witch: you should leave the place, if you try to disconnect manually by deleting the wifi from settings, then you can't re-connect automatically. (You should add the wifi network manually to recover the auto-connect behaviour)

Wifi Connection in Android 10 : the OS present a small push-notification to accept the connection, if you didn't add a pop-up to alert the user, he will be missed it; in Android 11, Google changed the notification with an alertBox to alert the user. if you use WifiNetworkSpecifier or another API you will have a wifi connection but without internet.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Nizar.. really appreciated. Finally, I have managed this thing with manually connect wifi and it's working as expected.
0

To restrict the control of third party app, Android has changed the way of connecting to wifi network in Android 10 and Android 11

If you look closely to your first solution, you can see that you are suggesting the system that these wifi are available to connect, now the system will decide whether to connect or not. Now here if system is already connection to some wifi which have active internet connection then Android will ignore your suggestion until that wifi is unavailable.

Right, if you use WifiNetworkSpecifier it restrict the uses of the network to your app only.

1 Comment

Correct, If you have any solution. Please provide...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.