Android 流量统计

news2024/10/5 21:21:41

Android 流量统计

最近项目上有一个应用流量统计的功能需要实现,在此总结一下

流量统计架构

在这里插入图片描述

Android9.0之前,流量监控是基于xt_qtaguid模块的,通过读取/proc/net/xt_qtaguid/stats文件内容进行解析获取对应流量数据。

Android9.0之后,改为基于eBPF的网络监控模块,更加灵活且更易于维护;Android9.0 通过读取/sys/fs/bpf/traffic_uid_stats_map获取数据;Android10.0通过读取/sys/fs/bpf/map_netd_app_uid_stats_map获取数据。

调试查看流量信息:

XXX:/ # dumpsys netd trafficcontroller

  TrafficController
    BPF module status: BPF_LEVEL_EXTENDED

    mCookieTagMap status: OK
    mUidCounterSetMap status: OK
    mAppUidStatsMap status: OK
    mStatsMapA status: OK
    mStatsMapB status: OK
    mIfaceIndexNameMap status: OK
    mIfaceStatsMap status: OK
    mConfigurationMap status: OK
    mUidOwnerMap status: OK

    Cgroup ingress program status: OK
    Cgroup egress program status: OK
    xt_bpf ingress program status: OK
    xt_bpf egress program status: OK
    xt_bpf bandwidth whitelist program status: OK
    xt_bpf bandwidth blacklist program status: OK

    BPF map content:

      mCookieTagMap:

      mUidCounterSetMap:
      1001 1
      1073 1
      1002 1
      10046 1
      1000 1
      10016 1
      1076 1
      10037 1
      10056 1
      10019 1

      mAppUidStatsMap::
      uid rxBytes rxPackets txBytes txPackets
      10020 11763 24 15904 37
      1076 324919 1159 208570 1326
      10036 171008 1213 143638 1239
      1051 19271 140 9751 154
      0 3106517 27677 3158691 28118
      10019 18591 30 5631 39
      1020 356303 1419 118037 454
      10045 19345 121 14092 167
      10037 16511616 13422 13875657 12921
      1000 3623643 35705 3038615 35624

      mStatsMapA:
      ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets

      mStatsMapB:
      ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets
      3 dummy0 0x0 0 0 0 0 152 2
      1 lo 0x0 1000 1 8232 98 8232 98
      3 dummy0 0x0 1020 0 1527 6 1527 6
      1 lo 0x0 1020 0 1176 6 1176 6

      mIfaceIndexNameMap:
      ifaceIndex=8 ifaceName=rmnet_ipa0
      ifaceIndex=6 ifaceName=sit0
      ifaceIndex=7 ifaceName=ip6tnl0
      ifaceIndex=4 ifaceName=ip_vti0
      ifaceIndex=2 ifaceName=bond0
      ifaceIndex=11 ifaceName=p2p0
      ifaceIndex=3 ifaceName=dummy0
      ifaceIndex=10 ifaceName=wlan0
      ifaceIndex=5 ifaceName=ip6_vti0
      ifaceIndex=1 ifaceName=lo

      mIfaceStatsMap::
      ifaceIndex ifaceName rxBytes rxPackets txBytes txPackets
      3 dummy0 50949 196 110002 501
      10 wlan0 4210802 7222 764069 6653
      1 lo 19812096 73362 19812096 73362

查询方法

这里主要介绍一下NetworkStatsManager的相关方法

TrafficStats

  • 获取所有网口总的统计数据
    • static long getTotalRxBytes() //返回设备启动后收到的字节数。
    • static long getTotalRxPackets() //返回设备启动后收到的数据包数量。
    • static long getTotalTxBytes() //返回设备启动后传输的字节数。
    • static long getTotalTxPackets() //返回设备启动后传输的数据包数量。
  • 根据UID获取统计数据
    • static long getUidRxBytes(int uid) //返回设备引导后给定UID收到的字节数。
    • static long getUidRxPackets(int uid) //返回设备启动后给定UID收到的数据包数量。
    • static long getUidTxBytes(int uid) //返回设备启动后收到的字节数。
    • static long getUidTxPackets(int uid) //返回设备启动后传输的数据包数量

NetworkStatsManager

