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

当前回答

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不允许你在主线程上运行这个程序。

其他回答

正如Android文档建议的那样,之后

getActiveNetworkInfo()在Android 10中已弃用。使用 而不是针对Android 10 (API级别)的应用程序的NetworkCallbacks 29)更高。

下面是我们目前检查网络连接的方法:

val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetwork: NetworkInfo? = cm.activeNetworkInfo
val isConnected: Boolean = activeNetwork?.isConnectedOrConnecting == true

使用NetworkCallbacks检查网络连接的新方法

步骤1:

    private lateinit var connectivityManager:ConnectivityManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    }

步骤2:创建回调:

private val callback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        super.onAvailable(network)
        Timber.e("Network:onAvailable")
    }

    override fun onLost(network: Network) {
        super.onLost(network)
        Timber.e("Network:onLost")
    }

}

步骤3:注册和取消注册回调:

private fun registerNetworkCallback() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        connectivityManager.registerDefaultNetworkCallback(callback)
    } else {
        // Old way to check network connection
    }
}

override fun onStop() {
    unRegisterNetworkCallback()
    super.onStop()
}

private fun unRegisterNetworkCallback() {
    connectivityManager.unregisterNetworkCallback(callback)
}

结帐更新详情如下链接:

https://developer.android.com/training/monitoring-device-state/connectivity-status-type

这段代码将帮助您找到互联网是否打开。

public final boolean isInternetOn() {
        ConnectivityManager conMgr = (ConnectivityManager) this.con
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = conMgr.getActiveNetworkInfo();
        return (info != null && info.isConnected());
}

此外,您应该提供以下权限

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

这种方法为您提供了一个非常快速的方法(用于实时反馈)或较慢的方法(用于需要可靠性的一次性检查)。

public boolean isNetworkAvailable(bool SlowButMoreReliable) {
    bool Result = false; 
    try {
        if(SlowButMoreReliable){
            ConnectivityManager MyConnectivityManager = null;
            MyConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkInfo MyNetworkInfo = null;
            MyNetworkInfo = MyConnectivityManager.getActiveNetworkInfo();

            Result = MyNetworkInfo != null && MyNetworkInfo.isConnected();

        } else
        {
            Runtime runtime = Runtime.getRuntime();
            Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");

            int i = ipProcess.waitFor();

            Result = i== 0;

        }

    } catch(Exception ex)
    {
        //Common.Exception(ex); //This method is one you should have that displays exceptions in your log
    }
    return Result;
}

你可以遍历所有的网络连接,检查是否至少有一个可用的连接:

public boolean isConnected() {
    boolean connected = false;

    ConnectivityManager cm = 
        (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        NetworkInfo[] netInfo = cm.getAllNetworkInfo();

        for (NetworkInfo ni : netInfo) {
            if ((ni.getTypeName().equalsIgnoreCase("WIFI")
                    || ni.getTypeName().equalsIgnoreCase("MOBILE"))
                    && ni.isConnected() && ni.isAvailable()) {
                connected = true;
            }

        }
    }

    return connected;
}
public static boolean isNetworkAvailable(Context ctx) {
ConnectivityManager connMgr = (ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
if(connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected() ||
    connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected()){
        return true;
}

return false;
 } 

用户这