Android 如何以编程方式显示所有应用程序的数据使用情况?

Android 如何以编程方式显示所有应用程序的数据使用情况?,android,usage-statistics,android-data-usage,Android,Usage Statistics,Android Data Usage,在Android 4.0以后的版本中,我们在手机中提供了数据使用控制选项。请检查所附的屏幕截图以进一步了解 现在我需要从我的应用程序中检查这些内容(特定时间段/特定天数内的所有应用程序的数据使用情况)。我怎样才能做到这一点?我还使用下面的类获取网络使用详细信息 请查看下面的链接图片。我需要开发同样的应用程序 感谢分享您的代码,但我需要知道每个应用程序而不是所有应用程序使用的数据。到目前为止,我在链接中观察到,没有人谈论单个应用程序的数据使用情况。我已经知道如何在设备中显示已安装的应用

在Android 4.0以后的版本中,我们在手机中提供了数据使用控制选项。请检查所附的屏幕截图以进一步了解

现在我需要从我的应用程序中检查这些内容(特定时间段/特定天数内的所有应用程序的数据使用情况)。我怎样才能做到这一点?我还使用下面的类获取网络使用详细信息

请查看下面的链接图片。我需要开发同样的应用程序

感谢分享您的代码,但我需要知道每个应用程序而不是所有应用程序使用的数据。到目前为止,我在链接中观察到,没有人谈论单个应用程序的数据使用情况。我已经知道如何在设备中显示已安装的应用程序。现在我想知道每个应用程序使用的数据是什么

我使用下面的代码列出设备中已安装的应用程序

