如何获取应用当前的网络使用情况(或总使用情况),即使是在Android N上?

aamkag61  于 2024-01-04  发布在  Android
关注(0)|答案(3)|浏览(177)

正如标题所述。我想知道在特定时间特定应用程序每秒使用多少字节。
也许我可以使用“netstat“命令?但如果是这样,我如何将其过滤到特定的应用程序/进程?
我也需要得到许可才能这么做吗?
目前人们说使用NetworkStats. getUidRxManager(packageInfo.uid),但是,从这里:https://developer.android.com/reference/android/net/NetworkStats.html#getUidRxManager(int),它说N不支持它,我应该使用NetworkStatsManager。有没有使用它的例子?
也许是一个合并的解决方案?
编辑:我试图在Android N上使用NetworkStatsManager,但我失败了.我找不到任何如何使用它的示例,和所有关于它的stackOverflow问题都是类似的,不能很好地使用它.请,如果有人知道如何使用它,写一下.

j2qf4p5b

j2qf4p5b1#

NetworkStats的用法并不复杂。
设备API级别必须至少为23。以下是开始使用x1m1 n1x之前所需的一些步骤
1.在AndroidManifest.xml中解密所需的权限:

  1. <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  2. <uses-permission
  3. android:name="android.permission.PACKAGE_USAGE_STATS"
  4. tools:ignore="ProtectedPermissions"/>

字符串
1.在Activity中请求许可
android.permission.PACKAGE_USAGE_STATS不是普通权限,不能简单请求。要检查权限是否已被授予,请检查:

  1. AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
  2. int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
  3. android.os.Process.myUid(), getPackageName());
  4. if (mode == AppOpsManager.MODE_ALLOWED) {
  5. return true;
  6. }


要请求此权限,只需调用Intent

  1. Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
  2. startActivity(intent);


还需要另一个权限:Manifest.permission.READ_PHONE_STATE。但是,这是普通权限,因此可以是requested as any other permission
1.使用NetworkStatsManager
要获取其引用,请调用:

  1. NetworkStatsManager networkStatsManager = (NetworkStatsManager) getApplicationContext().getSystemService(Context.NETWORK_STATS_SERVICE);


NetworkStatsManager检索的所有内容都打包到Buckets中。这只是一个简单的POJO,它保存数据。

全球:

获取WiFi的总体使用情况:

  1. NetworkStats.Bucket bucket;
  2. try {
  3. bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI,
  4. "",
  5. 0,
  6. System.currentTimeMillis());
  7. } catch (RemoteException e) {
  8. return -1;
  9. }


NetworkStats.Bucket,可以调用两个方法来获取使用情况(以Bps为单位):

  1. bucket.getRxBytes();
  2. bucket.getTxBytes();


获取移动的网络的数据比较困难,要获取x1m11 n1x呼叫:

  1. public long getAllRxBytesMobile(Context context) {
  2. NetworkStats.Bucket bucket;
  3. try {
  4. bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE,
  5. getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
  6. 0,
  7. System.currentTimeMillis());
  8. } catch (RemoteException e) {
  9. return -1;
  10. }
  11. return bucket.getRxBytes();
  12. }
  13. //Here Manifest.permission.READ_PHONE_STATS is needed
  14. private String getSubscriberId(Context context, int networkType) {
  15. if (ConnectivityManager.TYPE_MOBILE == networkType) {
  16. TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
  17. return tm.getSubscriberId();
  18. }
  19. return "";
  20. }

适用范围:

要获取特定应用程序的数据,请阅读queryDetailsForUID的文档。
获取WiFi套餐使用情况:

  1. NetworkStats networkStats = null;
  2. try {
  3. networkStats = networkStatsManager.queryDetailsForUid(
  4. ConnectivityManager.TYPE_WIFI,
  5. "",
  6. 0,
  7. System.currentTimeMillis(),
  8. packageUid);
  9. } catch (RemoteException e) {
  10. return -1;
  11. }
  12. NetworkStats.Bucket bucket = new NetworkStats.Bucket();
  13. networkStats.getNextBucket(bucket);