通过UID查询单个应用

  1. 通过包名获取UID
    private 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 ex) {
            ex.printStackTrace();
        }
        return uid;
    }
  1. 获取应用使用流量信息
    • 参数描述如下:
      • networkType 查询网络类型 (ConnectivityManager.TYPE_WIFIConnectivityManager.TYPE_MOBILE
      • subscriberId 设备唯一id(android 10及以后设备 获取不了,可不传)
      • startTime 查询指定时间段 开始时间戳
      • endTime 查询指定时间段 结束时间
      • uid 查询设备的Uid
NetworkStatsManager statsManager = (NetworkStatsManager) AccountApplication.getContext()
            .getSystemService(NETWORK_STATS_SERVICE);
        try (NetworkStats stats = statsManager.queryDetailsForUid(ConnectivityManager.TYPE_MOBILE,
            null, startTime, endTime, uid)) {
            NetworkStats.Bucket bucket = new NetworkStats.Bucket();
            stats.getNextBucket(bucket);
            totalSize = bucket.getRxBytes() + bucket.getTxBytes();
        }

问题

在使用queryDetailsForUid方法的过程中,发现获取到的数据为0,通过网上查阅才了解到,需要设置subscribeId为null而不是“”,源码中也有相关说明

  1. queryDetailsForUid(int networkType, String subscriberId,long startTime, long endTime, int uid)

在这里插入图片描述

  1. queryDetailsForUidTagState(int networkType, String subscriberId,long startTime, long endTime, int uid, int tag, int state)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sbCtthh2-1677057537429)(C:\Users\ts\AppData\Roaming\Typora\typora-user-images\image-20230222171356158.png)]

  1. createTemplate(int networkType, String subscriberId)

在这里插入图片描述

这里可以看到传入null进行查询就可以了;

然后是查询APP今日使用流量,发现总是获取为0,后来通过查询时间改为次日即可正常查询出来,very good!

参考连接

  1. (2条消息) android 统计应用流量 NetworkStatsManager_android获取流量使用情况_北极的松树的博客-CSDN博客
  2. Android-流量统计 - Wxy的个人博客 (leo-wxy.github.io)
  3. NetworkStatsManager.java - OpenGrok cross reference for /frameworks/base/core/java/android/app/usage/NetworkStatsManager.java (aospxref.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/363425.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

51单片机学习笔记_12 LCD1602 原理及其模块化代码

LCD1602 liquid crystal display 液晶显示屏,一种字符型液晶显示模块,可以显示 16*2 个字符,每个字符是 5*7 点阵。 P0 P2 会和数码管、LED 一定程度上冲突。 地。 Vcc。 调对比度的。 RS:数据指令端。1代表 DB 是数据&#x…

想要去字节跳动面试Android岗,给你这些面试知识点

关于面试字节跳动,我总结一些面试点,希望可以帮到更多的小伙伴,由于篇幅问题这里没有把全部的面试知识点问题都放上来!!目录:1.网络2.Java 基础&容器&同步&设计模式3.Java 虚拟机&内存结构…

实操go开发环境的配置

1、Go 安装包下载,下载地址如下: go语言中文网下载(本人电脑的系统是Windows,这里以Windows版本的安装包为例,安装就是傻瓜式安装,只要点下一步–下一步–完成就可以了,本人安装在C盘下。 我…

AQS学习:ReentrantLock源码解析

前言 多线程知识中理解了ReentrantLock之后,对于整个AQS也会有大概的理解,后面再去看其它锁的源码就会比较容易。下面带大家一块来学习ReentrantLock源码。 概述 ReentrantLock是可重入的互斥锁,虽然具有与synchronized相同功能&#xff0…

App.vue中读取不到路由的信息

问题: ​ 首先定义了一个路由,并且在路由元里面存储了一个变量,在App.vue里面访问这个变量的时候却显示undefined!在路由对应的组件中却能访问到! 定义的路由元信息: 为啥访问不到…,懵逼的我在App.vue里…

宝塔面板公网ip非80端口非443端口部署ssl

有不少人使用家用宽带,虽然申请下来了公网ip,但是运营商封了80与443端口,但仍想使用ssl证书 一、仅封80端口 1、先在宝塔面板里创建网站,域名为test.xxx.cn:8085 2、再到域名运营商做A记录解析,此时可以通过http://…

不同语言下的定时器,你都掌握了吗?

我们大家都对定时器不陌生,无论是现实中还是项目中,都离不开定时。在现实中,它叫闹钟,在项目上,它叫定时器,即定时触发某件事情。它能帮助我们在某一个既定的时间节点上,来提醒我们做一些事情&a…

Markdown基本语法简介

前言:当你在git平台创建一个仓库时,平台会自动创建一个README.md文件,并将它的内容展现在web端页面,方面其他读者查阅。README.md实则是一个适用Markdown语法的文本文件,从他的后缀md即可看出它是Markdown的缩写。在gi…

实战:kubeadm方式搭建k8s集群(k8s-v1.22.2,containerd-v1.5.5)-2023.2.22(测试成功)

实验环境 1、硬件环境 3台虚机 2c2g,20g。(nat模式,可访问外网) 角色主机名ipmaster节点master1172.29.9.51node节点node1172.29.9.52node节点node2172.29.9.53 2、软件环境 软件版本操作系统centos7.6_x64 1810 mini(其他centos7.x版本也行)containerdv1.5.5ku…

【项目】DTO、VO以及PO之间的关系和区别

【项目】DTO、VO以及PO之间的关系和区别 文章目录【项目】DTO、VO以及PO之间的关系和区别1.概念2. 作用1.概念 DTO:DTO是 Data Transfer Object 的缩写,也叫数据传输对象。 PO:PO是 Persistent Object 的缩写,也叫持久化对象。 …

Java 集合 --- HashMap的底层原理

Java 集合 --- HashMap的底层原理HashMap的下标计算计算步骤为什么要 h ^ (h >>> 16)为什么数组长度必须是2^nHashMap的树化HashMap的扩容HashMap的put流程HashMap的线程安全问题HashMap的下标计算 计算步骤 第一步: 计算hash值 将h 和 h右移十六位的结果 进行XOR操…

Java的dump文件分析及JProfiler使用

Java的dump文件分析及JProfiler使用 1 dump文件介绍 从软件开发的角度上,dump文件就是当程序产生异常时,用来记录当时的程序状态信息(例如堆栈的状态),用于程序开发定位问题。 idea配置发生OOM的时候指定路径生成dump文件 # 指定…

关于upstream的八种回调方法

1 creat_request调用背景:用于创建自己模板与第三方服务器的第一次连接步骤1) 在Nginx主循环(ngx_worker_process_cycle方法) 中,会定期地调用事件模块, 以检查是否有网络事件发生。2) 事件模块…

