android – Deal with inactive wi-fi networks-ThrowExceptions

Exception or error:

Suppose phone finds open wi-fi network and connects to it. But wi-fi network is “inactive”, i.e. when you open browser you see prompt for credentials. I have many apps on my phone(for example web-browser), which fail to work in such cases.
I want to send data using mobile network, but system still tries to use wi-fi.

NetworkInfo.isAvailable() and NetworkInfo.isConnected() still return true for the described wi-fi networks.
Any solution?

How to solve:

I’ve been having the same problem, and what I found is there is no such possibility via the Android SDK, you have to write your own way to do it.

It depends what do you want to do with the network and what do you mean by ‘inactive’ – you can be connected to a router, which doesn’t have connection to the Internet, and there is no Android method to check such situation. As MrMichael wrote, ping is one way to check it, but in that case positive test gives you just info about ping – the network can have some heavy firewall which allows you to send pings, but i. e. will not let HTTP request through.

In that case, you have to write your own custom test for your own needs, alas – that’s what I did. I just implemented simple ping-like protocol (I try to connect my socket on proper IP/port and send short message waiting for short answer). Only that gives me 100% warranty that the connection I want can be established.

###

As far as I am aware there is no way to force the use of a data connection over wifi (perhaps something that you shouldn’t do without user interaction anyway).

I have the same requirements in many of my applications, I want to know if they have a viable network connection whilst the splash screen is loading (for example I show a read only version of the app if not).

The way that I get around this is to fire a simple service call to my server called isAlive which just returns a true imedialtly. This not only tells me that I am able to see my service, it also confirms that my server is on-line (no issues at my end). In the case that I do not get a response back in a timely fashion I inform the user that they have no network connection and “Please ensure you have a valid data/wifi connection before continuing”. I then take the isConnected property for the wifi and modify this message to say “Your current Wireless connection does not internet access” or something similar.

Not quite the answer you were hoping for but maybe a possibility?

###

Just a suggestion: You may try using requestRouteToHost(). But first search SO for problems in using this method.

Also you’ll need the CHANGE_NETWORK_STATE permission.

###

Try this….

I needed to do some custom work..but got it up and running…

My code switches from Wifi to Mobile network when its off.

And I am using the TimeService at port 37 to know that the Internet is DEAD while the wifi connection is still ON

//////////////////////////Edited//////////////////////////////////

Now i am putting here a complete working code i made. Please pardon me as the DRY (Don’t Repeat Yourself Principle ) has been abused here. So please refactor the code and convert the duplicate codes into method , ie into a single sensible place, when using in production network

/////---------------------------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 Available Network Checking

/////-------------------------------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

Here i am using the Above Methods….

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



    }

###

You could connect to the wifi network, try connect to any page in background and verify if there is any redirection. If so, it is very likely to be the credential pages. In fact when I was trying to find how to implement the solution I have just described, I found it to be described in HttpURLConnection class documentation at Android developers site. There you can read:

Handling Network Sign-On

Some Wi-Fi networks block Internet access until the user clicks through a sign-on page. Such sign-on pages are typically presented by using HTTP redirects. You can use getURL() to test if your connection has been unexpectedly redirected. This check is not valid until after the response headers have been received, which you can trigger by calling getHeaderFields() or getInputStream(). For example, to check that a response was not redirected to an unexpected host:

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

###

Try

InetAddress.getByName(host).isReachable(timeOut)

Leave a Reply

Your email address will not be published. Required fields are marked *