activeNetworkInfo.type 在 API 级别 28 中已弃用

activeNetworkInfo.type is deprecated in API level 28

我想使用提供方法 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
    }

更新

The connectivityManager.activeNetworkInfo is also deprecated in API level 29

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

SAMPLE CODE USING 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
    }

旧答案

Yes getType() is deprecated in API level 28

现在我们需要使用 Callers should switch to checking NetworkCapabilities.hasTransport(int)

还有 getAllNetworkInfo() is deprecated in API level 29

现在我们需要使用 getAllNetworks() instead of getNetworkInfo(android.net.Network) .

getNetworkInfo()

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

getAllNetworks()

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

示例代码

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
}

没有,从这里看:https://developer.android.com/reference/android/net/ConnectivityManager.html#getActiveNetworkInfo()

getActiveNetworkInfo() 在 Android API 28 中仍然可用,并且没有任何地方说它已被弃用。

但是弃用的是 NetworkInfo getType() class。

https://developer.android.com/reference/android/net/NetworkInfo#getType()

This method was deprecated in API level 28.

Callers should switch to checking NetworkCapabilities.hasTransport(int) instead with one of the NetworkCapabilities#TRANSPORT_* constants : getType() and getTypeName() cannot account for networks using multiple transports. Note that generally apps should not care about transport; NetworkCapabilities.NET_CAPABILITY_NOT_METERED and NetworkCapabilities.getLinkDownstreamBandwidthKbps() are calls that apps concerned with meteredness or bandwidth should be looking at, as they offer this information with much better accuracy.

我根据自己的需要改编了 Nilesh Rathod 的回答:

enum class ConnectivityMode {
    NONE,
    WIFI,
    MOBILE,
    OTHER,
    MAYBE
}

var connectivityMode = ConnectivityMode.NONE

private fun checkConnectivity(context: Context): ConnectivityMode {

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

    cm?.run {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            getNetworkCapabilities(activeNetwork)?.run {
                return when {
                    hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> ConnectivityMode.WIFI
                    hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> ConnectivityMode.MOBILE
                    hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> ConnectivityMode.OTHER
                    hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> ConnectivityMode.MAYBE
                    else -> ConnectivityMode.NONE
                }
            }
        } else {
            @Suppress("DEPRECATION")
            activeNetworkInfo?.run {
                return when (type) {
                    ConnectivityManager.TYPE_WIFI -> ConnectivityMode.WIFI
                    ConnectivityManager.TYPE_MOBILE -> ConnectivityMode.MOBILE
                    ConnectivityManager.TYPE_ETHERNET -> ConnectivityMode.OTHER
                    ConnectivityManager.TYPE_BLUETOOTH -> ConnectivityMode.MAYBE
                    else -> ConnectivityMode.NONE
                }
            }
        }
    }
    return ConnectivityMode.NONE
}

然后我用okhttp检查连接:

fun updateData(manual: Boolean, windowContext: Context) = runBlocking {
    connectivityMode = checkConnectivity(MyApplication.context)
    if (connectivityMode != ConnectivityMode.NONE) {
        val conn : Boolean = GlobalScope.async {
            var retval = false
            try {
                val request = Request.Builder().url(WORK_URL).build()
                val response =  client.newCall(request).execute()
                Log.i(TAG, "code = ${response?.code}")
                if (response?.code == 200) {
                    // I use the response body since it is a small file and already downloaded
                    val input = response.body?.byteStream()
                    if (input != null) {
                        // do stuff
                        response.body?.close()
                        retval = true
                    }
                }
            }
            catch(exception: Exception) {
                Log.e(TAG, "error ${exception.message ?: ""}")
            }
            retval
        }.await()
        if (!conn) {
            connectivityMode = ConnectivityMode.NONE
        }
    }
    ....

如果您使用 min 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
    }
}

最近我不得不编写一个小函数来检查我的单个 WebView 中的网络连接。我还注意到 API 发生了很大的变化,尤其是当 Kotlin 出现时,找到有效参考花了几分钟时间。

这是我的小 NetworkConnectivityManager class,具有检查网络可用性的简单功能。

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
    }
}

这是我针对 SDK 29 的解决方案:一个名为 NetworkWatcher 的 class,它观察网络的变化。它提供原始变量,例如 isWifiOn 以及通过 Flow and LiveData.

