天無絕人之路,在TrafficStats身上無法滿足我們的需求,我們就要繼續(xù)尋找可以滿足我們需求的方法,最終找到一個NetworkStatsManager,雖然不盡完美但可勉強實現(xiàn)我們的功能。
NetworkStatsManager
在Android 6.0(API23)中新增加的類,提供網(wǎng)絡(luò)使用歷史統(tǒng)計信息,同時特別強調(diào)了可查詢指定時間間隔內(nèi)的統(tǒng)計信息。看看部分函數(shù)(非靜態(tài)):
//查詢指定網(wǎng)絡(luò)類型在某時間間隔內(nèi)的總的流量統(tǒng)計信息NetworkStats.BucketquerySummaryForDevice(intnetworkType,StringsubscriberId,longstartTime,longendTime)
//查詢某uid在指定網(wǎng)絡(luò)類型和時間間隔內(nèi)的流量統(tǒng)計信息NetworkStats.queryDetailsForUid(intnetworkType,StringsubscriberId,longstartTime,longendTime,intuid)
//查詢指定網(wǎng)絡(luò)類型在某時間間隔內(nèi)的詳細的流量統(tǒng)計信息(包括每個uid)NetworkStats.queryDetails(intnetworkType,StringsubscriberId,longstartTime,longendTime)
從上述函數(shù)和文檔看,NetworkStatsManager類克服了TrafficStats的查詢限制,而且統(tǒng)計信息也不再是設(shè)備重啟以來的數(shù)據(jù)。但它也有自己的限制和缺點。
(1)權(quán)限限制
NetworkStatsManager的使用需要額外的權(quán)限,”android.permission.PACKAGE_USAGE_STATS”是系統(tǒng)權(quán)限,需要主動引導(dǎo)用戶開啟應(yīng)用的“有權(quán)查看使用情況的應(yīng)用”(使用記錄訪問權(quán)限)權(quán)限,后面會有代碼示例。
(1)AndroidManifest中添加權(quán)限聲明
(2)代碼中主動引導(dǎo)用戶開啟權(quán)限
(3) 系統(tǒng)版本低于Android 6.0(API23)不可用
這里沒有說明READ_PHONE_STATE的主動獲取,大家根據(jù)自己的targetSdkVersion設(shè)置
(2)文檔不完善
不好說是文檔不全,還是我沒找對。首先文檔中沒有給出類的實例對象的構(gòu)造方法,一開始還是反射獲取的,后來才發(fā)現(xiàn)可以通過獲取系統(tǒng)服務(wù)方式得到。另外queryDetailsForUid函數(shù)中設(shè)置的時間間隔不太有用,沒能及時的獲取流量統(tǒng)計信息,而是有兩個小時的時間間隔。還好可以在querySummary函數(shù)中獲得。
(3)跟TrafficStats區(qū)別
TrafficStats關(guān)機和卸載應(yīng)用數(shù)據(jù)都會清空;NetworkStatsManager 卸載會清空,關(guān)機不會清空數(shù)據(jù);
/**
* 獲取一段時間間隔時的流量數(shù)據(jù)
*
*@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;
}