TrafficStats Api android and calculation of daily data usage
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";
}