74

在此处输入图像描述我想使用提供方法 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
    }
4

15 回答 15

146

更新

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
}
于 2018-11-29T05:32:21.123 回答
10

稍微简单的版本(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
    }
于 2020-04-11T05:07:12.707 回答
9

这是我对 SDK 29 的解决方案:一个名为的类NetworkWatcher,它观察网络的变化。它提供原始变量,例如通过FlowLiveDataisWifiOn观察网络随时间变化的选项。

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

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

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注入到我需要的地方。

于 2019-11-20T18:13:43.223 回答
7

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

@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
}
于 2020-01-08T10:23:06.283 回答
4

不,从这里可以看出:https://developer.android.com/reference/android/net/ConnectivityManager.html#getActiveNetworkInfo()

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

但不推荐使用的是getType()NetworkInfo

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

此方法在 API 级别 28 中已弃用。

调用者应该 NetworkCapabilities.hasTransport(int)转而使用其中之一 进行检查,NetworkCapabilities#TRANSPORT_* constants : getType()并且 getTypeName()不能考虑使用多个传输的网络。请注意,通常应用程序不应该关心传输; NetworkCapabilities.NET_CAPABILITY_NOT_METERED并且 NetworkCapabilities.getLinkDownstreamBandwidthKbps()是与计量或带宽有关的应用程序应该关注的呼叫,因为它们以更高的准确性提供此信息。

于 2018-11-29T05:39:20.977 回答
4

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;
}
于 2019-12-16T16:07:59.313 回答
4

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

小心版本检查(版本> = 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
    }
}
于 2020-02-18T14:59:07.423 回答
4

这是旧/新 api 两种方法的 Kotlin 实现:

@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)
    }
}
于 2020-12-02T10:29:31.860 回答
3

我已经根据我的需要改编了 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
        }
    }
    ....
于 2019-08-20T14:24:42.773 回答
2

我希望这对你有用!此代码从 api 21 开始工作

// 创建一个新类并添加以下内容

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

//在 OnCreate 方法中

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();
    }
于 2020-07-26T02:59:17.423 回答
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
    }
}
于 2019-10-03T09:44:06.090 回答
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
    }
}
于 2019-11-12T11:08:47.123 回答
0

完整的解决方案在一个包中创建这些类让我们说连接

  1. 接口连接提供者

导入 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. 抽象类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()) // 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. 类 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("弃用")

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
        }
于 2020-12-11T12:21:24.243 回答
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)
}
于 2021-03-30T05:47:18.290 回答
0

在 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()) { }
于 2021-08-23T15:59:00.667 回答