Может ли кто-нибудь объяснить, как TrafficStats работает с магией в ОС Android?
Я написал небольшое приложение для Android, чтобы проверить использование данных, к сожалению, он в значительной степени зависит от android.net.TrafficStats, который был представлен с Froyo (Android 2.2).
Я пытаюсь вернуть этот class для своих пользователей, не являющихся пользователями Froyo, и что я могу определить из источника Android :
- TrafficStats.java – это только собственный указатель на файл ac
- Файл c открывает два файла (см. Ниже) и считывает их содержимое
- Если либо содержит числовое значение, оно возвращает его обратно, как подсчет «байтов»
Вот мой вызов … когда я вызываю TrafficStats через API на своем устройстве, я получаю чтение (например, 1113853 байта). Когда я открываю два файла и проверяю их содержимое, один файл не существует, а другой файл – 0 байт.
- Карта Google для андроида
- Firebase Android: как читать из разных ссылок последовательно
- Android - открыть ресурс из @drawable String
- Символы Unicode, не отображаемые в TextView.setText
- Получение координат представления относительно корневого макета
Так ясно, что я неправильно понял, что делает TrafficStats. Может ли кто-нибудь пролить свет на то, как он работает, это волшебство?
Спасибо за помощь.
(вот моя попытка портировать файл c в java)
package com.suttco.net; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import com.suttco.IOUtils; import com.suttco.StringUtils; import android.util.Log; public class TrafficStatsFile { private static final String mobileRxFile_1 = "/sys/class/net/rmnet0/statistics/rx_bytes"; private static final String mobileRxFile_2 = "/sys/class/net/ppp0/statistics/rx_bytes"; private static final String mobileTxFile_1 = "/sys/class/net/rmnet0/statistics/tx_bytes"; private static final String mobileTxFile_2 = "/sys/class/net/ppp0/statistics/tx_bytes"; private static final String LOGGING_TAG = TrafficStatsFile.class.getSimpleName(); public long getMobileRxBytes() { return tryBoth(mobileRxFile_1, mobileRxFile_2); } public long getMobileTxBytes() { return tryBoth(mobileTxFile_1, mobileTxFile_2); } // Return the number from the first file which exists and contains data private static long tryBoth(String a, String b) { long num = readNumber(a); return num >= 0 ? num : readNumber(b); } // Returns an ASCII decimal number read from the specified file, -1 on error. private static long readNumber(String filename) { File f = new File(filename); if(f.exists()) { if(f.canRead()) { try { Log.d(LOGGING_TAG, "f.length() = " + f.length()); String contents = IOUtils.readFileAsString(f); if(StringUtils.IsNotNullOrEmpty(contents)) { try { return Long.parseLong(contents); } catch(NumberFormatException nfex) { Log.w(LOGGING_TAG, "File contents are not numeric: " + filename); } } else { Log.w(LOGGING_TAG, "File contents are empty: " + filename); } } catch (FileNotFoundException fnfex) { Log.w(LOGGING_TAG, "File not found: " + filename, fnfex); } catch(IOException ioex) { Log.w(LOGGING_TAG, "IOException: " + filename, ioex); } } else { Log.w(LOGGING_TAG, "Unable to read file: " + filename); } } else { Log.w(LOGGING_TAG, "File does not exist: " + filename); } return -1; } }
- Лучшие практики: макеты на Android (Programmatic vs XML)
- Как вы можете обнаружить двухъядерный процессор на Android-устройстве из кода?
- Запретить строку состояния для появления андроида (изменено)
- Подключение 2 экземпляров эмулятора в Android
- Как программно запускать программу запуска приложений по умолчанию?
- Ошибка: Status {statusCode = DEVELOPER_ERROR, разрешение = null}
- Android Studio не удалось найти версию, совместимую с com.android.support:appcompat-v7:+
- Как автоматически создать каталог на SD-карте
Вот рабочая, измененная версия вышеприведенного кода. Этот использует RandomAccessFile
и не полагается на пользовательский imports
но использует только встроенные функции String
с их Exceptions
.
import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import android.util.Log; public class TrafficStatsFile { private static final String mobileRxFile_1 = "/sys/class/net/rmnet0/statistics/rx_bytes"; private static final String mobileRxFile_2 = "/sys/class/net/ppp0/statistics/rx_bytes"; private static final String mobileTxFile_1 = "/sys/class/net/rmnet0/statistics/tx_bytes"; private static final String mobileTxFile_2 = "/sys/class/net/ppp0/statistics/tx_bytes"; private static final String LOGGING_TAG = TrafficStatsFile.class.getSimpleName(); public long getMobileRxBytes() { return tryBoth(mobileRxFile_1, mobileRxFile_2); } public long getMobileTxBytes() { return tryBoth(mobileTxFile_1, mobileTxFile_2); } // Return the number from the first file which exists and contains data private static long tryBoth(String a, String b) { long num = readNumber(a); return num >= 0 ? num : readNumber(b); } // Returns an ASCII decimal number read from the specified file, -1 on error. private static long readNumber(String filename) { try { RandomAccessFile f = new RandomAccessFile(filename, "r"); try { Log.d(LOGGING_TAG, "f.length() = " + f.length()); String contents = f.readLine(); if(!contents.isEmpty() && contents!=null) { try { return Long.parseLong(contents); } catch(NumberFormatException nfex) { Log.w(LOGGING_TAG, "File contents are not numeric: " + filename); } } else { Log.w(LOGGING_TAG, "File contents are empty: " + filename); } } catch (FileNotFoundException fnfex) { Log.w(LOGGING_TAG, "File not found: " + filename, fnfex); } catch(IOException ioex) { Log.w(LOGGING_TAG, "IOException: " + filename, ioex); } }catch(FileNotFoundException ffe){ Log.w(LOGGING_TAG, "File not found: " + filename, ffe); } return -1; } }
Изменение его на RandomAccessFile вместо файла.
Изменить: см. Ответ IBoS для рабочего кода. Изменение принятого ответа на него.