2

I'm trying to get my app to connect to a WiFi AP to provide Internet with WifiNetworkSpecifier using code like this. But it's always calling onUnavailable in the NetworkCallback.

private val callback: ConnectivityManager.NetworkCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        super.onAvailable(network)
    }
    override fun onLost(network: Network) {
        super.onLost(network)
    }
    override fun onLosing(network: Network, maxMsToLive: Int) {
        super.onLosing(network, maxMsToLive)
    }
    override fun onUnavailable() {
        super.onUnavailable()
    }
    override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
        super.onCapabilitiesChanged(network, networkCapabilities)
    }
    override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
        super.onLinkPropertiesChanged(network, linkProperties)
    }
    override fun onBlockedStatusChanged(network: Network, blocked: Boolean) {
        super.onBlockedStatusChanged(network, blocked)
    }
}

val networkSpecifier: NetworkSpecifier = WifiNetworkSpecifier.Builder()
        .setSsid("SsidName")
        .setWpa2Passphrase("wifipassword")
        .build()

    val networkRequest: NetworkRequest = NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        .setNetworkSpecifier(networkSpecifier)
        .build()
    connectivityManager.requestNetwork(networkRequest, callback, 100000)

1 Answer 1

5

The WifiNetworkSpecifier is only meant to connect to local-only Wifi networks, for example, to set up IoT devices, as confirmed here: https://developer.android.com/guide/topics/connectivity/wifi-bootstrap

enter image description here

So if you .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET), Android will always just do nothing and call onUnavailable.

You can see why in the Android platform code here: https://cs.android.com/android/platform/superproject/+/master:packages/modules/Wifi/service/java/com/android/server/wifi/WifiNetworkFactory.java;drc=08124f52b883c61f3e17bc57dc28eca4c7f7bb72;l=487

The message in your LogCat will be E/WifiNetworkFactory: Request with wifi network specifier cannot contain NET_CAPABILITY_INTERNET. Rejecting

If you want Internet, you need to remove the .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) line (which makes a lot of sense, wha!) and add connectivityManager.bindProcessToNetwork(network) in onAvailable as described over in this answer. Note this is a bit of a hack and will enable Internet via Wifi for your app only.

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

4 Comments

Thanks for the information! I didn’t know it! What happen if we want to connect to a wifi network from an app like we do it in the settings? Is there any way to do it in Android? Thanks in advance!!
@daaanigm in the latest Android versions, no. For our use case, we even had our Android devices rooted and I couldn't find a way to do it like you would manually by going to settings and having it work for all apps on the phone. If you figure out a way, report back!
I think if you use the class NetworkSuggestion we can do it, I need to try this class, but it will send a local notification to the user to connect to a specific wifi and I think this connection is a system level. Let me know if you try it before than me. Thanks!
@daaanigm ah yes that works, but we wanted to do it without any user interaction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.