Android应用流量统计——NetworkStatsManager使用

在没有Root的情况下,Android应用流量统计在6.0之前一直没有太好的办法,官方虽然提供了TrafficStats,但其主要功能是设备启动以来流量的统计信息,和时间信息无法很好的配合。最近再看TrafficStats类时,发现说明中提到,为获取更具鲁棒性的网络历史数据,建议使用NetworkStatsManager。

本文首先简单对比下TrafficStats和NetworkStatsManager各自的限制和优缺点,然后详细说明NetworkStatsManager的用法,并给出主要代码。

TrafficStats

Android API8提供了android.net.TrafficStats类。
通过此类能获取设备重启以来网络信息,部分函数如下所示:

static long  getMobileRxBytes()  //获取通过移动数据网络收到的字节总数
static long  getMobileTxBytes()  //通过移动数据网发送的总字节数  
static long  getTotalRxBytes()  //获取设备总的接收字节数 
static long  getTotalTxBytes()  //获取设备总的发送字节数
static long  getUidRxBytes(int uid)  //获取指定uid的接收字节数  
static long  getUidTxBytes(int uid) //获取指定uid的发送字节数 

通过文档及上述函数可以知道,TrafficStats能够获取设备的数据流量和总的网络流量消耗(一般情况下也就得到Wi-Fi下的流量信息);可以查询uid对应的流量信息,而uid可以通过应用的包名查询到,因此能够查询某个应用的流量统计信息(不考虑shareuid)。非常方便的是,它的使用不需要特别的权限。另一方面它也一些限制:
(1)无法获取应用的数据流量消耗
从文档中仅能获取到指定uid的流量,但无法区分不同网络类型下的消耗
间接方法是通过监听网络切换,做好流量记录(但是要保证你的应用一直存活,且一定准确接收到网络切换信息),基本不可用。
(2)无法获取某个时间段内的流量消耗
从API文档中看,函数参数没有与时间相关的信息。而且重要的一点是,TrafficStats类中记录的是设备重启以来的流量统计信息。因为TrafficStats 类,底层还是读取/proc/net/xt_qtaguid/stats 对内容进行解析,将得到对应的结果返回上层。

NetworkStatsManager

在Android 6.0(API23)中新增加的类,提供网络使用历史统计信息,同时特别强调了可查询指定时间间隔内的统计信息。看看部分函数(非静态):

//查询指定网络类型在某时间间隔内的总的流量统计信息
NetworkStats.Bucket querySummaryForDevice(int networkType, String subscriberId, long startTime, long endTime)//查询某uid在指定网络类型和时间间隔内的流量统计信息
NetworkStats queryDetailsForUid(int networkType, String subscriberId, long startTime, long endTime, int uid)  //查询指定网络类型在某时间间隔内的详细的流量统计信息(包括每个uid)
NetworkStats queryDetails(int networkType, String subscriberId, long startTime, long endTime) 

从上述函数和文档看,NetworkStatsManager类克服了TrafficStats的查询限制,而且统计信息也不再是设备重启以来的数据。但它也有自己的限制和缺点。
(1)权限限制
NetworkStatsManager的使用需要额外的权限,”android.permission.PACKAGE_USAGE_STATS”是系统权限,需要主动引导用户开启应用的“有权查看使用情况的应用”(使用记录访问权限)权限,后面会有代码示例。
(2)文档不完善
不好说是文档不全,还是我没找对。首先文档中没有给出类的实例对象的构造方法,一开始还是反射获取的,后来才发现可以通过获取系统服务方式得到。另外queryDetailsForUid函数中设置的时间间隔不太有用,没能及时的获取流量统计信息,而是有两个小时的时间间隔。还好可以在querySummary函数中获得。

代码示例

下面说说具体的使用和代码,使用前必须明确的是这里的统计信息都是在网络层以上的数据。
1.权限设置
(1)AndroidManifest中添加权限声明

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions"/>

(2)代码中主动引导用户开启权限
这里没有说明READ_PHONE_STATE的主动获取,大家根据自己的targetSdkVersion设置

    private boolean hasPermissionToReadNetworkStats() {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {return true;}final AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,android.os.Process.myUid(), getPackageName());if (mode == AppOpsManager.MODE_ALLOWED) {return true;}requestReadNetworkStats();return false;}// 打开“有权查看使用情况的应用”页面private void requestReadNetworkStats() {Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);startActivity(intent);}

