如何在Android上按应用程序查找数据使用情况?

我正在尝试在每个应用程序的基础上找出Android上的数据使用情况。 像Android数据使用应用程序和配额/大写监视器小工具:永远不会收取数据额外的费用或再次封顶!

我看了堆栈溢出问题如何去检测Android环境中的数据使用情况

但这并没有太大的帮助。


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

我按照Akos Cz的build议尝试了上面的代码。 不过,所有的UID都是数字,不像上面提到的app_79 。 这样好吗?

以下链接应该帮助您弄清楚如何以编程方式确定每个应用程序的数据使用情况。

  • cw-andtuning / TrafficMonitor (GitHub)

  • 使用Android的TrafficStats类创build一个networking监视器

  • Androidstream量统计里面

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

创build新的类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中的所有过程用法。

Prorammatically:

您可以声明ACTION_MANAGE_NETWORK_USAGE操作的意图filter(在Android 4.0中引入),以表明您的应用程序定义了一个活动,该活动提供了控制数据使用的选项。 ACTION_MANAGE_NETWORK_USAGE显示pipe理特定应用程序的networking数据使用情况的设置。 当您的应用程序具有允许用户控制networking使用情况的设置活动时,您应该为该活动声明此意图filter。 请参阅此处了解有关pipe理数据使用情况pipe理每个应用程序的使用情况

ACTION_MANAGE_NETWORK_USAGE的正确定义可以在这里看到。

这个片段也适用于那些实际在你的设备上运行应用程序的人

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

经过漫长的斗争,我能够find解决scheme获取通过Android设备中的每个已安装的应用程序的任何接口的数据。

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

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

在这里,我提到了通过Android中的任何接口获取每个应用程序的数据静态的步骤…

  1. build立一个“INetworkStatsSession”会话

    #import android.net.INetworkStatsSession;

INetworkStatsSession mStatsSession = mStatsService.openSession();

  1. 根据你想测量的界面创build一个networking寺庙。

     #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收集各个应用程序的networkingHIStory …

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