(我认为这是一个常见问题,但请不要太快,因为我相信我的答案会为讨论添加一些新内容.)
相关的API是TrafficStats,它从例如/ proc/uid_stat /获取其数据.
统计数据必须包括GCM等,而不仅仅是我发起的内容,因此基于线程和标记的计数器是不够的.
第一个问题是基于UID(即每个应用程序)获得移动数据使用的API显然不存在.有getMobile API和getUid API,但没有任何组合它们.我提出了一个解决方案,作为下面的一个答案.
更重要的是,我得到的印象是TrafficStats有太多的bug可用于这个通用目的.我把它作为一个可能的答案,如果这被接受,那么最好的解决方案是手动计算数据使用量.
我已经搜索了很多关于这一点.在任何地方找到相同的代码,部分地解决了目的.正如API文档所述,它会在设备重启后重置计数器.有时,即使没有重启,计数器也会重置.下面是代码
float totalRxBytes = (float)TrafficStats.getTotalRxBytes()/(float)1048576; // Received
float totalTxBytes = (float)TrafficStats.getTotalTxBytes()/(float)1048576; // Sent
float mobRxBytes = (float)TrafficStats.getMobileRxBytes()/(float)1048576;
float mobTxBytes = (float)TrafficStats.getMobileTxBytes()/(float)1048576;
float wifiRxBytes = totalRxBytes - mobRxBytes;
float wifiTxBytes = totalTxBytes - mobTxBytes;
Run Code Online (Sandbox Code Playgroud)
但我无法想出任何方式从特定日期或一个月获得这些数据?请帮忙.任何指针将不胜感激.谢谢.
我写了一个小小的android应用程序,发送Http请求,从服务器接收响应,并计算了发送和接收的字节数。代码简单如下
long receivedBytes = TrafficStats.getUidRxBytes(uid)-lastNumer
Run Code Online (Sandbox Code Playgroud)
我发现ReceivedBytes总是大于http Header + http Body,例如我在服务器中捕获(使用wireshark)的实际http帧大小为1645 bytes(header + body),但是android API返回的receiveBytes为1912,因此作为传输。
TrafficStats getUidRxBytes本身不准确(可能是此问题特定于我的带有cynogenmod 10.3的平台i9300)
最后,我找到了计算数据使用量的正确方法,我发现了其他方法来计算数据使用量,这似乎比TrafficStats API更准确。(非常感谢here)
private long[] getStat() {
String line, line2;
long[] stats = new long[2];
try {
File fileSnd = new File("/proc/uid_stat/"+uid+"/tcp_snd");
File fileRcv = new File ("/proc/uid_stat/"+uid+"/tcp_rcv");
BufferedReader br1 = new BufferedReader(new FileReader(fileSnd));
BufferedReader br2 = new BufferedReader(new FileReader(fileRcv));
while ((line = br1.readLine()) != null&& (line2 = br2.readLine()) != null) {
stats[0] = Long.parseLong(line);
stats[1] = Long.parseLong(line2);
}
br1.close();
br2.close();
} …Run Code Online (Sandbox Code Playgroud)