首页 > 解决方案 > 在 API 级别 28 中不推荐使用 activeNetworkInfo.type

问题描述

在此处输入图像描述我想使用提供方法 activeNetworkInfo.type 的连接管理器来检查 Android 中的网络类型。此方法在 API 级别 28 中已弃用。那么在 API 28 中检查网络类型的解决方案是什么。我的代码是:

/**
 * Check Wi Fi connectivity
 */
fun isWiFiConnected(context: Context): Boolean {
    val connManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    return connManager.activeNetworkInfo.type == ConnectivityManager.TYPE_WIFI
}

我的 Gradle 是这样的:

compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
        minSdkVersion 21
        targetSdkVersion 28
    }

标签: androidkotlindeprecatedandroid-connectivitymanager

解决方案


更新

connectivityManager.activeNetworkInfoAPI 级别 29 中也已弃用

现在我们需要使用ConnectivityManager.NetworkCallback API or ConnectivityManager#getNetworkCapabilities or ConnectivityManager#getLinkProperties

示例代码使用ConnectivityManager#getNetworkCapabilities

private 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.run {
                connectivityManager.activeNetworkInfo?.run {
                    result = when (type) {
                        ConnectivityManager.TYPE_WIFI -> true
                        ConnectivityManager.TYPE_MOBILE -> true
                        ConnectivityManager.TYPE_ETHERNET -> true
                        else -> false
                    }

                }
            }
        }

        return result
    }

旧答案

getType()在 API 级别 28 中已弃用

现在我们需要使用 Callers 应该切换到检查NetworkCapabilities.hasTransport(int)

在 API 级别 29 中也已弃用 getAllNetworkInfo()

现在我们需要使用getAllNetworks()而不是getNetworkInfo(android.net.Network).

getNetworkInfo()

  • 返回有关特定网络的连接状态信息。

getAllNetworks()

  • 返回框架当前跟踪的所有网络的数组。

示例代码

fun isWiFiConnected(context: Context): Boolean {
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        val network = connectivityManager.activeNetwork
        val capabilities = connectivityManager.getNetworkCapabilities(network)
        capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
    } else {
        connectivityManager.activeNetworkInfo.type == ConnectivityManager.TYPE_WIFI
    }
}

完整代码

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

推荐阅读