gpt4 book ai didi

android - 使用 NetworkStatsManager 获取移动数据使用历史记录

转载 作者:IT老高 更新时间:2023-10-28 23:33:04 28 4
gpt4 key购买 nike

我想知道数据使用历史并注意到"new"android-6 NetworkStatsManager这似乎是积极的(我已经使用了 TrafficStats 一段时间,但这不会涵盖重启之前的任何内容)。

来自 API 文档:

NOTE: This API requires the permission PACKAGE_USAGE_STATS, which is a system-level permission and will not be granted to third-party apps. However, declaring the permission implies intention to use the API and the user of the device can grant permission through the Settings application. Profile owner apps are automatically granted permission to query data on the profile they manage (that is, for any query except querySummaryForDevice(int, String, long, long)). Device owner apps likewise get access to usage data of the primary user.

我想知道聚合级别的数据使用情况,知道使用数据的应用程序,所以我尝试像这样使用它:

NetworkStatsManager service = context.getSystemService(NetworkStatsManager.class);

NetworkStats.Bucket bucket =
service.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE, null, from, to);
...

不幸的是,这会引发 SecurityException:

java.lang.SecurityException: NetworkStats: Neither user 10174 nor current process has android.permission.READ_NETWORK_USAGE_HISTORY.
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at android.net.INetworkStatsSession$Stub$Proxy.getDeviceSummaryForNetwork(INetworkStatsSession.java:259)
at android.app.usage.NetworkStats.getDeviceSummaryForNetwork(NetworkStats.java:316)
at android.app.usage.NetworkStatsManager.querySummaryForDevice(NetworkStatsManager.java:100)
...

第三方应用不允许使用 android.permission.READ_NETWORK_USAGE_HISTORY 权限。所以这似乎是一个死胡同。

但是,我深入了解了内部结构,发现您可以使用内部/隐藏 API 来执行相同的操作,而无需请求任何权限:

INetworkStatsService service =
INetworkStatsService.Stub.asInterface(
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));

INetworkStatsSession session = service.openSession();

NetworkTemplate mobileTemplate = NetworkTemplate.buildTemplateMobileWildcard();
int fields = NetworkStatsHistory.FIELD_RX_BYTES | NetworkStatsHistory.FIELD_TX_BYTES;

NetworkStatsHistory mobileHistory = session.getHistoryForNetwork(mobileTemplate, fields);

for (int i = 0; i < mobileHistory.size(); i++) {
NetworkStatsHistory.Entry entry = mobileHistory.getValues(i, null);
...
}

session.close();

我真的想对公共(public) API 做同样的事情,那么,我该怎么做呢?

最佳答案

有一种方法可以在不访问私有(private) API 的情况下获得对 NetworkStateManager 的访问权限。步骤如下:

  1. AndroidManifest.xml中声明所需的权限:

    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission
    android:name="android.permission.PACKAGE_USAGE_STATS"
    tools:ignore="ProtectedPermissions"/>
    1. 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。仅当您需要获取 mobile data statistics 时才需要它.但是,这是正常权限,因此可以是 requested as any other permission

    1. 使用NetworkStatsManager:

制作 sample Github repo演示用法。

关于android - 使用 NetworkStatsManager 获取移动数据使用历史记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36702621/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com