我得到了一个AsyncTask,应该检查对主机名的网络访问。但是doInBackground()永远不会超时。有人知道吗?
public class HostAvailabilityTask extends AsyncTask<String, Void, Boolean> {
private Main main;
public HostAvailabilityTask(Main main) {
this.main = main;
}
protected Boolean doInBackground(String... params) {
Main.Log("doInBackground() isHostAvailable():"+params[0]);
try {
return InetAddress.getByName(params[0]).isReachable(30);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean... result) {
Main.Log("onPostExecute()");
if(result[0] == false) {
main.setContentView(R.layout.splash);
return;
}
main.continueAfterHostCheck();
}
}
如果设备处于飞行模式(或者假设在没有可用网络的其他情况下),cm.getActiveNetworkInfo()将为空,因此您需要添加一个空检查。
修改(Eddie的解决方案)如下:
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
在AndroidManifest.xml中添加以下权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
还有一点,如果你在给定的时间点绝对需要一个网络连接,那么使用netInfo.isConnected()而不是netInfo.isConnectedOrConnecting可能会更好。不过,我想这取决于个人用例。
不要检查WIFI连接或移动数据连接,试着点击任何托管域。以便您可以检查WIFI/Mobile连接是否具有连接公共互联网的能力。
如果您的移动设备能够连接到所提供的公共域,则将返回以下内容。
boolean isReachable()
{
boolean connected = false;
String instanceURL = "Your trusted domain name";
Socket socket;
try {
socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(instanceURL, 80);
socket.connect(socketAddress, 5000);
if (socket.isConnected()) {
connected = true;
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
socket = null;
}
return connected;
}
希望对大家有所帮助。
在我目前所见过的所有方法中,最短、最干净的方法应该是:
public final static boolean isConnected( Context context )
{
final ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
PS:这不会ping任何主机,它只是检查连接状态,所以如果你的路由器没有互联网连接,而你的设备连接到它,这个方法将返回true,尽管你没有互联网。
对于实际的测试,我建议执行一个HttpHead请求(例如到www.google.com)并检查状态,如果它是200 OK,一切正常,并且您的设备有互联网连接。
The other answers that use ConnectivityManager are wrong because having a network connection doesn't mean you have internet access. For example, the user might be connected to a coffee shop's WiFi portal but can't get to the internet. To check that the internet is accessible you have to try to connect to an actual server. Normally when you want to do this you have a specific server in mind that you want to connect to, so go ahead and check if you can connect to that server. Here's a simple method for checking connectivity to a server.
private boolean isOnTheInternet() {
try {
URLConnection urlConnection = new URL("http://yourserver").openConnection();
urlConnection.setConnectTimeout(400);
urlConnection.connect();
return true;
} catch (Exception e) {
return false;
}
}
设置ConnectTimeout的原因是,否则它默认为TCP超时,可以有很多秒长。
还要注意的是,Android不允许你在主线程上运行这个程序。