简体   繁体   中英

checking internet connection for some time

I'm trying to make my app check if it is able to connect to the internet.

My research tells me that network-level connectivity doesn't necessarily mean you can access remote sites / services. For example:

Detect if Android device has Internet connection

I have tried the solutions in that Q&A, and they "sort of" work. My problem is that urlc.setConnectTimeout(50000) (ie a 50 second timeout) doesn't seem to have any effect. Instead, my application is reporting an error almost immediately.

I want my application to keep trying to connect for some time before reporting a failure.

The Android system already does that for you. Instead of constantly polling the phone for the network state, register BroadcastReceivers for WiFi and network state changes and process the Intents sent by the system when the WiFi or network state changes.

You should make a BroadcastReceiver that will be triggered when the connectivity status has changed.

NetworkChangeReceiver.java

 public class NetworkChangeReceiver extends BroadcastReceiver
  {
   @Override
    public void onReceive(final Context context, final Intent intent)
    {
    String status = NetworkUtil.getConnectivityStatusString(context);
    Toast.makeText(context, status, Toast.LENGTH_LONG).show();
     }
     }

NetworkUtil.java

    public class NetworkUtil
   {
 public static int TYPE_WIFI = 1;
  public static int TYPE_MOBILE = 2;
 public static int TYPE_NOT_CONNECTED = 0;
  public static int getConnectivityStatus(Context context) 
  {
   ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
 NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
 if (null != activeNetwork) 
 {
 if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
   return TYPE_WIFI;
   if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
  return TYPE_MOBILE;
  }
   return TYPE_NOT_CONNECTED;
}
 public static String getConnectivityStatusString(Context context)      
 { 
  int conn = NetworkUtil.getConnectivityStatus(context);
    String status = null;
   if (conn == NetworkUtil.TYPE_WIFI)
  {
 status = "Wifi enabled";
 }
 else if (conn == NetworkUtil.TYPE_MOBILE) 
{
status = "Mobile data enabled";
}
   else if (conn == NetworkUtil.TYPE_NOT_CONNECTED)
    {
 status = "Not connected to Internet";
  }
    return status;
    }
    }

Add Required Permission and Receiver in Androidmanifest.xml

The most likely explanation for your problem is that there are many possible reasons why your app may not be able to connect. These include:

  • Your app may not have permission to connect
  • The user's device could be out of mobile data or wifi range
  • The internet may have been disabled by the user
  • You may be trying to connect to a host whose IP or DNS entry is incorrect
  • The host or its home network may be temporarily offline
  • The service may not be running on the host
  • The service may be broken
  • There could be a some other networking issue affecting connectivity.

The "problem" is that only some of these manifest as a connection timeout. Others (eg incorrect DNS entries, local networking problems, service not running, etc) will typically result in a different symptom; eg a DNS lookup failure, a "Connection Refused", a "No route to network", etc. These typically occur immediately, and the network stack does not attempt to retry.

As mentioned in the comment, the solution is to implement a retry loop.

  • You need to discriminate the different kinds of failure ... based on the exception thrown.
  • For "timeout" exceptions, don't retry.
  • For exceptions that indicate a failure that won't recover (eg network permissions, no DNS entry, etc), retry is pointless.
  • For others, implement your own timer and retry logic.

Yes ... it is a bit complicated to implement this. And there are some traps. For example, it is unwise to have the retry logic attempt to retry immediately or for too many repetitions, as these can behave as "denial of service" attacks on the remote service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM