I am working on an application in which one the user has to follow these steps :
When the user is connected to the dedicated hotspot of the connected object, the application does some HTTP requests in order to configure it. Then, I would like to reconnect automatically the application to the global wifi of step 1.
From API 21 to API 28 this feature is very easy to implement because I know the SSID I want to reconnect the phone too. It can be done with a few line of code:
private fun changeCurrentWifiNetworkLegacy(ssidToConnect: String) {
val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
var ssidIdentifier: Int? = null
wifiManager.configuredNetworks?.forEach { config ->
Log.d("SSID", config.SSID)
if (config.SSID == "\"${ssidToConnect}\"") {
ssidIdentifier = config.networkId
}
}
ssidIdentifier?.let { id ->
wifiManager.enableNetwork(id, true)
}
}
On API 29 this simple code does not work anymore according to this article: https://developer.android.com/about/versions/10/privacy/changes#configure-wifi
According to the article, now, I should use 2 classes: WifiNetworkSpecifier
and/or WifiNetworkSuggestion
.
Unfortunately, I cannot find a working example using these classes in order to connect the user to a previous configured SSID.
Does someone already achieve that?
Thank you in advance for your help.
Just in case any poor soul encounters this, it's completely possible the API is just broken on your device. On my OnePlus 5, Android 10, Build 200513, this happens:
Created an Android bug for this: https://issuetracker.google.com/issues/158344328
Additionally, you can get the OS into state when it will no longer show the "Device to use with " dialog if you don't terminate your app and the dialogs in the correct order, and only reboot helps.
Just save yourself the trouble, target Android 9 and use the WifiManager APIs (that are helpfully broken if you target 10). It even has better user experience than the new requestNetwork APIs.
You can set which network to connect to with the following code:
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(
WifiNetworkSpecifier.Builder()
.setSsid("My ssid")
.build()
)
.build()
cm.requestNetwork(networkRequest, object: ConnectivityManager.NetworkCallback() {
override fun onUnavailable() {
Log.d("TEST", "Network unavailable")
}
override fun onAvailable(network: Network) {
Log.d("TEST", "Network available")
}
})
}
This uses the ConnectivityManager's networkRequest method to request a network with a specific SSID.
This method requires the caller to hold either the Manifest.permission.CHANGE_NETWORK_STATE
permission or the ability to modify system settings as determined by Settings.System.canWrite(Context)
.
See the NetworkCallback class for more documentation about what info you can get.
(edit: Missed adding Transport type.)
Further edit: I needed to use .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
to get it to work properly. Because in WifiNetworkSpecifier
can only be used to request a local wifi network (i.e no internet capability)
According to the docs
This gives me a request for devices popup, but then eventually shows me the Wifi network I asked for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With