项目中需要对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流量统计相关推荐

  1. Android流量统计TrafficStats类

    对于Android流量统计来说在2.2版中新加入了TrafficStats类可以轻松获取,其实本身TrafficStats类也是读取Linux提供的文件对象系统类型的文本进行解析. android.n ...

  2. android 双卡流量统计,android流量统计

    android流量统计 (2012-07-31 12:28:34) 标签: 杂谈 研究过一段时间的android流量统计 发个自己的总结帖 1 android有一个TrafficStats类可以直接获 ...

  3. android页面统计代码,android流量统计(示例代码)

    android.net.TrafficStats类中,提供了多种静态方法,可以直接调用获取,返回类型均为long型,如果返回等于-1代表 UNSUPPORTED 当前设备不支持统计. static l ...

  4. android 流量统计工具,Android 统计应用流量的使用情况

    Android 获取应用流量的使用情况有两种方法 TrafficStats NetworkStatsManager 是Android 6.0(API23)中新增加的类 这次我们使用的是第二种方法,记录 ...

  5. android 流量统计

    由于自己手机每月只有100M流量  最近总是不够用  所以 想研究一下android的流量统计  这样的话就能随时了解自己使用流量的记录 之初也咨询了一些朋友  发现研究这方面的人比较少 在网上也搜罗 ...

  6. android 流量统计助手,流量统计 My Data Manager v7.3.1

    更新时间:2017-02-19 资费提示:免费版 当前版本:7.3.1 软件语言:中文 软件类别:计费统计 软件大小:7.24 MB 适用固件:2.2及更高固件 内置广告:没有广告 开发商:Mobid ...

  7. android 流量统计换算,iOS 统计流量信息(转)

    在开发中,有时候需要获取流量统计信息.研究发现:通过函数getifaddrs来得到系统网络接口的信息,网络接口的信息,包含在if_data字段中, 有很多信息, 但我现在只关心ifi_ibytes, ...

  8. android 流量统计不准确_汽车里程表上显示的百公里油耗准确吗?是不是真的是欢乐表...

    汽车表显油耗准不准需要根据不同的实际工况来确定,如果是长期保持匀速行驶状态,那么表显油耗更接近实际油耗,但如果是混合工况下.走走停停,那么表现油耗就没准了,而这个时候表显油耗会比实际油耗低,所以表现油 ...

  9. android 流量统计换算,什么是流量?如何计算流量?流量的单位如何换算

    什么是流量?如何计算流量?流量的单位如何换算 上网流量通常用"位"(bit),"字节"(Byte),KB,MB,GB,TB等来表示.它是计算机信息技术用于计量存 ...

最新文章

  1. c java 的关系,c#与c、java的关系
  2. python将图像转换为8位单通道_Python OpenCV读取16位单通道图像并转换为8位灰度图显示...
  3. 关于window对象
  4. WPF 基础控件之 DataGrid 样式
  5. Matlab 7.1安装及打不开问题解决
  6. 文本识别新王者CharNet:卷积字符网络
  7. mvc+EF实现简单的登陆功能
  8. 脏写 脏读 不可重复读 幻读 读偏差 写偏差 丢失更新 示例
  9. java map原理_Java中的HashMap的工作原理是什么?
  10. 网页交互式MATLAB入门教程
  11. ASP程序部署在IIS上的步骤
  12. matlab卷积动画实现
  13. 用计算机制作flash动画教案,最新最完整Flash动画制作教案.doc
  14. Linux共享文件夹
  15. 计算机二级九月试题office,9月计算机二级office题库及答案
  16. Ubuntu 快捷截图
  17. 生活中的逻辑谬误02.稻草人谬误
  18. 捷径 播报日期、时间、星期
  19. 我的团长我的团第二十四集
  20. 艹,我竟然找到了克服「微信提示音」焦虑症的方法

热门文章

  1. 使用PDF24 将mathmatica 的.nb文件转化为PDF文档
  2. 微医与友邦中国战略合作,智能医务室为职员健康护航
  3. 互联网医疗泡沫破灭,一场从线上回归线下的技术圈地运动?
  4. Python silk 库 支持微信语音
  5. On persistence in mutual fund performance 1997翻译
  6. tensorflow实现对图片的读取(tf.image.decode_jepg和tf.image.decode_png)
  7. 多米诺骨牌java_通过递归和回溯找到所有可能的多米诺骨牌链
  8. 为什么要做访问学者?
  9. ESP8266 AT指令设置及51单片机的控制
  10. python之简介及入门