Android API 23以上版本如何监听网络连接状态变化?
解决API 23+网络连接变化监听的适配问题
兄弟,我太懂你这种找不到明确适配方案的困惑了!先给你拍板:API 23及以上版本,确实没有Manifest层面注册网络连接广播的解决方案——官方就是把这种隐式广播的静态注册权限砍掉了,目的是减少后台无用唤醒、优化设备功耗。
为什么Manifest注册失效?
从Android 6.0(API 23)开始,系统限制了大部分隐式广播的静态注册,CONNECTIVITY_ACTION就属于被限制的范畴,只有极少数特殊广播(比如BOOT_COMPLETED)还保留静态注册权限,网络广播不在其中,所以别再纠结Manifest的写法了,官方文档没提就是真的没有。
推荐的两种适配方案
方案1:代码动态注册BroadcastReceiver
这是官方文档提到的方式,具体步骤如下:
- 定义广播接收器子类
class ConnectivityReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (intent?.action == ConnectivityManager.CONNECTIVITY_ACTION) { // 这里处理网络状态变化逻辑 val connManager = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val activeNetwork = connManager.activeNetworkInfo val isConnected = activeNetwork?.isConnected == true // 示例:打印网络状态 Log.d("Connectivity", "网络连接状态:${if (isConnected) "已连接" else "已断开"}") } } }
- 在组件(Activity/Fragment/Service)中注册和注销
private lateinit var connReceiver: ConnectivityReceiver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) connReceiver = ConnectivityReceiver() // 创建IntentFilter并指定动作 val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) // 注册广播 registerReceiver(connReceiver, filter) } override fun onDestroy() { super.onDestroy() // 必须注销,避免内存泄漏 unregisterReceiver(connReceiver) }
方案2:使用更现代的NetworkCallback(推荐)
从API 21开始就有了ConnectivityManager.NetworkCallback,比广播接收器更高效,也更符合Android后续的设计趋势:
private val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { // 网络可用时触发 Log.d("Connectivity", "网络已连接") } override fun onLost(network: Network) { // 网络断开时触发 Log.d("Connectivity", "网络已断开") } } // 注册Callback val connManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val networkRequest = NetworkRequest.Builder().build() connManager.registerNetworkCallback(networkRequest, networkCallback) // 注销Callback(记得在组件销毁时调用) connManager.unregisterNetworkCallback(networkCallback)
注意事项
- 如果需要后台持续监听网络,API 26+之后动态注册的广播在后台也会被限制,这时候建议用
WorkManager定期检查网络状态,或者结合NetworkCallback和前台服务(如果业务需要)。 - 无论用哪种方式,都要记得在组件生命周期结束时注销接收器/Callback,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Thomas Cirksena
相关产品推荐
相关产品推荐

