问题
How to check if the device is connected to internet or it is just connected to external wifi network? Because NetworkInfo returns true if a device is connected to an external wifi network even there is no network connection.
When device is connected to wifi but there is no internet access,my app's network connectivity-check class returns true but application crashes with the exception that it cannot access the corresponding http url.
回答1:
If you want to know when you have an active internet connection, do something like this:
Some static variables:
/**
* Set the number of retries when reestablishing Internet connection.
*/
private static int retryConnectionNumber = 0;
/**
* The maximum number of retries allowed for Internet connection.
*/
private final static int CONNECTION_RETRY_MAX = 5;
/**
* The timeout of the HTTP request when checking for Internet connection.
*/
private final static int REQUEST_TIMEOUT = 2000;
The method to check if network is available:
private static void isNetworkAvailable(final Handler handler,
final int timeout) {
new Thread() {
private boolean responded = false;
@Override
public void run() {
URL url = null;
try {
url = new URL("http://your_server_addres.com");
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
String host = "";
if (null != url) {
host = url.getHost();
}
Log.i("NetworkCheck", "[PING] host: " + host);
Process process = null;
try {
process = new ProcessBuilder()
.command("/system/bin/ping", "-c 1",
"-w " + (timeout / 1000), "-n", host)
.redirectErrorStream(true).start();
} catch (IOException e) {
e.printStackTrace();
}
InputStream in = process.getInputStream();
StringBuilder s = new StringBuilder();
int i;
try {
while ((i = in.read()) != -1) {
s.append((char) i);
if ((char) i == '\n') {
Log.i("NetworkCheck",
"[PING] log: " + s.toString());
if (s.toString().contains("64 bytes from")) {
// If there were a response from the server at
// all, we have Internet access
responded = true;
}
s.delete(0, s.length());
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// Destroy the PING process
process.destroy();
try {
// Close the input stream - avoid memory leak
in.close();
} catch (IOException e) {
e.printStackTrace();
}
// Send the response to the handler, 1 for success, 0
// otherwise
handler.sendEmptyMessage(!responded ? 0 : 1);
}
}
}.start();
}
The handler:
/**
* Handler used that receives the connection status for the Internet.
* If no active Internet connection will retry #CONNECTION_RETRY_MAX times
*/
private static Handler listenForNetworkAvailability = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what != 1) { // code if not connected
Log.i("NetworkCheck", "not connected");
if (retryConnectionNumber <= CONNECTION_RETRY_MAX) {
Log.i("NetworkCheck", "checking for connectivity");
Here you could disable & re-enable your WIFI/3G connection before retry
// Start the ping process again with delay
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
isNetworkAvailable(listenForNetworkAvailability, REQUEST_TIMEOUT);
}
}, 5000);
retryConnectionNumber++;
} else {
Log.i("NetworkCheck", "failed to establish an connection");
// code if not connected
}
} else {
Log.i("NetworkCheck", "connected");
retryConnectionNumber = 0;
// code if connected
}
}
}
回答2:
Something like this would work:
private boolean haveNetworkConnection() {
boolean haveConnectedWifi = false;
boolean haveConnectedMobile = false;
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
if (ni.isConnected())
haveConnectedWifi = true;
if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
if (ni.isConnected())
haveConnectedMobile = true;
}
return haveConnectedWifi || haveConnectedMobile;
}
I have copied this code from here (I understand the code - I am just adding the code here for ease for the user + I got told by an admin that you should do this and credit the original post). Personally I would split this into two functions, one for mobile and one for wifi, but that choice is up to you.
来源:https://stackoverflow.com/questions/25309603/effective-way-to-check-for-slow-internet-connection-and-differentiate-between-ne