安卓NetworkStatsManager使用及demo

news2024/10/5 17:28:32

目录

  • 一、TrafficStats类简介
  • 二、demo示例


一、TrafficStats类简介

TrafficStats
Android API 8提供了android.net.TrafficStats类。
通过此类能获取设备重启以来网络信息,部分函数如下所示:

static long  getMobileRxBytes()  //获取通过移动数据网络收到的字节总数
static long  getMobileTxBytes()  //通过移动数据网发送的总字节数  
static long  getTotalRxBytes()  //获取设备总的接收字节数 
static long  getTotalTxBytes()  //获取设备总的发送字节数
static long  getUidRxBytes(int uid)  //获取指定uid的接收字节数  
static long  getUidTxBytes(int uid) //获取指定uid的发送字节数 

通过文档及上述函数可以知道,TrafficStats能够获取设备的数据流量和总的网络流量消耗(一般情况下也就得到Wi-Fi下的流量信息);可以查询uid对应的流量信息,而uid可以通过应用的包名查询到,因此能够查询某个应用的流量统计信息(不考虑shareuid)。非常方便的是,它的使用不需要特别的权限。另一方面它也一些限制:

(1)无法获取应用的数据流量消耗
从文档中仅能获取到指定uid的流量,但无法区分不同网络类型下的消耗
间接方法是通过监听网络切换,做好流量记录(但是要保证你的应用一直存活,且一定准确接收到网络切换信息),基本不可用。
(2)无法获取某个时间段内的流量消耗
从API文档中看,函数参数没有与时间相关的信息。而且重要的一点是,TrafficStats类中记录的是设备重启以来的流量统计信息。因为TrafficStats 类,底层还是读取/proc/net/xt_qtaguid/stats 对内容进行解析,将得到对应的结果返回上层。

链接:
Android应用流量统计——NetworkStatsManager使用

二、demo示例

本地使用demo验证流量消耗情况:获取一段时间内哪些应用进行了网络访问以及具体的流量消耗情况

package com.android.networktest;

import android.app.AppOpsManager;
import android.app.usage.NetworkStats;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.Settings;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        hasPermissionToReadNetworkStats();
        test();
    }



    private boolean hasPermissionToReadNetworkStats() {
        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);
    }

    public void test() {
        NetworkStatsManager networkStatsManager = (NetworkStatsManager) getSystemService(Context.NETWORK_STATS_SERVICE);

        long startTime = System.currentTimeMillis() - 1000 * 60 * 1000; // 从过去60x1000秒开始计算
        long endTime = System.currentTimeMillis();

        NetworkStats networkStats = null;
        NetworkStats.Bucket bucket = new NetworkStats.Bucket();

        try {
            networkStats = networkStatsManager.querySummary(
                    ConnectivityManager.TYPE_WIFI,
                    "",
                    startTime,
                    endTime
            );
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }

        networkStats.getNextBucket(bucket); // 获取第一个Bucket

        do {
            // 获取应用程序UID
            int uid = bucket.getUid();

            // 获取应用程序名称
            String packageName = getPackageManager().getNameForUid(uid);
            // 获取应用程序消耗的数据量
            long rxBytes = bucket.getRxBytes();
            long txBytes = bucket.getTxBytes();

            Log.d("henry------NetworkStats", "App: " + packageName + "  uid : " + uid +
                      " RX bytes: " + rxBytes + ", TX bytes: " + txBytes);
        } while (networkStats.getNextBucket(bucket)); // 获取下一个Bucket,直到没有更多Bucket为止
    }
}

Manifest权限添加一下:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions"/>

LOG打印如下:
在这里插入图片描述
在这里插入图片描述

可以看到对应uid 所消耗的流量情况
但是uid为1000 即系统权限的应用有很多,无法进一步区分哪些系统应用默认进行了网络访问。

NetworkStatsManager底层调用的是如下节点的数据:可以看多最多细分只能划分到uid。
在这里插入图片描述
总结:
NetworkStatsManager主要用来获取三方应用用户自行下载的app流量所消耗的情况,对于系统权限uid,uid相同但非同一个应用的app或服务无法进一步区分。

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

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

