Historie der mobilen Datennutzung mit NetworkStatsManager abrufen

Ich möchte die Datennutzungshistorie kennen und habe das "neue" Android-6 bemerktNetworkStatsManager das scheint positiv (ich habe @ verwendTrafficStats eine Weile, aber das wird nichts vor einem Neustart abdecken).

Aus der API-Dokumentation:

HINWEIS: Für diese API ist die Berechtigung PACKAGE_USAGE_STATS erforderlich. Hierbei handelt es sich um eine Berechtigung auf Systemebene, die nicht für Apps von Drittanbietern gewährt wird. Das Deklarieren der Berechtigung impliziert jedoch die Absicht, die API zu verwenden, und der Benutzer des Geräts kann die Berechtigung über die Anwendung "Einstellungen" erteilen. Profilbesitzer-Apps erhalten automatisch die Berechtigung zum Abfragen von Daten für das von ihnen verwaltete Profil (dh für alle Abfragen mit Ausnahme von querySummaryForDevice (int, String, long, long)). Gerätebesitzer-Apps erhalten ebenfalls Zugriff auf Nutzungsdaten des Hauptbenutzers.

Ich möchte die Datennutzung auf aggregierter Ebene kennen undnich bis zu welcher App, die die Daten verwendet, also habe ich versucht, es so zu verwenden:

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

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

Leider wirft das einSecurityException:

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

Dasandroid.permission.READ_NETWORK_USAGE_HISTORYie @ -Erlaubnis ist für Apps von Drittanbietern nicht zulässig. Das schien also eine Sackgasse zu sein.

Ich habe mich jedoch ein wenig mit den Interna befasst und festgestellt, dass Sie die interne / versteckte API verwenden können, um dasselbe zu tun, ohne Berechtigungen anzufordern:

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

Ich möchte wirklich dasselbe mit der öffentlichen API machen, also, wie mache ich genau das?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage