Android流量监控
16lz
2021-01-23
**
一、需求:
**
获得设备里程序耗费流量的具体情况。
二、代码实现:
1.首先是赋予权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permission android:name="android.permission.READ_PHONE_STATE"/>
2.自定义个bean对象,封装拿到的内容。
/** * Created by Jim斌 on 2017/8/27. */public class TrafficInfo { private String Packagename; private String Appname; private int Icon; private long Rx; private long Tx; public long getRx() { return Rx; } public void setRx(long rx) { Rx = rx; } public long getTx() { return Tx; } public void setTx(long tx) { Tx = tx; } public String getPackagename() { return Packagename; } public void setPackagename(String packagename) { Packagename = packagename; } public String getAppname() { return Appname; } public void setAppname(String appname) { Appname = appname; } public int getIcon() { return Icon; } public void setIcon(int icon) { Icon = icon; }}
3.下面的工具类为流量监控的代码实现
/** * Created by Jim斌 on 2017/8/29. */public class FlowUtil { private static long Rx;//上传的流量 private static long Tx;//下载的流量 /** * 通过uid查询文件夹中的数据 * * @param localUid * @return */ public static Long getTotalBytesManual(int localUid) {// Log.e("BytesManual*****", "localUid:" + localUid); File dir = new File("/proc/uid_stat/"); String[] children = dir.list(); StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < children.length; i++) { stringBuffer.append(children[i]); stringBuffer.append(" "); } if (!Arrays.asList(children).contains(String.valueOf(localUid))) { return 0L; } File uidFileDir = new File("/proc/uid_stat/" + String.valueOf(localUid)); File uidActualFileReceived = new File(uidFileDir, "tcp_rcv"); File uidActualFileSent = new File(uidFileDir, "tcp_snd"); String textReceived = "0"; String textSent = "0"; try { BufferedReader brReceived = new BufferedReader(new FileReader(uidActualFileReceived)); BufferedReader brSent = new BufferedReader(new FileReader(uidActualFileSent)); String receivedLine; String sentLine; if ((receivedLine = brReceived.readLine()) != null) { textReceived = receivedLine; } if ((sentLine = brSent.readLine()) != null) { textSent = sentLine; } } catch (IOException e) { e.printStackTrace(); } Rx=Long.valueOf(textReceived).longValue(); Tx=Long.valueOf(textSent).longValue();// Log.d(TAG, "上传: "+Long.valueOf(textReceived).longValue()+"下载:"+Long.valueOf(textSent).longValue()); return Long.valueOf(textReceived).longValue() + Long.valueOf(textSent).longValue(); } /** * 返回所有的有互联网访问权限的应用程序的流量信息。 * TrafficInfo 为一个Bean 模型类。使用的时候可以自定义一个、。 * * @return */ public static List getTrafficInfo(Context context) { //获取到配置权限信息的应用程序 PackageManager pms = context.getPackageManager(); List packinfos = pms .getInstalledPackages(PackageManager.GET_PERMISSIONS); //存放具有Internet权限信息的应用 List trafficInfos = new ArrayList(); for (PackageInfo packinfo : packinfos) { //获取该应用的所有权限信息 String[] permissions = packinfo.requestedPermissions; if (permissions != null && permissions.length > 0) { for (String permission : permissions) { //筛选出具有Internet权限的应用程序 if ("android.permission.INTERNET".equals(permission)) { //用于封装具有Internet权限的应用程序信息 TrafficInfo trafficInfo = new TrafficInfo(); //封装应用信息 trafficInfo.setPackagename(packinfo.packageName);// trafficInfo.setIcon(packinfo.applicationInfo.loadIcon(pms));//设置图标,用到时再改 trafficInfo.setAppname(packinfo.applicationInfo.loadLabel(pms).toString()); //获取到应用的uid(user id) int uid = packinfo.applicationInfo.uid; //TrafficStats对象通过应用的uid来获取应用的下载、上传流量信息 //发送的 上传的流量byte trafficInfo.setRx(TrafficStats.getUidRxBytes(uid)); //下载的流量 byte trafficInfo.setTx(TrafficStats.getUidTxBytes(uid));//不晓得为什么这两个为空 trafficInfos.add(trafficInfo); if (getTotalBytesManual(uid) != 0) { Log.d(TAG, "getTrafficInfo: "+"\n" + "包名: " + trafficInfo.getPackagename() +"\n"+ "APP名: " + trafficInfo.getAppname() +"\n"+ "uid: " + uid +"\n"+ "上传的流量 byte: " + Rx +"\n"+ "下载的流量 byte: " + Tx +"\n"+ "消耗总流量 byte:" + getTotalBytesManual(uid)); } trafficInfo = null; break; } } } } return trafficInfos; }}
三、总结:
Android其实封装了一个流量控制类TrafficStats,本来以为直接用就可以,但是在用的过程中遇到了一个
坑
。这个类里面的getUidRxBytes(int uid) 和 getUidTxBytes(int uid)好像没用….
getUidRxBytes(int uid) 和 getUidTxBytes(int uid)这两个方法时一直返回0,无论什么应用都说流量消耗为0,这明显是错误的。
一开始以为这两个方法只是获取2G或者3G消耗的流量,而我的手机信号显示的是4G,尝试了一下在网络上搜索“Android获取4G流量消耗”,毛都没收到,接着看到了日志里getMobileTxBytes()返回的数据不为空,猜应该是不分3G、4G的,可能是我的获取方法没起作用或获取错。
查了Android的API文档,确认方法调用时正确的,调试了下,发现方法返回的仍旧是空。很迷,后来在网上查到资料,通过访问“/proc/uid_stat/”这个文件可以获取到消耗的流量,就是上面演示的代码。
至于TrafficStats类里面拿两个方法为什么不能用我现在还没搞懂。
四、参考资料
http://dev.10086.cn/cmdn/bbs/thread-49242-1-1.html
http://www.cnblogs.com/0616–ataozhijia/p/6628462.html
更多相关文章
- Android发送短信方法实例详解
- android 解析 xml 文档的三种方法
- 几个Android小错误解决方法
- android读取assets大于1M文件的解决方法
- Android 通知Notification的两种实现方法
- android监听键盘弹出or隐藏方法
- Android 图片压缩的方法大全
- android Gide加载webp图片方法
- Android Battery一些信息获取方法