如何获得Android Q上的应用程序的网络使用率? [英] How to get network usage of apps on Android Q?

查看:64
本文介绍了如何获得Android Q上的应用程序的网络使用率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我们可以通过使用类似的内容(过去称为

I know that we can get the network usage (total bandwidth used of mobile&Wifi so far, from some specific time) of a specified app by using something like that (asked in the past, here) :

    private final static int[] NETWORKS_TYPES = new int[]{ConnectivityManager.TYPE_WIFI, ConnectivityManager.TYPE_MOBILE};

    long rxBytes=0L, txBytes=0L;
    final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    final String subscriberId = telephonyManager.getSubscriberId();
    final ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
    final int uid = applicationInfo.uid;
    for (int networkType : NETWORKS_TYPES) {
        final NetworkStats networkStats = networkStatsManager.queryDetailsForUid(networkType, subscriberId, 0, System.currentTimeMillis(), uid); 
        final Bucket bucketOut = new Bucket();
        while (true) {
                networkStats.getNextBucket(bucketOut);
                final long rxBytes = bucketOut.getRxBytes();
                if (rxBytes >= 0)
                    totalRx += rxBytes;
                final long txBytes = bucketOut.getTxBytes();
                if (txBytes >= 0)
                    totalTx += txBytes;
                if (!networkStats.hasNextBucket())
                    break;
            }
        }
    }

文档:

还可以获取全球网络使用情况(使用 TrafficStats.getUidRxBytes(applicationInfo.uid) TrafficStats.getUidTxBytes(applicationInfo.uid)),但这不是该线程的全部用途.

It's also possible to get the global network usage (using TrafficStats.getUidRxBytes(applicationInfo.uid) and TrafficStats.getUidTxBytes(applicationInfo.uid) ), but that's not what this thread is all about.

似乎计划将Android Q导致许多设备标识功能停止工作,而 getSubscriberId 是其中之一.

It seems Android Q is planned to cause a lot of device-identity functions to stop working anymore, and getSubscriberId is one of them.

我尝试将targetSdk设置为29(Q),看看当我尝试使用它时会发生什么.

I tried to set the targetSdk to 29 (Q) and see what happens when I try to use this.

不出所料,我遇到了一个异常,向我表明我不能再这样做了.它说:

As expected, I got an exception that shows me that I can't do it anymore. It says :

019-06-11 02:08:01.871 13558-13558/com.android.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.android.myapplication, PID: 13558
    java.lang.SecurityException: getSubscriberId: The user 10872 does not meet the requirements to access device identifiers.
        at android.os.Parcel.createException(Parcel.java:2069)
        at android.os.Parcel.readException(Parcel.java:2037)
        at android.os.Parcel.readException(Parcel.java:1986)
        at com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy.getSubscriberIdForSubscriber(IPhoneSubInfo.java:984)
        at android.telephony.TelephonyManager.getSubscriberId(TelephonyManager.java:3498)
        at android.telephony.TelephonyManager.getSubscriberId(TelephonyManager.java:3473)

在Internet和此处搜索时,我看不到提到的内容,但是我发现了类似的问题,即获取IMEI和其他标识符:

Searching the Internet and here, I don't see this mentioned, but I have found about similar issues, of getting IMEI and other identifiers:

因此,到目前为止,我只是在这里作了一个错误报告(包括一个示例项目):

So for now I just made a bug report about it here (including a sample project) :

https://issuetracker.google.com/issues/134919382

是否可以在Android Q上获得指定应用程序的网络使用率(定向到该应用程序时)?也许没有SubscriberId?

Is it possible to get network usage of a specified app on Android Q (when targeting to it) ? Maybe without subscriberId?

如果是,怎么办?

如果没有,是否可以通过拥有root或通过adb来实现?

If not, is it possible by having root, or via adb?

好的,我不知道如何正式使用它,但是至少对于root用户访问来说,可以使用 此解决方案 ,可从 此处 找到.

OK, I don't know how to officially use this, but at least for root access it is possible to get the subscriberId, using this solution, found from here.

意思是这样的:

@SuppressLint("MissingPermission", "HardwareIds")
fun getSubscriberId(telephonyManager: TelephonyManager): String? {
    try {
        return telephonyManager.subscriberId
    } catch (e: Exception) {
    }
    val commandResult = Root.runCommands("service call iphonesubinfo 1 | grep -o \"[0-9a-f]\\{8\\} \" | tail -n+3 | while read a; do echo -n \"\\u\${a:4:4}\\u\${a:0:4}\"; done")
    val subscriberId = commandResult?.getOrNull(0)
    return if (subscriberId.isNullOrBlank()) null else subscriberId
}

这当然不是官方的解决方案,但是总比没有好...

It's not an official solution, of course, but it's better than nothing...

通过root获得它的部分是错误的.它没有任何帮助.

the part of getting it via root is wrong. It doesn't help in any way.

推荐答案

我们正在使用NetworkStatsManager.querySummaryForDevice().由于一个偶然的错误,我们在Q中将null作为MOBILE的subscriberId传递了.它似乎正在我们的设备上运行.我不确定这是错误还是功能,但是这些值是否符合我们预期的蜂窝电话使用率.

We are using NetworkStatsManager.querySummaryForDevice(). Due to a serendipitous bug, we were passing null as the subscriberId for MOBILE in Q. It appears to be working on our devices. I'm not sure if this is a bug or a feature, but the values match our expected cellular usage.

话虽如此,我们只能在这个用例中使用TrafficStats,但是在Pie之前是不稳定的.

All the said, we could just use TrafficStats for this use case, but it's erratic before Pie.

这篇关于如何获得Android Q上的应用程序的网络使用率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