Как узнать, что подключенный WiFi - это Walled Gardened (Captive Portal)?
Я знаю, что есть способ узнать, является ли сеть Wi-Fi пленарным порталом, проверив реакцию чего-то вроде "http://clients3.google.com/generate_204"
,
Но мой вопрос несколько другой. Все мы знаем, что в Android при подключении к сети WiFi цикл подключения проходит через ряд состояний, упомянутых в классе NetworkInfo.DetailedState, например: AUTHENTICATING
, OBTAINING_IPADDR
, VERIFYING_POOR_LINK
и т.д. Кроме того, одно из состояний CAPTIVE_PORTAL_CHECK
и система Android проверяет, является ли сеть, которая подключена, пленной или нет. Для этого Android использует CaptivePortalTracker # isCaptivePortal (сервер InetAddress), что приводит к boolean
, Таким образом, мы уверены, что Android знает, является ли соединение ограниченным (пленным) или нет
Итак, мой вопрос заключается в том, дает ли система Android какой-либо обратный вызов или какое-то состояние, с помощью которого мы можем узнать, что сеть является подчиненным порталом, не проверяя его вручную? Поскольку система Android уже проверила сеть на наличие портала, нужно ли нам делать то же самое снова?
PS Я ориентируюсь только на API 19 (KitKat 4.4.2).
1 ответ
Вы можете получить сетевые возможности из сети и проверить, имеет ли она 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
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