对以下两种Android TrafficStats方法感到困惑: getUidTxBytes(int uid)和getUidRxBytes(int uid), 这两种方法返回通过网络为此UID发送和接收的字节数。但它的时间单位是多少,是每秒? 如果我想计算每个应用每天传输和接收的数据,我该怎么办。我想过一种方法,在sql中存储数据并继续向表中添加数据。这是正确的方式吗?
答案 0 :(得分:6)
这些是“自接口启动以来”的计数器“或”因为具有此UID的应用程序已启动“。所以说如果你的手机进入“飞行模式”然后再回来,计数器可能会再次从零开始。如果需要每秒的值,则需要每秒调用这些函数,然后使用上次调用的增量。如果delta是负数,只需按原样使用该值,这意味着计数器再次从零开始。
还有一件事:据我所知,这些计数器只计算TCP / IP。不是UDP。因此,如果您需要非常精确的记帐,并且有问题的应用程序使用UDP / IP或TCP之外的任何其他协议,这些计数器将是错误的。
要了解此功能的工作原理,请查看免费提供的Android源代码。有问题的文件是./frameworks/base/core/jni/android_net_TrafficStats.cpp
此函数从/proc/uid_stat/[uid]/tcp_snd
获取数据。如果您需要更多信息,那么您需要深入了解Linux内核......
答案 1 :(得分:4)
这些计数器包含自上次重新引导以来的字节数。一些电话这些计数器可能会定期重置,但大部分时间它们只会在重启后重置。进入飞行模式或在移动和Wi-Fi之间切换不会重置这些计数器。
重要的一点是这些计数器不包括数据包开销,只包括有效负载大小。因此,通常这意味着3-4%的数据可能无法计算。但是,如果它是数据包有效负载较小的流媒体,torrent或VoIP应用程序,则可能会有更多的数据未计入。
有趣的是,getTotalRxBytes(所有接口上的接收字节,移动和Wi-Fi组合)和getMobileRxBytes(仅在移动接口上接收的字节)包括所有字节,包括开销。基本上,您的应用字节数总计将小于您的接口字节数总计,因此小于网络运营商为您收费的数据量。
最后一点,大多数流媒体应用都不会在自己的UID下占用他们的数据。它们在system.media UID下计算。因此,如果您要监控YouTube的数据使用情况,那么该应用下只会显示非常少量的数据;其余的将在媒体UID(1013)下。
答案 2 :(得分:2)
在这里,我获得了那些拥有互联网许可的应用, 您可以根据需要更改权限名称并获取应用程序。
ArrayList<AppObject> listApps;
public void getAllAppList() {
listApps = new ArrayList<AppObject>();
PackageManager p = getPackageManager();
List<ApplicationInfo> packages = p.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo applicationInfo : packages) {
try {
PackageInfo packageInfo = p.getPackageInfo(applicationInfo.packageName, PackageManager.GET_PERMISSIONS);
String[] permissions = packageInfo.requestedPermissions;
for (String permissionName : permissions) {
if (permissionName.equals("android.permission.INTERNET")) {
ApplicationInfo appInfo = packageInfo.applicationInfo;
AppObject appObject = new AppObject();
appObject.appDrawable = getPackageManager().getApplicationIcon(appInfo);
appObject.appName = (String) getPackageManager().getApplicationLabel(appInfo);
appObject.dataUsage = getDataUsage(appInfo);
listApps.add(appObject);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
Debug.e("APP_SIZE", ":" + listApps.size());
appsAdapter.addAll(listApps);
}
public String getDataUsage(ApplicationInfo appInfo) {
int uid = appInfo.uid;
double received = (double) TrafficStats.getUidRxBytes(uid) / (1024 * 1024);
double sent = (double) TrafficStats.getUidTxBytes(uid) / (1024 * 1024);
double total = received + sent;
return String.format("%.2f", total) + " MB";
}
答案 3 :(得分:0)
getUidRxBytes()和getUidTxBytes()基本上分别用于接收和发送的字节。要监控每个应用程序的数据,只需找到每个进程的uid并找到每个进程的相应数据,这将是每个应用程序的数据,然后您可以使用此代码进行计算。
TextView totData = (TextView)findViewById(R.id.totData);
TextView wifiTot = (TextView)findViewById(R.id.wifitotData);
TextView wifiTX = (TextView)findViewById(R.id.wifiUpData);
TextView wifiRX = (TextView)findViewById(R.id.wifiDownData);
TextView mobileTot = (TextView)findViewById(R.id.mobtotData);
TextView mobTX = (TextView)findViewById(R.id.mobUpData);
TextView mobRX = (TextView)findViewById(R.id.mobDownData);
/*
* Converting bytes to MB
*/
long rxBytes = TrafficStats.getTotalRxBytes()/1048576;
long txBytes = TrafficStats.getTotalTxBytes()/1048576;
long mobUpload = TrafficStats.getMobileTxBytes()/1048576;
long mobDown = TrafficStats.getMobileRxBytes()/1048576;
long wifiUpload = txBytes-(mobUpload);
long wifiDown = rxBytes-(mobDown);
wifiRX.setText(Long.toString(wifiDown));
wifiTX.setText(Long.toString(wifiUpload));
long wifitot = wifiUpload+wifiDown;
wifiTot.setText(Long.toString(wifitot));
mobTX.setText(Long.toString(mobUpload));
mobRX.setText(Long.toString(mobDown));
long mobTot = mobUpload+mobDown;
mobileTot.setText(Long.toString(mobTot));
totData.setText(Long.toString(wifitot+mobTot));