Question

I am trying to find out the data usage on Android on a per-application basis. Something like Android Data Usage Apps and Quota / Cap Monitor Widgets: never get charged extra for data or get capped again!.

I looked at Stack Overflow question How to go about detecting data usage in the Android environment.

But it's not been of much help.


ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo mInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo( mInfo );
List<RunningAppProcessInfo> listOfRunningProcess = activityManager.getRunningAppProcesses();
Log.d(TAG, "XXSize: " + listOfRunningProcess.size());

for (RunningAppProcessInfo runningAppProcessInfo : listOfRunningProcess) {

    if (runningAppProcessInfo.uid > 1026)
    {
        Log.d(TAG, "ANS " + runningAppProcessInfo.processName +
                   " Id :" + runningAppProcessInfo.pid +
                   " UID: " + runningAppProcessInfo.uid);
    }
}

I tried the above code as suggested by Akos Cz. However all the UIDs are numbers, unlike app_79 as you have mentioned above. Is this all right?

Was it helpful?

Solution

The following links should help you figure out how to programmatically determine the data usage per application.

You will need to implement your code to use the TraficStats API and track the number of bytes sent/received per UID (application).

OTHER TIPS

Use this method after create a new class PackageInformationTotal.

public void getPakagesInfoUsingHashMap() {
    final PackageManager pm = getPackageManager();
    // get a list of installed apps.
    List<ApplicationInfo> packages = pm.getInstalledApplications(0);

    // loop through the list of installed packages and see if the selected
    // app is in the list
    for (ApplicationInfo packageInfo : packages) {
        // get the UID for the selected app
        UID = packageInfo.uid;
        String package_name = packageInfo.packageName;
        ApplicationInfo app = null;
        try {
            app = pm.getApplicationInfo(package_name, 0);
        } catch (NameNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String name = (String) pm.getApplicationLabel(app);
        Drawable icon = pm.getApplicationIcon(app);
        // internet usage for particular app(sent and received)
        double received = (double) TrafficStats.getUidRxBytes(UID)

                / (1024 * 1024);
        double send = (double) TrafficStats.getUidTxBytes(UID)
                / (1024 * 1024);
        double total = received + send;

        if(total>0)
        {
            PackageInformationTotal pi=new PackageInformationTotal();
            pi.name=name;
            pi.packageName=package_name;
            pi.icon=icon;               
            pi.totalMB=String.format( "%.2f", total )+" MB";
            pi.individual_mb=String.format( "%.2f", total );
            totalData+=Double.parseDouble(String.format( "%.2f", total ));
            dataHash.add(pi);
        Log.e(name,String.format( "%.2f", total )+" MB");
        }

    }
    Editor edit=shared.edit();
    edit.putString("Total",String.format( "%.2f", totalData));
    edit.commit();
}

After that you can track all process usages in MB.

Prorammatically:

You can declare the intent filter for the ACTION_MANAGE_NETWORK_USAGE action (introduced in Android 4.0) to indicate that your application defines an activity that offers options to control data usage. ACTION_MANAGE_NETWORK_USAGE shows settings for managing the network data usage of a specific application. When your app has a settings activity that allows users to control network usage, you should declare this intent filter for that activity. Check this out for more information about managing data usage manage usage per application.

The proper definition of ACTION_MANAGE_NETWORK_USAGE is you can see here.

 public class Main extends Activity {

    private Handler mHandler = new Handler();
    private long mStartRX = 0;
    private long mStartTX = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mStartRX = TrafficStats.getTotalRxBytes();
        mStartTX = TrafficStats.getTotalTxBytes();
        if (mStartRX == TrafficStats.UNSUPPORTED || mStartTX == TrafficStats.UNSUPPORTED) {
            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.setTitle("Uh Oh!");
            alert.setMessage("Your device does not support traffic stat monitoring.");
            alert.show();
        } else {
            mHandler.postDelayed(mRunnable, 1000);
        }
    }

    private final Runnable mRunnable = new Runnable() {
        public void run() {
            TextView RX = (TextView)findViewById(R.id.RX);
            TextView TX = (TextView)findViewById(R.id.TX);
            long rxBytes = TrafficStats.getTotalRxBytes()- mStartRX;
            RX.setText(Long.toString(rxBytes));
            long txBytes = TrafficStats.getTotalTxBytes()- mStartTX;
            TX.setText(Long.toString(txBytes));
            mHandler.postDelayed(mRunnable, 1000);
        }
     };
}

You can also checkout https://github.com/commonsguy/cw-andtuning/tree/master/TrafficMonitor

This snippet also works for those actually running apps in your device

final PackageManager pm = getPackageManager();

