概述
安卓是基於Linux改編的,在2.2版本中加入了TrafficStats類,通過使用這個類可以輕鬆獲取到手機從開機到使用本類時手機所使用的流量以及單應用的上下行流量。
在安卓2.2版本之前如果需要查詢流量,需要利用Linux提供的方法來讀取流浪存儲的文件,這個文件在“/proc/uid_stat/UID/”文件夾下(UID是應用在手機內的唯一ID號),在這個文件夾下有兩個文件,這兩個文件記錄了手機從開機到現在的上行流量和下行流量。
在安卓4.3版本中不知原因不支持TrafficStats利用UID獲取流量的方法,但在4.4版本中又支持,所以在4.3版本中只能用讀取文本的方式代替TrafficStats類進行解析。
無論是利用TrafficStats或是讀取文件的方式進行查看單應用所用的流量,記錄的這些數據都是從這次開機開始到查詢時的流量,這些流量統計關機之後將被清除。
TrafficStats類中,提供了多種靜態方法,可以直接調用獲取,返回類型均爲long型,如果返回等於-1代表 UNSUPPORTED ,表示當前設備不支持統計。
具體使用
使用TrafficStats獲取
public PackagesInfo(Context context) {
// 通包管理器,檢索所有的應用程序(甚至卸載的)與數據目錄
this.context = context;
pm = context.getApplicationContext().getPackageManager();
appList = pm
.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES
| PackageManager.GET_PERMISSIONS);
// appList = pm.getInstalledPackages(PackageManager.GET_ACTIVITIES);
// appList = pm.getInstalledPackages(0);
}
/**
* 通過一個程序名返回該程序的一個Application對象。
*
* @param name 程序名
* @return ApplicationInfo
*/
public ApplicationInfo getInfo(String name) {
if (name == null) {
return null;
}
for (ApplicationInfo appinfo : appList) {
if (name.equals(appinfo.processName)) {
return appinfo;
}
}
return null;
}
/**
*
* @param name
* 單應用流量獲取
*
* @return List<AppInfo>
*/
public List<AppInfo> getRunningProcess() {
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
// 獲取正在運行的應用
List<RunningAppProcessInfo> run = am.getRunningAppProcesses();
List<AppInfo> list = new ArrayList<AppInfo>();
List<AppInfo> slist = new ArrayList<AppInfo>();
for (RunningAppProcessInfo ra : run) {
// 過濾掉沒有聯網的
int result = context.getPackageManager().checkPermission(
"android.permission.INTERNET", ra.processName);
if (result != PackageManager.PERMISSION_GRANTED) {
continue;
}
long appSent = TrafficStats.getUidTxBytes(ra.uid);
long appRev = TrafficStats.getUidRxBytes(ra.uid);
appSent = appSent/1024;
appRev = appRev/1024;
if (appSent < 0 || appRev < 0
|| (appSent == 0 && appRev == 0)) {
continue;
}
// 過濾掉無對應的程序
if (getInfo(ra.processName) != null) {
if ((getInfo(ra.processName).flags & ApplicationInfo.FLAG_SYSTEM) == 0<span style="font-family: Arial, Helvetica, sans-serif;">// 非系統應用</span>
&&
(getInfo(ra.processName).flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0) {
// 本來是系統應用但升級後成爲安裝應用的
AppInfo appInfo = new AppInfo();
appInfo.setApp_name(getInfo(ra.processName).loadLabel(pm)
.toString());
appInfo.setApp_package(ra.processName);
appInfo.setApp_sent(appSent);
appInfo.setApp_rev(appRev);
list.add(appInfo);
} else {// 系統應用
AppInfo appInfo = new AppInfo();
appInfo.setApp_name(getInfo(ra.processName).loadLabel(pm)
.toString());
appInfo.setApp_package(ra.processName);
appInfo.setApp_sent(appSent);
appInfo.setApp_rev(appRev);
slist.add(appInfo);
}
}
}
list.addAll(slist);
return list;
}
使用讀取文件的方式獲取
List<AppInfo> list = new ArrayList<AppInfo>();
File dir = new File("/proc/uid_stat/");
String[] children = dir.list();
if (children != null) {
for (int i = 0; i < children.length; i++) {
int uid = Integer.parseInt(children[i]);
AppInfo appInfo = new AppInfo();
String uidString = String.valueOf(uid);
File uidFileDir = new File("/proc/uid_stat/" + uidString);
File uidrec = new File(uidFileDir, "tcp_rcv");
File uidsent = new File(uidFileDir, "tcp_snd");
StringBuilder text = new StringBuilder();
try {
BufferedReader rec = new BufferedReader(new FileReader(
uidrec));
BufferedReader sent = new BufferedReader(new FileReader(
uidsent));
appInfo.setApp_rev((Integer.valueOf(rec.readLine()))/1024);
appInfo.setApp_sent((Integer.valueOf(sent.readLine()))/1024);
String packageName = pm.getNameForUid(uid);
appInfo.setApp_package(packageName);
String lableName;
lableName = pm.getApplicationLabel(
pm.getApplicationInfo(packageName,
PackageManager.GET_META_DATA)).toString();
appInfo.setApp_name(lableName);
// Log.i("PackageInfo",appInfo.toString() );
list.add(appInfo);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// handle this
e.printStackTrace();
}
}
}
return list;
}