16

データ使用履歴を知りたいのですが、「新しい」android-6NetworkStatsManagerが肯定的に見えることに気付きました (TrafficStatsしばらく使用しましたが、再起動前のものはカバーされません)。

API ドキュメントから:

注: この API には PACKAGE_USAGE_STATS 権限が必要です。これはシステム レベルの権限であり、サードパーティ アプリには付与されません。ただし、許可を宣言することは API を使用する意図を意味し、デバイスのユーザーは設定アプリケーションを介して許可を与えることができます。プロファイル所有者アプリには、管理するプロファイルのデータを照会するアクセス許可が自動的に付与されます (つまり、querySummaryForDevice(int, String, long, long) を除くすべてのクエリに対して)。同様に、デバイス オーナー アプリは、プライマリ ユーザーの使用状況データにアクセスできます。

データを使用するアプリではなく、集計レベルでのデータ使用量を知りたいので、次のように使用しようとしました。

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();

私は本当にパブリック API で同じことをしたいのですが、どうすればそれを行うことができますか?

4

2 に答える 2