0

I am trying to find out if my app is connected to the internet or not. I have a timeout set to 3 seconds. Sometimes the Internet Check will come back as "Not Connected" (even if I do have an internet connection) and sometimes it doesn't. Why does it take longer sometimes to check than others? Would I be able to have a dialogbox or something to popup while this is being checked?

public void isNetworkAvailable(final Handler handler)
{
    new Thread()
    {
        private boolean responded = false;

        @Override
        public void run()
        {
            new Thread()
            {
                @Override
                public void run()
                {
                    HttpGet requestForTest = new HttpGet("http://m.google.com");
                    try
                    {
                        new DefaultHttpClient().execute(requestForTest);
                        responded = true;
                    }
                    catch (Exception e)
                    {
                    }
                }
            }.start();

            try
            {
                int waited = 0;
                while (!responded && (waited < 3000))
                {
                    sleep(100);
                    if (!responded)
                    {
                        waited += 1000;
                    }
                }
            }
            catch (InterruptedException e)
            {
            } // do nothing
            finally
            {
                if (!responded)
                {
                    handler.sendEmptyMessage(0);
                }
                else
                {
                    handler.sendEmptyMessage(1);
                }
            }
        }
    }.start();
}

Handler h = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    { 
        if (msg.what != 1)
        { // code if not connected
            Log.i("Internet check", "Not connected");
        }
        else
        { // code if connected
            Log.i("Internet check", "Connected");
        }
    }
};
Howli
  • 12,291
  • 19
  • 47
  • 72
  • Howlin then inside info.isRoaming() method try to check packets exchanged or not via code it will provide your answer .... –  Sep 26 '13 at 14:09

5 Answers5

0
    public static Boolean isOnline(Context context) {
        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
        if(ni != null && ni.isConnected())
            return true;

        //Toast.makeText(context, context.getString(R.string.no_internet_connection), Toast.LENGTH_SHORT).show();
        return false;
     }

Requires permission:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

Edit:

As you correctly point out this is not a solid solution. In my case (which I indeed failed to mention) this is sufficient as a first check paired with LocationClient.isConnected().

Looking at your code I would think that it is worth taking a look at LocationClient, even if you are not planning to use location awareness of you app.

My reasoning for this is that you get rid of the need to repeatedly use resources to check if you have a valid connection. LocationClient uses the already in place communication with Google Play to tell you whether you are connected or not.

This solution of course only works if you assume that your users have a Google Account added to their device.

Here is a link to the official guidelines: http://developer.android.com/training/location/retrieve-current.html the onConnected and onDisconnected parts are found in the Define Location Services Callbacks section.

