如何知道连接的 WiFi 是 Walled Gardened (Captive Portal)?

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

我知道有一种方法可以通过检查 "http://clients3.google.com/generate_204" 之类的响应来确定 WiFi 网络是否为强制门户。

但我的问题有些不同。我们都知道,在 Android 上,当我们连接到 WiFi 网络时,连接周期会经历 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) 中提到的许多状态,从而导致 boolean。所以我们确定 Android 知道连接是否被限制(捕获)

所以,我的问题是 Android 系统是否会提供一些回调或一些状态,我们可以通过这些回调或状态来了解网络是强制门户,而无需手动检查?由于 Android 系统已经检查了强制网络门户的网络,我们是否需要再次做同样的事情?

P.S。我只针对 API 19 (KitKat 4.4.2)。

您可以从网络获取网络功能并检查它是否具有 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 是在 API 21 中引入的,因此您可以为

执行此操作

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;
    }
}

派对可能要迟到了。但是如果文档正确,那么有一种方法可以从 connectivityManager 检测强制门户。 https://developer.android.com/reference/android/net/NetworkInfo.DetailedState.html#CAPTIVE_PORTAL_CHECK

ConnectivityManager connectivityManager
                = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
NetworkInfo.DetailedState detailedState = activeNetworkInfo.getDetailedState();
return detailedState == NetworkInfo.DetailedState.CAPTIVE_PORTAL_CHECK;

PS:这在 API 29

中已弃用