經過2,3周的時間研究流量的監控,什麼TrafficStats提供的方法,做的時候蛋疼的要屎,2G/3G的流量獲取根本就不准確,至於什麼原因網絡上面也有說,就不講了。經過研究,通過讀取/proc/uid_stat/項目uid/下面的兩個文件,獲取流量信息。再通過自己的邏輯算法,解決了流量監控和統計的問題。可能也有不准確的地方,請多多指導
本監控軟件,實現的是監控一個月的程序使用流量
1,開啟一個服務,每5分鐘跑動一次更新流量,用於能夠准確記錄流量
每一個小時,更新一次流量,用於清除非本月的流量
2,保存流量的時候,進行判斷
a,若是數據庫中保存的 舊流量oldFlow > 文件流量newFlow,說明手機重啟過, 保存流量 = 前一次數據庫保存流量 + 文件流量
b,若是數據庫中保存的 舊流量oldFlow <= 文件流量newFlow,說明軟件消耗了新流量,保存流量=oldFlow-newFlow+前一次數據庫保存流量
3,晚上24點的處理
文件流量不為o的時候,當前一天oldFLow > newFlow,保存流量 = newFlow + 0; 此時oldFlow = newFLow
當前一天oldFlow <= newFlow, 保存流量 = newFlow - oldFlow +0; 此時oldFlow = newFlow;
/**
* 關鍵代碼
*/
FlowInfo uidInfo;
public List<FlowInfo> getGPRSData() {
List<FlowInfo> uidList = new ArrayList<FlowInfo>();
PackageManager pm = context.getPackageManager();
List<PackageInfo> packinfos = pm
.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES
| PackageManager.GET_PERMISSIONS);
long newFlow = 0;
long[] oldStandardFlow = null;
String date = TimeUtil.getInstance().getStringDate();
for (PackageInfo info : packinfos) {
uidInfo = new FlowInfo();
String[] premissions = info.requestedPermissions;
if (premissions != null && premissions.length > 0) {
for (String premission : premissions) {
if ("android.permission.INTERNET".equals(premission)) {
int uid = info.applicationInfo.uid;
uidInfo.setUid(uid);
newFlow = Long.valueOf(getSndFlowByUid(uid))
+ Long.valueOf(getRcvFlowByUid(uid));
tableHelp = TableHelp.getInstance(context,
"FlowMonitors.db", 1);
sqlite = tableHelp.getSqliteDatabase();
oldStandardFlow = tableHelp.getOldStandardFlow(sqlite,
uid, date); // 保存的舊流量和標准流量
if (oldStandardFlow[0] == 0 && oldStandardFlow[1] == 0
&& newFlow != 0) { // 晚上24點後的處理
int d = Integer.valueOf(TimeUtil.getInstance()
.getStringDate1());
String d2;
if (d < 10) {
d2 = TimeUtil.getInstance().getYearAndMonth()
+ "-0" + (d - 1);
} else {
d2 = TimeUtil.getInstance().getYearAndMonth()
+ "-" + (d - 1);
}
sqlite = tableHelp.getSqliteDatabase();
oldStandardFlow = tableHelp.getOldStandardFlow(
sqlite, uid, d2); // 保存的舊流量和標准流量
setFlowAfter24(oldStandardFlow, newFlow);
} else { // 當天處理
setFlowToday(oldStandardFlow, newFlow);
}
uidInfo.setDate(date);
uidList.add(uidInfo);
}
}
}
}
return uidList;
}
public void setFlowToday(long[] oldStandardFlow, long newFlow) {
if (oldStandardFlow[0] > newFlow) {
uidInfo.setOldFlow(newFlow);
newFlow = oldStandardFlow[1] + newFlow;
uidInfo.setFlow(newFlow);
} else {
uidInfo.setOldFlow(newFlow);
newFlow = newFlow - oldStandardFlow[0] + oldStandardFlow[1];
uidInfo.setFlow(newFlow);
}
}
public void setFlowAfter24(long[] oldStandardFlow, long newFlow) {
if (oldStandardFlow[0] > newFlow) {
uidInfo.setOldFlow(newFlow);
newFlow = 0 + newFlow;
uidInfo.setFlow(newFlow);
} else {
uidInfo.setOldFlow(newFlow);
newFlow = newFlow - oldStandardFlow[0] + 0;
uidInfo.setFlow(newFlow);
}
}