在API 28级中,activeNetworkInfo.type已被弃用。

93

在此输入图像描述我想使用Connectivity Manager来检查Android中网络的类型,该管理器提供了activeNetworkInfo.type方法。但是,这个方法在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
    }
17个回答

1
在 Kotlin 中,您可以检查 Android 版本,并根据版本检查连接管理器。
fun Context.isInternetAvailable(): Boolean {
    val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    when {
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
            val cap = cm.getNetworkCapabilities(cm.activeNetwork) ?: return false
            return cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        }
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
            val networks = cm.allNetworks
            for (n in networks) {
                val nInfo = cm.getNetworkInfo(n)
                if (nInfo != null && nInfo.isConnected) return true
            }
        }
        else -> {
            val networks = cm.allNetworkInfo
            for (nInfo in networks) {
                if (nInfo != null && nInfo.isConnected) return true
            }
        }
    }
    return false
}

在您的活动中调用扩展函数

if (applicationContext.isInternetAvailable()) { }

0

这是我的工作。在“if语句”的第一部分中,我检查用户是否正在使用新版本的Android,在第二部分中,我使用ActiveNetworkInfo来处理旧版Android SDK。

fun isNetworkAvailable(context: Context): Boolean {  

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

    //return depending on the version in the last version of API
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

      val network = connectivityManager.activeNetwork ?: return false
               
val activeNetwork = 
                connectivityManager.getNetworkCapabilities(network) ?: return false
            return when {
                    activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                    activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                    activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) ->true

            else -> false
        }

    } else {
        //for the old version of android sdk we use follow code
        val networkInfo = connectivityManager.activeNetworkInfo
        return networkInfo != null && networkInfo.isConnectedOrConnecting
    }

}

0

完整解决方案 在一个名为connectivity的包中创建这些类

  1. 接口ConnectivityProvider

import android.content.Context import android.content.Context.CONNECTIVITY_SERVICE import android.net.ConnectivityManager

import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET

import android.net.NetworkInfo
import android.os.Build

import androidx.annotation.RequiresApi

interface ConnectivityProvider {
    interface ConnectivityStateListener {
        fun onStateChange(state: NetworkState)
    }

fun addListener(listener: ConnectivityStateListener)
fun removeListener(listener: ConnectivityStateListener)

fun getNetworkState(): NetworkState

@Suppress("MemberVisibilityCanBePrivate", "CanBeParameter")
sealed class NetworkState {
    object NotConnectedState : NetworkState()

    sealed class ConnectedState(val hasInternet: Boolean) : NetworkState() {

        @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
        data class Connected(val capabilities: NetworkCapabilities) : ConnectedState(
            capabilities.hasCapability(NET_CAPABILITY_INTERNET)
        )

