How can I find the data usage on a per-application basis on Android?

只谈情不闲聊 提交于 2019-11-26 10:19:51
Akos Cz

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

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.

NIlesh Sharma

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

Srishti Roy

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

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()));
    
    }
    
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!