本文介绍了Android的 - 为什么ConnectivityManager.isActiveNetworkMetered总是(当无线连)返回true的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Android版我的音乐流媒体应用程序中,code路径下有助于基于由ConnectivityManager类实例返回值的高比特率流与较低的比特率之间的决定。

In my music streaming app for Android, the code path below helps decides between a high bitrate stream vs. a lower bitrate based on values returned by the ConnectivityManager class instance.

我试图理解为什么ConnectivityManager.isActiveNetworkMetered()将返回真,当它的明显,我在本地无线网络上。看看下面的Andr​​oid / Java的code:

I am trying to understand why ConnectivityManager.isActiveNetworkMetered() would return "true", when it's evident I'm on a local Wifi network. Take the following Android/Java code:

boolean isMetered = false;
boolean isWifi = false;
boolean isEthernet = false;
boolean isRoaming = false;
boolean isConnected = false;

NetworkInfo netinfo = connManager.getActiveNetworkInfo();
if (netinfo != null)
{
    isWifi = (netinfo.getType() == ConnectivityManager.TYPE_WIFI);
    isEthernet = (netinfo.getType() == ConnectivityManager.TYPE_ETHERNET);
    isRoaming = netinfo.isRoaming();
    isConnected = netinfo.isConnected();

    Log.d(TAG, "active network type = " + netinfo.getTypeName());
    Log.d(TAG, "active network subtype = " + netinfo.getSubtypeName());


    Log.d(TAG, "isConnected = " + isConnected);
    Log.d(TAG, "isWifi = " + isWifi);
    Log.d(TAG, "isEthernet = " + isEthernet);
    Log.d(TAG, "isRoaming = " + isRoaming);
}

// isActiveNetworkMetered was introduced in API 16 (Jelly Bean)
if (android.os.Build.VERSION.SDK_INT >= 16)
{
    isMetered = connManager.isActiveNetworkMetered();
    Log.d(TAG, "isMetered = " + isMetered);
}

当我有wifi关闭,我只能连接到AT& T公司的LTE网络,它打印出以下到日志控制台:

When I have Wifi turned off and my only connection is to AT&T's LTE network, it prints out the following to the log console:

active network type = mobile
active network subtype = LTE
isConnected = true
isWifi = false
isEthernet = false
isRoaming = false
isMetered = true

以上一切都符合预期 - 我是一个移动运营商的网络,是计量上

Everything above matches expectations - I'm on a mobile carrier network that is metered.

现在切换到我的家庭WiFi和code打印同一块这样的:

Now switch to my home Wifi and the same block of code prints this:

active network type = WIFI
active network subtype = 
isConnected = true
isWifi = true
isEthernet = false
isRoaming = false
isMetered = true

为什么 isMetered isActiveNetworkMetered ,仍然显示为真正的结果呢?这导致以下code路径青睐,即使我为我的家庭WiFi网络上的低比特率流:

Why is isMetered, the result of isActiveNetworkMetered, still showing as true? This is causing the following code path to favor the lower bitrate stream even though I'm on my home wifi network:

if ((isWifi || isEthernet) && !isMetered)
{
    result = BITRATE_HIGH_KBIT_SEC;
}
else
{
    result = BITRATE_LOW_KBIT_SEC;
}

如何isActiveNetworkMetered()决定是否在网络计量?这是部分WIFI谈判或在SSID广播一点?在网络上Android的设置?我无法找到我让我切换或者发现设置计量网络的Andr​​oid奇巧设备上的任何设置。

How does isActiveNetworkMetered() decide if the network is metered? Is this part of the WIFI negotiation or a bit in the SSID broadcast? A network setting on Android? I couldn't find any setting on my Android Kitkat device that let me toggle or discover the setting for a metered network.

上周,我在我的ISP(边境)给我发了一个新的WiFi路由器。可能有关系吗?我没有看到这样的设置路由器的固件页面的任何东西。

Last week I my ISP (Frontier) sent me a new Wifi router. Possibly related? I didn't see anything on the router's firmware pages for such a setting.

我会用工作后的今天来荡去看看它是如何表现的另一个网络上。在任何情况下,我可能会修改上面的code跳过计量检查,除非我能某处证明它只是一个不正确的设置。

