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;

}

你可能感兴趣的:(Android 流量监控的开发(3))