正如标题所说。我想知道特定应用在特定时间每秒使用的字节数。
也许我可以使用“netstat”命令?但如果是这样,我如何将其过滤到特定的应用/流程?
我是否还需要获得一些许可?
目前人们说使用TrafficStats.getUidRxBytes(packageInfo.uid),但是,从这里:https://developer.android.com/reference/android/net/TrafficStats.html#getUidRxBytes(int),它表示N不支持它,我应该使用NetworkStatsManager。有没有使用它的例子?
也许合并后的解决方案?
编辑:我尝试在Android N上使用NetworkStatsManager,但我失败了。我找不到任何关于如何使用它的示例,并且关于它的所有stackOverflow问题都是类似的,因为它无法很好地使用它。如果有人知道如何使用它,请写下来。答案 0 :(得分:19)
NetworkStats
的用法并不复杂。
设备API级别必须至少为23.以下是开始使用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
不是正常的权限,因此无法简单地请求。要检查是否已授予权限,请检查:
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
:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
还需要另外的许可:Manifest.permission.READ_PHONE_STATE
。但是,这是正常的权限,因此可以requested as any other permission
使用NetworkStatsManager
:
要获得它的参考,请致电:
NetworkStatsManager networkStatsManager = (NetworkStatsManager) getApplicationContext().getSystemService(Context.NETWORK_STATS_SERVICE);
从NetworkStatsManager
检索到的所有内容都会打包到Buckets
中。这只是一个简单的POJO,它保存数据。
<强> GLOBAL:强>
获取 WiFi 的整体使用情况:
NetworkStats.Bucket bucket;
try {
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI,
"",
0,
System.currentTimeMillis());
} catch (RemoteException e) {
return -1;
}
来自NetworkStats.Bucket
,可以调用两种方法来获取用法(以Bps为单位):
bucket.getRxBytes();
bucket.getTxBytes();
获取移动网络的数据更难。为了获得Bucket
电话:
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 "";
}
<强>应用强>
要获取特定应用程序的数据,请阅读queryDetailsForUID的文档。
获取 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);
获取移动的包裹使用情况:
Unfortunalety
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);
不幸的是,根据this piece of code获取统计数据仅适用于ConnectivityManager.TYPE_MOBILE
和ConnectivityManager.TYPE_WIFI
。
制作样本Github repo,说明用法。
答案 1 :(得分:7)
还有一种复杂的方法来获取统计信息,但这适用于所有适配器:(但它很昂贵,因为你必须不断读取文件),
cat /proc/net/dev
cat /sys/class/net/**wlan0**/statistics/**rx**_bytes
wlan0 可能是您的所有适配器,但您需要在应用中维护该值,因为如果您关闭/打开适配器,该值将再次为0。 (您可以拥有RX和TX值)
cat /proc/net/**tcp6**
这也可以通过 tcp , tcp6 ,更新, upd6
来完成在这里你有&#34; uid&#34;列,这是您安装的应用程序的UID。 (所以应用程序现在正在使用网络)
从这个文件中你也可以看到连接端点。
cat /proc/uid_stat/**10348**/tcp_snd
这里的 id 是应用程序UID。 您已发送: tcp_snd 和收到的: tcp_rcv 文件。
cat /proc/**17621**/status
此处的ID是您可以从中获取的进程ID。 顶部命令。 在状态文件中,您将拥有UID,即已安装的/系统应用UID。
1。你也可以看看这个文件,TrafficStats API使用这个:
cat /proc/net/xt_qtaguid/stats
接头:
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
值:
6 eth0 0x0 10005 0 0 0 80 2 0 0 0 0 0 0 80 2 0 0 0 0
7 eth0 0x0 10005 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
8 eth0 0x0 10007 0 11133 25 4751 24 11133 25 0 0 0 0 4751 24 0 0 0 0
9 eth0 0x0 10007 1 5965514 4358 102028 2327 5965514 4358 0 0 0 0 102028 2327 0 0 0 0
10 eth0 0x0 10014 0 95 1 40 1 95 1 0 0 0 0 40 1 0 0 0 0
因此,将第一个答案与这些知识混合起来,您可以获得更多更好的统计数据。
答案 2 :(得分:1)
添加我的简化功能可以通过/ proc / net / dev获得整个网络的使用情况。
不需要唯一权限。
public static long[] getNetworkUsageKb() {
BufferedReader reader;
String line;
String[] values;
long[] totalBytes = new long[2];//rx,tx
try {
reader = new BufferedReader(new FileReader("/proc/net/dev"));
while ((line = reader.readLine()) != null) {
if (line.contains("eth") || line.contains("wlan")){
values = line.trim().split("\\s+");
totalBytes[0] +=Long.parseLong(values[1]);//rx
totalBytes[1] +=Long.parseLong(values[9]);//tx
}
}
reader.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
//transfer to kb
totalBytes[0] = totalBytes[0] / 1024;
totalBytes[1] = totalBytes[1] / 1024;
return totalBytes;
}