You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android ConnectivityManager回调异常:蜂窝网络onAvailable不触发

问题分析与解决方案

你的问题出在两个核心点:NetworkRequest配置缺失,以及对NetworkCallback回调触发时机的误解。

核心原因

  1. onAvailable仅触发网络从「不可用」变为「可用」的瞬间:当WiFi和蜂窝网络同时存在时,蜂窝网络本来就处于可用状态,关闭WiFi并不会让蜂窝网络触发「不可用到可用」的状态变化,因此不会触发onAvailable回调。
  2. 未指定正确的网络监听规则:如果注册回调时没有配置明确的NetworkRequest,系统可能只会监听默认网络的部分状态变化,导致无法感知到已存在的蜂窝网络。

修复步骤

1. 创建带完整条件的NetworkRequest

注册回调时,必须明确指定需要监听的网络类型和核心能力(比如互联网访问权限):

val networkRequest = NetworkRequest.Builder()
    // 要求网络具备互联网访问能力
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    // 同时监听WiFi和蜂窝网络
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
    .build()

2. 传入NetworkRequest注册回调

替换原有的默认注册方式,改用带规则的注册:

val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
connectivityManager.registerNetworkCallback(networkRequest, connectivityCallback)

3. 重写onDefaultNetworkChanged处理网络切换

当WiFi关闭后,系统会将默认网络切换到蜂窝,但此时蜂窝已处于可用状态,不会触发onAvailable。因此需要监听默认网络的切换事件:

private val connectivityCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        Log.debug("网络可用: $network")
    }

    override fun onLost(network: Network) {
        Log.debug("网络丢失: $network")
    }

    // 监听默认网络切换,处理WiFi转蜂窝的场景
    override fun onDefaultNetworkChanged(network: Network?) {
        network?.let {
            val capabilities = connectivityManager.getNetworkCapabilities(it)
            if (capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true) {
                Log.debug("默认网络切换为可用网络: $it")
                // 在这里更新你的应用网络状态
            } else {
                Log.debug("默认网络无互联网访问")
            }
        } ?: run {
            Log.debug("无默认网络")
        }
    }
}

4. 初始状态检查

由于回调仅在网络变化时触发,注册回调前需要先检查当前网络状态,避免启动时误判:

connectivityManager.activeNetwork?.let { currentNetwork ->
    val capabilities = connectivityManager.getNetworkCapabilities(currentNetwork)
    if (capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true) {
        Log.debug("初始状态: 当前有可用网络")
    } else {
        Log.debug("初始状态: 当前网络无互联网访问")
    }
} ?: run {
    Log.debug("初始状态: 无任何网络")
}

额外注意事项

  • 页面销毁或不再需要监听时,务必调用connectivityManager.unregisterNetworkCallback(connectivityCallback)取消注册,避免内存泄漏。
  • 若需区分WiFi/蜂窝网络类型,可通过NetworkCapabilities.hasTransport()方法在回调中判断。

内容的提问来源于stack exchange,提问作者Tobias Reich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 13:45:14