2.查看设备和某应用的流量统计
(1)获取NetworkStatsManager示例对象

NetworkStatsManager networkStatsManager = (NetworkStatsManager) getSystemService(NETWORK_STATS_SERVICE);

(2)查询设备总的流量统计信息

NetworkStats.Bucket bucket = null;
// 获取到目前为止设备的Wi-Fi流量统计
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI, "", 0, System.currentTimeMillis());
Log.i("Info", "Total: " + (bucket.getRxBytes() + bucket.getTxBytes()));

(3)查询某应用(uid)的数据流量统计信息

// 获取subscriberId
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
String subId = tm.getSubscriberId();NetworkStats summaryStats;
long summaryRx = 0;
long summaryTx = 0;
NetworkStats.Bucket summaryBucket = new NetworkStats.Bucket();
long summaryTotal = 0;summaryStats = networkStatsManager.querySummary(ConnectivityManager.TYPE_MOBILE, subId, getTimesMonthmorning(), System.currentTimeMillis());
do {summaryStats.getNextBucket(summaryBucket);int summaryUid = summaryBucket.getUid();if (uid == summaryUid) {summaryRx += summaryBucket.getRxBytes();summaryTx += summaryBucket.getTxBytes();}Log.i(MainActivity.class.getSimpleName(), "uid:" + summaryBucket.getUid() + " rx:" + summaryBucket.getRxBytes() +
" tx:" + summaryBucket.getTxBytes());summaryTotal += summaryBucket.getRxBytes() + summaryBucket.getTxBytes();
} while (summaryStats.hasNextBucket());

3.附赠实用函数
(1)应用包名查uid

public static int getUidByPackageName(Context context, String packageName) {int uid = -1;PackageManager packageManager = context.getPackageManager();try {PackageInfo packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_META_DATA);uid = packageInfo.applicationInfo.uid;Log.i(MainActivity.class.getSimpleName(), packageInfo.packageName + " uid:" + uid);} catch (PackageManager.NameNotFoundException e) {}return uid;
}

(2)获得本月第一天0点时间

public static long getTimesMonthMorning() {Calendar cal = Calendar.getInstance();cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));return cal.getTimeInMillis();}

4.提示无权限信息

15:39:06.531 5276-5276/cn.arainfo.test.android.testapp1 E/AndroidRuntime: FATAL EXCEPTION: main
Process: cn.arainfo.test.android.testapp1, PID: 5276
java.lang.SecurityException: Network stats history of uid 10145 is forbidden for caller 10144at android.os.Parcel.readException(Parcel.java:1665)at android.os.Parcel.readException(Parcel.java:1618)at android.net.INetworkStatsSession$Stub$Proxy.getHistoryIntervalForUid(INetworkStatsSession.java:425)at android.app.usage.NetworkStats.startHistoryEnumeration(NetworkStats.java:433)at android.app.usage.NetworkStatsManager.queryDetailsForUidTag(NetworkStatsManager.java:254)at android.app.usage.NetworkStatsManager.queryDetailsForUid(NetworkStatsManager.java:219)

统计测试

(1)测试设备
小米5S Plus Android 6.0 和 华为Mate9 Android 7.0设备上实际测试
(2)流量差距
实际测试流量有30M左右,和运营商流量统计相差2M左右

转载请注明出处:http://blog.csdn.net/w7849516230,欢迎关注微信公众号“编程阳光”
“编程阳光”微信公众号

参考链接:
1.android.net.TrafficStats
2.android.app.usage.NetworkStatsManager
3.stack overflow里的两个问题
http://stackoverflow.com/questions/38783836/how-to-fetch-data-usage-report-for-all-uids-using-the-new-networkstatsmanager-c

http://stackoverflow.com/questions/36702621/getting-mobile-data-usage-history-using-networkstatsmanager

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/28977.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

仿设置流量使用——细讲android获取流量使用情况,以及解决调用流量接口不准问题(非TrafficStats,而是NetworkStatsHistory)

不积跬步无以至千里 流量使用情况,好多软件都会带这个功能,比如360的流量监控,好多之类的,手机管家都会带上这个流量计算的功能,连系统应用设置里面也会带一个流量使用情况的查看功能,为什么呢?因为流量的使用关乎到用户使用流量的计费,当流量使用了很多,会给用…

