【发布时间】:2019-10-29 20:36:30
【问题描述】:
背景
我知道我们可以通过使用类似的东西(过去问过,here)来获取指定应用程序的网络使用情况(到目前为止,从某个特定时间开始,移动和 Wifi 使用的总带宽):
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) ),但这不是这个线程的全部内容。
问题
Android Q 似乎计划导致许多设备身份功能停止工作,getSubscriberId 就是其中之一。
我尝试过的
我尝试将 targetSdk 设置为 29 (Q),看看当我尝试使用它时会发生什么。
正如预期的那样,我遇到了一个异常,表明我不能再这样做了。它说:
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)
搜索互联网和这里,我没有看到提到这一点,但我发现了类似的问题,获取 IMEI 和其他标识符:
- I am getting IMEI null in Android Q?
- https://issuetracker.google.com/issues/130202003
- https://issuetracker.google.com/issues/129583175
- https://developer.android.com/preview/privacy/data-identifiers#device-ids
所以现在我只是在这里做了一个关于它的错误报告(包括一个示例项目):
https://issuetracker.google.com/issues/134919382
问题
是否可以在 Android Q 上获取指定应用的网络使用情况(针对它时)?也许没有subscriberId?
如果有,怎么做?
如果没有,是否可以通过root或adb?
编辑:
好的,我不知道如何正式使用它,但至少对于 root 访问来说,可以使用从 here 找到的 this solution 获取subscriberId。
意思是这样的:
@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
}
这当然不是官方的解决方案,但总比没有好...
编辑:通过 root 获取它的部分是错误的。没有任何帮助。
【问题讨论】:
-
从 Android Q 开始,应用程序必须具有 READ_PRIVILEGED_PHONE_STATE 特权权限才能访问设备的不可重置标识符,包括 IMEI 和序列号。您是否尝试添加此权限?
-
是的,但它不适用于普通应用程序。它仅适用于系统应用程序。其他人已经问过了。示例:stackoverflow.com/a/51987160/878126。也见这里:developer.android.com/preview/privacy/…
标签: android networking android-10.0