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

如何检测Android已连接WiFi但无互联网连接的状态

Android平台可靠网络连接检测方案(适配Unity项目)

你的现有代码只判断了设备连接的网络传输类型(WiFi/蜂窝/以太网),但没有验证该网络是否真正能访问互联网——这就是为什么连接无网WiFi时会误判为CONNECTIVITY_WIFI的原因。

修复现有代码:加入互联网连通性验证

从Android API 23开始,NetworkCapabilities提供了两个关键能力来判断网络有效性:

  • NET_CAPABILITY_INTERNET:网络具备访问互联网的权限
  • NET_CAPABILITY_VALIDATED:系统已验证该网络可以实际访问互联网(比如通过网关检测、DNS解析等)

修改后的代码如下:

// for Build.VERSION.SDK_INT > 23
int connectionType = NO_CONNECTIVITY;

Network[] networksList = connectivityManager.getAllNetworks();
int len = networksList.length;

if(len == 0) {
    return NO_CONNECTIVITY;
}

for(Network network : networksList) {
    NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
    if(networkCapabilities == null) {
        continue;
    }

    // 先验证网络是否具备有效互联网访问能力
    boolean hasValidInternet = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
    
    if(!hasValidInternet) {
        continue; // 跳过无有效互联网的网络
    }

    // 再判断网络传输类型,优先级:以太网 > WiFi > 蜂窝
    if(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
        connectionType = CONNECTIVITY_ETHERNET;
        break; // 以太网优先级最高,直接跳出循环
    } else if(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
            && !networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
        connectionType = CONNECTIVITY_WIFI;
    } else if(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
        if(connectionType != CONNECTIVITY_WIFI) {
            connectionType = CONNECTIVITY_CELLULAR;
        }
    }
}

return connectionType;

其他可行的Android原生方案

1. 使用NetworkCallback实时监听网络状态

主动轮询不如监听网络状态变化高效,你可以注册ConnectivityManager.NetworkCallback,在网络连接、断开或验证状态变化时收到回调:

ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        // 网络可用,可在此验证有效性并更新状态
        NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
        boolean isValid = capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
        if(isValid) {
            // 更新为有效连接状态
        }
    }

    @Override
    public void onLost(Network network) {
        // 网络断开,更新为无连接状态
    }

    @Override
    public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
        // 网络能力变化,重新验证有效性
        boolean isValid = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
        // 更新状态
    }
};

// 注册回调
connectivityManager.registerNetworkCallback(
    new NetworkRequest.Builder()
        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        .build(),
    networkCallback
);

2. 轻量级网络探测(极端场景兜底)

如果某些特殊网络环境下NET_CAPABILITY_VALIDATED不准确(比如企业内网、特殊代理环境),可以发起一个HEAD请求到一个稳定的、资源极小的端点(比如自己服务器的空接口,或公共的静态资源),避免使用ping(ping可能被防火墙拦截)。示例:

private boolean isInternetAvailable() {
    try {
        HttpURLConnection urlConnection = (HttpURLConnection) new URL("https://your-server.com/ping").openConnection();
        urlConnection.setRequestMethod("HEAD");
        urlConnection.setConnectTimeout(1000); // 1秒超时
        urlConnection.setReadTimeout(1000);
        return urlConnection.getResponseCode() == 200;
    } catch (Exception e) {
        return false;
    }
}

注意:要在子线程执行此操作,避免阻塞UI线程;同时需要申请INTERNET权限。

适配Unity的建议

将修改后的Android代码打包成AAR包,在Unity项目中通过AndroidJavaClass或AndroidJavaObject调用原生方法,实现跨平台的网络检测逻辑(后续iOS平台可类似实现原生检测)。

内容的提问来源于stack exchange,提问作者Isma Rekathakusuma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 15:05:21