起因:
原本是打算监听一下网络中断状态的,但发现利用广播的方法弃用了,去官网查资料是推荐使用ConnectivityManager.NetworkCallback(),而且能监听的网络状态还挺多的。
另外官网上说是支持API 21的,但IDE警告是最低支持到API 24,而亲测API 31、API 30有效,也就是android11和android12的机子测试能够监听到。(后面有通过广播的方式监听的demo)
前期处理:
网络权限是必须的,在AndroidManifest.xml里添加权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
操作代码
1、ConnectivityManager
2、调用registerDefaultNetworkCallback方法
3、然后像重写activity生命周期的方法一样重写NetworkCallback的onXXX方法,不需要的可以不写
class ConnectStateActivity : AppCompatActivity() {
@RequiresApi(Build.VERSION_CODES.N)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_connect_state)
//获取管理器
val connectivityManager =
getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
//注册
connectivityManager.registerDefaultNetworkCallback(object :
ConnectivityManager.NetworkCallback() {
//以下是可以监听的状态
/**
* 当框架连接并声明一个新的网络可供使用时调用。
*Called when the framework connects and
* has declared a new network ready for use.
*/
override fun onAvailable(network: Network) {
super.onAvailable(network)
Log.d(TAG, "onAvailable>>>>>start")
}
/**
*当对指定网络的访问被阻止或解除阻止时调用。
* Called when access to the specified
* network is blocked or unblocked.
*/
override fun onBlockedStatusChanged(network: Network, blocked: Boolean) {
super.onBlockedStatusChanged(network, blocked)
Log.d(TAG, "onBlockedStatusChanged>>>>>start")
}
/**
* 当与此请求对应的网络更改功能但仍满足请求的条件时调用。
* Called when the network corresponding to this
* request changes capabilities but still satisfies the requested criteria.
*/
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
) {
super.onCapabilitiesChanged(network, networkCapabilities)
Log.d(TAG, "onCapabilitiesChanged>>>>>start")
}
/**
* 当该请求对应的网络发生变化时调用LinkProperties。
* Called when the network corresponding
* to this request changes LinkProperties.
*/
override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
super.onLinkPropertiesChanged(network, linkProperties)
Log.d(TAG, "onLinkPropertiesChanged>>>>>start")
}
/**
* 当网络即将丢失时调用,通常是因为没有未完成的请求。
* Called when the network is about to be lost,
* typically because there are no outstanding requests left for it.
*/
override fun onLosing(network: Network, maxMsToLive: Int) {
super.onLosing(network, maxMsToLive)
Log.d(TAG, "onLosing>>>>>start")
}
/**
* 当网络断开连接或不再满足此请求或回调时调用。
* Called when a network disconnects or otherwise
* no longer satisfies this request or callback.
*/
override fun onLost(network: Network) {
super.onLost(network)
Toast.makeText(this@ConnectStateActivity, "网络中断", Toast.LENGTH_SHORT).show()
Log.d(TAG, "onReceive>>>>>网络中断")
}
/**
* 如果在调用中指定的超时时间内没有找到网络,
* 或者如果请求的网络请求无法完成(无论是否指定了超时),则调用。
* Called if no network is found
* within the timeout time specified in ConnectivityManager.
* requestNetwork(android.net.NetworkRequest,
* android.net.ConnectivityManager.NetworkCallback, int)
* call or if the requested network request cannot
* be fulfilled (whether or not a timeout was specified).
*
*/
override fun onUnavailable() {
super.onUnavailable()
Log.d(TAG, "onUnavailable>>>>>start")
}
})
}
}
广播形式监听网络中断
同样也需要声明网络权限
class BroadcastReceiverActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// val binding = ActivityBroadcastReceiverBinding.inflate(layoutInflater)
// setContentView(binding.root)
setContentView(R.layout.activity_broadcast_receiver)
//过滤器
val intentFilter = IntentFilter()
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE")
//注册监听
registerReceiver(object : BroadcastReceiver(){
//监听到广播
override fun onReceive(context: Context?, intent: Intent?) {
val connectivityManager =
context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
//网络中断了
val activeNetwork = connectivityManager.activeNetworkInfo
if (activeNetwork==null||!activeNetwork.isConnected){
Toast.makeText(context,"网络中断",Toast.LENGTH_SHORT).show()
Log.d(TAG,"onReceive>>>>>网络中断")
}
}
},intentFilter)
}
最后
官方推荐的方法底层没具体看过,粗浅猜测也是用广播的形式监听然后封装的,不一定对,有知道的朋友请告诉我一声。