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

如何判断设备WiFi/移动网络连接状态?连接中如何触发ProgressBar显示?

嘿,这个问题我之前帮好几个开发者捋清楚过,核心就是要精准监听网络状态的整个生命周期——从开始连接到真正能访问互联网的全过程,而不只是简单判断“有没有网络”。下面分平台给你具体的实现思路:

一、核心逻辑拆解

首先得明确两个关键状态的区别:

  • 连接中:设备正在和WiFi接入点/移动基站建立链路(比如用户刚点开WiFi按钮后的2-3秒),这时候系统还没确认网络可用,但已经处于连接流程中。
  • 已联网:设备不仅和接入点连通,还能真正访问互联网(这时候你的按钮才该启用)。

所以我们需要两步走:先监听系统的网络连接状态变化捕捉「连接中」,再主动验证互联网连通性确认「真能上网」。

二、Android平台具体实现

1. 监听网络连接状态(捕捉「连接中」)

用ConnectivityManager.NetworkCallback可以精准监听网络从无到有、连接中、已连接的全流程:

val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

val networkCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        super.onAvailable(network)
        // 设备刚和接入点建立连接,但还不确定能不能上网
        showProgressBar(true) // 显示加载框
        checkInternetAccess() // 立刻验证互联网连通性
    }

    override fun onLosing(network: Network, maxMsToLive: Int) {
        super.onLosing(network, maxMsToLive)
        // 网络正在断开,更新UI
        disableFetchButton()
        showProgressBar(false)
    }

    override fun onUnavailable() {
        super.onUnavailable()
        // 完全无网络,禁用按钮
        disableFetchButton()
        showProgressBar(false)
    }
}

// 注册回调(记得在页面销毁时调用unregisterNetworkCallback避免泄漏)
connectivityManager.registerDefaultNetworkCallback(networkCallback)

另外,用户手动点击WiFi按钮时,可以先主动显示ProgressBar,不用等系统回调:

wifiToggleButton.setOnClickListener {
    showProgressBar(true)
}

2. 验证互联网连通性(确认「真能上网」)

系统提示网络可用后,必须主动发一个轻量级请求验证——因为有时候设备和WiFi连好了,但路由器没联网,这时候还是拿不到后端数据:

private fun checkInternetAccess() {
    CoroutineScope(Dispatchers.IO).launch {
        val isOnline = try {
            // 优先用你的后端健康检查接口(比如返回200的空接口),比公共节点更靠谱
            val url = URL("https://your-backend.com/health")
            val connection = url.openConnection() as HttpURLConnection
            connection.connectTimeout = 3000
            connection.readTimeout = 3000
            connection.responseCode == HttpURLConnection.HTTP_OK
        } catch (e: Exception) {
            false
        }

        // 切回主线程更新UI
        withContext(Dispatchers.Main) {
            showProgressBar(false)
            if (isOnline) {
                enableFetchButton() // 能上网,启用按钮
            } else {
                disableFetchButton()
                Toast.makeText(this@YourActivity, "网络已连接但无法访问服务器", Toast.LENGTH_SHORT).show()
            }
        }
    }
}
三、iOS平台思路补充

iOS上用NWPathMonitor监听网络状态,逻辑和Android一致:

let networkMonitor = NWPathMonitor()
networkMonitor.pathUpdateHandler = { path in
    DispatchQueue.main.async {
        switch path.status {
        case .requiresConnection:
            // 正在连接中,显示加载框
            self.showProgressBar(true)
            self.disableFetchButton()
        case .satisfied:
            // 链路可用,验证互联网
            self.showProgressBar(true)
            self.checkInternetAccess()
        default:
            // 无网络
            self.disableFetchButton()
            self.showProgressBar(false)
        }
    }
}

// 启动监听(记得在页面销毁时调用networkMonitor.cancel())
let queue = DispatchQueue(label: "NetworkMonitorQueue")
networkMonitor.start(queue: queue)

验证互联网的方法类似,用URLSession发起一个简单请求即可。

四、注意事项
  • 权限:Android需要ACCESS_NETWORK_STATE和INTERNET权限;iOS无需额外权限,但要注意ATS配置。
  • 避免频繁请求:验证用的接口要尽量轻量(比如只返回状态码),不要请求大资源。
  • 内存泄漏:页面销毁时一定要注销网络监听回调,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Lilian Sorlanski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:20:24