智慧校园平台源码 智慧教务 智慧电子班牌系统

系统介绍 智慧校园系统是通过信息化手段,实现对校园内各类资源的有效集成 整合和优化,实现资源的有效配置和充分利用,将校务管理过程的优化协调。为校园提供数字化教学、数字化学习、数字化科研和数字化管理。 致力于为家长和教师提供一个全方位、多层…

ChatGPT的出现网络安全专家是否会被替代?

ChatGPT的横空出世,在业界掀起了惊涛骇浪。很多人开始担心,自己的工作岗位是否会在不久的将来被ChatGPT等人工智能技术所取代。网络安全与先进技术发展密切相关,基于人工智能的安全工具已经得到很多的应用机会,那么未来是否更加可…

关于表格表头和第一列固定

主要是使用黏性布局 position: sticky; top: 0;//left:0; 来实现 给test-table一个固定的宽和高 然后trauma-table开启inline-flex布局(注意不能用flex布局 否则 trauma-table的宽度不能被子元素撑起来 会滚动到一定宽度后吸左侧的效果就没有了)&am…

Spring 用到了哪些设计模式

关于设计模式,如果使用得当,将会使我们的代码更加简洁,并且更具扩展性。本文主要讲解Spring中如何使用策略模式,工厂方法模式以及Builder模式。1. 策略模式关于策略模式的使用方式,在Spring中其实比较简单,…

【每日一题】缓存穿透、缓存击穿、缓存雪崩及解决方案

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 当下ChatGPT很火,让人心痒痒想试一试好不好用,因此我就试着借它写一篇文章,但是试了几次最终还是没有…

电子技术——负反馈特性

电子技术——负反馈特性 本节我们进一步深入介绍负反馈特性。 增益脱敏性 假设 β\betaβ 是一个常数。考虑下面的微分方程: dAfdA(1Aβ)2dA_f \frac{dA}{(1 A\beta)^2} dAf​(1Aβ)2dA​ 将上式除以 AfA1AβA_f \frac{A}{1A\beta}Af​1AβA​ 得到&#xff1…

LDAP使用docker安装部署与使用

一、准备工作本地或者服务器中安装dockerapt update apt install -y docker.io systemctl restart docker将openLDAP的docker镜像拉取到本地。镜像拉取命令:docker pull osixia/openldap将openLDAP的可视化管理工具phpldapadmin的镜像拉取到本地。镜像拉取命令&am…