Android流量统计
项目中需要对Android设备进行流量统计来进行资费结算,所以对Android设备流量统计进行了一些调研。发现流量统计主流上有两种方式
- 使用系统统计类TrafficStats获取
- 通过系统文件解析读取
TrafficStats
- static long getMobileRxBytes() //获取通过Mobile连接收到的字节总数,不包含WiFi
- static long getMobileRxPackets() //获取Mobile连接收到的数据包总数
- static long getMobileTxBytes() //Mobile发送的总字节数
- static long getMobileTxPackets() //Mobile发送的总数据包数
- static long getTotalRxBytes() //获取总的接受字节数,包含Mobile和WiFi等
- static long getTotalRxPackets() //总的接受数据包数,包含Mobile和WiFi等
- static long getTotalTxBytes() //总的发送字节数,包含Mobile和WiFi等
- static long getTotalTxPackets() //发送的总数据包数,包含Mobile和WiFi等
- static long getUidRxBytes(int uid) //获取某个网络UID的接受字节数
- static long getUidTxBytes(int uid) //获取某个网络UID的发送字节数
这些方法 获取到的流量数据都是从手机上次开机到当前的流量使用情况,这个没关系,我们可以监听手机的开机和关机。关机的时候(或者每间隔一段时间) 将数据都存储起来,下次开机后通过以上方法获取到的数据在叠加上.
但是这些方法里面,只能我发现在这些方法里,缺少我最需要的那个方法,我想获取某个app接受和发送的2G/3G流量,不包含wifi,这些API无法满足该需求。
于是乎,便从系统文件的解析上着手吧
/proc/net/xt_qtaguid/stats格式
/proc/net/xt_qtaguid/stats内包含着各个app使用流量的情况,先来简单看一下这个文件的内容
这输出内容整体是一个表结构,首先我们需要看一下表中各列字段代表什么
- idx : 序号
- iface : 代表流量类型(rmnet表示2G/3G, wlan表示Wifi流量,lo表示本地流量)
- acct_tag_hex :线程标记(用于区分单个应用内不同模块/线程的流量)
- uid_tag_int : 应用uid,据此判断是否是某应用统计的流量数据
- cnt_set : 应用前后标志位:1:前台, 0:后台
- rx_btyes : receive bytes 接受到的字节数
- rx_packets : 接收到的任务包数
- tx_bytes : transmit bytes 发送的总字节数
- tx_packets : 发送的总包数
- rx_tcp_types : 接收到的tcp字节数
- rx_tcp_packets : 接收到的tcp包数
- rx_udp_bytes : 接收到的udp字节数
- rx_udp_packets : 接收到的udp包数
- rx_other_bytes : 接收到的其他类型字节数
- rx_other_packets : 接收到的其他类型包数
- tx_tcp_bytes : 发送的tcp字节数
- tx_tcp_packets : 发送的tcp包数
- tx_udp_bytes : 发送的udp字节数
- tx_udp_packets : 发送的udp包数
- tx_other_bytes : 发送的其他类型字节数
- tx_other_packets : 发送的其他类型包数
可以看到,用文件解析的方式获取流量可以获得比直接使用acct_tag_hex要丰富的多的信息,包括区分WIFI和移动网络,区分应用内不同模块功能流量,前后台流量等。
使用shell命令来查看进程流量
接下来说明下uid_tag_int这个字段
pid:Processid(进程id)
获取pid的shell命令:
grep com.car.tencent
- uid:每个应用程序一个uid(如果一个app拥有两个进程,则有两个不同pid,但两个pid对应的uid是相同的)
根据pid获取uid
adb shell cat /proc/1643/status
- 根据uid获取流量
adb shell cat /proc/net/xt_qtaguid/stats | grep uid
如何使用代码解析/proc/net/xt_qtaguid/stats文件
static const char *QTAGUID_UID_STATS = "/proc/net/xt_qtaguid/stats";struct Stats {uint64_t rxBytes;uint64_t rxPackets;uint64_t txBytes;uint64_t txPackets;uint64_t tcpRxPackets;uint64_t tcpTxPackets;
};static int parseUidStats(const uint32_t uid, struct Stats *stats) {FILE *fp = fopen(QTAGUID_UID_STATS, "r");if (fp == NULL) {return -1;}char buffer[384];char iface[32];uint32_t idx, cur_uid, set;uint64_t tag, rxBytes, rxPackets, txBytes, txPackets;while (fgets(buffer, sizeof(buffer), fp) != NULL) {if (sscanf(buffer,"%" SCNu32 " %31s 0x%" SCNx64 " %u %u %" SCNu64 " %" SCNu64" %" SCNu64 " %" SCNu64 "",&idx, iface, &tag, &cur_uid, &set, &rxBytes, &rxPackets,&txBytes, &txPackets) == 9) {//绕过本地回环地址if (strcmp(iface, "lo") && uid == cur_uid && tag == 0L) {stats->rxBytes += rxBytes;stats->rxPackets += rxPackets;stats->txBytes += txBytes;stats->txPackets += txPackets;}}}if (fclose(fp) != 0) {return -1;}return 0;
}static jlong getUidStat(JNIEnv *env, jclass clazz, jint uid, jint type) {struct Stats stats;memset(&stats, 0, sizeof(Stats));if (parseUidStats(uid, &stats) == 0) {return getStatsType(&stats, (StatsType) type);} else {return UNKNOWN;}
}
这段代码里面,需要注意的点是如何忽略本地回环流量
if (strcmp(iface, "lo") && uid == cur_uid && tag == 0L) {
因为iface是网络类型,一共只有三个类型,rmnet表示2G/3G, wlan表示Wifi流量,lo表示本地流量。所以这里直接使用了字符串比对的方式。
扩展
- /proc/net/xt_qtaguid/iface_stat_fmt:该文件中已经按照类型统计出了不同类型网络数据的总数,因此获取当前设备的总接受字节数等设备级统计信息,直接分析该文件,能最快获取结果
- /proc/net/xt_qtaguid/stats:该文件中则是按照uid进行了分类,适合于做更细力度(应用级/线程级)的分析
附录:
- 博客原地址:https://chchaooo.github.io/2018/06/13/Android%E6%B5%81%E9%87%8F%E7%BB%9F%E8%AE%A1/
- 如果有问题交流请移步:https://www.cnblogs.com/weilf/p/9180373.html
参考资料:
- Android流量优化(一):模块化流量统计
- Android性能测试之网络流量
转载于:https://www.cnblogs.com/weilf/p/9180373.html
Android流量统计相关推荐
- Android流量统计TrafficStats类
对于Android流量统计来说在2.2版中新加入了TrafficStats类可以轻松获取,其实本身TrafficStats类也是读取Linux提供的文件对象系统类型的文本进行解析. android.n ...
- android 双卡流量统计,android流量统计
android流量统计 (2012-07-31 12:28:34) 标签: 杂谈 研究过一段时间的android流量统计 发个自己的总结帖 1 android有一个TrafficStats类可以直接获 ...
- android页面统计代码,android流量统计(示例代码)
android.net.TrafficStats类中,提供了多种静态方法,可以直接调用获取,返回类型均为long型,如果返回等于-1代表 UNSUPPORTED 当前设备不支持统计. static l ...
- android 流量统计工具,Android 统计应用流量的使用情况
Android 获取应用流量的使用情况有两种方法 TrafficStats NetworkStatsManager 是Android 6.0(API23)中新增加的类 这次我们使用的是第二种方法,记录 ...
- android 流量统计
由于自己手机每月只有100M流量 最近总是不够用 所以 想研究一下android的流量统计 这样的话就能随时了解自己使用流量的记录 之初也咨询了一些朋友 发现研究这方面的人比较少 在网上也搜罗 ...
- android 流量统计助手,流量统计 My Data Manager v7.3.1
更新时间:2017-02-19 资费提示:免费版 当前版本:7.3.1 软件语言:中文 软件类别:计费统计 软件大小:7.24 MB 适用固件:2.2及更高固件 内置广告:没有广告 开发商:Mobid ...
- android 流量统计换算,iOS 统计流量信息(转)
在开发中,有时候需要获取流量统计信息.研究发现:通过函数getifaddrs来得到系统网络接口的信息,网络接口的信息,包含在if_data字段中, 有很多信息, 但我现在只关心ifi_ibytes, ...
- android 流量统计不准确_汽车里程表上显示的百公里油耗准确吗?是不是真的是欢乐表...
汽车表显油耗准不准需要根据不同的实际工况来确定,如果是长期保持匀速行驶状态,那么表显油耗更接近实际油耗,但如果是混合工况下.走走停停,那么表现油耗就没准了,而这个时候表显油耗会比实际油耗低,所以表现油 ...
- android 流量统计换算,什么是流量?如何计算流量?流量的单位如何换算
什么是流量?如何计算流量?流量的单位如何换算 上网流量通常用"位"(bit),"字节"(Byte),KB,MB,GB,TB等来表示.它是计算机信息技术用于计量存 ...
最新文章
- c java 的关系,c#与c、java的关系
- python将图像转换为8位单通道_Python OpenCV读取16位单通道图像并转换为8位灰度图显示...
- 关于window对象
- WPF 基础控件之 DataGrid 样式
- Matlab 7.1安装及打不开问题解决
- 文本识别新王者CharNet:卷积字符网络
- mvc+EF实现简单的登陆功能
- 脏写 脏读 不可重复读 幻读 读偏差 写偏差 丢失更新 示例
- java map原理_Java中的HashMap的工作原理是什么?
- 网页交互式MATLAB入门教程
- ASP程序部署在IIS上的步骤
- matlab卷积动画实现
- 用计算机制作flash动画教案,最新最完整Flash动画制作教案.doc
- Linux共享文件夹
- 计算机二级九月试题office,9月计算机二级office题库及答案
- Ubuntu 快捷截图
- 生活中的逻辑谬误02.稻草人谬误
- 捷径 播报日期、时间、星期
- 我的团长我的团第二十四集
- 艹,我竟然找到了克服「微信提示音」焦虑症的方法
热门文章
- 使用PDF24 将mathmatica 的.nb文件转化为PDF文档
- 微医与友邦中国战略合作,智能医务室为职员健康护航
- 互联网医疗泡沫破灭,一场从线上回归线下的技术圈地运动?
- Python silk 库 支持微信语音
- On persistence in mutual fund performance 1997翻译
- tensorflow实现对图片的读取(tf.image.decode_jepg和tf.image.decode_png)
- 多米诺骨牌java_通过递归和回溯找到所有可能的多米诺骨牌链
- 为什么要做访问学者?
- ESP8266 AT指令设置及51单片机的控制
- python之简介及入门