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)