TrafficStats Api android and calculation of daily data usage
Asked Answered
P

4

10

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?

Probity answered 3/10, 2011 at 17:8 Comment(2)
Have you tried just doing some logging and seeing if/when the counters get reset? I would assume the counters start whenever the process is created and reset when ever the process is finished (i.e. the phone shuts down).Shawndashawnee
Thankx for your answer. Its counter set to zero after phone shut down. Now, i will proceed to next step of calculation of data usage based on uptimeProbity
S
6

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...

Squiffy answered 3/10, 2011 at 20:58 Comment(6)
what is the difference between total network interface and only mobile network interface.getMobileRxBytes retrns very low value, while getTotalRxBytes returning reasonable value.Probity
getMobileRxBytes returns data received over 3G/4G/GPRS, etc. getTotalRxBytes includes all data received, including over Wi-Fi.Squiffy
How to reset the counter for Traffic Stats Api. Is there any system call for that. Actually everytime, device reboot, it removes the earlier file and create new one , thus setting new counter on each reboot. Can i do it programatically from my AppProbity
Thnkx. I got it working based on substracting present values from last stored values while clicking resetProbity
Hi Haimg, when i played you tube , the total bytes received of the device ,i.e getTotalRxBytes, increased almost by 5 MB, but the bytes received from getUidRxBytes(int uid),where uid is YouTube User id, happen to be very less. Am i doing anything wrong.Probity
@haimg: For the current API versions (20/21), it seems that TrafficStats count both TCP and UDP.Monkshood
T
6

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).

Tunic answered 2/4, 2013 at 20:49 Comment(2)
Is this answer actually correct? See here.Blackpoll
My answer is over 6 years old and was correct at the time of posting. The packet header discrepancy between the functions could have been corrected. My advice would be to have your app download a known file size and verify if the UID API returns a byte count larger than the file size, which would verify that packet header sizes are now being included. Just keep in mind that behaviour might be different on different OS versions and the documented vs actual behavior can differ.Tunic
U
2

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";

}
Unweighed answered 30/3, 2016 at 10:56 Comment(5)
Are you sure? It gives me data statistics in all the android OS?Surah
Yes, Why Not. Already implemented in play.google.com/store/apps/…Unweighed
when i run into the api level 23 it's not getting me any MB or BYTESSurah
When i installed you suggested application in nougat and kitkat i am not getting any data. App showing me "No apps Available!". Could you please help me?Surah
Why you given 1 star ?Unweighed
B
0

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));
Balikpapan answered 28/2, 2014 at 7:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.