相关文章

Java苍穹外卖02-公共字段自动填充-菜品管理

一、公共字段自动填充 1.问题分析 需要有一种手段能够在mapper层&#xff08;持久层&#xff09;知道当前操作是否是insert或者update。 为mapper中需要进行拦截的方法加注解&#xff0c;然后去为这些赋值 2.代码开发 注解创建&#xff1a; 注意这里的Retention注解一定要是…

MySQL—MySQL的存储引擎之InnoDB

MySQL—MySQL的存储引擎之InnoDB 存储引擎及种类 存储引擎说明MyISAM高速引擎&#xff0c;拥有较高的插入&#xff0c;查询速度&#xff0c;但不支持事务InnoDB5.5版本后MySQL的默认数据库存储引擎&#xff0c;支持事务和行级锁&#xff0c;比MyISAM处理速度稍慢ISAMMyISAM的…

Unity AssetsBundle打包

为什么要使用AssetsBundle包 减少安装包的大小 默认情况下&#xff0c;unity编译打包是对项目下的Assets文件夹全部内容进行压缩打包 那么按照这个原理&#xff0c;你的Assets文件夹的大小将会影响到你最终打包出的安装包的大小&#xff0c;假如你现在正在制作一个游戏项目&…

Apollo 7周年大会:百度智能驾驶的展望与未来

本心、输入输出、结果 文章目录 Apollo 7周年大会&#xff1a;百度智能驾驶的展望与未来前言百度集团副总裁、智能驾驶事业群组总裁王云鹏发言 直播回放大会相关内容先了解 Apollo&#xfeff;开放平台 9.0架构图 发布产品Apollo 定义自己对于智能化的认知百度集团副总裁 王云鹏…

阿斯达年代记三强争霸服务器没反应 安装中发生错误的解决方法

阿斯达年代记三强争霸服务器没反应 安装中发生错误的解决方法 最近刚上线的由影视剧改编的游戏《阿斯达年代记三强争霸》可谓是在游戏圈内引起了轩然大波&#xff0c;这是一款由网石集团与龙工作室联合开发的MMORPG游戏&#xff0c;游戏背景设定在一个名为阿斯大陆的区域&…

Java之复制图片

从文件夹中复制图片 从这个文件夹&#xff1a; 复制到这个空的文件夹&#xff1a; 代码如下&#xff1a; import java.io.*; import java.util.Scanner;/*** 普通文件的复制*/public class TestDome10 {public static void main(String[] args) {// 输入两个路径// 从哪里(源路…

IOMMU和SMMU详解

前言&#xff1a; IOMMU&#xff08;输入输出内存管理单元&#xff09;的原理与CPU中的MMU&#xff08;内存管理单元&#xff09;相似。它的作用是管理设备的内存访问请求&#xff0c;允许安全、高效地在设备和内存之间直接传输数据。IOMMU通常用于支持高速数据传输的设备&…

了解时间复杂度和空间复杂度

在学习数据结构前&#xff0c;我们需要了解时间复杂度和空间复杂度的概念&#xff0c;这能够帮助我们了解数据结构。 算法效率分为时间效率和空间效率 时间复杂度 一个算法的复杂度与其执行的次数成正比。算法中执行基础操作的次数&#xff0c;为算法的时间复杂度。 我们采…

墨水屏技术在工业智能化领域的创新应用

墨水屏技术在工业智能化领域的创新应用 随着科技的快速发展&#xff0c;各种显示技术层出不穷&#xff0c;其中墨水屏作为一种独特的显示技术&#xff0c;逐渐在工业领域展现出其独特的优势和价值。墨水屏以其低功耗、高对比度和阅读舒适度高等特点&#xff0c;正成为工业应用…

9【PS作图】像素画Tips

放大缩小 “窗口”-排列-为…画布新建窗口&#xff0c;就可以新建一个窗口&#xff0c;实时看作图效果 如果要保持放大或缩小的像素画仍然保持硬边缘&#xff0c;需要设置两个东西 将 编辑 > 首选项 > 常规 中的 插值方式 改为 “邻近&#xff08;靠近硬边缘&#xff09…

