The Better Way of Determining Internet Connectivit

2020-07-31 05:16发布

问题:

Originally a question about why a web view was failing when a broadcastReceiver said the device was connected to the internet: WebView Fails w/ Good Connection

This lead to two answers, a technically correct and a workaround. However, neither is perfect. My question is: What is the better way of determining a valid internt connect?

(1)

public static boolean isConnectedToInternet()
{
    ConnectivityManager cm =      (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isConnected = false;

    if(activeNetwork != null &&
            activeNetwork.isConnected())
    {
        isConnected = true;
    }

    return isConnected;
}

//WebViewClient override
public void onReceivedError (WebView view, int errorCode, String description, String failingUrl)
{
    super.onReceivedError(view, errorCode, description, failingUrl);
    Log.e("web view error: "+errorCode, description);

    if(errorCode == -6 && 
               isConnectedToInternet())
    {
        view.reload();
    }
    else
    {
        view.loadUrl("");
    }
}

(2)

public class MainActivity extends Activity {
    boolean mConnected = false;
    String mURL = "http://www.google.com";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        VerifyInternetConnectionTask task = new VerifyInternetConnectionTask();
        try {
            mConnected = task.execute(mURL).get();
        } catch (InterruptedException e) {
            Log.e(TAG, "AsyncTask Interrupted Exception", e);
        } catch (ExecutionException e) {
            Log.e(TAG, "AsyncTask Execution Exception", e);
        } 

        if (mConnected) {
            Toast.makeText(this, "Connected to Internet",  Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "Unable to connect to the Internet",  Toast.LENGTH_LONG).show();
        }
    }

    private class VerifyInternetConnectionTask extends AsyncTask<String, Void, Boolean> {

       private static final String TAG = "VerifyInternetConnectionTask";

       private boolean isNetworksAvailable() {
          ConnectivityManager mConnMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
          if (mConnMgr != null)  {
             NetworkInfo[] mNetInfo = mConnMgr.getAllNetworkInfo();
             if (mNetInfo != null) {
                for (int i = 0; i < mNetInfo.length; i++) {
                   if (mNetInfo[i].getState() == NetworkInfo.State.CONNECTED) {
                      return true;
                   }
                }
             }
          }
          return false;
       }

       @Override
       protected Boolean doInBackground(final String... params) {
          final int CONNECTION_TIMEOUT = 2000;

          if (isNetworksAvailable()) {
             try {
                HttpURLConnection mURLConnection = (HttpURLConnection) (new URL(params[0]).openConnection());
                mURLConnection.setRequestProperty("User-Agent", "ConnectionTest");
                mURLConnection.setRequestProperty("Connection", "close");
                mURLConnection.setConnectTimeout(CONNECTION_TIMEOUT);
                mURLConnection.setReadTimeout(CONNECTION_TIMEOUT);
                mURLConnection.connect();
                return (mURLConnection.getResponseCode() == 200);
             } catch (IOException ioe) {
                Log.e(TAG, "Exception occured while checking for Internet connection: ", ioe);
             }
          } else {
             Log.e(TAG, "Not connected to WiFi/Mobile and no Internet available.");
          }
          return false;
       }
    }
 }

Thanks for the help in advance

回答1:

In our apps that use web services, we actually take a two step approach. The first step would include your "technical test" to just see if we are network enabled, in theory. If we fail that, we give a warning message like "No network connection detected".

The second step we do, is we ping our servers with a minimal call, just to see if we can hit them. It doesn't matter if we can hit a gajillion sites on the web, only if we can hit ours, so we do our first quick call, and if it fails, we say "Can't connect to siteX. Please try again later"