观察网络随时间变化的选项
@ExperimentalCoroutinesApi
class NetworkWatcher
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
private constructor(
    application: Application
) {

    private val connectivityManager =
        application.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE)
                as ConnectivityManager

    // general availability of Internet over any type
    var isOnline = false
        get() {
            updateFields()
            return field
        }

    var isOverWifi = false
        get() {
            updateFields()
            return field
        }

    var isOverCellular = false
        get() {
            updateFields()
            return field
        }

    var isOverEthernet = false
        get() {
            updateFields()
            return field
        }

    companion object {
        @Volatile
        private var INSTANCE: NetworkWatcher? = null

        fun getInstance(application: Application): NetworkWatcher {
            synchronized(this) {
                if (INSTANCE == null) {
                    INSTANCE = NetworkWatcher(application)
                }
                return INSTANCE!!
            }
        }
    }

    @Suppress("DEPRECATION")
    private fun updateFields() {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            val networkAvailability =
                connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)

            if (networkAvailability != null &&
                networkAvailability.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                networkAvailability.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
            ) {
                //has network
                isOnline = true

                // wifi
                isOverWifi =
                    networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)

                // cellular
                isOverCellular =
                    networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)

                // ethernet
                isOverEthernet =
                    networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
            } else {
                isOnline = false
                isOverWifi = false
                isOverCellular = false
                isOverEthernet = false
            }
        } else {

            val info = connectivityManager.activeNetworkInfo
            if (info != null && info.isConnected) {
                isOnline = true

                val wifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
                isOverWifi = wifi != null && wifi.isConnected

                val cellular = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
                isOverCellular = cellular != null && cellular.isConnected

                val ethernet = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET)
                isOverEthernet = ethernet != null && ethernet.isConnected

            } else {
                isOnline = false
                isOverWifi = false
                isOverCellular = false
                isOverEthernet = false
            }
        }
    }

    fun watchNetwork(): Flow<Boolean> = watchWifi()
        .combine(watchCellular()) { wifi, cellular -> wifi || cellular }
        .combine(watchEthernet()) { wifiAndCellular, ethernet -> wifiAndCellular || ethernet }

    fun watchNetworkAsLiveData(): LiveData<Boolean> = watchNetwork().asLiveData()

    fun watchWifi(): Flow<Boolean> = callbackFlowForType(NetworkCapabilities.TRANSPORT_WIFI)

    fun watchWifiAsLiveData() = watchWifi().asLiveData()

    fun watchCellular(): Flow<Boolean> = callbackFlowForType(NetworkCapabilities.TRANSPORT_CELLULAR)

    fun watchCellularAsLiveData() = watchCellular().asLiveData()

    fun watchEthernet(): Flow<Boolean> = callbackFlowForType(NetworkCapabilities.TRANSPORT_ETHERNET)

    fun watchEthernetAsLiveData() = watchEthernet().asLiveData()

    private fun callbackFlowForType(@IntRange(from = 0, to = 7) type: Int) = callbackFlow {

        offer(false)

        val networkRequest = NetworkRequest.Builder()
            .addTransportType(type)
            .build()

        val callback = object : ConnectivityManager.NetworkCallback() {
            override fun onLost(network: Network?) {
                offer(false)
            }

            override fun onUnavailable() {
                offer(false)
            }

            override fun onLosing(network: Network?, maxMsToLive: Int) {
                // do nothing
            }

            override fun onAvailable(network: Network?) {
                offer(true)
            }
        }

        connectivityManager.registerNetworkCallback(networkRequest, callback)

        awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
    }
}

例如,您可以在您的应用程序中订阅有关 phone 网络状态的更新,例如:

GlobalScope.launch {
    NetworkWatcher.getInstance(this@MyApplication).watchNetwork().collect { connected ->
        Log.d("TAG", "Network In App: $connected")
    }
}

或者要回答您的问题,只需读取 Wifi 值,例如:

if (NetworkWatcher.getInstance(this@BaseApp).isOverWifi) {
    // do stuff
}

旁注:我没有一直使用 getInstance(),而是使用 Koin 等 DI 框架在我需要的地方注入 NetworkWatcher。

Java代码:

