即使在Android N上,如何获取应用程序(或总计)的当前网络使用率? [英] How to get current network usage of app (or in total), even on Android N?
问题描述
如标题所述.我想知道特定应用程序在特定时间每秒使用多少个字节.
As the title says. I wish to know how many bytes per second a specific app use at specific time.
也许我可以使用" netstat "命令?但是,如果是这样,我如何将其过滤到特定的应用程序/进程?
Maybe I can use "netstat" command? But if so, how can I filter it to a specific app/process ?
我还需要获得许可吗?
Do I also need to have some permission to do it?
目前,人们说要使用TrafficStats.getUidRxBytes(packageInfo.uid),但是从这里开始:
Currently people say to use TrafficStats.getUidRxBytes(packageInfo.uid) , but, from here: https://developer.android.com/reference/android/net/TrafficStats.html#getUidRxBytes(int) , it says it's not supported from N , and that I should use NetworkStatsManager instead. Is there any example to use it?
也许是合并的解决方案?
Maybe a merged solution?
我试图在Android N上使用NetworkStatsManager,但是失败了.我找不到任何有关如何使用它的示例,并且所有关于它的stackOverflow问题在不能很好地使用它方面都是相似的.请,如果有人知道如何使用它,请写下它.
I tried to use NetworkStatsManager on Android N, but I failed. I can't find any sample of how to use it, and all stackOverflow questions about it were similar in term of not being able to use it well. Please, if anyone knows how to use it, write about it.
推荐答案
NetworkStats
的用法并不复杂.
设备API级别必须至少为23.这是开始使用NetworkStatsManager
The device API level must be at minimum 23. Here are some steps required prior to starting the usage of NetworkStatsManager
-
在
AndroidManifest.xml
中声明所需的权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions"/>
在Activity
android.permission.PACKAGE_USAGE_STATS
不是普通权限,因此不能简单地请求它.为了检查是否已授予许可,请检查:
android.permission.PACKAGE_USAGE_STATS
is not a normal permission, therefore cannot be simply requested. In order to check, whether the permission has been granted, check:
AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
android.os.Process.myUid(), getPackageName());
if (mode == AppOpsManager.MODE_ALLOWED) {
return true;
}
要请求此权限,只需致电Intent
:
To ask for this permission, simply call Intent
:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
还需要另一个权限:Manifest.permission.READ_PHONE_STATE
.但是,这是正常权限,因此可以被要求为其他任何权限
Another permmission is also needed: Manifest.permission.READ_PHONE_STATE
. However, this is normal permission so can be requested as any other permission
使用NetworkStatsManager
:
要获取参考,请致电:
NetworkStatsManager networkStatsManager = (NetworkStatsManager) getApplicationContext().getSystemService(Context.NETWORK_STATS_SERVICE);
从NetworkStatsManager
中检索到的所有内容都打包到 Buckets
.这只是一个简单的POJO,用于保存数据.
Everything that is retrieved from NetworkStatsManager
is packed into Buckets
. This is just a simple POJO, that holds the data.
全球:
要获取 WiFi 的总体使用情况:
To get the overall usage for WiFi:
NetworkStats.Bucket bucket;
try {
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI,
"",
0,
System.currentTimeMillis());
} catch (RemoteException e) {
return -1;
}
NetworkStats.Bucket
开始,可以调用两种方法来获取用法(以Bps为单位):
from NetworkStats.Bucket
, two methods can be called to get the usage (in Bps):
bucket.getRxBytes();
bucket.getTxBytes();
获取移动网络的数据比较困难.为了获得Bucket
呼叫:
Obtaining the data for mobile network is harder. In order to obtain the Bucket
call:
public long getAllRxBytesMobile(Context context) {
NetworkStats.Bucket bucket;
try {
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE,
getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
0,
System.currentTimeMillis());
} catch (RemoteException e) {
return -1;
}
return bucket.getRxBytes();
}
//Here Manifest.permission.READ_PHONE_STATS is needed
private String getSubscriberId(Context context, int networkType) {
if (ConnectivityManager.TYPE_MOBILE == networkType) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.getSubscriberId();
}
return "";
}
应用:
For obtaining the data for specific application, read the documentation for queryDetailsForUID.
要获取 WiFi 的软件包使用情况,请执行以下操作:
To get the package usage for WiFi:
NetworkStats networkStats = null;
try {
networkStats = networkStatsManager.queryDetailsForUid(
ConnectivityManager.TYPE_WIFI,
"",
0,
System.currentTimeMillis(),
packageUid);
} catch (RemoteException e) {
return -1;
}
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
networkStats.getNextBucket(bucket);
要获取移动的软件包使用情况,请执行以下操作:
To get the package usage for Mobile:
NetworkStats networkStats = null;
try {
networkStats = networkStatsManager.queryDetailsForUid(
ConnectivityManager.TYPE_MOBILE,
getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
0,
System.currentTimeMillis(),
packageUid);
} catch (RemoteException e) {
return -1;
}
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
networkStats.getNextBucket(bucket);
Unfortunately, according to this piece of code getting statistics is only possible for ConnectivityManager.TYPE_MOBILE
and ConnectivityManager.TYPE_WIFI
.
制作了一个示例 Github存储库降低了使用率.
Made a sample Github repo demostrating the usage.
这篇关于即使在Android N上,如何获取应用程序(或总计)的当前网络使用率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!