vnstat流量统计(2.8版本)

vnstat流量统计&#xff08;2.8版本&#xff09; vnStat 是一个基于控制台的 Linux 和 BSD 网络流量监视器&#xff0c;它为所选接口保留网络流量日志。它使用内核提供的网络接口统计信息作为信息源。这意味着 vnStat 实际上不会嗅探任何流量&#xff0c;并且无论网络流量率如…

中职流量包分析attack/capture(1)

我希望网络安全的世界大家可以贡献自己的一部分&#xff0c;而不是拿来自私自利 作者拿到的流量包和题目是有出入的&#xff0c;但是因为出的题大同小异所以能分析出来 attack 1. 分 析 attack.pcapng 数 据 包 文 件 &#xff0c;通 过 分 析数据 包 attack.pcapng 找出恶意…

抓包部分软件时无网络+过代理检测 解决办法 安卓黄鸟httpcanary+vmos

解决软件抓包时无网络和代理检测&#x1f680; 需要准备的工具&#xff1a; 安卓手机 vmos pro 需要抓包的软件 第一步&#xff1a;下载好相应版的本的vmos room 第二步&#xff1a;文件中转站->我要导入->导入对应真机需要抓包APP 第三步&#xff1a;测试软件在vmos…

测试apk-异常管控NetTraffic攻击者开发

1. 目的 基于《软件绿色联盟应用体验标准》中 NetTraffic 资源的定义&#xff0c;对 NetTraffic 后台多次小流量数据包的行为模拟。旨在触发手机中异常功耗管控机制。 本次灭屏NetTraffic使用次数至少超过的二个等级:30次,60次&#xff0c;执行如下判断&#xff1a; 绿线不管控…

雷电模拟器无法修改网络,没有出现修改网络的选项,导致fiddler无法连接

对于一个小白来说&#xff0c;可能这就能耗掉一个下午的时间了&#xff0c;比如我&#xff0c;&#xff0c;&#xff0c;&#xff0c;要命的是这种问题对于绝大多数小白还完全不是问题&#xff0c;所以找了很久都没有解决答案&#xff0c;所以我是。。小白中的小白。。 模拟器…

TrackingNet上进行评估

TrackingNet上进行评估 说明&#xff1a;在目标跟踪测试数据集中&#xff0c;在TrackingNet和GOT-10K上的评估结果需要通过在线评估的方式获取。 website&#xff1a;Welcome - EvalAI 自行注册账户&#xff0c;注册好后按照以下操作就可以进行评估了。 在All Changes中找到…

ARP欺骗攻击(流量图片)——dsniff与driftnet使用

ARP欺骗攻击&#xff08;流量&图片&#xff09; 原理&#xff1a; 首先我们![请添加图片描述](https://img-blog.csdnimg.cn/7de7923387224bcda1ea4be958032ae9.png 要明白何为ARP&#xff08;地址解析协议&#xff09;&#xff1a;是根据 IP地址 获取 物理地址 的一个 TC…

Google pixel 原生安卓出现 WiFi 网络受限、优化网速、网络无法连接问题

谷歌从 Android 5.0 开始就引入了「Captive Portal」机制&#xff0c;主要用来检测 WiFI 网络认证是否正常&#xff0c;默认检测访问的是谷歌服务器。 众所周知谷歌服务器是需要404工具才能正常访问&#xff0c;所以如果你没有404工具的情况下&#xff0c;WiFi 就会出现网络受…

悉尼科技大学计算机专业就业,悉尼科技大学计算机专业怎么样

悉尼科技大学计算机科学是一门包含各种各样与计算和信息处理相关主题的系统学科&#xff0c;从抽象的算法分析、形式化语法等等&#xff0c;到更具体的主题如编程语言、程序设计、软件和硬件等。信息化产业的今天&#xff0c;这类专业的重要性也愈加显现。悉尼科技大学的互联网…

悉尼大学计算机专业本科2019,2019申请悉尼大学读本科有哪些要求

