移动流量监控 demo
AS4.0 jdk1.8 测试的android系统 6.0 以上 在7.1安卓板 和 手机 android13 上测试了可以使用 。只写了移动流量的展示
网络数据管理类 Android 6.0后推出的 提供对网络使用历史和统计数据的访问,分为Summary queries(摘要查询)和 History queries(历史查询) 根据实际场景 个人建议尽量使用Summary queries
查询网络使用统计摘要。(查询多个应用流量统计) 会返回多个桶 需要循环遍历 在根据uid 的到每一个的实时流量
querySummary(int networkType, String subscriberId, long startTime, long endTime)
查询网络使用统计摘要。结果是整个设备的汇总数据使用情况。结果是随着时间、状态、uid、标签、计量和漫游聚合的单个存储桶
querySummaryForDevice(int networkType, String subscriberId, long startTime, long endTime)
1.networkType 查询网络类型 (ConnectivityManager.TYPE_WIFI,ConnectivityManager.TYPE_MOBILE)
2.subscriberId 设备唯一id(android 10及以后设备 获取不了,可不传)
3.startTime 查询指定时间段 开始时间戳
4.endTime 查询指定时间段 结束时间戳
5.uid 查询设备的Uid 这个我用的是在方法里判断了
/**
* 获取 所有移动使用流量信息
*
* @param context 上下文
* @param isDayAndMonth 是否是当天还是当月
* @return 返回 当天 还是当月的流量信息
*/
public TrafficBean getAllDay_MonthMobileInfo(Context context, boolean isDayAndMonth) {
TrafficBean trafficBean = new TrafficBean();
NetworkStats.Bucket bucket;
try {
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE,
getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
isDayAndMonth ? getTimesmorning() : getTimesMonthmorning(),
System.currentTimeMillis());
} catch (RemoteException e) {
return trafficBean;
}
trafficBean.setRxBytes(bucket.getRxBytes());
trafficBean.setTxBytes(bucket.getTxBytes());
trafficBean.setTotalData(bucket.getTxBytes() + bucket.getRxBytes());
return trafficBean;
}
我使用这个是查询每一个应用的的实时流量情况
记得使用过后 记得释放 网络统计信息 networkStats.close() 记得判空 我开始没有释放这个,报系统system 异常 但是不影响使用
/**
* 获取今日 或者今月的实时流量使用情况
*
* @param context 上下文
* @param isDayAndMonth 是否是今天还是今月
* @return 获取今日 或者今月的流量使用情况
*/
public TrafficBean getSummaryTrafficMobile(Context context, boolean isDayAndMonth) {
TrafficBean trafficBean = new TrafficBean();
trafficBean.setUid(packageUid + "");
NetworkStats networkStats = null;
try {
networkStats = networkStatsManager.querySummary(
ConnectivityManager.TYPE_MOBILE,
getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
isDayAndMonth ? getTimesmorning() : getTimesMonthmorning(),
System.currentTimeMillis());
long mobileTraffic = 0;//
long mobileRx = 0;
long mobileTx = 0;
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
do {
networkStats.getNextBucket(bucket);
int summaryUid = bucket.getUid();
if (packageUid == summaryUid) {
mobileTx += bucket.getTxBytes();
mobileRx += bucket.getRxBytes();
}
} while (networkStats.hasNextBucket());
mobileTraffic = mobileRx + mobileTx;
trafficBean.setTxBytes(mobileTx);
trafficBean.setRxBytes(mobileRx);
trafficBean.setTotalData(mobileTraffic);
} catch (RemoteException e) {
e.printStackTrace();
} finally {
if (networkStats != null) {
networkStats.close();
}
}
return trafficBean;
}
import android.annotation.SuppressLint;
import android.app.usage.NetworkStats;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import androidx.annotation.RequiresApi;
import com.tjf.traffic.bean.TrafficBean;
/**
* @author: tjf
* @date: 2022-12-10
* @desc: NetworkStatsHelper 流量查询辅助类
*
* <p> 使用方式
* * NetworkStatsManager networkStatsManager = (NetworkStatsManager) getSystemService(NETWORK_STATS_SERVICE);
* * NetworkStatsHelper helper = new NetworkStatsHelper(networkStatsManager);
* </p>
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public class NetworkStatsHelper {
NetworkStatsManager networkStatsManager;
int packageUid;
public void setPackageUid(int packageUid) {
this.packageUid = packageUid;
}
public NetworkStatsHelper(NetworkStatsManager networkStatsManager) {
this.networkStatsManager = networkStatsManager;
}
public NetworkStatsHelper(NetworkStatsManager networkStatsManager, int packageUid) {
this.networkStatsManager = networkStatsManager;
this.packageUid = packageUid;
}
/**
* 获取 所有移动使用流量信息
*
* @param context 上下文
* @param isDayAndMonth 是否是当天还是当月
* @return 返回 当天 还是当月的流量信息
*/
public TrafficBean getAllDay_MonthMobileInfo(Context context, boolean isDayAndMonth) {
TrafficBean trafficBean = new TrafficBean();
NetworkStats.Bucket bucket;
try {
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE,
getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
isDayAndMonth ? DateUtil.getTimesmorning() :DateUtil. getTimesMonthmorning(),
System.currentTimeMillis());
} catch (RemoteException e) {
return trafficBean;
}
trafficBean.setRxBytes(bucket.getRxBytes());
trafficBean.setTxBytes(bucket.getTxBytes());
trafficBean.setTotalData(bucket.getTxBytes() + bucket.getRxBytes());
return trafficBean;
}
/**
* 获取所有应用一天使用的移动流量信息
*
* @param context 上下文
* @param startTime 开始时间
* @return 流量信息
*/
public TrafficBean getOneDayMobileInfo(Context context, long startTime) {
TrafficBean trafficBean = new TrafficBean();
NetworkStats.Bucket bucket;
try {
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE,
getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
startTime,
startTime + 86400000
);
trafficBean.setRxBytes(bucket.getRxBytes());
trafficBean.setTxBytes(bucket.getTxBytes());
trafficBean.setTotalData(bucket.getTxBytes() + bucket.getRxBytes());
} catch (RemoteException e) {
return trafficBean;
}
return trafficBean;
}
/**
* 获取今日 或者今月的 应用 的实时流量使用情况
*
* @param context 上下文
* @param isDayAndMonth 是否是今天还是今月
* @return 获取今日 或者今月的流量使用情况
*/
public TrafficBean getSummaryTrafficMobile(Context context, boolean isDayAndMonth) {
TrafficBean trafficBean = new TrafficBean();
trafficBean.setUid(packageUid + "");
NetworkStats networkStats = null;
try {
networkStats = networkStatsManager.querySummary(
ConnectivityManager.TYPE_MOBILE,
getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
isDayAndMonth ? DateUtil.getTimesmorning() :DateUtil. getTimesMonthmorning(),
System.currentTimeMillis());
long mobileTraffic = 0;//
long mobileRx = 0;
long mobileTx = 0;
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
do {
networkStats.getNextBucket(bucket);
int summaryUid = bucket.getUid();
if (packageUid == summaryUid) {
mobileTx += bucket.getTxBytes();
mobileRx += bucket.getRxBytes();
}
} while (networkStats.hasNextBucket());
mobileTraffic = mobileRx + mobileTx;
trafficBean.setTxBytes(mobileTx);
trafficBean.setRxBytes(mobileRx);
trafficBean.setTotalData(mobileTraffic);
} catch (RemoteException e) {
e.printStackTrace();
} finally {
if (networkStats != null) {
networkStats.close();
}
}
return trafficBean;
}
/**
* 获取用户id android 10 以后获取不了 传null 即可
* 需要权限
* <uses-permission android:name="android.permission.READ_PHONE_STATE" />
*
* @param context 上下文
* @param networkType 网络类型
* @return null
*/
@SuppressLint("MissingPermission")
private String getSubscriberId(Context context, int networkType) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return null;
}
if (ConnectivityManager.TYPE_MOBILE == networkType) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.getSubscriberId();
}
return null;
}
}
大家先在 AndroidManifest.xml 添加如下权限内
<!--Android 11获取应用列表 权限-->
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<!-- 适配安卓12&11获取当前已安装的所有应用列表-->
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent>
</queries>
<!--包使用情况统计-->
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
<!--读取手机状态 这个是在getSubscriberId()用到的 android10后就可删除,因为不让获取了 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
1.获取使用情况统计权限
// 打开 "有权查看使用情况的应用"页面
private void requestReadNetworkStats() {
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// 经过测试,只有在 Android 10 及以上加包名才有效果
// 如果在 Android 10 以下加包名会导致无法跳转
intent.setData(Uri.parse("package:" + getPackageName()));
}
startActivity(intent);
}
private boolean hasPermissionToReadNetworkStats() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.i("流量-", "==当前版本小于23==");
return true;
}
final AppOpsManager appOps = (AppOpsManager)getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
Process.myUid(), getPackageName());
if (mode == AppOpsManager.MODE_ALLOWED) {
return true;
}
requestReadNetworkStats();
return false;
}
2.读取应用列表权限 下面这俩个选择一个就可以 点击应用排行列表的时候需要手动授权
<!-- Android 11获取应用列表 权限–>-->
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<!-- 适配安卓12&11获取当前已安装的所有应用列表-->
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent>
</queries>
1.获取拥有internet权限的应用列表
/**
* 获取拥有internet权限的应用列表
*
* @return
*/
public List<TrafficInfo> getInternetTrafficInfos() {
List<TrafficInfo> trafficInfos = new ArrayList<TrafficInfo>();
//获取手机中安装的并且具有权限的应用 PackageManager.GET_UNINSTALLED_PACKAGES |
List<PackageInfo> installedPackages = pm.getInstalledPackages(
PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_PERMISSIONS);
for (PackageInfo info : installedPackages) {
//获取权限数组
String[] permissions = info.requestedPermissions;
if (permissions != null && permissions.length > 0) {
for (String permission : permissions) {
if (permission.equals(Manifest.permission.INTERNET)) {
ApplicationInfo applicationInfo = info.applicationInfo;
Drawable icon = applicationInfo.loadIcon(pm);
String appname = applicationInfo.loadLabel(pm).toString();
String packagename = applicationInfo.packageName;
int uid = applicationInfo.uid;
TrafficInfo trafficInfo = new TrafficInfo(icon, appname, packagename, uid);
trafficInfos.add(trafficInfo);
}
}
}
}
return trafficInfos;
}
2.获取所有 的应用列表
/**
* 获取所有 的应用列表
*
* @return
*/
public List<TrafficInfo> getInstalledApplications() {
List<TrafficInfo> trafficInfos = new ArrayList<TrafficInfo>();
List<ApplicationInfo> installedPackages = pm.getInstalledApplications(
0);
for (ApplicationInfo applicationInfo : installedPackages) {
Drawable icon = applicationInfo.loadIcon(pm);
String appname = applicationInfo.loadLabel(pm).toString();
String packagename = applicationInfo.packageName;
int uid = applicationInfo.uid;
TrafficInfo trafficInfo = new TrafficInfo(icon, appname, packagename, uid);
trafficInfos.add(trafficInfo);
}
return trafficInfos;
}
这个是展示App流量排行时 需要把获取到的icon 转成bitmap 进行显示
/**
* 将Drawable转成Bitmap
*
* @param drawable
* @return
*/
public static Bitmap drawableToBitmap(Drawable drawable) {
Bitmap bitmap;
try {
bitmap = Bitmap.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
drawable.draw(canvas);
} catch (Exception e) {
bitmap = null;
}
return bitmap;
}
/**
* @author: tjf
* @desc: 流量文本格式化工具类
*/
public class TrafficFormat {
//定义TB的计算常量
private static final double TB = 1024f * 1024f * 1024f * 1024f;
//定义GB的计算常量
private static final double GB = 1024f * 1024f * 1024f;
//定义MB的计算常量
private static final double MB = 1024f * 1024f;
//定义KB的计算常量
private static final double KB = 1024f;
/**
* 格式化数据
*
* @param data
* @return
*/
public static String formatByte(long data) {
DecimalFormat format = new DecimalFormat("####.##");
if (data < KB) {
return data + "B";
} else if (data < MB) {
return format.format(data / KB) + "KB";
} else if (data < GB) {
return format.format(data / MB) + "MB";
} else if (data < TB) {
return format.format(data / GB) + "GB";
} else {
return "超出统计范围";
}
}
}
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/**
* @author: tjf
* @desc: 日期操作工具类.
*/
public class DateUtil {
/**
* 格式到天
*
* @param time
* @return
*/
public static String getDay(long time) {
return new SimpleDateFormat("yyyy-MM-dd").format(time);
}
/**
* 获得当前时间的<code java.util.Date</code 对象
*
* @return
*/
public static Date now() {
return new Date();
}
/**
* 获取当天的零点时间
*/
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 long getTimesMonthmorning() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1); // M月置1
cal.set(Calendar.HOUR_OF_DAY, 0);// H置零
cal.set(Calendar.MINUTE, 0);// m置零
cal.set(Calendar.SECOND, 0);// s置零
cal.set(Calendar.MILLISECOND, 0);// S置零
return cal.getTimeInMillis();
}
/**
* 获得当前月的第一天
* <p>
* HH:mm:ss SS为零
*
* @return
*/
public static Date firstDayOfMonthData() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1); // M月置1
cal.set(Calendar.HOUR_OF_DAY, 0);// H置零
cal.set(Calendar.MINUTE, 0);// m置零
cal.set(Calendar.SECOND, 0);// s置零
cal.set(Calendar.MILLISECOND, 0);// S置零
return cal.getTime();
}
/**
* 获得当前月的第一天
* <p>
* HH:mm:ss SS为零
*
*
*/
public static long firstDayOfMonth(int DAY_OF_MONTH) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, DAY_OF_MONTH); // M月置1
cal.set(Calendar.HOUR_OF_DAY, 0);// H置零
cal.set(Calendar.MINUTE, 0);// m置零
cal.set(Calendar.SECOND, 0);// s置零
cal.set(Calendar.MILLISECOND, 0);// S置零
return cal.getTimeInMillis();
}
/**
* 获得当前月的第一天到当前时间的时间戳集合
* <p>
* HH:mm:ss SS为零
*
*
*/
public static List<Long> getListDayOfMonth() {
List<Long> dayOfMonth = new ArrayList<>();
long days = getDayDiff(firstDayOfMonthData(), now());
for (int i = 1; i <= days; i++) {
long day = firstDayOfMonth(i);
dayOfMonth.add(day);
}
Collections.sort(dayOfMonth, new Comparator<Long>() {
@Override
public int compare(Long o1, Long o2) {
return (int) (o2 - o1);
}
});
return dayOfMonth;
}
/**
* 获得天数差
*
* @param begin 开始
* @param end 结束
* @return 天数
*/
public static long getDayDiff(Date begin, Date end) {
long day = 1;
if (end.getTime() < begin.getTime()) {
day = -1;
} else if (end.getTime() == begin.getTime()) {
day = 1;
} else {
day += (end.getTime() - begin.getTime()) / (24 * 60 * 60 * 1000);
}
return day;
}
}
import android.app.AppOpsManager;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.tjf.traffic.adapter.TrafficDateAdapter;
import com.tjf.traffic.bean.TrafficDayInfo;
import com.tjf.traffic.utils.DateUtil;
import com.tjf.traffic.utils.NetworkStatsHelper;
import com.tjf.traffic.bean.TrafficBean;
import com.tjf.traffic.utils.TrafficFormat;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* 流量监控首页 进行整个流量及每一天的总流量展示
*/
public class TrafficActivity extends AppCompatActivity {
@BindView(R.id.traffic_list_rev)
RecyclerView trafficListRev;
@BindView(R.id.traffic_month_all_tv)
TextView trafficMonthAllTv;
@BindView(R.id.traffic_day_all_tv)
TextView trafficDayAllTv;
@BindView(R.id.traffic_month_downall_tv)
TextView trafficMonthDownallTv;
@BindView(R.id.traffic_month_upall_tv)
TextView trafficMonthUpallTv;
@BindView(R.id.traffic_day_downall_tv)
TextView trafficDayDownallTv;
@BindView(R.id.traffic_day_upall_tv)
TextView trafficDayUpallTv;
@BindView(R.id.total_traffic_tv)
TextView totalTrafficTv;
@BindView(R.id.total_up_traffic_tv)
TextView totalUpTrafficTv;
@BindView(R.id.total_down_traffic_tv)
TextView totalDownTrafficTv;
@BindView(R.id.traffic_app_sort_lly)
LinearLayout trafficAppSortLly;
@BindView(R.id.traffic_goback)
ImageView trafficGoback;
TrafficDateAdapter trafficDateAdapter;//每天流量展示适配器
NetworkStatsManager networkStatsManager = null;//网络数据管理
NetworkStatsHelper helper = null;//网络数据助手
List<TrafficDayInfo> dateTraficlist = new ArrayList<>();//每天的流量集合
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_traffic);
ButterKnife.bind(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
networkStatsManager = (NetworkStatsManager) getSystemService(NETWORK_STATS_SERVICE);
}
helper = new NetworkStatsHelper(networkStatsManager);
trafficAppSortLly.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkUserAppListPerMission();
}
});
trafficGoback.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onResume() {
super.onResume();
if (!hasPermissionToReadNetworkStats()) {
Log.i("流量-", "==有权查看使用情况的应用的权限未授权==");
return;
}
Log.i("流量-", "==有权查看使用情况的应用的权限授权成功==");
setTrafficList();
}
@RequiresApi(api = Build.VERSION_CODES.M)
public void setTrafficList() {
TrafficBean monthTraffic = helper.getAllDay_MonthMobileInfo(this, false);
TrafficBean dayTraffic = helper.getAllDay_MonthMobileInfo(this, true);
trafficMonthAllTv.setText(String.format("当月已用总流量\n%s", TrafficFormat.formatByte(
monthTraffic.getTotalData())));
trafficDayAllTv.setText(String.format("当天已用总流量\n%s", TrafficFormat.formatByte(
dayTraffic.getTotalData())));
trafficMonthDownallTv.setText(String.format("当月下载流量\n%s", TrafficFormat.formatByte(
monthTraffic.getRxBytes())));
trafficMonthUpallTv.setText(String.format("当月上传流量\n%s", TrafficFormat.formatByte(
monthTraffic.getTxBytes())));
trafficDayDownallTv.setText(String.format("当天下载流量\n%s", TrafficFormat.formatByte(
dayTraffic.getRxBytes())));
trafficDayUpallTv.setText(String.format("当天上传流量\n%s", TrafficFormat.formatByte(
dayTraffic.getTxBytes())));
getDateAndMonthInfo();
trafficDateAdapter = new TrafficDateAdapter(this,
dateTraficlist, R.layout.traffic_date_item);
trafficListRev.setLayoutManager(new LinearLayoutManager(this));
trafficListRev.setAdapter(trafficDateAdapter);
}
public void startAppListPage() {
Toast.makeText(this, "点击了应用排行", Toast.LENGTH_SHORT).show();
startActivity(new Intent(TrafficActivity.this,
TrafficAppActivity.class));
}
// 打开 "有权查看使用情况的应用"页面
private void requestReadNetworkStats() {
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// 经过测试,只有在 Android 10 及以上加包名才有效果
// 如果在 Android 10 以下加包名会导致无法跳转
intent.setData(Uri.parse("package:" + getPackageName()));
}
startActivity(intent);
}
/**
* 检查是否有有权查看使用情况的应用的权限
*
* @return true false
*/
private boolean hasPermissionToReadNetworkStats() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.i("流量-", "==当前版本小于23==");
return true;
}
final AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, Process.myUid(), getPackageName());
if (mode == AppOpsManager.MODE_ALLOWED) {
return true;
}
requestReadNetworkStats();
return false;
}
/**
* 查询应用列表权限进行跳页
*/
public void checkUserAppListPerMission() {
startAppListPage();
}
@RequiresApi(api = Build.VERSION_CODES.M)
public void getDateAndMonthInfo() {
dateTraficlist.clear();
long totalTx = 0;
long totalRx = 0;
long totalTraffic;
List<Long> dateList = DateUtil.getListDayOfMonth();
for (Long datelong : dateList) {
TrafficBean oneTraffic = helper.getOneDayMobileInfo(this, datelong);
TrafficDayInfo usageDate = new TrafficDayInfo();
usageDate.setDateDay(datelong);
usageDate.setDateDayStr(DateUtil.getDay(datelong));
usageDate.setTotalRxBytes(TrafficFormat.formatByte(oneTraffic.getRxBytes()));
usageDate.setTotalTxBytes(TrafficFormat.formatByte(oneTraffic.getTxBytes()));
usageDate.setTotalTraffic(TrafficFormat.formatByte(oneTraffic.getTotalData()));
dateTraficlist.add(usageDate);
totalTx += oneTraffic.getTxBytes();
totalRx += oneTraffic.getRxBytes();
}
totalTraffic = totalRx + totalTx;
setTotalTraffic(TrafficFormat.formatByte(totalTraffic),
TrafficFormat.formatByte(totalTx), TrafficFormat.formatByte(totalRx));
Log.i("流量-", "==流量的汇总==\n"
+ TrafficFormat.formatByte(totalTraffic)
+ "\n上传流量合计:" +
TrafficFormat.formatByte(totalTx)
+ "\n下载流量合计:" + TrafficFormat.formatByte(totalRx));
}
/**
* 流量合计
*/
public void setTotalTraffic(String totalTraffic, String upTraffic, String downTraffic) {
totalTrafficTv.setText(String.format("总流量:%s", totalTraffic));
totalUpTrafficTv.setText(String.format("上传总流量:%s", upTraffic));
totalDownTrafficTv.setText(String.format("下载总流量:%s", downTraffic));
}
}
import android.app.usage.NetworkStatsManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.tjf.traffic.adapter.TrafficAppAdapter;
import com.tjf.traffic.bean.TrafficInfo;
import com.tjf.traffic.utils.NetworkStatsHelper;
import com.tjf.traffic.bean.TrafficBean;
import com.tjf.traffic.utils.TrafficFormat;
import com.tjf.traffic.utils.TrafficManagerApp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* 应用流量排行APP页 进行今日和今月列表切换 App流量的排行展示
*/
public class TrafficAppActivity extends AppCompatActivity {
@BindView(R.id.traffic_list_rev)
RecyclerView trafficListRev;
@BindView(R.id.traffic_day_month_tv)
TextView trafficDayMonthTv;
@BindView(R.id.total_traffic_tv)
TextView totalTrafficTv;
@BindView(R.id.total_up_traffic_tv)
TextView totalUpTrafficTv;
@BindView(R.id.total_down_traffic_tv)
TextView totalDownTrafficTv;
@BindView(R.id.traffic_goback)
ImageView trafficGoback;
TrafficAppAdapter trafficAppAdapter;
NetworkStatsManager networkStatsManager = null;
NetworkStatsHelper helper;
List<TrafficInfo> trafficApplist = new ArrayList<>();
TrafficManagerApp trafficManagerApp;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_traffic_app);
ButterKnife.bind(this);
trafficManagerApp = new TrafficManagerApp(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
networkStatsManager = (NetworkStatsManager) getSystemService(NETWORK_STATS_SERVICE);
}
helper = new NetworkStatsHelper(networkStatsManager);
getDayAndMonthInfo(true);
trafficAppAdapter = new TrafficAppAdapter(this,
trafficApplist, R.layout.traffic_app_item);
trafficListRev.setLayoutManager(new LinearLayoutManager(this));
trafficListRev.setAdapter(trafficAppAdapter);
trafficDayMonthTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (trafficDayMonthTv.getText().toString().equals("今日")) {
trafficDayMonthTv.setText("今月");
getDayAndMonthInfo(false);
} else if (trafficDayMonthTv.getText().toString().equals("今月")) {
trafficDayMonthTv.setText("今日");
getDayAndMonthInfo(true);
}
Toast.makeText(TrafficAppActivity.this,
"点击了" + trafficDayMonthTv.getText().toString(), Toast.LENGTH_SHORT).show();
if (trafficAppAdapter != null) {
trafficAppAdapter.notifyDataSetChanged();
}
}
});
trafficGoback.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@RequiresApi(api = Build.VERSION_CODES.M)
public void getDayAndMonthInfo(boolean isDayAndMonth) {
trafficApplist.clear();
trafficApplist.addAll(trafficManagerApp.getInternetTrafficInfos());
long totalTx = 0;
long totalRx = 0;
long totalTraffic;
for (TrafficInfo trafficInfo : trafficApplist) {
helper.setPackageUid(trafficInfo.getUid());
TrafficBean trafficBean = helper.getSummaryTrafficMobile(this, isDayAndMonth);
trafficInfo.setTraffic(TrafficFormat.formatByte(trafficBean.getTotalData()));
trafficInfo.setMobleTotalData(trafficBean.getTotalData());
trafficInfo.setMobleRxBytes(trafficBean.getRxBytes());
trafficInfo.setMobleTxBytes(trafficBean.getTxBytes());
totalTx += trafficBean.getTxBytes();
totalRx += trafficBean.getRxBytes();
}
totalTraffic = totalRx + totalTx;
Log.i("流量-", "==流量的汇总==\n"
+ TrafficFormat.formatByte(totalTraffic)
+ "\n上传流量合计:" +
TrafficFormat.formatByte(totalTx)
+ "\n下载流量合计:" + TrafficFormat.formatByte(totalRx));
setTotalTraffic(TrafficFormat.formatByte(totalTraffic),
TrafficFormat.formatByte(totalTx), TrafficFormat.formatByte(totalRx));
for (int i = trafficApplist.size() - 1; i >= 0; i--) {
TrafficInfo trafficInfo = trafficApplist.get(i);
if (trafficInfo.getTraffic().startsWith("0")) {
trafficApplist.remove(i);
}
}
Log.i("流量-", "过滤后的app的数量=" + trafficApplist.size());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Collections.sort(trafficApplist, new Comparator<TrafficInfo>() {
@Override
public int compare(TrafficInfo o1, TrafficInfo o2) {
//流量最大值排列
int max = (int) (o2.getMobleTotalData() - o1.getMobleTotalData());
return max;
}
});
}
}
/**
* 流量合计
*/
public void setTotalTraffic(String totalTraffic, String upTraffic, String downTraffic) {
totalTrafficTv.setText(String.format("总流量:%s", totalTraffic));
totalUpTrafficTv.setText(String.format("上传总流量:%s", upTraffic));
totalDownTrafficTv.setText(String.format("下载总流量:%s", downTraffic));
}
demo项目地址 https://toscode.gitee.com/code_tjf/traffic-demo
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。