Android 流量监控的开发(3)
天无绝人之路,在TrafficStats身上无法满足我们的需求,我们就要继续寻找可以满足我们需求的方法,最终找到一个NetworkStatsManager,虽然不尽完美但可勉强实现我们的功能。
NetworkStatsManager
在Android 6.0(API23)中新增加的类,提供网络使用历史统计信息,同时特别强调了可查询指定时间间隔内的统计信息。看看部分函数(非静态):
//查询指定网络类型在某时间间隔内的总的流量统计信息NetworkStats.BucketquerySummaryForDevice(intnetworkType,StringsubscriberId,longstartTime,longendTime)
//查询某uid在指定网络类型和时间间隔内的流量统计信息NetworkStats.queryDetailsForUid(intnetworkType,StringsubscriberId,longstartTime,longendTime,intuid)
//查询指定网络类型在某时间间隔内的详细的流量统计信息(包括每个uid)NetworkStats.queryDetails(intnetworkType,StringsubscriberId,longstartTime,longendTime)
从上述函数和文档看,NetworkStatsManager类克服了TrafficStats的查询限制,而且统计信息也不再是设备重启以来的数据。但它也有自己的限制和缺点。
(1)权限限制
NetworkStatsManager的使用需要额外的权限,”android.permission.PACKAGE_USAGE_STATS”是系统权限,需要主动引导用户开启应用的“有权查看使用情况的应用”(使用记录访问权限)权限,后面会有代码示例。
(1)AndroidManifest中添加权限声明
(2)代码中主动引导用户开启权限
(3) 系统版本低于Android 6.0(API23)不可用
这里没有说明READ_PHONE_STATE的主动获取,大家根据自己的targetSdkVersion设置
(2)文档不完善
不好说是文档不全,还是我没找对。首先文档中没有给出类的实例对象的构造方法,一开始还是反射获取的,后来才发现可以通过获取系统服务方式得到。另外queryDetailsForUid函数中设置的时间间隔不太有用,没能及时的获取流量统计信息,而是有两个小时的时间间隔。还好可以在querySummary函数中获得。
(3)跟TrafficStats区别
TrafficStats关机和卸载应用数据都会清空;NetworkStatsManager 卸载会清空,关机不会清空数据;
/**
* 获取一段时间间隔时的流量数据
*
*@paramnetworkType
*@return
*/
public longcurrentData(intnetworkType, intbeginDay, intendDay) {
longsummaryRx =0;
longsummaryTx =0;
longsummaryTotal =0;
longbeginTime = TimeUtil.getYesterdayBegin(beginDay);
longendTime = TimeUtil.getYesterdayEnd(endDay);
LogUtil.i("time="+ TimeUtil.MillisToStr(beginTime,1) +"-"+ TimeUtil.MillisToStr(endTime,1));
NetworkStats summaryStats;
NetworkStats.Bucket summaryBucket =newNetworkStats.Bucket();
try{
summaryStats =networkStatsManager.querySummary(networkType,getSubscriberId(networkType),
beginTime,
endTime);
do{
summaryStats.getNextBucket(summaryBucket);
intsummaryUid = summaryBucket.getUid();
if(getUidByPackageName() == summaryUid) {
summaryRx += summaryBucket.getRxBytes();
summaryTx += summaryBucket.getTxBytes();
summaryTotal += summaryBucket.getRxBytes() + summaryBucket.getTxBytes();
}
}while(summaryStats.hasNextBucket());
}catch(RemoteException e) {
e.printStackTrace();
}
LogUtil.i("rx:"+ summaryRx /1024+"kb"+"+tx:"+ summaryTx /1024+"kb"+"=total:"+ summaryTotal /1024+"kb");
FlowsDataBean data =newFlowsDataBean();
data.setRxMobile(summaryRx /1024);
data.setTxMobile(summaryTx /1024);
data.setTotalMobile(summaryTotal /1024);
data.save();
returnsummaryTotal /1024;
}