Howli
Howli

Reputation: 12469

Check for an actual internet connection

I have the following code in an app that will check for an internet connection. It does work i.e. will say there is no internet if there isn't one (unlike using, ConnectivityManager which will only tell you if you are connected to a router/3g, but doesn't actually check for an internet connection), but only until someone connects to a wifi spot that redirects the user to a login page. Then the app will return a 200 code and try continue, but will ultimately crash (and is crashing quiet a bit). My app would be used mostly in an location that has such a wifi spot. How can I check if a request has been redirected?

class online extends AsyncTask<String, String, String> 
{
    boolean responded = false;
    @Override
    protected void onPreExecute() 
    {
        super.onPreExecute();
        pDialog2 = new ProgressDialog(Main.this);
        pDialog2.setMessage("Checking internet, please wait...");
        pDialog2.setIndeterminate(false);
        pDialog2.setCancelable(false);
        pDialog2.show();
    }

    protected String doInBackground(String... args) 
    {
        try
        {

            URL url = new URL("http://mydomain.com/connectionTest.html");

            HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
            urlc.setConnectTimeout(6000); // Timeout is in seconds
            urlc.setReadTimeout(6000);
            urlc.connect();
            if (urlc.getResponseCode() == 200) 
            {
                responded = true;
            } else 
            {

            }

        } catch (IOException e)
        {
        }

        try
        {
            int waited = 0;
            while (!responded && (waited < 5000))
            {
                mHandler.postDelayed(new Runnable() 
                {
                    public void run() 
                    {
                    }
                }, 100);
                waited += 100;
            }
        }
        finally
        {
            if (!responded)
            {
                h.sendEmptyMessage(0);
            }
            else
            {
                h.sendEmptyMessage(1);
            }
        }
        return null;
    }

    protected void onPostExecute(String file_url) 
    {
        pDialog2.dismiss();
    }
}

Upvotes: 2

Views: 15784

Answers (1)

marcus.ramsden
marcus.ramsden

Reputation: 2633

If you have control over the webservice that you are connecting to you can use a similar trick to how Google check for Wi-Fi redirect portals.

You'll occasionally see a request go out to http://google.com/generate_204. If you are behind a public access point password page then you will generally receive a 200 Ok from the server that intercepted the web request in order to serve the login page. If the user has already logged in then you will receive a HTTP 204 No Content status from the service.

To check to see if you have access to the public web then you could run the following;

URL url = new URL("http://google.com/generate_204");
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setConnectTimeout(6000); // Timeout is in seconds
httpUrlConnection.setReadTimeout(6000);
httpUrlConnection.connect();
if (httpUrlConnection.getResponseCode() == HttpURLConnection.HTTP_NO_CONTENT) {
    // Great you have free access to the web
} else {
    // Either your server is mis-configured or you are behind a hotspot login screen
}

Ideally you would host your own /generate_204 on your webserver then you won't be caught out by an undocumented change by Google. Also it can act as a means of checking reachability to your server from the device.

Using this in conjunction with the ConnectivityManager should start to give you a pretty clear picture of the status of networking and the reachability of your server.

Upvotes: 4

Related Questions