我正在构建一个应用程序,它在一段时间内监视应用程序网络数据的使用情况。
在 android 5 上,我对 TrafficStats 没有任何问题,尽管在使用 NetworkStats 的 android 8 上,我总是收到相同的数据。我读过桶每 30 分钟左右刷新一次,所以我尝试听 youtube 大约 1 小时,但数据使用量仍然相同(在 com.google.android.youtube 包中)。
那么,我的问题是,为什么 NetworkStats 总是返回相同的数据?
这是我的代码:
public class DataService extends Service {
private int interval = 1000 * 5; //Time interval
private List<ApplicationInfo> infos;
private PackageManager packageManager;
private static int counter = 0;
private ArrayList<ValuesHolder> values;
private Context context;
private Handler mHandler;
public static final String DATA_INTENT_FILTER = "Transmitted data updated";
private Runnable mHandlerTask = new Runnable() {
@Override
public void run() {
update();
Intent intent = new Intent();
intent.setAction(DATA_INTENT_FILTER);
sendBroadcast(intent);
mHandler.postDelayed(mHandlerTask, interval);
}
};
@Override
public void onCreate() {
super.onCreate();
mHandler = new Handler();
context = this;
values = new ArrayList<>();
packageManager = getPackageManager();
infos = packageManager.getInstalledApplications(0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
getNonSystemPackages();
}
mHandlerTask.run();
}
@RequiresApi(api = Build.VERSION_CODES.N)
private void getNonSystemPackages() {
PackageManager pm = getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo : packages) {
if (pm.getLaunchIntentForPackage(packageInfo.packageName) != null) {
String currAppName = packageInfo.packageName;
try {
int uid = pm.getPackageUid(currAppName, 0);
values.add(counter, new ValuesHolder(currAppName,
getTotalDataForMobile(uid) + getTotalDataForWifi(uid),
uid));
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
} else {
//System App
}
}
}
private void update() {
String saveString;
long difference;
long data;
int uid;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
try {
for (int i = 0; i < values.size(); i++) {
uid = values.get(i).getUid();
if (TrafficStats.getUidTxBytes(uid) == TrafficStats.UNSUPPORTED) {
data = getTotalDataForMobile(uid) + getTotalDataForWifi(uid);
//Always same data
Log.i(values.get(i).getPackageName(), " data" + data);
} else {
data = TrafficStats.getUidRxBytes(uid) + TrafficStats.getUidTxBytes(uid);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
private long getTotalDataForWifi(int uid) {
NetworkStatsManager networkStatsManager = (NetworkStatsManager) getApplicationContext().getSystemService(Context.NETWORK_STATS_SERVICE);
NetworkStats.Bucket bucket;
long totalData = 0;
NetworkStats networkStats = null;
try {
networkStats = networkStatsManager.queryDetailsForUid(
ConnectivityManager.TYPE_WIFI,
"",
0,
System.currentTimeMillis(),
uid);
} catch (RemoteException e) {
return -1;
}
do {
bucket = new NetworkStats.Bucket();
networkStats.getNextBucket(bucket);
totalData += bucket.getRxBytes() + bucket.getTxBytes();
} while (networkStats.hasNextBucket());
return totalData;
}
@RequiresApi(api = Build.VERSION_CODES.M)
private long getTotalDataForMobile(int uid) {
NetworkStatsManager networkStatsManager = (NetworkStatsManager) getApplicationContext().getSystemService(Context.NETWORK_STATS_SERVICE);
NetworkStats.Bucket bucket;
NetworkStats networkStats = null;
long totalData = 0;
try {
networkStats = networkStatsManager.queryDetailsForUid(
ConnectivityManager.TYPE_MOBILE,
"",
0,
System.currentTimeMillis(),
uid);
} catch (RemoteException e) {
return -1;
}
do {
bucket = new NetworkStats.Bucket();
networkStats.getNextBucket(bucket);
totalData += bucket.getRxBytes() + bucket.getTxBytes();
} while (networkStats.hasNextBucket());
return totalData;
}
}
我在 MainActivity 中请求运行时权限,如下所示:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, Permissions.ARR_PHONE_STATE, Permissions.REQUEST_PHONE_STATE);
}
if
((checkSelfPermission(Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED)
|| (checkSelfPermission(Manifest.permission.ACCESS_WIFI_STATE) != PackageManager.PERMISSION_GRANTED)
|| (checkSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions(this, Permissions.ARR_NETWORK, Permissions.REQUEST_NETWORK);
}
AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
android.os.Process.myUid(), getPackageName());
if (mode == AppOpsManager.MODE_ALLOWED) {
} else {
}
if (!Permissions.checkForPermission(this)) {
startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
} else {
Log.i("SYSTEM", "PERMISSION GRANTED");
}
}
授予权限,我也在 android manifest 中请求它们。
谢谢你的帮助。