在Android系統下有個文件夾專門記錄App的流量詳情。這個方法支持Android 2.2以上版本。
<Android>
package com.cx.cm.trafficbox.sys.u;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import com.cx.cm.trafficbox.sys.u.m.UidStat;
public final class TrafficStats {
private static String UID_CONF = "/proc/uid_stat";
private static String TCP_RCV = "tcp_rcv";
private static String TCP_SND = "tcp_snd";
public static List<UidStat> getStats(Context ctx) throws IOException {
File temp = new File(UID_CONF);
if (temp != null && temp.exists() && temp.isDirectory()) {
// Mtk: high performance.
return getUidStats();
} else {
// All of platform versions.
return getUidStats(ctx);
}
}
public static List<UidStat> getUidStats() throws IOException {
List<UidStat> uidStats = new ArrayList<UidStat>();
File temp = new File(UID_CONF);
if (temp.exists() && temp.isDirectory()) {
String[] a = temp.list();
if (a != null && a.length > 0) {
// LogUtils.df("getLoc", "<loc>", -1);
for (int i = 0; i < a.length; i++) {
File src = new File(UID_CONF + File.separator + a[i]);
if (src.exists() && src.isDirectory()) {
File tcpRcv = new File(src.getAbsolutePath()
+ File.separator + TCP_RCV);
File tcpSnd = new File(src.getAbsolutePath()
+ File.separator + TCP_SND);
int uid = Integer.parseInt(a[i]);
UidStat uidStat = new UidStat();
uidStat.uid = uid;
long tcp_rcv = 0, tcp_snd = 0;
if (tcpRcv.exists() && tcpRcv.isFile()) {
FileReader in = new FileReader(tcpRcv);
BufferedReader fr = new BufferedReader(in);
tcp_rcv = Long.parseLong("" + fr.readLine());
fr.close();
in.close();
}
if (tcpSnd.exists() && tcpSnd.isFile()) {
FileReader in = new FileReader(tcpSnd);
BufferedReader fr = new BufferedReader(in);
tcp_snd = Long.parseLong("" + fr.readLine());
fr.close();
in.close();
}
uidStat.tcp_rcv = tcp_rcv;
uidStat.tcp_snd = tcp_snd;
uidStats.add(uidStat);
// LogUtils.df("uid:rcv:snd", uidStat.uid + ":"
// + uidStat.tcp_rcv + ":" + uidStat.tcp_snd, 0);
}
} // for
// LogUtils.df("getLoc", "</loc>", -1);
}
}
// LogUtils.df("", "size:" + uidStats.size(), -1);
return uidStats;
}
public static List<UidStat> getUidStats(Context ctx) {
PackageManager pm = ctx.getPackageManager();
List<PackageInfo> infos = pm
.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES
| PackageManager.GET_PERMISSIONS);
List<UidStat> uidStats = new ArrayList<UidStat>();
int l = infos == null ? 0 : infos.size();
for (int i = 0; i < l; i++) {
PackageInfo info = infos.get(i);
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;
long rcv = android.net.TrafficStats.getUidRxBytes(uid);
long snd = android.net.TrafficStats.getUidTxBytes(uid);
// 如果返回-1,代表系統版本爲2.2以下,不支持使用該方法
if (rcv < 0 || snd < 0) {
continue;
} else {
if (rcv > 0 && snd > 0) {
UidStat stat = new UidStat();
stat.pkg = info.packageName;
stat.uid = uid;
stat.tcp_rcv = rcv;
stat.tcp_snd = snd;
uidStats.add(stat);
}
}
}
}
}
}
return uidStats;
}
}
</Android>
UidStat.java:
<Android>
package com.cx.cm.trafficbox.sys.u.m;
public final class UidStat {
public int uid = -1;
public String name = "";
public String pkg = "";
public long tcp_rcv = 0;
public long tcp_snd = 0;
public long stamp;
}
</Android>
在該文件夾下,按App(lication)的UID來分類保存其send和receive的所有TCP數據包的大小。每次開機後,該數據會重置爲0。