Kotlin:如果网络断开,则使用 ConnectivityManager returns 检查网络状态 null。怎么会?

Kotlin: Checking network status using ConnectivityManager returns null if network disconnected. How come?

我尝试使用此功能检查我的网络状态(连接或断开连接):

// Check Network status
private fun isNetworkAvailable(): Boolean {
    val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE)
    return if (connectivityManager is ConnectivityManager) {
        val networkInfo = connectivityManager.activeNetworkInfo
        networkInfo.isConnected
    }
    else false
}

这给了我一个 java.lang.IllegalStateException: networkInfo 不能为空 - 错误 当 运行 网络断开时。为什么?我该如何解决这个问题?

根据 docs activeNetworkInfo 可能为空:

Returns details about the currently active default data network. When connected, this network is the default route for outgoing connections. You should always check isConnected() before initiating network traffic. This may return null when there is no default network.

为了确保它不会崩溃,只需使用这个:

 private fun isNetworkAvailable(): Boolean {
        val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE)
        return if (connectivityManager is ConnectivityManager) {
            val networkInfo: NetworkInfo? = connectivityManager.activeNetworkInfo
            networkInfo?.isConnected ?: false
        } else false
    }

最简单的方法之一是,向上下文添加扩展 class,如下所示,

val Context.isConnected: Boolean
get() {
    return (getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager)
        .activeNetworkInfo?.isConnected == true
}

现在您可以在 activity 中使用它,例如,

 if (!isConnected) {
 // connection is not available...
 }

您可以在 activity、片段或上下文中的任何地方使用这种方式。

使用这段代码,一定会有帮助


fun checkConnectivity(context: Context): Boolean {

        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

        val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
    
        if(activeNetwork?.isConnected!=null){
            return activeNetwork.isConnected
        }
        else{
            return false
        }
    }

getActiveNetwork 已在 API 29 中弃用,因此这是最佳解决方案:

fun isInternetAvailable(context: Context): Boolean {
    var result = false
    val connectivityManager =
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val networkCapabilities = connectivityManager.activeNetwork ?: return false
        val actNw =
            connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
        result = when {
            actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
            actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
            actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
            else -> false
        }
    } else {
        connectivityManager.activeNetworkInfo?.run {
            result = when (type) {
                ConnectivityManager.TYPE_WIFI -> true
                ConnectivityManager.TYPE_MOBILE -> true
                ConnectivityManager.TYPE_ETHERNET -> true
                else -> false
            }

        }
    }
    return result
}