如何在 Android 上找到每个应用程序的数据使用情况?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11939939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I find the data usage on a per-application basis on Android?
提问by yuvi
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!.
我试图在每个应用程序的基础上找出 Android 上的数据使用情况。像Android 数据使用应用程序和配额/上限监视器小部件:永远不会为数据收取额外费用或再次上限!.
I looked at Stack Overflow question How to go about detecting data usage in the Android environment.
我查看了堆栈溢出问题如何检测 Android 环境中的数据使用情况。
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 UIDsare numbers, unlike app_79
as you have mentioned above. Is this all right?
我按照Akos Cz 的建议尝试了上述代码。然而,所有的UID都是数字,不像app_79
你上面提到的。这一切都好吗?
采纳答案by Akos Cz
The following links should help you figure out how to programmatically determine the data usage per application.
以下链接可帮助您了解如何以编程方式确定每个应用程序的数据使用情况。
cw-andtuning/TrafficMonitor(GitHub)
You will need to implement your code to use the TraficStatsAPI and track the number of bytes sent/received per UID (application).
您需要实现代码以使用TraficStatsAPI 并跟踪每个 UID(应用程序)发送/接收的字节数。
回答by Mahmudul
Use this method after create a new class PackageInformationTotal.
在创建新类 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.
之后,您可以以 MB 为单位跟踪所有进程使用情况。
回答by 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.
您可以为ACTION_MANAGE_NETWORK_USAGE
操作(在 Android 4.0 中引入)声明意图过滤器,以指示您的应用程序定义了一个活动,该活动提供控制数据使用的选项。ACTION_MANAGE_NETWORK_USAGE
显示用于管理特定应用程序的网络数据使用的设置。当您的应用具有允许用户控制网络使用的设置活动时,您应该为该活动声明此意图过滤器。查看有关管理数据使用情况的更多信息管理每个应用程序的使用情况。
The proper definition of ACTION_MANAGE_NETWORK_USAGE
is you can see here.
的正确定义ACTION_MANAGE_NETWORK_USAGE
是你可以在这里看到。
回答by 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;
}
}
回答by Akshay Chopde
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
您还可以查看https://github.com/commonsguy/cw-andtuning/tree/master/TrafficMonitor
回答by Anshuman
After a long struggle,I am able to find the Solution for getting data over any interface for each installed Application in android device.
经过长时间的努力,我能够找到通过任何接口为 android 设备中安装的每个应用程序获取数据的解决方案。
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.
由于 Android 提供了 TrafficStats API,但这些 API 为每个应用 uid 提供了完整的数据统计,因为设备启动和 Even API 不支持通过特定应用的任何接口获取数据。即使我们依赖 TraffiucStates APIS,我们也会为每个应用程序获得一个新的数据统计信息。
So I thought to use the hidden APIs to USe this..
所以我想使用隐藏的API来使用这个..
Here I am mentioning the Steps to get the data statstics for each application over any Interface in Android...
在这里,我提到了通过 Android 中的任何接口获取每个应用程序的数据统计信息的步骤...
Estabalish a "INetworkStatsSession" session
#import android.net.INetworkStatsSession;
建立“INetworkStatsSession”会话
#import android.net.INetworkStatsSession;
INetworkStatsSession mStatsSession = mStatsService.openSession();
INetworkStatsSession mStatsSession = mStatsService.openSession();
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()));
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); }
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; }
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())); }
根据要测量的界面创建网络模板。
#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()));
获取活动订阅者 ID:
private static String getActiveSubscriberId(Context context) { final TelephonyManager tele = TelephonyManager.from(context); final String actualSubscriberId = tele.getSubscriberId(); return SystemProperties.get(TEST_SUBSCRIBER_PROP, actualSubscriberId); }
通过传递应用程序 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; }
获取总消耗数据:
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())); }