Android NetworkStats.Bucket数据不更新问题咨询
嘿,我之前帮朋友排查过类似的问题,Android 8+上用NetworkStats确实有不少坑,你遇到的“数据始终不变”大概率是这几个原因之一,咱们一步步来捋:
首先,最容易踩的坑:权限没真正拿到
你说申请了运行时权限,但PACKAGE_USAGE_STATS这个权限和普通的读写权限不一样,它不能通过常规的requestPermissions()弹窗申请,必须引导用户手动去系统设置里开启“使用情况访问权限”。
你可以先检查自己的权限状态:
AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE); int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), getPackageName()); boolean hasValidPermission = mode == AppOpsManager.MODE_ALLOWED;
如果返回false,就得引导用户去开启:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivity(intent);
很多人以为申请了权限就完事了,其实这个权限是需要用户手动授权的,这是最常见的原因。
其次,检查你的查询参数是否正确
1. 目标应用的UID是否获取正确
你要监控的是YouTube(com.google.android.youtube),不能硬编码UID,得通过包名动态查询:
PackageManager pm = getPackageManager(); try { ApplicationInfo appInfo = pm.getApplicationInfo("com.google.android.youtube", 0); int targetUid = appInfo.uid; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); }
如果UID错了,查出来的自然不是YouTube的流量数据。
2. 是否区分了网络类型
你测试时看YouTube用的是Wi-Fi还是移动网络?如果代码里只查询了移动网络(TelephonyManager.NETWORK_TYPE_MOBILE),但实际用的是Wi-Fi,那数据肯定不会变。Android 8+推荐用NetworkCapabilities的常量来指定网络类型:
- Wi-Fi:
NetworkCapabilities.TRANSPORT_WIFI - 移动网络:
NetworkCapabilities.TRANSPORT_CELLULAR
查询时要对应上你实际使用的网络类型,比如查Wi-Fi的流量:
long endTime = System.currentTimeMillis(); long startTime = endTime - 3600 * 1000; // 查过去1小时的数据 NetworkStats stats = networkStatsManager.querySummary( NetworkCapabilities.TRANSPORT_WIFI, "", // Wi-Fi的subscriberId传空即可 startTime, endTime );
3. 时间段参数是否合理
如果你的起始时间设成了固定值(比如写死的某个时间戳),而不是动态计算的“当前时间-测试时长”,那可能每次都查的是同一个时间段的数据,自然不会变。一定要确保startTime和endTime是动态更新的。
然后,确认系统本身的统计是否更新
先去系统设置的「流量使用情况」里找到YouTube,看看它的流量数据有没有变化:
- 如果系统里的数据也没更新,那可能是厂商定制系统的问题(比如某些国产ROM会延迟流量统计的刷新),或者系统的Bucket刷新机制没触发(比如设备没充电、处于低功耗模式等)。
- 如果系统里的数据更新了,但你的代码查不到,那肯定是查询逻辑有问题,再回头检查参数和权限。
最后,特殊情况:厂商定制系统的坑
有些国内厂商会修改Android原生的流量统计逻辑,导致NetworkStats的数据更新不及时甚至不准确。如果前面的排查都没问题,你可以试试:
- 重启设备后再测试,有时候系统缓存会导致数据不更新;
- 避开低功耗模式,某些设备在低功耗下会暂停流量统计;
- 实在不行的话,可以考虑通过AccessibilityService读取系统设置里的流量数据,但这种方式稳定性差,只能作为备选。
内容的提问来源于stack exchange,提问作者Gomez

