Сделка с неактивными wi-fi сетями
Предположим, что телефон обнаруживает открытую сеть wi-fi и подключается к ней. Но wi-fi сеть "неактивна", т.е. При открытии браузера вы видите запрос для учетных данных. У меня есть много приложений на моем телефоне (например, веб-браузер), которые не работают в таких случаях.
Я хочу отправить данные с помощью мобильной сети, но система все еще пытается использовать wi-fi.
NetworkInfo.isAvailable()
и NetworkInfo.isConnected()
все еще возвращают true
для описанных wi-fi сетей,
Любое решение?
Ответы
Ответ 1
У меня была такая же проблема, и я обнаружил, что такой возможности нет в Android SDK, вам нужно написать свой собственный способ сделать это.
Это зависит от того, что вы хотите делать с сетью, и что вы подразумеваете под "неактивным" - вы можете подключиться к маршрутизатору, который не имеет подключения к Интернету, и нет метода Android для проверки такая ситуация. Как писал MrMichael, ping - это один из способов проверить это, но в этом случае положительный тест дает вам только информацию о ping - в сети может быть какой-то тяжелый брандмауэр, который позволяет отправлять пинги, но я. е. не будет пропускать HTTP-запрос.
В этом случае вы должны написать свой собственный тест для своих собственных нужд, увы - это то, что я сделал. Я просто реализовал простой пинговый протокол (я пытаюсь подключить свой сокет на надлежащем IP-порту и отправить короткое сообщение, ожидая короткого ответа). Только это дает мне 100% гарантию того, что соединение, которое я хочу, может быть установлено.
Ответ 2
Насколько мне известно, нет способа принудительно использовать соединение с данными по Wi-Fi (возможно, то, что вы не должны делать без взаимодействия с пользователем).
У меня одинаковые требования во многих моих приложениях, я хочу знать, есть ли у них жизнеспособное сетевое соединение, пока загружается экран заставки (например, я показываю только версию для чтения приложения, если нет).
Способ, которым я обходился, - запустить простой вызов службы на мой сервер под названием isAlive
, который просто возвращает true imedialtly. Это не только говорит мне, что я могу видеть свою услугу, но также подтверждает, что мой сервер работает в режиме онлайн (никаких проблем на моем конце). В случае, если я не получаю ответ своевременно, я сообщаю пользователю, что у них нет сетевого подключения, и "Пожалуйста, убедитесь, что у вас есть действительное соединение с данными /Wi -Fi перед продолжением". Затем я беру свойство isConnected
для Wi-Fi и изменяю это сообщение, чтобы сказать: "Ваше текущее беспроводное соединение не имеет доступа к Интернету" или что-то подобное.
Не совсем ответ, на который вы надеялись, но, возможно, возможность?
Ответ 3
Просто предложение: вы можете попробовать requestRouteToHost(). Но сначала найдите SO для проблем с использованием этого метода.
Также вам понадобится разрешение CHANGE_NETWORK_STATE
.
Ответ 4
Попробуйте это....
Мне нужно было выполнить какую-то обычную работу... но все встало и работает...
Мой код switches from Wifi to Mobile network
, когда его выключен.
И я использую TimeService at port 37
, чтобы знать, что Интернет DEAD, пока соединение Wi-Fi все еще включено
//////////////////////////Edited//////////////////////////////////
Теперь я помещаю здесь complete working code
i. Пожалуйста, извините меня как DRY
(Не повторяйте сам принцип) был подвергнут насилию здесь. Поэтому, пожалуйста, реорганизовать код и преобразовать дубликаты кодов в метод, т.е. В single sensible place
, при использовании в производственной сети
/////---------------------------Intial Available Network Checking
private boolean checkConnection(){
boolean connected = false;
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if ((ni.getTypeName().equalsIgnoreCase("WIFI")
|| ni.getTypeName().equalsIgnoreCase("MOBILE"))
& ni.isConnected() & ni.isAvailable()) {
connected = true;
}
}
}
return connected;
} ///// --------------------------- Intial Доступная проверка сети
/////-------------------------------Check for the working Internet Connection
public boolean inetAddr(){
boolean x1 = false;
try {
Socket s = new Socket("utcnist.colorado.edu", 37);
InputStream i = s.getInputStream();
Scanner scan = new Scanner(i);
while(scan.hasNextLine()){
System.out.println(scan.nextLine());
x1 = true;
}
} catch (Exception e) {
x1 = false;
}
return x1;
}
/////-------------------------------Check for the working Internet Connection
////-------------------------------Check Mobile Conectivity Again
public boolean mobileConnect(){
boolean conn = false;
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNet = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if(activeNet != null){
conn = true;
}else{
conn = false;
}
return conn;
}
////------------------------------Check Mobile Conectivity Again
Здесь я использую выше методы....
try{
if (!checkConnection()){
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(YumZingSplashActivity.this);
myAlertDialog.setTitle("--- Connectivity Check ---");
myAlertDialog.setMessage("No Internet Connectivity");
myAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YumZingSplashActivity.this.finish();
//splashHandler.removeCallbacks(launcherRunnable);
}});
System.out.println("No Internet Connectivity");
myAlertDialog.show();
}
else{
if(inetAddr()){
aphandle = APIHandling.getInstance();
aphandle.xmlCreateSession();
System.out.println("Net Connectivity is Present");
DURATION = Integer.valueOf(getString(R.string.splash_duration));
splashHandler = new Handler();
// ================ Main Code of the Application
launcherRunnable = new Runnable() {
public void run() {
Intent i = new Intent(YumZingSplashActivity.this, YumZingTabHostActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
YumZingSplashActivity.this.finish();
}
};
if (DEBUG)
{
splashHandler.post(launcherRunnable);
}
else{
splashHandler.postDelayed(launcherRunnable, DURATION);
}
}
else{
if(mobileConnect()){
if(inetAddr()){
aphandle = APIHandling.getInstance();
aphandle.xmlCreateSession();
System.out.println("Net Connectivity is Present");
DURATION = Integer.valueOf(getString(R.string.splash_duration));
splashHandler = new Handler();
// ================ Main Code of the Application
launcherRunnable = new Runnable() {
public void run() {
Intent i = new Intent(YumZingSplashActivity.this, YumZingTabHostActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
YumZingSplashActivity.this.finish();
}
};
if (DEBUG)
{
splashHandler.post(launcherRunnable);
}
else{
splashHandler.postDelayed(launcherRunnable, DURATION);
}
}else{
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(YumZingSplashActivity.this);
myAlertDialog.setTitle("--- Connectivity Check ---");
myAlertDialog.setMessage("No Internet Connectivity");
myAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YumZingSplashActivity.this.finish();
//splashHandler.removeCallbacks(launcherRunnable);
}});
System.out.println("No Internet Connectivity");
myAlertDialog.show();
}
}else{
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(YumZingSplashActivity.this);
myAlertDialog.setTitle("--- Connectivity Check ---");
myAlertDialog.setMessage("No Internet Connectivity");
myAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YumZingSplashActivity.this.finish();
//splashHandler.removeCallbacks(launcherRunnable);
}});
System.out.println("No Internet Connectivity");
myAlertDialog.show();
}
}
}
//setContentView(R.layout.yumzing_splash_layout);
} catch(Exception ex){
System.out.println("Leak ko catch");
}
}
Ответ 5
Вы можете подключиться к сети Wi-Fi, попытаться подключиться к любой странице в фоновом режиме и проверить, есть ли перенаправление. Если это так, вероятно, это страницы учетных данных. Фактически, когда я пытался найти, как реализовать решение, которое я только что описал, я нашел его описанным в HttpURLConnection
документации по классам в Сайт разработчиков Android. Там вы можете прочитать:
Управление подключением к сети
Некоторые сети Wi-Fi блокируют доступ в Интернет до тех пор, пока пользователь не перейдет на страницу входа. Такие входные страницы обычно представлены с помощью перенаправления HTTP. Вы можете использовать getURL()
, чтобы проверить, было ли неожиданно перенаправлено ваше соединение. Эта проверка недействительна до тех пор, пока не будут получены заголовки ответов, которые вы можете вызвать, вызывая getHeaderFields()
или getInputStream()
. Например, чтобы проверить, что ответ не перенаправлен на неожиданный хост:
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
if (!url.getHost().equals(urlConnection.getURL().getHost())) {
// we were redirected! Kick the user out to the browser to sign on?
...
} finally {
urlConnection.disconnect();
}
}
Ответ 6
Попробуйте
InetAddress.getByName(host).isReachable(timeOut)