Я хочу знать историю использования данных и заметил "новый" android-6 NetworkStatsManager
, который кажется положительным (я использовал 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);
...
К сожалению, это вызывает a 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, так как я могу это сделать?