我得到了一个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();
    }   
}

当前回答

我已经应用了@Levit提供的解决方案,并创建了不会调用额外Http请求的函数。

它将解决无法解析主机的错误

public static boolean isInternetAvailable(Context context) {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (activeNetwork == null) return false;

    switch (activeNetwork.getType()) {
        case ConnectivityManager.TYPE_WIFI:
            if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
                    activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
                    isInternet())
                return true;
            break;
        case ConnectivityManager.TYPE_MOBILE:
            if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
                    activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
                    isInternet())
                return true;
            break;
        default:
            return false;
    }
    return false;
}

private static boolean isInternet() {

    Runtime runtime = Runtime.getRuntime();
    try {
        Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
        int exitValue = ipProcess.waitFor();
        Debug.i(exitValue + "");
        return (exitValue == 0);
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    }

    return false;
}

现在叫它,

if (!isInternetAvailable(getActivity())) {
     //Show message
} else {
     //Perfoem the api request
}

其他回答

不要检查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;
        }

希望对大家有所帮助。

以下是来自我的Utils类的代码:

public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager 
              = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
public boolean isOnline() {
    boolean var = false;
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    if ( cm.getActiveNetworkInfo() != null ) {
        var = true;
    }
    return var;
} 

我是这样做的。 我想会更短更有可读性。

干杯!

Saiyan

我做了这个代码,它是最简单的,它只是一个布尔值。 通过询问if(isOnline()){

如果存在连接,并且可以连接到页面,则会得到状态代码200(稳定连接)。

确保添加正确的INTERNET和ACCESS_NETWORK_STATE权限。

public boolean isOnline() {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnected()) {
        try {
            URL url = new URL("http://www.google.com");
            HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
            urlc.setConnectTimeout(3000);
            urlc.connect();
            if (urlc.getResponseCode() == 200) {
                return new Boolean(true);
            }
        } catch (MalformedURLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return false;
}

Android提供了ConnectivityManager类来了解互联网连接状态。下面的方法将是非常有用的,以了解互联网连接状态。

首先在AndroidManifest.xml中添加INTERNET和ACCESS_NETWORK_STATE权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

然后使用下面的方法检查设备是否连接到互联网。如果设备已连接到互联网,此方法将返回true。

public boolean isInternetAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) 
    context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
    return activeNetwork != null
            && activeNetwork.isConnectedOrConnecting();
}

参考链接:—http://www.androidtutorialshub.com/android-check-internet-connection-status/