androidnetworkingcaptivenetwork

How to know the connected WiFi is Walled Gardened (Captive Portal)?


I know there is way to find out whether a WiFi network is a captive portal by checking the response of something like "http://clients3.google.com/generate_204".

But my question is somewhat different. We all know that on Android when we connect to a WiFi network the connection cycle goes through a number of state mentioned in the class NetworkInfo.DetailedState, like AUTHENTICATING, OBTAINING_IPADDR, VERIFYING_POOR_LINK etc. Also, one of the states is CAPTIVE_PORTAL_CHECK and android system check whether the network which is being connected is captive or not. For this Android uses the CaptivePortalTracker#isCaptivePortal(InetAddress server) which results in a boolean. So we are certain that Android knows whether the connection is restricted (captive) or not

So, my question is does Android system gives some callback or some state by which we can get to know the Network is captive portal without checking it manually? Since Android system have already checked the network for captive portal, do we need to do the same thing again?

P.S. I'm only targeting API 19 (KitKat 4.4.2).


Solution

  • You can get the networkcapabilities from the network and check if it has the NET_CAPABILITY_CAPTIVE_PORTAL :

    API 23

    ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    Network activeNetwork=connectivityManager.getActiveNetwork();
    NetworkCapabilities networkCapabilities=connectivityManager.getNetworkCapabilities(activeNetwork);
    if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL)){
            //DO SOMETHING
    }
    

    http://developer.android.com/intl/es/reference/android/net/NetworkCapabilities.html

    NetworkCapabilities was introduced in API 21, so you can do this for

    API >= 21

    ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    Network[] activeNetworks=connectivityManager.getAllNetworks();
    for(Network network:activeNetworks){
        if(connectivityManager.getNetworkInfo(network).isConnected()){
            NetworkCapabilities networkCapabilities=connectivityManager.getNetworkCapabilities(network);
            if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL)){
               //DO SOMETHING
            }
            break;
        }
    }