41、流量统计--代码实现

类似程序管理器、进程管理器里的软件信息、进程信息,设置一个TrafficInfo结构体来表示流量信息:

package com.example.mobilesafe.engine;

import android.graphics.drawable.Drawable;

/**
 * Created by sing on 14-1-26.
 * desc:
 */
public class TrafficInfo {
    private static final String TAG = "TrafficInfo";

    //应用的包名
    private String packname;
    //应用的名称
    private String appname;
    //上传的数据
    private long tx;
    //下载的数据
    private long rx;
    //应用图标
    private Drawable icon;
    public String getPackname() {
        return packname;
    }
    public void setPackname(String packname) {
        this.packname = packname;
    }
    public String getAppname() {
        return appname;
    }
    public void setAppname(String appname) {
        this.appname = appname;
    }
    public long getTx() {
        return tx;
    }
    public void setTx(long tx) {
        this.tx = tx;
    }
    public long getRx() {
        return rx;
    }
    public void setRx(long rx) {
        this.rx = rx;
    }
    public Drawable getIcon() {
        return icon;
    }
    public void setIcon(Drawable icon) {
        this.icon = icon;
    }
}
获取流量信息的TrafficInfoProvider:

package com.example.mobilesafe.engine;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.TrafficStats;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by sing on 14-1-26.
 * desc:
 */
public class TrafficInfoProvider {
    private static final String TAG = "TrafficInfoProvider";

    private PackageManager pm;
    private Context context;

    public TrafficInfoProvider(Context context) {
        this.context = context;
        pm = context.getPackageManager();
    }

    /**
     * 返回所有的有互联网访问权限的应用程序的流量信息。
     *
     * @return
     */
    public List<TrafficInfo> getTrafficInfos() {
        //获取到配置权限信息的应用程序
        List<PackageInfo> packinfos = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS);
        //存放具有Internet权限信息的应用
        List<TrafficInfo> trafficInfos = new ArrayList<TrafficInfo>();
        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.setPackname(packinfo.packageName);
                        trafficInfo.setIcon(packinfo.applicationInfo.loadIcon(pm));
                        trafficInfo.setAppname(packinfo.applicationInfo.loadLabel(pm).toString());
                        //获取到应用的uid(user id)
                        int uid = packinfo.applicationInfo.uid;
                        //TrafficStats对象通过应用的uid来获取应用的下载、上传流量信息
                        trafficInfo.setRx(TrafficStats.getUidRxBytes(uid));
                        trafficInfo.setTx(TrafficStats.getUidTxBytes(uid));
                        trafficInfos.add(trafficInfo);
                        trafficInfo = null;
                        break;
                    }
                }
            }
        }
        return trafficInfos;
    }
}
原理是获取具有internet权限的程序。

TrafficInfoActivity代码:

package com.example.mobilesafe;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.text.format.Formatter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.example.mobilesafe.engine.TrafficInfo;
import com.example.mobilesafe.engine.TrafficInfoProvider;

import java.util.List;

/**
 * Created by sing on 14-1-26.
 * desc:
 */
public class TrafficInfoActivity extends Activity {

    //展示数据列表
    private ListView lv;
    //获取到所有具有Intenet权限的应用的流量信息
    private TrafficInfoProvider provider;
    //ProgressBar和TextView(正在加载...)的父控件,用于控制其显示
    private View ll_loading;
    //封装单个具有Intenet权限的应用的流量信息
    private List<TrafficInfo> trafficInfos;
    //处理子线程发送过来的消息,更新UI
    private Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            ll_loading.setVisibility(View.INVISIBLE);
            lv.setAdapter(new TrafficAdapter());
        };
    };

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.trafficinfo_layout);

        lv = (ListView) findViewById(R.id.lv_traffic);
        provider = new TrafficInfoProvider(this);
        ll_loading = findViewById(R.id.ll_loading);
        ll_loading.setVisibility(View.VISIBLE);
        //获取到具有Internet权限的应用所产生的流量
        new Thread(){
            public void run() {
                trafficInfos = provider.getTrafficInfos();
                //想主线程中发送一个空消息,用于通知主线程更新数据
                handler.sendEmptyMessage(0);
            };
        }.start();
    }

    //数据适配器
    private class TrafficAdapter extends BaseAdapter {

        public int getCount() {
            return trafficInfos.size();
        }

        public Object getItem(int position) {
            return trafficInfos.get(position);
        }

        public long getItemId(int position) {
            return position;
        }
        //ListView中显示多少个Item,该方法就被调用多少次
        public View getView(int position, View convertView, ViewGroup parent) {
            View view;
            ViewHolder holder = new ViewHolder();
            TrafficInfo info = trafficInfos.get(position);
            //复用缓存的View
            if(convertView==null){
                view = View.inflate(getApplicationContext(), R.layout.traffic_item, null);
                holder.iv_icon = (ImageView) view.findViewById(R.id.iv_traffic_icon);
                holder.tv_name = (TextView) view.findViewById(R.id.tv_traffic_name);
                holder.tv_rx = (TextView) view.findViewById(R.id.tv_traffic_rx);
                holder.tv_tx = (TextView) view.findViewById(R.id.tv_traffic_tx);
                holder.tv_total = (TextView) view.findViewById(R.id.tv_traffic_total);
                view.setTag(holder);
            }else{
                view = convertView;
                holder = (ViewHolder) view.getTag();
            }
            holder.iv_icon.setImageDrawable(info.getIcon());
            holder.tv_name.setText(info.getAppname());
            //下载所产生的流量
            long rx = info.getRx();
            //上传所产生的流量
            long tx = info.getTx();
            //增强程序的健壮性。因为在模拟器上运行时返回值为-1.
            if(rx<0){
                rx = 0;
            }
            if(tx<0){
                tx = 0;
            }
            holder.tv_rx.setText(Formatter.formatFileSize(getApplicationContext(), rx));
            holder.tv_tx.setText(Formatter.formatFileSize(getApplicationContext(), tx));
            //总流量
            long total = rx + tx;
            //通过Formatter将long类型的数据转换为MB或这KB,当数字较小时,自动采用KB
            holder.tv_total.setText(Formatter.formatFileSize(getApplicationContext(), total));
            return view;
        }
    }
    //通过static的修饰,保证了栈内存中存在唯一一份字节码且被共用
    static class ViewHolder{
        ImageView iv_icon;
        TextView tv_name;
        TextView tv_tx;
        TextView tv_rx;
        TextView tv_total;
    }
}
运行效果图:




  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

asmcvc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值