Have a confusion over following two methods of TrafficStats of Android: getUidTxBytes(int uid) and getUidRxBytes(int uid) , These two methods return the number of bytes transmitted and received through the network for this UID. But what is the time unit of it, is it per second? If I want to calculate data transmitted and received per day per app, what should I do. I thought one way, to store data in sql and keep on adding data to the table. Is it proper way?
These are counters "since the interface went up" or "since the application with this UID has started". So say if your phone goes into "Airplane mode" and then back, the counters might start from zero again. If you need per-second values, you'll need to call these functions every second, and then use the delta from the last call. If the delta is negative, just use the value as-is, it means the counter started from zero again.
One more thing: As far as I know, these counters count TCP/IP only. Not UDP. So if you need a very precise accounting, and the application in question uses UDP/IP, or any other protocol besides TCP, these counters will be wrong.
For the insight how this function works, look at the source of Android, freely available. File in question is ./frameworks/base/core/jni/android_net_TrafficStats.cpp
This function gets the data from /proc/uid_stat/[uid]/tcp_snd
. If you need more info about that, you'll need to dive into the Linux kernel...
These counters contain the byte count since the last reboot. One some phones these counters may periodically reset, but most of the time they only reset after a reboot. Going into airplane mode or changing between mobile and Wi-Fi will not reset these counters.
One important point is that these counters do not include packet overhead, only payload size. So typically this would mean 3-4% of the data may be unaccounted for. However, if it is a streaming, torrent or VoIP app where packet payloads are small, there may be a much higher amount of data unaccounted for.
Interestingly, getTotalRxBytes (received bytes across all interfaces, ex mobile and Wi-Fi combined) and getMobileRxBytes (received bytes only on the mobile interface) include all bytes including overhead. So basically, your app byte count total will be less that your interface byte count total, and therefore less than the amount of data your network operator is billing you for.
One last point, most streaming apps don't account for their data under their own UID. They are accounted under the system.media UID. So if you are monitoring data usage for YouTube, only a very small amount of data will actually appear under that app; the rest will be under the media UID (1013).
Here, I getting those apps, which has permission of Internet, You can change the Permission name and get apps as per you needed.
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";
}
getUidRxBytes() and getUidTxBytes() are basically used for received and transmitted bytes respectively. To monitor your data for each app just find the uid of each process and find the corresponding data to each process and that will be your data for each app and then you can use this code for calculations.
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));
来源:https://stackoverflow.com/questions/7638292/trafficstats-api-android-and-calculation-of-daily-data-usage