Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getUidRxBytes() and getUidTxBytes() always return 0 in Android 4.3

Tags:

android

I feel like I am on crazy pills right now. A specific part of my application has been working just fine for several days, and today it just stopped working and I can not figure out why. This part of my code used to output the total data since boot that each specific app has sent and received. Now, the values always show up as 0.

A couple things that may or may not be affecting this:

1.) My Nexus 4 was just updated to Android 4.3 today, but I doubt this is an issue because this worked just fine right after I updated.

2.) With the Android API 18 update, some methods from the Traffic Stats API are now deprecated, but these are methods I am not even using, so this should have no effect. http://developer.android.com/reference/android/net/TrafficStats.html

All help is greatly appreciated.

PackageManager packageManager=this.getPackageManager();
List<ApplicationInfo> appList=packageManager.getInstalledApplications(0);

for (ApplicationInfo appInfo : appList) {
    String appLabel = (String) packageManager.getApplicationLabel(appInfo);
    int uid = appInfo.uid;
    Log.d("data", String.valueOf(TrafficStats.getUidRxBytes(uid) + TrafficStats.getUidTxBytes(uid)));

Update[January 23, 2014]: Testing the getUidRxBytes() and getUidTxBytes() on my Nexus 4 running Android 4.4.2 shows that the values are no longer 0, but are reporting the correct statistics.

like image 686
Dick Lucas Avatar asked Jul 27 '13 06:07

Dick Lucas


3 Answers

I have reported the issue to the AOSP issue tracker: here

I have also created an alternate solution to the problem which I have pasted below:

private Long getTotalBytesManual(int localUid){

File dir = new File("/proc/uid_stat/");
String[] children = dir.list();
if(!Arrays.asList(children).contains(String.valueOf(localUid))){
    return 0L;
}
File uidFileDir = new File("/proc/uid_stat/"+String.valueOf(localUid));
File uidActualFileReceived = new File(uidFileDir,"tcp_rcv");
File uidActualFileSent = new File(uidFileDir,"tcp_snd");

 String textReceived = "0";
 String textSent = "0";

 try {
        BufferedReader brReceived = new BufferedReader(new FileReader(uidActualFileReceived));
        BufferedReader brSent = new BufferedReader(new FileReader(uidActualFileSent));
        String receivedLine;
        String sentLine;

        if ((receivedLine = brReceived.readLine()) != null) {
            textReceived = receivedLine;
        }
        if ((sentLine = brSent.readLine()) != null) {
            textSent = sentLine;
        }

    }
    catch (IOException e) {

    }
 return Long.valueOf(textReceived).longValue() + Long.valueOf(textReceived).longValue();

}
like image 181
Dick Lucas Avatar answered Nov 20 '22 17:11

Dick Lucas


The TrafficStats class get the information about network traffic from the /proc/uid_stat/<uid> directory. This contains information about the tcp, udp bytes and packets sent and received. If the files are not present the TrafficStats class can't get the network stats. You can check if the files are present, If not you are out of luck and should look for other way.

If the files are present you can try to read it yourself.

Also the getUidTxBytes() and getUIDRxBytes() report only the TCP traffic and miss UDP traffic. So if your app is doing lots of UDP traffic (like voip) then you'll not get any info. There is already a bug filed for this : https://code.google.com/p/android/issues/detail?id=32410

like image 22
Srikant Sahay Avatar answered Nov 20 '22 19:11

Srikant Sahay


I have done some detailed research about this, and to clarify some details, since Android 4.3 the TrafficStats API has changed in the way it extracts details from the device.

Prior to Android 4.3 the UID traffic stats were available for TCP and UDP and included API for bytes and packets & sent and received. That data was extracted from the /proc/uid_stat/[pid]/* files.

In Android 4.3, the developers has decided to switch to a better and more safe API, using the xt_qtaguid UID statistics, which is part of the netfilter kernel module in Linux. This API (procfs) allows access based on process UID, and this is why when you try to access to TrafficStats API in Android=>4.3 you will get zero information for not-own UID.

btw, the commit that caused the issue is the following: https://github.com/android/platform_frameworks_base/commit/92be93a94edafb5906e8bc48e6fee9dd07f5049e

*Improve TrafficStats UID APIs. Deprecate transport layer statistics, leaving only the summarized network layer statistics. Improve documentation to be clear about layers where measurements occur, and their behavior since boot. Under the hood, move to using xt_qtaguid UID statistics. Bug: 6818637, 7013662 Change-Id: I9f26992e5fcdebd88c671e5765bd91229e7b0016*

like image 2
Roman Blachman Avatar answered Nov 20 '22 18:11

Roman Blachman