在获取应用程序数据使用情况时,适用于运行Jelly Bean的设备以及晚于Jelly Bean的版本

我想迎合运行在果冻豆版本和以下以及果冻豆以上版本的设备。

我的方法应该是基于应用程序ID获取所有应用程序的应用程序使用情况/stream量。 请注意这行rx = Long.parseLong(String.valueOf(id)); 在第一个if语句上,它可以运行小于或等于Jelly Bean的设备。

使用TrafficStats.getUidTxBytes(uid)获得已安装应用程序的数据使用情况,但仅在4.3中返回0值,然而,使用TrafficStats.getUidTxBytes(uid)else子句会准确地检索每个应用程序的应用程序使用情况5以上的版本。

我特别关心的 ,在这种情况下,迎合运行android版本低于5的设备的if子句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的版本"

尽pipe文档中说stream量统计看起来似乎4.3上运行良好,在某些情况下,它适用于某些应用程序ID,而不是一些,所以我会绕过整个trafficstats类,并创build两个自定义方法指向本机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; }