ActivityManager activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
//final List<ActivityManager.RunningTaskInfo> recentTasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (int i = 0; i < appProcesses.size(); i++) {
    Log.d("Executed app", "Application executed : " + appProcesses.get(i).processName + "\t\t ID: " + appProcesses.get(i).pid + "");
    //  String packageName = activityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
    //String packageName = appProcesses.get(i)..getPackageName();
    ApplicationInfo app = null;
    try {
        app = pm.getApplicationInfo(appProcesses.get(i).processName, 0);
        if ((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1) {
            //it's a system app, not interested
        } else if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
            //Discard this one
            //in this case, it should be a user-installed app
        } else {
            // tx = TrafficStats.getUidTxBytes(app.uid);
            //rx = TrafficStats.getUidRxBytes(app.uid);
            long delta_rx = TrafficStats.getUidRxBytes(app.uid) - rx;

            long delta_tx = TrafficStats.getUidTxBytes(app.uid) - tx;
        }
    }

To access an individual app stats you will need the uid of that app, which is an int value assigned by the system to each app at install time.

PackageManager packageManager = context.getPackageManager();

ApplicationInfo info = packageManager.getApplicationInfo("com.example.app", 0); 

int packageUid = info.uid;

To get all Rx and Tx bytes of Mobile for package :

NetworkStats.Bucket bucket = networkStatsManager.queryDetailsForUid(ConnectivityManager.TYPE_MOBILE, getSubscriberId(context, ConnectivityManager.TYPE_MOBILE), 0, System.currentTimeMillis(),packageUid);
            
            
    
long rxBytes = 0L;
           
long txBytes = 0L;
            
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
           
while (networkStats.hasNextBucket()) {
            
     networkStats.getNextBucket(bucket);
     rxBytes += bucket.getRxBytes();
     txBytes += bucket.getTxBytes(); 
}
networkStats.close();

For more clarification about this, check: How do I programmatically show data usage of all applications?

After a long struggle,I am able to find the Solution for getting data over any interface for each installed Application in android device.

As Android provides TrafficStats Apis but these APIs are providing comple Data stastics for each app uid since device boot and Even APIs are not supporting to get the data over any interface for a particular application. Even if we rely over TraffiucStates APIS ,we get a new data statstics for each Application.

So I thought to use the hidden APIs to USe this..

Here I am mentioning the Steps to get the data statstics for each application over any Interface in Android...

  1. Estabalish a "INetworkStatsSession" session

    #import android.net.INetworkStatsSession;

INetworkStatsSession mStatsSession = mStatsService.openSession();

  1. Create a Network Templeate according to interafce which you want to measure..

    #import static android.net.NetworkTemplate.buildTemplateEthernet;
    #import static android.net.NetworkTemplate.buildTemplateMobile3gLower;
    #import static android.net.NetworkTemplate.buildTemplateMobile4g;
    #import static android.net.NetworkTemplate.buildTemplateMobileAll;
    #import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
    
    #import android.net.NetworkTemplate;
    
    private NetworkTemplate mTemplate;
    
    mTemplate = buildTemplateMobileAll(getActiveSubscriberId(this
                    .getApplicationContext()));
    
  2. GetActive SubcriberID:

    private static String getActiveSubscriberId(Context context) {
        final TelephonyManager tele = TelephonyManager.from(context);
        final String actualSubscriberId = tele.getSubscriberId();
        return SystemProperties.get(TEST_SUBSCRIBER_PROP, actualSubscriberId);
    }
    
  3. Collect the network HIStory of respective application byt passing application UIDs...

     private NetworkStatsHistory collectHistoryForUid(NetworkTemplate template,
            int uid, int set) throws RemoteException {
        final NetworkStatsHistory history = mStatsSession.getHistoryForUid(
                template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
        return history;
    
    }
    
  4. Get the total Consumption data:

    public void showConsuption(int UID){
        NetworkStatsHistory history = collectHistoryForUid(mTemplate, UID,
                SET_DEFAULT);
    
        Log.i(DEBUG_TAG, "load:::::SET_DEFAULT:.getTotalBytes:"+ Formatter.formatFileSize(context, history.getTotalBytes()));
    
        history = collectHistoryForUid(mTemplate, 10093,
                SET_FOREGROUND);
        Log.i(DEBUG_TAG, "load::::SET_FOREGROUND::.getTotalBytes:"+ Formatter.formatFileSize(context, history.getTotalBytes()));
    
        history = collectHistoryForUid(mTemplate, 10093,
                SET_ALL);
        Log.i(DEBUG_TAG, "load::::SET_ALL::.getTotalBytes:"+ Formatter.formatFileSize(context, history.getTotalBytes()));
    
    }
    
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top