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_HISTORY
ie @ -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?