Android - обнаружение, если Wi-Fi требует входа в браузер
Мой университет имеет открытую точку доступа Wi-Fi, однако он требует, чтобы вы вводили свой адрес электронной почты, прежде чем он позволит вам использовать Интернет. Моя проблема в том, что Wi-Fi глуп в том, что он, кажется, отключает мое соединение и заставляет меня вводить мой e-mail снова каждые 10 минут.
Я хотел создать собственное приложение, которое я могу использовать для автоматического выполнения этого действия для меня, но я не могу найти документацию для приятного и простого способа определить, имеет ли точка доступа Wifi страницу входа в браузер. Есть ли способ в Android получить эту информацию, или просто посмотреть, не связано ли мое соединение с чем-либо с 1.1.1.1?
Ответы
Ответ 1
См. раздел "Обработка входа в сеть" документация HttpUrlConnection
:
Некоторые сети Wi-Fi блокируют доступ в Интернет до тех пор, пока пользователь не перейдет на страницу входа. Такие входные страницы обычно представлены с помощью перенаправления HTTP. Вы можете использовать getURL(), чтобы проверить, было ли неожиданно перенаправлено ваше соединение. Эта проверка недействительна до тех пор, пока не будут получены заголовки ответов, которые вы можете вызвать, вызвав getHeaderFields() или getInputStream().
У них есть фрагмент кода примера. Я не могу сказать, будет ли это охватывать вашу конкретную точку доступа Wi-Fi, но это стоит того.
Ответ 2
Введите внешний IP-адрес (например, google.com), чтобы узнать, отвечает ли он.
try {
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("ping -c 1 " + "google.com");
proc.waitFor();
int exitCode = proc.exitValue();
if(exitCode == 0) {
Log.d("Ping", "Ping successful!";
} else {
Log.d("Ping", "Ping unsuccessful.");
}
}
catch (IOException e) {}
catch (InterruptedException e) {}
Единственным недостатком является то, что это также указывает на то, что требуется веб-логин, когда нет доступа к Интернету в точке доступа WiFi.
@CommonsWare Я считаю, что это лучший ответ, чем открытие UrlConnection и проверка хоста, поскольку хост не всегда меняется даже при отображении страницы перенаправления. Например, я тестировал на маршрутизаторе Belkin, и он оставляет все, что вы набрали в браузере, как есть, но все же отображает свою собственную страницу. urlConnection.getUrl(). getHost() возвращает то, что должно из-за этого.
Ответ 3
Я думаю, что @FlyWheel находится на правильном пути, но я бы использовал http://clients1.google.com/generate_204, и если вы не получите 204, вы знайте, что вы находитесь за пленным порталом. Вы можете запустить это в цикле, пока не получите 204, в этом случае вы знаете, что вы больше не находитесь за пленным порталом.
@FlyWheel wrote: Единственным недостатком является то, что это также означает, что требуется веб-логин, когда нет доступа к Интернету в точке доступа WiFi.
Вы можете решить эту проблему, зарегистрировав приемник на android.net.conn.CONNECTIVITY_CHANGE. Вы можете проверить, включен ли Wi-Fi и подключен ли он, посмотрев на состояние поставщика соединения.
Вот фрагмент, но я его не запускал:
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wm.getConnectionInfo();
SupplicantState suppState = wifiInfo.getSupplicantState();
if (wm.isWifiEnabled()) {
if (suppState == SupplicantState.COMPLETED){
// TODO - while loop checking generate_204 (FlyWheels code)Using intent service.
}
}
Я не могу вспомнить, будет ли ПОСТОЯННОЕ или АССОЦИАЦИЯ ПОСТАВЛЕННОГО СОСТОЯНИЯ, вам нужно будет это проверить. Вы должны использовать IntentService для проверки generate_204, поскольку широковещательные приемники имеют короткий срок службы.
Ответ 4
Я использовал следующий код, используя конечную точку Google 204
.
private boolean networkAvailable() {
ConnectivityManager mManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if(mManager != null) {
NetworkInfo activeNetwork = mManager.getActiveNetworkInfo();
if(activeNetwork== null || !activeNetwork.isConnectedOrConnecting()){
return false;
}
}
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://clients1.google.com/generate_204")
.build();
try {
Response response = client.newCall(request).execute();
if(response.code() != 204)
return false; // meaning it either responded with a captive html page or did a redirection to captive portal.
return true;
} catch (IOException e) {
return true;
}
}
Многие приложения, в том числе Google Chrome, используют http://clients1.google.com/generate_204 для проверки того, что соединение не заблокировано на подчиненном портале.
Ответ 5
Возможно, проблема - по крайней мере, сегодня - то, что новые версии Android (5.1+?) поддерживают подключение 3G/4G до тех пор, пока логин wifi не приведет к полностью функциональному Wi-Fi-соединению.
Я не пробовал, но, возможно, с значением enum CAPTIVE_PORTAL_CHECK
NetworkInfo
DetailedState
можно попытаться обнаружить такой режим должным образом?