获取移动的套餐使用情况:

  1. NetworkStats networkStats = null;
  2. try {
  3. networkStats = networkStatsManager.queryDetailsForUid(
  4. ConnectivityManager.TYPE_MOBILE,
  5. getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
  6. 0,
  7. System.currentTimeMillis(),
  8. packageUid);
  9. } catch (RemoteException e) {
  10. return -1;
  11. }
  12. NetworkStats.Bucket bucket = new NetworkStats.Bucket();
  13. networkStats.getNextBucket(bucket);


不幸的是,根据这段代码,只能对ConnectivityManager.TYPE_MOBILEConnectivityManager.TYPE_WIFI获取统计信息。
做了一个Github repo的例子来演示用法。

展开查看全部
tkqqtvp1

tkqqtvp12#

还有一种复杂的方法来获取统计数据,但这应该适用于所有适配器:(但它很昂贵,因为你必须连续读取文件),
1.在这里,您可以看到所有适配器和发送/接收的数据:

  1. cat /proc/net/dev

字符串
1.您可以从这些文件中获取每个适配器的统计信息:

  1. cat /sys/class/net/**wlan0**/statistics/**rx**_bytes

wlan 0可以是您所有的适配器,但您需要在应用中维护该值,因为如果您关闭/打开适配器,该值将再次为0。(您可以有RX和TX值)

1.您可以获取当前正在发送/接收的活动应用程序列表

  1. cat /proc/net/**tcp6**


这也可以通过tcptcp 6updupd 6来完成
这里有一个“uid”列,它是你安装的应用程序的UID。(所以那个应用程序现在正在使用网络)
从这个文件中,您还可以看到连接端点。
1.检查每个应用程序的发送/接收字节数(如JavaScriptStats API调用)

  1. cat /proc/uid_stat/**10348**/tcp_snd


这里的id是应用程序的UID,你也有发送的:tcp_snd和接收的:tcp_rcv文件。
1.您还可以使用以下命令进行一些进程和UID匹配:

  1. cat /proc/**17621**/status


这里的id是你可以从例如top命令中获得的进程id。在status文件中,你将拥有UID,即已安装/系统应用程序的UID。
+1.你也可以看看这个文件,JumicStats API使用这个:

  1. cat /proc/net/xt_qtaguid/stats


标题:

  1. 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


价值观:

  1. 6 eth0 0x0 10005 0 0 0 80 2 0 0 0 0 0 0 80 2 0 0 0 0
  2. 7 eth0 0x0 10005 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  3. 8 eth0 0x0 10007 0 11133 25 4751 24 11133 25 0 0 0 0 4751 24 0 0 0 0
  4. 9 eth0 0x0 10007 1 5965514 4358 102028 2327 5965514 4358 0 0 0 0 102028 2327 0 0 0 0
  5. 10 eth0 0x0 10014 0 95 1 40 1 95 1 0 0 0 0 40 1 0 0 0 0


所以也许把第一个答案和这些知识结合起来,你可以得到更多更好的统计数据。

展开查看全部
xzabzqsa

xzabzqsa3#

**更新:**不适用于Android 10及更高版本

通过/proc/net/dev添加我的简化函数以获取整体网络使用情况。
不需要唯一权限。

  1. public static long[] getNetworkUsageKb() {
  2. BufferedReader reader;
  3. String line;
  4. String[] values;
  5. long[] totalBytes = new long[2];//rx,tx
  6. try {
  7. reader = new BufferedReader(new FileReader("/proc/net/dev"));
  8. while ((line = reader.readLine()) != null) {
  9. if (line.contains("eth") || line.contains("wlan")){
  10. values = line.trim().split("\\s+");
  11. totalBytes[0] +=Long.parseLong(values[1]);//rx
  12. totalBytes[1] +=Long.parseLong(values[9]);//tx
  13. }
  14. }
  15. reader.close();
  16. }
  17. catch (FileNotFoundException e) {
  18. e.printStackTrace();
  19. }
  20. catch (IOException e) {
  21. e.printStackTrace();
  22. }
  23. //transfer to kb
  24. totalBytes[0] = totalBytes[0] / 1024;
  25. totalBytes[1] = totalBytes[1] / 1024;
  26. return totalBytes;
  27. }

字符串

展开查看全部

相关问题