21

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?

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
  • Would it be possible to simple ping a website like google? if there would be a login page behind the access point, this would simply fail where it normally would succeed. – Viezevingertjes Aug 20 '12 at 09:05
  • This is akin to http://stackoverflow.com/a/1085054/193892 but for Android is instead Windows. Would be nice if it existed. – Prof. Falken Aug 20 '12 at 14:22

6 Answers6

2

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.

Fenix Voltres
  • 3,448
  • 1
  • 29
  • 36
  • 1
    "you can be connected to a router, which doesn't have connection to the Internet" - exactly –  Aug 20 '12 at 10:41
  • So with this [method](http://stackoverflow.com/a/12136830/4385913) if router has not connection to internet it will return `true`? because host is different thant `url.getHost()`? – Skizo-ozᴉʞS ツ Jul 30 '15 at 14:03
2

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?

melodiouscode
  • 2,105
  • 1
  • 20
  • 41
  • How do you check server isAlive? Simple http request? –  Aug 20 '12 at 12:36
  • 1
    In my case it is a call to my webservice that is hard coded to reply with TRUE. That way if I can't hit the service I know that it is false. But you could just use a http request, if you get an exception presume false. – melodiouscode Aug 20 '12 at 12:55
2

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.

Dheeraj Vepakomma
  • 26,870
  • 17
  • 81
  • 104
1

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



    }
Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
  • @Mighter i have optimized my code, see the `inetAddr()` method.. previously i was trying to do a name resolution, but that would sometime be deceptive as the DNS table might not have been flushed yet, when the internet goes off and the wifi router is still on... `So NOW i am using the TimeService which runs at port 37.` – Kumar Vivek Mitra Aug 23 '12 at 16:41
1

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();
   }
 }
André Oriani
  • 3,553
  • 22
  • 29
0

Try

InetAddress.getByName(host).isReachable(timeOut)
Mustafa Genç
  • 2,569
  • 19
  • 34