        @Suppress("DEPRECATION")
        data class ConnectedLegacy(val networkInfo: NetworkInfo) : ConnectedState(
            networkInfo.isConnectedOrConnecting
        )
    }
}

companion object {
    fun createProvider(context: Context): ConnectivityProvider {
        val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            ConnectivityProviderImpl(cm)
        } else {
            ConnectivityProviderLegacyImpl(context, cm)
        }
    }
}

}

  • 抽象类 ConnectivityProviderBaseImpl

     abstract class ConnectivityProviderBaseImpl : ConnectivityProvider {
     private val handler = Handler(Looper.getMainLooper())
     private val listeners = mutableSetOf<ConnectivityStateListener>()
     private var subscribed = false
    
     override fun addListener(listener: ConnectivityStateListener) {
         listeners.add(listener)
         listener.onStateChange(getNetworkState()) // 传播初始状态
         verifySubscription()
     }
    
     override fun removeListener(listener: ConnectivityStateListener) {
         listeners.remove(listener)
         verifySubscription()
     }
    
     private fun verifySubscription() {
         if (!subscribed && listeners.isNotEmpty()) {
             subscribe()
             subscribed = true
         } else if (subscribed && listeners.isEmpty()) {
             unsubscribe()
             subscribed = false
         }
     }
    
     protected fun dispatchChange(state: NetworkState) {
         handler.post {
             for (listener in listeners) {
                 listener.onStateChange(state)
             }
         }
     }
    
     protected abstract fun subscribe()
     protected abstract fun unsubscribe()
    

    }

  • ConnectivityProviderImpl

  • @RequiresApi(Build.VERSION_CODES.N)

    class ConnectivityProviderImpl(private val cm: ConnectivityManager) :
        ConnectivityProviderBaseImpl() {
    
        private val networkCallback = ConnectivityCallback()
    
        override fun subscribe() {
            cm.registerDefaultNetworkCallback(networkCallback)
        }
    
        override fun unsubscribe() {
            cm.unregisterNetworkCallback(networkCallback)
        }
    
        override fun getNetworkState(): NetworkState {
            val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
            return if (capabilities != null) {
                Connected(capabilities)
            } else {
                NotConnectedState
            }
        }
    
        private inner class ConnectivityCallback : NetworkCallback() {
    
            override fun onCapabilitiesChanged(network: Network, capabilities: NetworkCapabilities) {
                dispatchChange(Connected(capabilities))
            }
    
            override fun onLost(network: Network) {
                dispatchChange(NotConnectedState)
            }
        }
    }
    
    1. ConnectivityProviderLegacyImpl 类

    @Suppress("DEPRECATION")

    class ConnectivityProviderLegacyImpl(
    private val context: Context,
     private val cm: ConnectivityManager
    ) : ConnectivityProviderBaseImpl() {
    
        private val receiver = ConnectivityReceiver()
    
        override fun subscribe() {
            context.registerReceiver(receiver, IntentFilter(CONNECTIVITY_ACTION))
        }
    
        override fun unsubscribe() {
            context.unregisterReceiver(receiver)
        }
    
        override fun getNetworkState(): NetworkState {
            val activeNetworkInfo = cm.activeNetworkInfo
            return if (activeNetworkInfo != null) {
                ConnectedLegacy(activeNetworkInfo)
            } else {
                NotConnectedState
            }
        }
    
        private inner class ConnectivityReceiver : BroadcastReceiver() {
            override fun onReceive(c: Context, intent: Intent) {
                // on some devices ConnectivityManager.getActiveNetworkInfo() does not provide the correct network state
                // https://issuetracker.google.com/issues/37137911
                val networkInfo = cm.activeNetworkInfo
                val fallbackNetworkInfo: NetworkInfo? = intent.getParcelableExtra(EXTRA_NETWORK_INFO)
                // a set of dirty workarounds
                val state: NetworkState =
                    if (networkInfo?.isConnectedOrConnecting == true) {
                        ConnectedLegacy(networkInfo)
                    } else if (networkInfo != null && fallbackNetworkInfo != null &&
                        networkInfo.isConnectedOrConnecting != fallbackNetworkInfo.isConnectedOrConnecting
                    ) {
                        ConnectedLegacy(fallbackNetworkInfo)
                    } else {
                        val state = networkInfo ?: fallbackNetworkInfo
                        if (state != null) ConnectedLegacy(state) else NotConnectedState
                    }
                dispatchChange(state)
            }
        }
    }
    

    使用方法:- 主页活动

    class HomeActivity : BaseActivity(), ConnectivityProvider.ConnectivityStateListener {
        val provider: ConnectivityProvider by lazy { ConnectivityProvider.createProvider(this@HomeActivity) }
     override fun onStart() {
            super.onStart()
            provider.addListener(this)
        }
    
    override fun onStop() {
        super.onStop()
        provider.removeListener(this)
    }
    
    override fun onStateChange(state: ConnectivityProvider.NetworkState) {
        val hasInternet = state.hasInternet()
    }
    
    companion object {
        fun ConnectivityProvider.NetworkState.hasInternet(): Boolean {
            return (this as? ConnectivityProvider.NetworkState.ConnectedState)?.hasInternet == true
        }
    }
    

    在按钮点击或任何 API 调用时

     if(provider.getNetworkState().hasInternet()){
                    // do work    
                    }
    }
    

    如果你想在主页活动的片段中检查互联网

    if ((activity as HomeActivity).provider.getNetworkState().hasInternet()) {
                // api call
            }
    

    0

    对于版本>= Build.VERSION_CODES.M

    private fun isConnected(context: Context): Boolean {
        val manager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
        val capabilities = manager?.getNetworkCapabilities(manager.activeNetwork) ?: return false
    
        return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
    }
    

    0
    最近我不得不编写一个小函数,用于检查我的单一 WebView 中的网络连接性。我还注意到 API 很大程度上得到了发展,特别是 Kotlin 的出现,因此要找到有效的参考资料需要花费一些时间。
    这是我的小型 NetworkConnectivityManager 类,其中包含一个简单的函数,用于检查网络可用性。
    import android.content.Context
    import android.content.Context.CONNECTIVITY_SERVICE
    import android.net.ConnectivityManager
    import android.net.NetworkCapabilities
    import android.os.Build
    
    class NetworkConnectivityManager(context: Context) {
        private val connectivityManager =
            context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
    
        @Suppress("DEPRECATION")
        fun isNetworkAvailable(): Boolean {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                val nc = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
    
                nc != null 
                        && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                        && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
            }
    
            val networkInfo = connectivityManager.activeNetworkInfo
            return networkInfo != null && networkInfo.isConnected
        }
    }
    

    0

    如果您使用最低API级别为23,则可以使用此缩短的Kotlin版本。

    fun isNetworkAvailable(context: Context): Boolean {
        (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).apply {
            return getNetworkCapabilities(activeNetwork)?.run {
                when {
                    hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                    hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                    hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                    else -> false
                }
            } ?: false
        }
    }
    

    0

    根据Android开发者文档指南,这种方式可能会很有用。

    Java

            boolean enabled;
            ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
            assert connectivityManager != null;
            NetworkInfo info = connectivityManager.getActiveNetworkInfo();
    
            ConnectivityManager cm = getSystemService(ConnectivityManager.class);
    
            if ((info == null ||  !cm.getActiveNetworkInfo().isConnectedOrConnecting() || !info.isAvailable())) {
               
                enabled = false;
            } else enabled = true;
    

    对于这个getActiveNetworkInfo(),你需要ACCESS_NETWORK_STATE权限。

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

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接