今天写了个Demo,测试Android 判断网络连接(一) 所记录的内容,发现还是有点问题:就是连接像CMCC-EDU之类的需要验证的WIFI下,在未通过验证时,居然仍然表示网络连接.
于是,又要找方法解决这个问题,结果找到了一个解决方法时,直接通过Ping来判断网络.直接看代码吧.
Runnable isReachable = new Runnable() {
String result = null;
ConnectivityManager netManager;
NetworkInfo networkInfo;
int status;
long now, timeoutInMillis, finish;
Process p ;
@Override
public void run() {
while (!systemExitFlag) {
try {
Thread.sleep(5000);
mHandler.sendEmptyMessage(MSG_NET);
netManager = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
networkInfo = netManager.getActiveNetworkInfo();
if (networkInfo != null) {
// ping 的地址,可以换成任何一种可靠的外网
String ip = "www.baidu.com";
// ping网址1次 超时为3秒
p = Runtime.getRuntime().exec(
"ping -c 1 -w 3 " + ip);
//由于p.waitfor()会阻塞,所以设置了一个超时时间
now = System.currentTimeMillis();
timeoutInMillis = 1000 * 10;
finish = now + timeoutInMillis;
while (isAlive(p)
&& System.currentTimeMillis() > finish) {
throw new InterruptedException(
"Process timeout out after " + 10+ " seconds");
}
// ping的状态
status = p.waitFor();
if (status == 0) {
result = "success";
isNetConnected = true;
} else {
result = "failed";
isNetConnected = false;
}
} else {
result = "failed";
isNetConnected = false;
}
} catch (Exception e) {
// TODO Auto-generated catch block
p.destroy();
result = "failed";
isNetConnected = false;
e.printStackTrace();
} finally {
Log.i(TAG, "网络" + result);
}
}
}
};
public static boolean isAlive(Process p) {
try {
p.exitValue();
return false;
} catch (IllegalThreadStateException e) {
return true;
}
}
通过这样一种方法,便可以准确地判断网络连接了。
其中,
now = System.currentTimeMillis();
timeoutInMillis = 1000 * 10;
finish = now + timeoutInMillis;
while (isAlive(p)
&& System.currentTimeMillis() > finish) {
throw new InterruptedException(
"Process timeout out after " + 10+ " seconds");
}
这一段代码,是因为,在测试时,当网络连接着,突然断开时,p.waitfor()大概会阻塞1分钟,这样会导致网络判断不及时,所以设置了一个超时时间,当超过10秒则抛出异常,在异常中,把网络连接状态,设置为false。(因为,在测试中发现当网络断开着,突然连接时,p.waitfor()可以及时判断网络)。