通过 android.net.NetworkCapabilities 上网检查不工作

Posted

技术标签:

【中文标题】通过 android.net.NetworkCapabilities 上网检查不工作【英文标题】:Internet check over android.net.NetworkCapabilities not working 【发布时间】:2016-07-21 09:21:56 【问题描述】:

我有一个关于android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET 的问题。根据 JavaDocs,这“表明该网络应该能够访问互联网”。

不幸的是,这似乎无法正常工作 - 或者我在这里做错了什么。我输出了三种不同 Wi-Fi 网络的能力值:

    可以访问互联网的 Wi-Fi。

    没有互联网接入的 Wi-Fi(我在这里手动禁用了互联网)。

    公共热点(“Telekom”热点)

在所有三种情况下,功能值都是[ Transports: WIFI Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_*** LinkUpBandwidth>=1048576Kbps LinkDnBandwidth>=1048576Kbps]

这是我的代码:

ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
boolean capability = capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET

与某些 Wi-Fi 连接时,布尔值始终为 true

如果相关,我测试的设备在 Android 5.0.1 (API 21) 下运行。我将应用程序编译到 API 级别 23。

【问题讨论】:

为什么这个值会是假的? 如果 Wi-Fi 不提供互联网,我会期待NO_INTERNET 的功能。但即使没有提供互联网,也会设置功能INTERNET 所以你想知道wifi网络是否连接到互联网? 是的,但我不想为此进行 ping。我想使用 Android 的内置检查。 3年后这仍然无法正常工作,真是太遗憾了,有没有人有任何解决方案?除了ping 【参考方案1】:

对于具有 API 23+ 的设备,您可以检查标志 NET_CAPABILITY_VALIDATED

@RequiresApi(api = Build.VERSION_CODES.M)
private static boolean hasInternetConnectionM(final Context context) 
    final ConnectivityManager connectivityManager = (ConnectivityManager)context.
            getSystemService(Context.CONNECTIVITY_SERVICE);

    final Network network = connectivityManager.getActiveNetwork();
    final NetworkCapabilities capabilities = connectivityManager
            .getNetworkCapabilities(network);

    return capabilities != null
            && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);

我在不同的设备上检查它,它工作正常。除了小米 Redmi 3S MIUI 8 - 它返回 NET_CAPABILITY_VALIDATED 用于没有互联网访问的 Wi-Fi。

对于 API

【讨论】:

capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) 在 Android Wear API 26 模拟器上返回 true,即使没有 Internet 连接也是如此。有没有办法解决这个问题? 当您从 wifi 切换到移动数据连接时,这无法正常工作 @Ultimo_m 我正在使用 NetworkCapabilities.TRANSPORT_CELLULAR 类型检查,然后它就可以工作了 这种方法似乎在模拟器上可靠地工作,即使坐在公司代理后面。如果代理需要重新登录,此代码将检测问题并返回 false。不过,当这种情况发生时,我观察到了一些延迟。所以,当系统认为有互联网,但实际上没有时,会有一点时间窗口。据我所知,如果您需要尽快了解 Internet 连接,那么根据我的观察,我建议您尝试检查与给定 IP(例如 8.8.8.8)的套接字连接是否可行. 在 Pixel 3 上检查了这一点,也有 NET_CAPABILITY_VALIDATED 但网络请求失败【参考方案2】:

不幸的是,您不能依赖 NET_CAPABILITY_INTERNET && NET_CAPABILITY_VALIDATED,您只需关闭 wifi 路由器上的互联网(通过电缆或以编程方式)并检查 - 即使经过很长时间的延迟,这两个参数都会正确。

【讨论】:

以上是关于通过 android.net.NetworkCapabilities 上网检查不工作的主要内容,如果未能解决你的问题,请参考以下文章

下拉框多选框单选框 通过TagHelper绑定数据

酶:测试孩子通过安装渲染失败,但通过浅时通过

java是通过值传递,也就是通过拷贝传递——通过方法操作不同类型的变量加深理解

通过代码进行 Spring 配置与通过注释进行配置

如何理解“不要通过共享内存来通信,而应该通过通信来共享内存”?

通过邮递员通过 API 使用 Rails 主动存储上传文件(.pdf、.jpg 等)? (不通过 Rails 视图)