TrafficStats Api android и расчет ежедневного использования данных
Имеют путаницу в отношении следующих двух методов TrafficStats для Android:getUidTxBytes (int uid) и getUidRxBytes(int uid). Эти два метода возвращают количество байтов, переданных и полученных по сети для этого UID. Но какова его единица времени Это в секунду. Если я хочу рассчитать данные, передаваемые и получаемые за день для каждого приложения, что мне делать. Я нашел один способ, чтобы хранить данные в SQL и продолжать добавлять данные в таблицу. Это правильно.
4 ответа
Это счетчики "с момента запуска интерфейса" или "с момента запуска приложения с этим UID". Так, скажем, если ваш телефон переходит в "Режим полета", а затем обратно, счетчики могут снова начать с нуля. Если вам нужны посекундные значения, вам нужно будет вызывать эти функции каждую секунду, а затем использовать дельту из последнего вызова. Если дельта отрицательна, просто используйте значение как есть, это означает, что счетчик снова начал с нуля.
Еще одна вещь: насколько мне известно, эти счетчики учитывают только TCP/IP. Не UDP. Поэтому, если вам нужен очень точный учет, и рассматриваемое приложение использует UDP/IP или любой другой протокол, кроме TCP, эти счетчики будут неправильными.
Чтобы понять, как работает эта функция, посмотрите на источник Android, который доступен бесплатно. Файл в вопросе ./frameworks/base/core/jni/android_net_TrafficStats.cpp
Эта функция получает данные от /proc/uid_stat/[uid]/tcp_snd
, Если вам нужна дополнительная информация об этом, вам нужно погрузиться в ядро Linux...
Эти счетчики содержат количество байтов с момента последней перезагрузки. На некоторых телефонах эти счетчики могут периодически сбрасываться, но большую часть времени они сбрасываются только после перезагрузки. Переход в режим полета или переключение между мобильным и Wi-Fi не сбрасывает эти счетчики.
Важным моментом является то, что эти счетчики не включают служебные данные пакета, а только размер полезной нагрузки. Таким образом, обычно это означает, что 3-4% данных могут быть пропущены. Однако, если это потоковое, торрентное или VoIP-приложение, в котором полезные нагрузки пакетов невелики, может быть гораздо больший объем неучтенных данных.
Интересно, что getTotalRxBytes (полученные байты через все интерфейсы, за исключением мобильного устройства и Wi-Fi вместе) и getMobileRxBytes (полученные байты только через мобильный интерфейс) включают все байты, включая служебные данные. Таким образом, в общем, общее количество байтов в вашем приложении будет меньше общего количества байтов в интерфейсе и, следовательно, меньше, чем объем данных, за который выставляет счет ваш оператор сети.
И последнее замечание: большинство потоковых приложений не учитывают свои данные под собственным UID. Они учитываются под UID системы.media. Поэтому, если вы отслеживаете использование данных для YouTube, в этом приложении будет отображаться только очень небольшой объем данных; остальное будет под UID носителя (1013).
Здесь я получаю те приложения, у которых есть разрешение Интернета, вы можете изменить название разрешения и получать приложения в соответствии с вашими потребностями.
ArrayList<AppObject> listApps;
public void getAllAppList() {
listApps = new ArrayList<AppObject>();
PackageManager p = getPackageManager();
List<ApplicationInfo> packages = p.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo applicationInfo : packages) {
try {
PackageInfo packageInfo = p.getPackageInfo(applicationInfo.packageName, PackageManager.GET_PERMISSIONS);
String[] permissions = packageInfo.requestedPermissions;
for (String permissionName : permissions) {
if (permissionName.equals("android.permission.INTERNET")) {
ApplicationInfo appInfo = packageInfo.applicationInfo;
AppObject appObject = new AppObject();
appObject.appDrawable = getPackageManager().getApplicationIcon(appInfo);
appObject.appName = (String) getPackageManager().getApplicationLabel(appInfo);
appObject.dataUsage = getDataUsage(appInfo);
listApps.add(appObject);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
Debug.e("APP_SIZE", ":" + listApps.size());
appsAdapter.addAll(listApps);
}
public String getDataUsage(ApplicationInfo appInfo) {
int uid = appInfo.uid;
double received = (double) TrafficStats.getUidRxBytes(uid) / (1024 * 1024);
double sent = (double) TrafficStats.getUidTxBytes(uid) / (1024 * 1024);
double total = received + sent;
return String.format("%.2f", total) + " MB";
}
getUidRxBytes() и getUidTxBytes() в основном используются для принятых и переданных байтов соответственно. Чтобы отслеживать ваши данные для каждого приложения, просто найдите uid каждого процесса и найдите соответствующие данные для каждого процесса, и это будут ваши данные для каждого приложения, а затем вы можете использовать этот код для расчетов.
TextView totData = (TextView)findViewById(R.id.totData);
TextView wifiTot = (TextView)findViewById(R.id.wifitotData);
TextView wifiTX = (TextView)findViewById(R.id.wifiUpData);
TextView wifiRX = (TextView)findViewById(R.id.wifiDownData);
TextView mobileTot = (TextView)findViewById(R.id.mobtotData);
TextView mobTX = (TextView)findViewById(R.id.mobUpData);
TextView mobRX = (TextView)findViewById(R.id.mobDownData);
/*
* Converting bytes to MB
*/
long rxBytes = TrafficStats.getTotalRxBytes()/1048576;
long txBytes = TrafficStats.getTotalTxBytes()/1048576;
long mobUpload = TrafficStats.getMobileTxBytes()/1048576;
long mobDown = TrafficStats.getMobileRxBytes()/1048576;
long wifiUpload = txBytes-(mobUpload);
long wifiDown = rxBytes-(mobDown);
wifiRX.setText(Long.toString(wifiDown));
wifiTX.setText(Long.toString(wifiUpload));
long wifitot = wifiUpload+wifiDown;
wifiTot.setText(Long.toString(wifitot));
mobTX.setText(Long.toString(mobUpload));
mobRX.setText(Long.toString(mobDown));
long mobTot = mobUpload+mobDown;
mobileTot.setText(Long.toString(mobTot));
totData.setText(Long.toString(wifitot+mobTot));