Питание для устройств, на которых работает Jelly bean, а также версии позже Jelly bean при использовании данных приложений

Я хотел бы обслуживать устройства, работающие на версии желе и ниже, а также версии выше Jelly Bean.

Предполагается, что мой метод получит использование приложения / трафик для всех приложений на основе идентификатора приложения. Обратите внимание на эту строку rx = Long.parseLong(String.valueOf(id)); В первом условии if, который предназначен для устройств с версиями, которые меньше или равны Jelly Bean.

Использование данных установленного приложения на основе его идентификатора получено с использованием TrafficStats.getUidTxBytes(uid) но оно возвращает только значение 0 в 4.3, но предложение else с использованием TrafficStats.getUidTxBytes(uid) точно использовать приложение для каждого приложения Версии выше 5.

Меня особенно беспокоит предложение if , которое обслуживает версию Android с версией ниже 5, например, в этом случае 4.3 (Jelly Bean)

 public void recordSnapshot(Context context) { TinyDB settings = new TinyDB(context); int boot_id = settings.getInt(AppPreferences.BOOT_ID); PackageManager pm = context.getPackageManager(); for (ApplicationInfo app : pm.getInstalledApplications(0)) { String androidOS = Build.VERSION.RELEASE; int currentapiVersion = android.os.Build.VERSION.SDK_INT; long tx = 0; long rx = 0; int uid = app.uid; if(currentapiVersion <= Build.VERSION_CODES.JELLY_BEAN) { File dir = new File("/proc/uid_stat/"); String[] children = dir.list(); List<Integer> uids = new ArrayList<Integer>(); for (int i = 0; i < children.length; i++) { uid = Integer.parseInt(children[i]); String uidString = String.valueOf(uid); File uidFileDir = new File("/proc/uid_stat/" + uidString); File uidActualFile = new File(uidFileDir, "tcp_rcv"); StringBuilder text = new StringBuilder(); try { BufferedReader br = new BufferedReader(new FileReader(uidActualFile)); String line; while ((line = br.readLine()) != null) { Log.d(String.valueOf(uid), line);//this returns the amount of data received for the particular uid rx = Long.parseLong(String.valueOf(uid)); text.append(line); text.append('\n'); } } catch (IOException e) { //handle this } uids.add(id); } } else { tx = TrafficStats.getUidTxBytes(uid); rx = TrafficStats.getUidRxBytes(uid); } } 

Весь метод

 public void recordSnapshot(Context context) { TinyDB settings = new TinyDB(context); int boot_id = settings.getInt(AppPreferences.BOOT_ID); ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); int networkType = NetworkState.GetNetworkState(context, info, "DataUsageRecorder"); // wifi, data, data roaming // Get all apps PackageManager pm = context.getPackageManager(); for (ApplicationInfo app : pm.getInstalledApplications(0)) { String androidOS = Build.VERSION.RELEASE; int currentapiVersion = android.os.Build.VERSION.SDK_INT; long tx = 0; long rx = 0; int uid = app.uid; if(currentapiVersion <= Build.VERSION_CODES.JELLY_BEAN_MR2) { File dir = new File("/proc/uid_stat/"); String[] children = dir.list(); List<Integer> uids = new ArrayList<Integer>(); for (int i = 0; i < children.length; i++) { uid = Integer.parseInt(children[i]); String uidString = String.valueOf(uid); File uidFileDir = new File("/proc/uid_stat/" + uidString); File uidActualFile = new File(uidFileDir, "tcp_rcv"); StringBuilder text = new StringBuilder(); try { BufferedReader br = new BufferedReader(new FileReader(uidActualFile)); String line; while ((line = br.readLine()) != null) { Log.d(String.valueOf(uid), line);//this returns the amount of data received for the particular uid rx = Long.parseLong(String.valueOf(uid)); //text.append(line); //text.append('\n'); } } catch (IOException e) { //handle this } uids.add(uid); } } else { tx = TrafficStats.getUidTxBytes(uid); rx = TrafficStats.getUidRxBytes(uid); } if ((tx == 0 || rx == 0)) { // Skip inactive items continue; } else if (Globals.DEBUG && (tx < DEBUG_5MB && rx < DEBUG_5MB)) { // Let's skip all the BS for quick testing continue; } // Get package name String package_name; try { CharSequence name = pm.getApplicationLabel(app); package_name = name != null ? name.toString() : ""; } catch (Exception e) { e.printStackTrace(); package_name = ""; } AppUsage totals; AppUsage appUsage; // Get current data entry for app //appUsage = appUsageDao.queryBuilder().where(AppUsageDao.Properties.App_uid.eq(uid), AppUsageDao.Properties.Type.eq(networkType), AppUsageDao.Properties.Boot_id.eq(boot_id)).limit(1).unique(); // Get last recorded totals since device boot totals = appUsageDao.queryBuilder().where(AppUsageDao.Properties.App_uid.eq(uid), AppUsageDao.Properties.Type.eq(NetworkState.ALL), AppUsageDao.Properties.Boot_id.eq(boot_id)).limit(1).unique(); long tx_diff = tx; long rx_diff = rx; if (totals != null) { // Get difference, and update tx_diff -= totals.getTx(); rx_diff -= totals.getRx(); totals.setTx(tx); totals.setRx(rx); } else { // add new master totals = new AppUsage(null, new Date(), uid, package_name, NetworkState.ALL, tx_diff, rx_diff, 0, 0, boot_id); } // add new app appUsage = new AppUsage(null, new Date(), uid, package_name, networkType, tx_diff, rx_diff, 0, 0, boot_id); /*if (appUsage == null) { // Create new appUsage = new AppUsage(null, new Date(), uid, package_name, networkType, tx, rx, 0, 0, boot_id); } else { // Update appUsage.setTx(tx); appUsage.setRx(rx); }*/ try { // master appUsageDao.insertOrReplace(totals); } catch (DaoException e) { e.printStackTrace(); } try { appUsageDao.insertOrReplace(appUsage); } catch (DaoException e) { e.printStackTrace(); } //apps.put(app.uid, new DataUsageItem(app.uid, app.packageName, pm.getApplicationLabel(app).toString())); } } 

Solutions Collecting From Web of "Питание для устройств, на которых работает Jelly bean, а также версии позже Jelly bean при использовании данных приложений"

Несмотря на то, что документация говорит, что статистика трафика не работает хорошо на 4.3 в том смысле, что в некоторых случаях она работает для некоторого идентификатора приложения, а не для некоторых, поэтому я бы обошел весь класс trafficstats и создал два настраиваемых метода, указывающих на нативный c Файл, содержащий данные об использовании приложения для извлечения tx (передаваемых данных) и Rx (полученные данные) в пределах одного класса

  long tx = yourClass.getUidTxBytes(uid); long rx = yourClass.getUidRxBytes(uid); 

Тогда для RX

 public static Long getUidRxBytes(int uid) { BufferedReader reader; Long rxBytes = 0L; try { reader = new BufferedReader(new FileReader("/proc/uid_stat/" + uid + "/tcp_rcv")); rxBytes = Long.parseLong(reader.readLine()); reader.close(); } catch (FileNotFoundException e) { rxBytes = TrafficStats.getUidRxBytes(uid); //e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return rxBytes; }** 

Тогда для TX

  public static Long getUidTxBytes(int uid) { BufferedReader reader; Long txBytes = 0L; try { reader = new BufferedReader(new FileReader("/proc/uid_stat/" + uid + "/tcp_snd")); txBytes = Long.parseLong(reader.readLine()); reader.close(); } catch (FileNotFoundException e) { txBytes = TrafficStats.getUidTxBytes(uid); //e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return txBytes; }