public static boolean isConnectingToInternet(Context mContext) {
    if (mContext == null) return false;

    ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            final Network network = connectivityManager.getActiveNetwork();
            if (network != null) {
                final NetworkCapabilities nc = connectivityManager.getNetworkCapabilities(network);

                return (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                        nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
            }
        } else {
            NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();
            for (NetworkInfo tempNetworkInfo : networkInfos) {
                if (tempNetworkInfo.isConnected()) {
                    return true;
                }
            }
        }
    }
    return false;
}

我只是想知道,如果设备连接到互联网,无论连接类型如何:

@Suppress("DEPRECATION")
fun isOnline(context: Context?): Boolean {
    var connected = false
    @Suppress("LiftReturnOrAssignment")
    context?.let {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val networkCapabilities = cm.activeNetwork ?: return false
            val actNw = cm.getNetworkCapabilities(networkCapabilities) ?: return false
            connected = actNw.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        } else {
            val netInfo = cm.activeNetworkInfo
            connected = netInfo?.isConnectedOrConnecting == true
        }
    }
    return connected
}

我正在使用这个 Kotlin 函数来检查互联网连接:

Be careful about version checking (Version >= M)

private fun isInternetConnected():Boolean{

    val connectivityManager = this.getSystemService(android.content.Context.CONNECTIVITY_SERVICE)
            as ConnectivityManager

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val networkCapabilities = connectivityManager.activeNetwork ?: return false
        val activeNetwork = connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false

        return when {

            activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                    activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) ||
                    activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
            else -> false
        }
    }
    else {
        return connectivityManager.activeNetworkInfo != null &&
                connectivityManager.activeNetworkInfo!!.isConnectedOrConnecting
    }
}

稍微简单的版本(minSdkVersion 23+)

fun isNetworkAvailable(context: Context) =
    (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).run {
        getNetworkCapabilities(activeNetwork)?.run {
            hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                || hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                || hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
        } ?: false
    }

希望这对您有用! 此代码在 api 21 之后有效

// 创建一个新的 class 并添加以下

public class CheckNetwork {

public static boolean isNetworkConnected;
private Context context;

public CheckNetwork(Context context) {
    this.context = context;
}

public boolean isOnline(){
    isNetworkConnected = false;
    ConnectivityManager connectivityMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    Network[] allNetworks = connectivityMgr.getAllNetworks(); // added in API 21 (Lollipop)

    for (Network network : allNetworks) {
        NetworkCapabilities networkCapabilities = connectivityMgr.getNetworkCapabilities(network);
        if (networkCapabilities != null) {
            if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                    || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                    || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET))
                isNetworkConnected = true;
            }
        }
    return isNetworkConnected;
    }

}

// 在 MainActivity

CheckNetwork myNetwork = new CheckNetwork(this);

//在OnCreateMethod

myNetwork.isOnline();
    if (myNetwork.isNetworkConnected){
        Toast.makeText(this, "Please check your Internet Connection", Toast.LENGTH_SHORT).show();
    }else {
        Toast.makeText(this, "Your Internet Connction is Ok", Toast.LENGTH_SHORT).show();
    }

这是两种方法的 Kotlin 实现 old/new api:

@Suppress("DEPRECATION")
fun isConnectedOld(context: Context): Boolean {
    val connManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
    val networkInfo = connManager.activeNetworkInfo
    return networkInfo.isConnected

}


@RequiresApi(Build.VERSION_CODES.M)
fun isConnectedNewApi(context: Context): Boolean {
    val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
    val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
    return capabilities?.hasCapability(NET_CAPABILITY_INTERNET) == true
}

和常用方法:

fun isConnected(context: Context): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        isConnectedNewApi(context)
    } else{
        isConnectedOld(context)
    }
}

完整的解决方案 在包中创建这些 class 让我们说 connectivity

  1. 接口 ConnectivityProvider

进口android.content.Context 导入 android.content.Context.CONNECTIVITY_SERVICE 导入 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)
        }
    }
}

}

  1. 摘要classConnectivityProviderBaseImpl

     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()) // propagate an initial state
         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()
    

    }

  2. class 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. class ConnectivityProviderLegacyImpl

@Suppress("弃用")

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)
        }
    }
}

用法:- 首页Activity

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
        }

版本 >= 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)
}

在 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
}

调用你的扩展函数activity

if (applicationContext.isInternetAvailable()) { }

这就是我所做的。在“if 语句”的第一部分,我检查用户是否正在使用 android 的新版本,在第二部分,我对旧的 Android SDK 使用 AciveNetworkInfo。

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
    }

}