android脱壳第二发:grpc-dumpdex加修复

上一篇我写的dex脱壳&#xff0c;写到银行类型的app的dex修复问题&#xff0c;因为dex中被抽取出来的函数的code_item_off 的偏移所在的内存&#xff0c;不在dex文件范围内&#xff0c;所以需要进行一定的修复&#xff0c;然后就停止了。本来不打算接着搞得&#xff0c;但是写了…

Hadoop伪分布式平台搭建

搭建Hadoop伪分布式环境是在单台机器上模拟完整的Hadoop分布式系统&#xff0c;使得所有的Hadoop守护进程&#xff08;如NameNode、DataNode、ResourceManager、NodeManager等&#xff09;都在同一台机器上运行。这样可以在一台机器上体验Hadoop的分布式特性&#xff0c;适合学…

openWebUI+ollamawindows+不用docker+webLite本地安装

openWebUI & ollama & windows & 不用docker & webLite 本地安装 总结一下安装教程 10核CPU16G内存 两个web框架都可以&#xff0c;先说简单的 ollama-webui-lite(https://github.com/ollama-webui/ollama-webui-lite) 轻量级&#xff0c;只使用nodejs 先装…

RTK负载(4K可见光+高分热成像+超广角+激光测距)四光AI智能识别跟踪吊舱技术详解

无人机光电吊舱的RTK负载&#xff08;4K可见光高分热成像超广角激光测距&#xff09;AI智能识别跟踪吊舱技术是一种高度集成和先进的无人机观测系统。系统结合了无人机的飞行能力和光电吊舱的多功能传感器&#xff0c;通过集成RTK&#xff08;实时动态差分定位&#xff09;技术…

php 编译安装oracel扩展

第一步安装Oracle客户端 1&#xff0c;需要下载基础包和sdk oracle客户端下载链接&#xff1a;Oracle Instant Client Downloads for Linux x86-64 (64-bit) https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html 选择最新版本 versi…

【智能算法】向日葵优化算法(SFO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2019年&#xff0c;GF Gomes等人受到自然界向日葵运动行为启发&#xff0c;提出了向日葵优化算法&#xff08;Sunflower Optimization, SFO&#xff09;。 2.算法原理 2.1算法思想 SFO模拟向日葵行…

数据库原理与应用实验二 SQL SERVER查询分析器的使用

实验目的和要求 熟悉SQL SERVER环境&#xff0c;熟悉查询分析器的使用&#xff0c;能够熟练运用sql命令完成数据库&#xff0c;基本表、主码、外码和其它必要的约束条件的定义。 实验环境 Windows10 SQLServer 实验内容与过程 1 利用sql建立图书管理数据库&#xff0c;并定…

勒索软件安全防护手册

文章目录 相关背景勒索软件概述勒索软件主要类型文件加密类勒索软件数据窃取类勒索软件系统加密类勒索软件。屏幕锁定类勒索软件 勒索软件典型传播方式利用安全漏洞传播利用钓鱼邮件传播利用网站挂马传播利用移动介质传播利用软件供应链传播利用远程桌面入侵传播 典型勒索软件攻…

string的OJ题

1.字符串相加 给定两个字符串形式的非负整数 num1 和num2 &#xff0c;计算它们的和并同样以字符串形式返回。 你不能使用任何內建的用于处理大整数的库&#xff08;比如 BigInteger&#xff09;&#xff0c; 也不能直接将输入的字符串转换为整数形式。 思路&#xff1a;从字…

区块链技术与应用学习笔记(10-11节)——北大肖臻课程

目录 10.分岔 ①什么是分叉&#xff1f; ②导致分叉的原因&#xff1f; ③在比特币新共识规则发布会会导致什么分叉&#xff1f; 什么是硬分叉&#xff1f; 硬分叉例子&#xff1f; 什么是软分叉&#xff1f; 软分叉和硬分叉区别&#xff1f; 软分叉实例 11.问答 转…