I'm going to swing by work later today to see how it behaves on another network. In any case, I'm likely to edit the above code to skip the metered check unless I can prove its just an incorrect setting somewhere.

更新 - 问题总是返回计量网络对我的HTC One M8手机(运行奇巧)再现,却没有关于我的Nexus 7从2012年(也升级到Android 4.4奇巧)

UPDATE - issue of always returning metered network reproduces on my HTC One M8 phone (running Kitkat), but not on my Nexus 7 from 2012 (also upgraded to Android 4.4 Kitkat).

问题解决了 - 事实证明我的WiFi被举报我的手机作为一个移动热点。如何找到并切换这个标志是这里更多细节。

PROBLEM SOLVED - it turns out my Wifi was flagged by my phone as a "Mobile Hotspot". More details on how to find and toggle this flag is here.

推荐答案

我测试过这一点,但我观察了预期的结果:假的WiFi和真正的3G。这是一台Nexus 4与Android 4.4.2。

I've tested this too, but I'm observing the "expected" result: false for WiFi and true for 3G. This is in a Nexus 4 with Android 4.4.2.

奇怪的是在 ConnectivityManagerCompat 类在支持库的确实的返回false无线网络。

Curiously enough the ConnectivityManagerCompat class in the support library does return false for WiFi.

final int type = info.getType();
switch (type) {
    case TYPE_MOBILE:
        return true;
    case TYPE_WIFI:
        return false;
    default:
        // err on side of caution
        return true;
}

编辑 - 发现它(我认为)

NetworkPolicyManagerService 似乎是,最终产生的结果,这个方法的类。而且根据它的WiFi连接的确可以计量。它包含一个BroadcastReceiver是的听(S)支持WiFi状态变化捕捉计量提示的(线567)。此信息是从 NetworkInfo.getMeteredHint获得(),其中,仔细观察,包含了这个有趣的评论:

NetworkPolicyManagerService seems to be the class that ultimately produces the result for this method. And according to it, WiFi connections can indeed be metered. It contains a BroadcastReceiver that "listen(s) for wifi state changes to catch metered hint" (line 567). This information is obtained from NetworkInfo.getMeteredHint(), which, on closer inspection, contains this interesting comment:

/**
 * Flag indicating that AP has hinted that upstream connection is metered,
 * and sensitive to heavy data transfers.
 */
private boolean mMeteredHint;

该标志是由加载中国Dhc presults.hasMeteredHint()

/**
 * Test if this DHCP lease includes vendor hint that network link is
 * metered, and sensitive to heavy data transfers.
 */
public boolean hasMeteredHint() {
    if (vendorInfo != null) {
        return vendorInfo.contains("ANDROID_METERED");
    } else {
        return false;
    }
}

因此​​,它似乎的确,AP可以底层的网络连接是通过计量使用此标志通知其无线客户端。

So it would seem that, indeed, the AP may notify its WiFi clients that the underlying internet connection is metered by using this flag.

编辑#2 相关资料显示,从 HTTP:// WWW。 lorier.net/docs/android-metered

当Android手机是使用其他android手机的热点,它  知道这是一个计量连接,因此禁用  昂贵的同步选项(如:照片同步)。它是如何知道的呢?该  Android的热点发送DHCP选项43(供应商特定选项)与  值ANDROID_METERED。在客户端,如果它看到ANDROID_METERED  在选项43的值的任何地方,打开了昂贵的数据  连接选项。

貌似这个标志被添加到玩好与其它Android设备提供了一个热点。

Looks like this flag was added to "play nice" with a hotspot offered by another Android device.

编辑#3 的提交介绍了此功能:

连接计量D​​HCP暗示的Wi-Fi网络。

当DHCP租约包括供应商信息,表明远程无线网络  网络计量,劝NetworkPolicy。用户仍然可以手动  改变计量标志设置。

When DHCP lease includes vendor info indicating that remote Wi-Fi network is metered, advise NetworkPolicy. Users can still manually change the metered flag in Settings.

您可以通过访问该设置:

You can access this setting by going:

设置 - >数据用途 - >(溢出菜单) - >移动热点

这篇关于Android的 - 为什么ConnectivityManager.isActiveNetworkMetered总是(当无线连)返回true的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 01:04