cYrixmorten
  • 7,110
  • 3
  • 25
  • 33
  • That will return true even if you have no actual access to the internet e.g. connected to a router but no internet or a router with a login page. – Howli Sep 26 '13 at 13:54
  • Made an edit that shows a solid method of determin whether a real internet connection is available. – cYrixmorten Sep 26 '13 at 19:52
  • this definitely does not work. Returns even through if the device can connect to a modern router which is just turned out, but does not have internet connectivity (ISP error, or the telephone/fiber cable is not plugged) – tony9099 Sep 26 '13 at 20:21
  • @tony9099 How is it able to connect to the Google Play servers in that situation? – cYrixmorten Sep 26 '13 at 20:38
  • because it happens that at the moment, given the situation, you have connectivity and internet. (connectivity = the ability to use the device's wifi to connect to another node ---- internet = after connecting to the wifi device, reach and get a response from website).. for example, if you go to a caffe, and you need a username/pass to connect to internet,, your code would return true, even though the device cannot enter google.com ...just try my code. – tony9099 Sep 26 '13 at 20:41
  • Then I would consider the guide from Google on LocationClient misleading. It, to me, clearly indicates a working connection to the servers, as it uses the all knowing Google servers to get a good estimate of your current location. – cYrixmorten Sep 26 '13 at 20:46
0

are you consider use this http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html and/or register a BroadcastReceiver to notify it when connection is down/up, then you can handle it in any place of your application?

public class CustomApplication extends Application {

    public static final String INTERNET_ACTION = "internet_action";
    public static final String EXTRA_STATUS = "status";

    @Override
    public void onCreate() {
        super.onCreate();


        monitorNetworkAvailability();
    }

    private void monitorNetworkAvailability() {

        //
        // Improve the way to handle Thread
        // 
        new Thread() {

            private boolean responded = false;

            @Override
            public void run() {

                while (true) {

                    new Thread() {
                        @Override
                        public void run() {
                            HttpGet requestForTest = new HttpGet("http://m.google.com");
                            try {
                                new DefaultHttpClient().execute(requestForTest);
                                responded = true;
                            } catch (Exception e) {
                            }
                        }
                    }.start();

                    try {
                        int waited = 0;
                        while (!responded && (waited < 3000)) {
                            sleep(100);
                            if (!responded) {
                                waited += 1000;
                            }
                        }
                    } catch (InterruptedException e) {
                    } // do nothing
                    finally {
                        Intent i = new Intent(INTERNET_ACTION);
                        i.putExtra(EXTRA_STATUS, responded);
                        sendBroadcast(i);
                    }

                    try {
                        Thread.sleep(1 * 60 * 1000);
                    } catch (InterruptedException e) {
                    }

                }


            }


        }.start();
    };
}

class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(receiver, i);
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(receiver);
    }

    IntentFilter i = new IntentFilter(CustomApplication.INTERNET_ACTION);
    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            boolean responded = intent.getBooleanExtra(CustomApplication.EXTRA_STATUS, false);
            if (!responded) {
                Toast.makeText(MyActivity.this, "No connection", Toast.LENGTH_SHORT).show();
            }
        }
    };

}
betorcs
  • 2,771
  • 22
  • 28
  • That will return true even if you have no actual access to the internet e.g. connected to a router but no internet or a router with a login page. – Howli Sep 26 '13 at 13:55
  • too much code mate. for nothing. check my answer. just 1 line. – tony9099 Sep 26 '13 at 20:19
0

Use the following code

if(!haveInternet()){

                    <Your Alert Dialog Here>

                }





private boolean haveInternet() {
            NetworkInfo info = ((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE))
            .getActiveNetworkInfo();
            if (info == null || !info.isConnected()) {
                return false;
            }
            if (info.isRoaming()) {
                return true;
            }
            return true;
        }
  • I already added exact same code :P btw info.isRoaming() adds no value to the code – cYrixmorten Sep 26 '13 at 13:52
  • That will return true even if you have no actual access to the internet e.g. connected to a router but no internet or a router with a login page. – Howli Sep 26 '13 at 13:54
  • then check this inside if loop of info.isRoaming() TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); if(tm .getDataState() == tm .DATA_CONNECTED) return true; –  Sep 26 '13 at 14:00
  • That still returns true, if my tab is connected to a router, but the router doesn't have internet access. – Howli Sep 26 '13 at 14:18
0

You are right. Your problem is that, the device checks for internet connection, and sometimes get a response from the router which says it cannot connect to internet, but that itself is a response, so your code might think that there is a response. Below is a sample method to test if you really can connect to the internet.

public static boolean hasActiveInternetConnection()
{
    try
    {
        new Socket().connect(new InetSocketAddress("google.com", 80), 4000);

        return true;
    } catch (Exception e)
    {
        return false;
    }
}

Then inside your activity you can call. (Make sure not to run this inside the MAIN/UI thread. Use an async or thread/handler/runnable strategy)

if(hasActiveInternetConnection())
{
//yey I have internet
}
else
{
//no internet connection
}
tony9099
  • 4,567
  • 9
  • 44
  • 73
  • That will cause the app to hang for about 15/20 seconds if the device is connected to a router, but the router doesn't have an internet connection. – Howli Sep 26 '13 at 21:05
0

I was able to complete this by putting it inside an AsyncTask.

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) 
    {

        HttpGet requestForTest = new HttpGet("http://m.google.com");
        try
        {
            new DefaultHttpClient().execute(requestForTest); // can
            responded = true;
        }
        catch (Exception 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();
    }
}
Howli
  • 12,291
  • 19
  • 47
  • 72