private ArrayList<PInfo> getInstalledApps(boolean getSysPackages) {
    ArrayList<PInfo> res = new ArrayList<PInfo>();

    List<PackageInfo> packs = getPackageManager().getInstalledPackages(0);

    for (int i=0; i<packs.size(); i++) {
        PackageInfo p = packs.get(i);
        if ((!getSysPackages) && (p.versionName == null)) {
            continue ;
        }
        PInfo newInfo = new PInfo();
        newInfo.setAppname(p.applicationInfo.loadLabel(getPackageManager()).toString());
        newInfo.setPname(p.packageName);
        newInfo.setVersionName(p.versionName);
        newInfo.setVersionCode(p.versionCode);
        newInfo.setIcon(p.applicationInfo.loadIcon(getPackageManager()));

        res.add(newInfo);
    }
    return res;
}
private ArrayList getInstalledApps(布尔getSysPackages){
ArrayList res=新的ArrayList();
列表包=getPackageManager()。getInstalledPackages(0);

对于(int i=0;i您可以使用
android.net.TrafficStats
获取网络使用详细信息

请在下面找到同样的示例程序

package com.anchit.trafficstatus;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

public class TrafficStatus extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        Log.e("bytes recvd", "" + android.net.TrafficStats.getMobileRxBytes());

        Log.e("Total", "Bytes received" + android.net.TrafficStats.getTotalRxBytes());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

旧答案(主要适用于Api级别23以下的设备) 首先,获取所有正在运行的应用程序的进程信息列表:

List<RunningAppProcessInfo>
可以从“设置->安全->应用程序使用权限访问”屏幕授予此权限。要请求此权限,只需使用设置启动活动。操作\u使用\u访问\u设置旨在帮助用户达到目的:


startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
设置完所有内容后,您可以获得NetworkStatsManager的实例,我们需要该实例来获取网络使用数据:

NetworkStatsManager networkStatsManager = (NetworkStatsManager) context.getSystemService(Context.NETWORK_STATS_SERVICE);
  • 无论执行什么查询,都会得到一个NetworkStats.Bucket或NetworkStats(它基本上是多个Bucket的容器,使用hasNextBucket()和getNextBucket()方法访问实际数据(还记得在对象超出范围之前使用close())

  • 在每个查询中,您必须指定网络类型(ConnectivityManager.type_WIFI或ConnectivityManager.type_MOBILE)。


  • 进行查询所需的用户Id,除非用户切换SIM卡或运营商,否则该Id将保持不变。若要获取该Id

  • 要访问单个应用程序统计信息,您需要该应用程序的uid,它是系统在安装时分配给每个应用程序的int值
用于网络使用的UID由以下原因引起: 


  • 未安装的应用程序:UID\u已删除

  • 栓系:油液栓系
  • 安卓操作系统:系统

  • 获取所有应用的统计信息:UID\u all
一些示例查询:

- To get Total Rx bytes          -  TrafficStats.getTotalRxBytes();
   
- To get Total Tx bytes          -  TrafficStats.getTotalTxBytes();
    
- To get all Mobile Rx bytes     -  TrafficStats.getMobileRxBytes();
        
- To get all Mobile Tx bytes     -  TrafficStats.getMobileTxBytes();
        
- To get all Wifi Rx bytes       -  TrafficStats.getTotalRxBytes() - TrafficStats.getMobileRxBytes();
    
- To get all Wifi Tx bytes       -  TrafficStats.getTotalTxBytes() - TrafficStats.getMobileTxBytes();
- To get Package Rx Bytes :      -  TrafficStats.getUidRxBytes(packageUid);
- To get Package Tx Bytes :      -  TrafficStats.getUidTxBytes(packageUid);
要获取移动设备的所有接收和发送字节:

要获取Wifi的所有接收和发送字节:

要获取手机包的所有接收和发送字节:

要获取包的所有Wifi接收和发送字节:

注:

  • 这些查询不应该在主线程或 它们将导致你的应用程序掉帧
  • NetworkStatsManager.query*引发RemoteException
  • 漫游和标签是在API级别24(安卓7.0牛轧糖)中添加的,所以如果你的目标是棉花糖(API级别23),你将无法使用它们
  • 由于API level 24(Android 7.0 Nougat)如果您只想获取应用程序数据,则可以使用NetworkStatsManager,而无需获得PACKAGE\u USAGE\u STATS权限。如果您的目标是访问其他应用程序的统计数据,则仍然需要它
2.TrafficStats:它还提供了所需的信息,但存在一些缺点,使其不可靠,至少:


  • 每次重新启动后数据都会重置

  • 在某些设备上也可能不支持它
TrafficStats的一些示例方法:

- To get Total Rx bytes          -  TrafficStats.getTotalRxBytes();
   
- To get Total Tx bytes          -  TrafficStats.getTotalTxBytes();
    
- To get all Mobile Rx bytes     -  TrafficStats.getMobileRxBytes();
        
- To get all Mobile Tx bytes     -  TrafficStats.getMobileTxBytes();
        
- To get all Wifi Rx bytes       -  TrafficStats.getTotalRxBytes() - TrafficStats.getMobileRxBytes();
    
- To get all Wifi Tx bytes       -  TrafficStats.getTotalTxBytes() - TrafficStats.getMobileTxBytes();
- To get Package Rx Bytes :      -  TrafficStats.getUidRxBytes(packageUid);
- To get Package Tx Bytes :      -  TrafficStats.getUidTxBytes(packageUid);

2015年Arunendra的解决方案在SDK 28(Pie)上没有立即对我起作用

所以我修改如下:

void networkUsage() {
    // Get running processes
    ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> runningApps = manager.getRunningAppProcesses();
    for (ActivityManager.RunningAppProcessInfo runningApp : runningApps) {
        long received = TrafficStats.getUidRxBytes(runningApp.uid);
        long sent = TrafficStats.getUidTxBytes(runningApp.uid);
        Log.d(LOG_TAG, String.format(Locale.getDefault(), 
                "uid: %1d - name: %s: Sent = %1d, Rcvd = %1d", runningApp.uid, runningApp.processName, sent, received));
    }
}
void networkUsage(){
//获取正在运行的进程
ActivityManager=(ActivityManager)getSystemService(ActivityU服务);
List runningApps=manager.getrunningappprocesss();
对于(ActivityManager.RunningAppProcessInfo runningApp:runningApps){
long received=TrafficStats.getUidRxBytes(runningApp.uid);
long sent=TrafficStats.getUidTxBytes(runningApp.uid);
Log.d(Log_标记,String.format(Locale.getDefault(),
“uid:%1d-名称:%s:Sent=%1d,Rcvd=%1d”,runningApp.uid,runningApp.processName,Sent,received));
}
}
请注意,此类返回的统计信息会在每次重新启动后重置并从零开始。若要访问更可靠的历史网络统计信息数据,请改用

Src:


有关如何使用NetworkStatsManager的详细信息,请查看此答案:

请完整准确地解释您需要“检查”的“这些东西”是什么来自您的应用程序。您好,Commonware我更新了我的帖子。您现在可以检查一下吗?您是否得到了问题的正确答案,或者您成功地实现了您的要求?如果是,请分享解决方案,我也在寻找它。@kiran_b您也可以使用TrafficStats类中可用的UIDs相关方法谢谢分享您的代码,但我需要知道每个应用程序使用的数据,而不是所有应用程序使用的数据applications@Kiran_b亲爱的,这就是为什么我提到你需要使用TrafficStats类的API来了解UID。这些可以是特定于进程的,可以为你获取每个进程的详细信息。请遵循下面提到的stackoverflow链接@AnchiMittal,可能吗要获取日常使用量?我知道我们可以获取详细信息,并从上一个中减去它,但除此之外还有其他建议吗?如何将其修改为查询onl
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 

String subscriberId = manager.getSubscriberId();
PackageManager packageManager = context.getPackageManager();

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

int uid = info.uid;
NetworkStats.Bucket bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE, getSubscriberId(context, ConnectivityManager.TYPE_MOBILE), 0, System.currentTimeMillis());
        
    
bucket.getRxBytes();
bucket.getTxBytes();
        
NetworkStats.Bucket bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI, ””, 0, System.currentTimeMillis());
       
bucket.getRxBytes();
bucket.getTxBytes();
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();
NetworkStats.Bucket bucket = networkStatsManager.queryDetailsForUid(ConnectivityManager.TYPE_WIFI, “”, 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();
- To get Total Rx bytes          -  TrafficStats.getTotalRxBytes();
   
- To get Total Tx bytes          -  TrafficStats.getTotalTxBytes();
    
- To get all Mobile Rx bytes     -  TrafficStats.getMobileRxBytes();
        
- To get all Mobile Tx bytes     -  TrafficStats.getMobileTxBytes();
        
- To get all Wifi Rx bytes       -  TrafficStats.getTotalRxBytes() - TrafficStats.getMobileRxBytes();
    
- To get all Wifi Tx bytes       -  TrafficStats.getTotalTxBytes() - TrafficStats.getMobileTxBytes();
- To get Package Rx Bytes :      -  TrafficStats.getUidRxBytes(packageUid);
- To get Package Tx Bytes :      -  TrafficStats.getUidTxBytes(packageUid);
void networkUsage() {
    // Get running processes
    ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> runningApps = manager.getRunningAppProcesses();
    for (ActivityManager.RunningAppProcessInfo runningApp : runningApps) {
        long received = TrafficStats.getUidRxBytes(runningApp.uid);
        long sent = TrafficStats.getUidTxBytes(runningApp.uid);
        Log.d(LOG_TAG, String.format(Locale.getDefault(), 
                "uid: %1d - name: %s: Sent = %1d, Rcvd = %1d", runningApp.uid, runningApp.processName, sent, received));
    }
}