如何在Android上基于每个应用程序查找数据使用情况?

时间:2012-08-13 18:14:38

标签: android usage-statistics

我试图在每个应用程序的基础上找出Android上的数据使用情况。类似于 Android Data Usage Apps and Quota / Cap Monitor Widgets: never get charged extra for data or get capped again!

我查看了Stack Overflow问题 How to go about detecting data usage in the Android environment

但它没有多大帮助。


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

我尝试了上面的代码suggested by Akos Cz。但是,所有UIDs都是数字,与上面提到的app_79不同。这样可以吗?

7 个答案:

答案 0 :(得分:38)

以下链接可帮助您了解如何以编程方式确定每个应用程序的数据使用情况。

您需要实现代码才能使用TraficStats API并跟踪每个UID(应用程序)发送/接收的字节数。

答案 1 :(得分:9)

在创建新类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();
}

之后,您可以以MB为单位跟踪所有流程使用情况。

答案 2 :(得分:1)

<强> Prorammatically:

您可以声明ACTION_MANAGE_NETWORK_USAGE操作的意图过滤器(在Android 4.0中引入),以指示您的应用程序定义了一个活动,该活动提供控制数据使用的选项。 ACTION_MANAGE_NETWORK_USAGE显示用于管理特定应用程序的网络数据使用情况的设置。当您的应用具有允许用户控制网络使用的设置活动时,您应该为该活动声明此意图过滤器。 有关管理数据使用情况manage usage per application的详细信息,请查看此内容。

ACTION_MANAGE_NETWORK_USAGE的正确定义是here

答案 3 :(得分:0)

此代码段也适用于在您的设备中实际运行应用的用户

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

答案 4 :(得分:0)

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

您还可以结帐https://github.com/commonsguy/cw-andtuning/tree/master/TrafficMonitor

答案 5 :(得分:0)

要访问单个应用程序统计信息,您将需要该应用程序的uid,这是系统在安装时为每个应用程序分配的int值。

PackageManager packageManager = context.getPackageManager();

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

int packageUid = info.uid;

获取包的Mobile的所有Rx和Tx字节:

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();

有关此的更多说明,请检查: How do I programmatically show data usage of all applications?

答案 6 :(得分:-1)

经过长时间的努力,我能够找到解决方案,通过android中每个安装的应用程序的任何界面获取数据 设备

由于Android提供TrafficStats Apis,但这些API为自设备启动和均匀后的每个应用程序提供了完整的数据存储 API不支持通过特定应用程序的任何接口获取数据。 即使我们依赖TraffiucStates APIS,我们也会为每个应用程序获得一个新的数据统计数据。

所以我想用隐藏的API来使用它..

在这里,我提到了通过Android中的任何界面获取每个应用程序的数据统计信息的步骤...

  1. 建立&#34; INetworkStatsSession&#34;会议

    #import android.net.INetworkStatsSession;

  2. INetworkStatsSession mStatsSession = mStatsService.openSession();

    1. 根据您要测量的interfce创建网络模板。

      #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. 通过传递应用程序UID来收集相应应用程序的网络HIStory ......

       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. 获取总消费数据:

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