Reputation: 687
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:
Now coming to the point, I am facing the following issue with the targeted 30 SDK.
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)
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]
Upvotes: 2
Views: 1132
Reputation: 1009
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.
Upvotes: 1
Reputation: 1
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.
Upvotes: 0