使用 Connectivity Manager 监听网络变化

Listening to network changes using Connectivity Manager

我正在尝试使用 conenctivityManager 的方法 registerDefaultNetworkCallback() 来监听网络变化 使用此 answer

中的以下代码
     val connectivityManager = cotnext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        connectivityManager?.let {
            it.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network) {
                    //take action when network connection is gained
                }
                override fun onLost(network: Network) {
                    //take action when network connection is lost
                }
            })
        }

但是我对这个方法有几个问题:

  1. 如果phone连接了wifi但wifi没有连接到互联网怎么办
  2. 在方法文档中我读到这个我不明白,具体什么时候会达到限制?如果回调被调用 100 次,那么会抛出 Exception 吗?以及如何处理?

To avoid performance issues due to apps leaking callbacks, the system will limit the number of outstanding requests to 100 per app (identified by their UID), shared with all variants of this method, of requestNetwork as well as ConnectivityDiagnosticsManager.registerConnectivityDiagnosticsCallback. Requesting a network with this method will count toward this limit. If this limit is exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources, make sure to unregister the callbacks with unregisterNetworkCallback(ConnectivityManager.NetworkCallback).

首先,添加 ConnectivityReceiver class:

class ConnectivityReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (connectivityReceiverListener != null) {
            connectivityReceiverListener!!.onNetworkConnectionChanged(
                isConnectedOrConnecting(
                    context
                )
            )
        }
    }

    private fun isConnectedOrConnecting(context: Context): Boolean {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

        if (cm != null) {
            if (Build.VERSION.SDK_INT < 23) {
                val ni = cm.activeNetworkInfo
                if (ni != null) {
                    return ni.isConnected && (ni.type == ConnectivityManager.TYPE_WIFI || ni.type == ConnectivityManager.TYPE_MOBILE)
                }
            } else {
                val n = cm.activeNetwork
                if (n != null) {
                    val nc = cm.getNetworkCapabilities(n)
                    return nc!!.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || nc!!.hasTransport(
                        NetworkCapabilities.TRANSPORT_WIFI
                    )
                }
            }
        }
        return false
    }

    interface ConnectivityReceiverListener {
        fun onNetworkConnectionChanged(isConnected: Boolean)
    }

    companion object {
        var connectivityReceiverListener: ConnectivityReceiverListener? = null
    }

}

然后在您的 BaseActivityMainActivity 中添加这些行:

 abstract class BaseActivity:AppCompatActivity(), 
      ConnectivityReceiver.ConnectivityReceiverListener {

var receiver: ConnectivityReceiver? = null

override fun onResume() {
        super.onResume()
        try {
            receiver = ConnectivityReceiver()
            registerReceiver(
                receiver!!,
                IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
            )
            connectivityReceiverListener = this
        } catch (ex: Exception) {
            //Timber.d("Base ex ${ex.localizedMessage}")
        }

    }

    override fun onPause() {
        try {
            unregisterReceiver(receiver!!)
            receiver = null

        } catch (ex: Exception) {
        }
        super.onPause()

    }

 override fun onNetworkConnectionChanged(isConnected: Boolean) {
        showMessage(isConnected)
    }


private fun showMessage(isConnected: Boolean) {
    try {
        if (!isConnected) {
           Log.d("Connection state"," disconnected")
        } else {
            Log.d("Connection state"," connected")
        }
    } catch (ex: Exception) {
       
    }
} 
}

您应该在 OnResume 方法中注册接收器并在 OnPause 方法

中取消注册
  1. what if the phone is connected to wifi but the wifi is not connected to Internet

答案,这个方法会return false

  1. In the method documentation I read this which I don't understand, when exactly will the limit will hit? If the callback is called 100 times then an Exception will be thrown? And how to handle this?

我认为这意味着如果你不能注册超过 100 个回调