Android 统计应用流量的使用情况

您所在的位置:网站首页 安卓查看当前网络使用情况 Android 统计应用流量的使用情况

Android 统计应用流量的使用情况

2024-05-10 14:45| 来源: 网络整理| 查看: 265

Android 获取应用流量的使用情况有两种方法

TrafficStats NetworkStatsManager 是Android 6.0(API23)中新增加的类

这次我们使用的是第二种方法,记录一下实现过程 首先说明NetworkStatsManager能提供哪些功能

区分 Wifi 和手机网络的流量使用 查询指定应用的流量使用 查询指定时间段的流量使用(当天/当月/总共) 区分接收和发送的流量使用

看下方法使用代码

/** * 本机使用的 wifi 总流量 */ public long getAllBytesWifi() { NetworkStats.Bucket bucket; try { bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI, "", 0, System.currentTimeMillis()); } catch (RemoteException e) { return -1; } //这里可以区分发送和接收 return bucket.getTxBytes() +bucket.getRxBytes() ; } /** * 本机使用的 mobile 总流量 */ public long getAllBytesMobile() { NetworkStats.Bucket bucket; try { bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE, getSubscriberId(context, ConnectivityManager.TYPE_MOBILE), 0, System.currentTimeMillis()); } catch (RemoteException e) { return -1; } //这里可以区分发送和接收 return bucket.getTxBytes() +bucket.getRxBytes() ; } private String getSubscriberId(Context context, int networkType) { if (ConnectivityManager.TYPE_MOBILE == networkType) { TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); return tm.getSubscriberId(); } return ""; } /** * 获取指定应用 wifi 发送的当天总流量 * @param packageUid 应用的uid * @return */ public long getPackageTxDayBytesWifi(int packageUid) { NetworkStats networkStats = null; try { networkStats = networkStatsManager.queryDetailsForUid( ConnectivityManager.TYPE_WIFI, "", getTimesmorning(), System.currentTimeMillis(), packageUid); } catch (RemoteException e) { return -1; } NetworkStats.Bucket bucket = new NetworkStats.Bucket(); networkStats.getNextBucket(bucket); return bucket.getTxBytes(); } /** * 获取当天的零点时间 * * @return */ public static long getTimesmorning() { Calendar cal = Calendar.getInstance(); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.MILLISECOND, 0); return (cal.getTimeInMillis()); } //获得本月第一天0点时间 public static int getTimesMonthmorning() { Calendar cal = Calendar.getInstance(); cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH)); return (int) (cal.getTimeInMillis()); } /** * 根据包名获取uid * @param context 上下文 * @param packageName 包名 */ public static int getUidByPackageName(Context context, String packageName) { int uid = -1; PackageManager packageManager = context.getPackageManager(); try { PackageInfo packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_META_DATA); uid = packageInfo.applicationInfo.uid; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return uid; }

调用过程

//以上的方法封装在了NetworkStatsHelper类里 public class NetworkStatsHelper { NetworkStatsManager networkStatsManager; int packageUid; public NetworkStatsHelper(NetworkStatsManager networkStatsManager) { this.networkStatsManager = networkStatsManager; } } //初始化这个工具类 NetworkStatsManager networkStatsManager = (NetworkStatsManager) getSystemService(NETWORK_STATS_SERVICE); helper = new NetworkStatsHelper(networkStatsManager);

循环遍历应用

PackageManager packageManager = getPackageManager(); final List applicationInfoList = packageManager.getInstalledPackages(0); for (PackageInfo info : applicationInfoList) { try { PackageInfo pack = packageManager.getPackageInfo(info.packageName,PackageManager.GET_PERMISSIONS); String[] requestedPermissions = pack.requestedPermissions; if (requestedPermissions == null) continue; if (info.applicationInfo.uid == 1000) continue; for (String str : requestedPermissions) { if (str.equals("android.permission.INTERNET")) { long mobileTodayRx = helper.getPackageDayRxBytesMobile(mContext, uid); //...添加自己的代码 break; } } } catch (PackageManager.NameNotFoundException exception) { exception.printStackTrace(); } }

这里说明下为什么要过滤掉info.applicationInfo.uid == 1000 因为没有获取uid == 1000的进程的流量权限

好了现在说到权限,下面就是需要配置的权限

其中tools:ignore 就是忽略这个错误的意思,不然它会报红 仅仅在manifest里配置权限还是不够的,还要动态申请

private boolean hasPermissionToReadNetworkStats() { int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE); if (permissionCheck != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE); } else { } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return true; } final 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) { return true; } requestReadNetworkStats(); return false; } // 打开“有权查看使用情况的应用”页面 private void requestReadNetworkStats() { Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivity(intent); }

OK,到此就应该能成功获取流量统计信息了



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3