悉尼大学是澳洲名校&#xff0c;每年都有不少学生慕名前来留学。那你们知道申请悉尼大学读本科有哪些要求呢? 大师兄留学网【留学网 dsxliuxue.com】小编为大家带来悉尼大学申请条件&#xff0c;希望对大家有帮助。 悉尼大学本科申请条件&#xff1a; 学术要求&#xff1a; 对…

悉尼大学理学院计算机科学,澳洲悉尼大学理学院中国留学生

1 悉尼大学理学院简介 据立思辰留学360介绍&#xff0c;悉尼大学理学院的正式建立是1882年。在之后的50年内&#xff0c;悉尼大学理学院一共培养了353名本科学生&#xff0c;以及聘用了6名在物理&#xff0c;化学&#xff0c;动物学&#xff0c;地质学&#xff0c;植物学&#…

悉尼大学计算机专业新生,2020年悉尼大学计算机科学专业课程设置难不难

悉尼大学计算机科学专业课程设置难不难 阅读&#xff1a;786次 更新时间&#xff1a;2016-10-19 09:06:03 添加时间&#xff1a;2016-10-19 编辑&#xff1a;jingwen 来源&#xff1a; 悉尼大学 索取招生简章 已发送786份2020年招生简章 我对该学校感兴趣&#xff0c;请发资料给…

悉尼大学商业数据科学与计算机学院,悉尼大学数据科学专业

悉尼大学的数据科学硕士&#xff0c;比较适合热衷于从数据中挖掘有价值信息&#xff0c;并借此推动商业决策制定和研究成果的人士。悉尼大学数据科学硕士项目旨在培养学生的分析能力、专业技能&#xff0c;引导学生利用数据科学在专业领域作出战略性决策。同时&#xff0c;该项…

悉尼大学理学院计算机科学,悉尼大学理学院本科申请

悉尼大学理学院(Faculty of Science)共开设有以下11个学位项目&#xff0c;国际学生均可申请&#xff0c;分别是&#xff1a; 课程名称 课程英文名 学制 IELTS要求 预科GPA A-level IB课程 通识教育与科学学士 B Liberal Arts and Science 3年 6.5 (6.0) 6.7 BBC 27 医学科学学…

悉尼科大计算机专业,2020年悉尼科技大学专业排名

悉尼科技大学(University of Technology Sydney)&#xff0c;简称“悉尼科大”(UTS)&#xff0c;世界百强名校。是一所位于澳大利亚第一大城市悉尼的著名公立研究型大学。学校在2020年与美国匹兹堡大学并列QS世界大学排名第140名&#xff0c;2019年获得世界五星级高校认证。 悉…

悉尼科技大学硕士计算机课程,悉尼科技大学硕士课程学制

悉尼科技大学位于澳大利亚新南威尔士州首府悉尼的市中心&#xff0c;是一所以商、法、教育、科技为主的重点综合性大学&#xff0c;澳大利亚世界名校之一。 悉尼科技大学信息技术学院是澳大利亚领先的IT学院并以与IT业的紧密联系而着称。该院把计算机科学技术和面向商业的信息系…

悉尼大学计算机学士,2017年悉尼大学计算机学士介绍

悉尼大学是澳大利亚的第一所大学&#xff0c;创立于1850年&#xff0c;位于新南威尔士州的首府悉尼。悉尼大学是澳大利亚历史最悠久和最负盛名的大学&#xff0c;被称为“澳大利亚第一校”&#xff0c;在世界范围内亦是最优秀的高等学府之一。悉尼大学有八大校区及多所分校&…

悉尼大学计算机研究生学制,悉尼大学研究生学制

澳大利亚悉尼大学具有丰富的研究生专业课程&#xff0c;学制安排一般在1-2年时间。 悉尼大学硕士申请要求 要求非211大学申请者&#xff0c;暂不需清华认证 (毕业证、学位证、成绩单) 入学要求&#xff1a; 工程类专业(Engineering,IT) Master of Professional Engineering 985…

悉尼大学计算机科学gpa,悉尼大学计算机gpa

悉尼大学的计算机硕士对于双非学生gpa要求80分以上&#xff0c;但是如果有较强的科研背景或者工作经验&#xff0c;是可以加分的。 悉尼大学计算机硕士IELTS入学要求 立思辰留学介绍&#xff0c;直接入读硕士课程的IELTS要求为平均分不低于6.5分&#xff0c;四个单项不低于6分&…