在获取应用程序数据使用时,请为运行Jelly bean的设备以及Jelly bean之后的版本提供服务

Zid*_*ane 9 java android android-studio

我想迎合在果冻豆版本及以下版本上运行的设备以及Jelly Bean以上的版本.

我的方法应该根据应用程序ID获取所有应用程序的应用程序使用/流量.请注意rx = Long.parseLong(String.valueOf(id));第一个if子句中的这一行,该子句适用于运行版本小于或等于Jelly Bean的设备.

基于其ID的已安装应用程序的数据使用是使用using获得的,TrafficStats.getUidTxBytes(uid)但仅在4.3中返回值0,但是,else子句使用TrafficStats.getUidTxBytes(uid)在5以上版本中准确检索每个应用程序的app使用情况.

我特别关注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);
     }
}
Run Code Online (Sandbox Code Playgroud)

整个方法

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()));
        }
    }
Run Code Online (Sandbox Code Playgroud)

小智 1

尽管文档说流量统计在 4.3 上似乎效果不佳,因为在某些情况下它适用于某些应用程序 id 而不适用于某些应用程序 id,因此我将绕过整个 Trafficstats 类并创建两个指向本机 c 的自定义方法包含应用程序使用数据的文件,用于检索同一类中的 tx(传输的数据)和 Rx(接收的数据)

   long tx = yourClass.getUidTxBytes(uid);
    long rx = yourClass.getUidRxBytes(uid);
Run Code Online (Sandbox Code Playgroud)

然后对于 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;
    }**
Run Code Online (Sandbox Code Playgroud)

然后去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;
    }
Run Code Online (Sandbox Code Playgroud)