在我的Android音乐流媒体应用中,下面的代码路径有助于根据ConnectivityManager类实例返回的值在高比特率流与较低比特率之间做出决定。
我试图理解为什么ConnectivityManager.isActiveNetworkMetered()会返回“true”,这显然是我在本地Wifi网络上。请使用以下Android / Java代码:
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网络时,它将以下内容打印到日志控制台:
active network type = mobile
active network subtype = LTE
isConnected = true
isWifi = false
isEthernet = false
isRoaming = false
isMetered = true
以上所有内容都符合预期 - 我正在计量的移动运营商网络上。
现在切换到我的家庭Wifi,同样的代码块打印出来:
active network type = WIFI
active network subtype =
isConnected = true
isWifi = true
isEthernet = false
isRoaming = false
isMetered = true
为什么isMetered
isActiveNetworkMetered
的结果仍然显示为 true ?这导致以下代码路径支持较低比特率的流,即使我在我的家庭wifi网络上:
if ((isWifi || isEthernet) && !isMetered)
{
result = BITRATE_HIGH_KBIT_SEC;
}
else
{
result = BITRATE_LOW_KBIT_SEC;
}
isActiveNetworkMetered()如何决定网络是否计量?这是WIFI协商的一部分还是SSID广播中的一部分? Android上的网络设置?我在Android Kitkat设备上找不到任何设置,让我可以切换或发现计量网络的设置。
上周我的ISP(Frontier)发给我一个新的Wifi路由器。可能相关?对于这样的设置,我没有在路由器的固件页面上看到任何内容。
我将在今天晚些时候开始工作,看看它在另一个网络上的表现如何。在任何情况下,我都可能编辑上面的代码以跳过计量检查,除非我能在某处证明它只是一个不正确的设置。
更新 - 我的HTC One M8手机(运行Kitkat)总是返回计量网络的问题,但2012年我的Nexus 7没有(也升级到Android 4.4 Kitkat)。
问题已解决 - 事实证明我的Wifi被我的手机标记为“移动热点”。有关如何查找和切换此标志的更多详细信息是here。
答案 0 :(得分:14)
我也测试了这个,但我观察到了“预期的”结果:WiFi为假,3G为真。这是在Android 4.4.2的Nexus 4中。
奇怪的是,支持库中的ConnectivityManagerCompat
class 为WiFi返回false。
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,“监听wifi状态更改以捕获计量提示”(第567行)。此信息来自NetworkInfo.getMeteredHint()
,经过仔细检查后,其中包含此有趣的评论:
/**
* Flag indicating that AP has hinted that upstream connection is metered,
* and sensitive to heavy data transfers.
*/
private boolean mMeteredHint;
此标志从DhcpResults.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确实可以通过使用此标志通知其WiFi客户端计量基础互联网连接。
编辑#2 来自http://www.lorier.net/docs/android-metered
的相关信息当Android手机正在使用另一个Android手机的热点时,它 知道它是在“计量连接”上,因此禁用了 昂贵的同步选项(例如:照片同步)。怎么知道这个?该 android hotspot发送DHCP Option 43(Vendor specific options) 值ANDROID_METERED。客户端,如果它看到ANDROID_METERED 在选项43值的任何地方,打开“昂贵的数据 连接“选项。
看起来这个标志被添加到另一个Android设备提供的热点“玩得很好”。
编辑#3 commit that introduced this feature:
连接针对Wi-Fi网络的计量DHCP提示。
当DHCP租约包含指示远程Wi-Fi的供应商信息时 网络计量,建议NetworkPolicy。用户仍然可以手动 更改“设置”中的计量标志。
您可以通过以下方式访问此设置:
设置 - >数据使用 - > (溢出菜单) - >移动热点