android 前后台流量监测

测试应用流量的时候,需要区分前台和后台试用的流量,但是目前一些Android 手机自带的流量监控已经没有那么细的一个区分,通常只有一个百分数。由于测试需要我自己写了一个APP 来测试

原理很简单,其实就是 使用 TrafficStats 来获取流量,其api如下:
static long getMobileRxBytes() //获取通过Mobile连接收到的字节总数,不包含WiFi
static long getMobileRxPackets() //获取Mobile连接收到的数据包总数
static long getMobileTxBytes() //Mobile发送的总字节数
static long getMobileTxPackets() //Mobile发送的总数据包数
static long getTotalRxBytes() //获取总的接受字节数,包含Mobile和WiFi等
static long getTotalRxPackets() //总的接受数据包数,包含Mobile和WiFi等
static long getTotalTxBytes() //总的发送字节数,包含Mobile和WiFi等
static long getTotalTxPackets() //发送的总数据包数,包含Mobile和WiFi等
static long getUidRxBytes(int uid) //获取某个网络UID的接受字节数
static long getUidTxBytes(int uid) //获取某个网络UID的发送字节数

效果图:
android 前后台流量监测_第1张图片
android 前后台流量监测_第2张图片

代码:
activity_main.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.maple.trafficmonitoring.MainActivity">

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/listView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_above="@+id/btnStart" />

    <Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="流量监控"
    android:id="@+id/btnStart"
    android:background="@drawable/test_button"
    android:textSize="@dimen/text_size_test"
    android:textColor="@color/white"
    android:layout_above="@+id/btnStart1"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

RelativeLayout>

MainActivity

package com.maple.trafficmonitoring;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.TrafficStats;
import android.os.Parcelable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;

import java.math.BigDecimal;
import java.util.List;

public class MainActivity extends Activity {
    private Button btnStart,btnStart1;
    private ListView lstViProgramme; ;
    private ProcessInfo processInfo;
    private int pid;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnStart = (Button) findViewById(R.id.btnStart);
        lstViProgramme = (ListView) findViewById(R.id.listView);
        btnStart1 = (Button) findViewById(R.id.btnStart1);


        processInfo = new ProcessInfo();
        lstViProgramme.setAdapter(new ListAdapter());
        lstViProgramme.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView adapterView, View view, int i, long l) {
                RadioButton rdBtn = (RadioButton) ((LinearLayout) view).getChildAt(0);
                rdBtn.setChecked(true);
            }
        });

        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ListAdapter adapter = (ListAdapter) lstViProgramme.getAdapter();
                if (adapter.checkedProg != null){
                    String packageName = adapter.checkedProg.getPackageName();
                    String APPName = adapter.checkedProg.getProcessName();
                    Intent intent = new Intent(MainActivity.this,StartMonitor.class);
                    intent.putExtra("packageName",packageName);
                    intent.putExtra("APPName",APPName);
                    startActivity(intent);
                }else {
                    Toast.makeText(MainActivity.this, "请选择需要测试的应用程序", Toast.LENGTH_SHORT).show();
                }

            }
        });
    private class ListAdapter extends BaseAdapter {
        List programes;
        Programe checkedProg;
        int lastCheckedPosition = -1;

        public ListAdapter() {
            programes = processInfo.getAllPackages(getBaseContext());
        }

        @Override
        public int getCount() {
            return programes.size();
        }

        @Override
        public Object getItem(int position) {
            return programes.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Programe pr = (Programe) programes.get(position);
            if (convertView == null)
                convertView = getLayoutInflater().inflate(R.layout.list_item, parent, false);
            Viewholder holder = (Viewholder) convertView.getTag();
            if (holder == null) {
                holder = new Viewholder();
                convertView.setTag(holder);
                holder.imgViAppIcon = (ImageView) convertView.findViewById(R.id.image);
                holder.txtAppName = (TextView) convertView.findViewById(R.id.text);
                holder.rdoBtnApp = (RadioButton) convertView.findViewById(R.id.rb);
                holder.rdoBtnApp.setFocusable(false);
                holder.rdoBtnApp.setOnCheckedChangeListener(checkedChangeListener);
            }
            holder.imgViAppIcon.setImageDrawable(pr.getIcon());
            holder.txtAppName.setText(pr.getProcessName());
            holder.rdoBtnApp.setId(position);
            holder.rdoBtnApp.setChecked(checkedProg != null && getItem(position) == checkedProg);
            return convertView;
        }

        CompoundButton.OnCheckedChangeListener checkedChangeListener = new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    final int checkedPosition = buttonView.getId();
                    if (lastCheckedPosition != -1) {
                        RadioButton tempButton = (RadioButton) findViewById(lastCheckedPosition);
                        if ((tempButton != null) && (lastCheckedPosition != checkedPosition)) {
                            tempButton.setChecked(false);
                        }
                    }
                    checkedProg = programes.get(checkedPosition);
                    lastCheckedPosition = checkedPosition;
                }
            }
        };
    }

    /**
     * save status of all installed processes
     *
     * @author andrewleo
     */
    static class Viewholder {
        TextView txtAppName;
        ImageView imgViAppIcon;
        RadioButton rdoBtnApp;
    }


}

StartMonitor

package com.maple.trafficmonitoring;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.TrafficStats;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * Created by liu on 1/12/16.
 */
public class StartMonitor extends Activity{
    private Drawable icon ;
    private int uid = 0,i;
    private String version;
    private ImageView imageView;
    private TextView tv ,tv2, tv3,tv5,tv4,tv6,tvTime,testTime,tv7;
    private Button btnStart;
    private int Hcont=0,interval=5,Qcont=0,cont = 0;
    private SeekBar timeBar ,TestTimeBar;
    private long r;
    private long rx;
    private long tx;
    private long Tms;
    private long Htraf=0;
    private long Qtraf=0;
    private boolean first = false,testEnd=true,isTime=true,SaveCSV = false;
    private Context c;
    private String packageName;
    private String AppName;
    private String rt;
    private WriteCSV write= new WriteCSV();
    private String    mDateTime;
    private CheckBox chkSaveCsv;

    final Handler handler = new Handler();
    final Runnable runnable = new Runnable() {
        @Override
        public void run() {

            i = Integer.parseInt(String.valueOf(tvTime.getText()))*1000;
            int isB = isBackground(c);
            rx = TrafficStats.getUidRxBytes(uid);
            tx = TrafficStats.getUidTxBytes(uid);
            rt = String.valueOf(Qtraf + Htraf);
            tv5.setText(getString(R.string.str)+AppName+getString(R.string.UseTotal) + bytes2kb(Qtraf + Htraf));
            if (isB==1){
                long ms = Hcont * i;
                SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
                formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
                String hms = formatter.format(ms);
                Htraf = rx + tx - r - Qtraf;
                tv6.setText(getString(R.string.BackgroundOperation) + hms + getString(R.string.useTraffic) +bytes2kb(Htraf) );
                Hcont = Hcont + 1;
                System.out.println(rx + tx + "   " + hms);
                writeData("后台",hms,rt,String.valueOf(Qtraf),String.valueOf(Htraf));
            }else if (isB == 2) {
                long ms =Qcont * i;
                SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
                formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
                String hms = formatter.format(ms);
                Qtraf = rx + tx - r - Htraf;
                tv7.setText(getString(R.string.foreground) + hms + getString(R.string.useTraffic) +bytes2kb(Qtraf) );
                Qcont = Qcont + 1;
                System.out.println(rx + tx+ "   " + hms);
                writeData("前台",hms,rt,String.valueOf(Qtraf),String.valueOf(Htraf));
            }
            Tms = cont*i;
            cont=cont+1;
            handler.postDelayed(this, i);// 50是延时时长
            if (isB ==3){
                Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage(packageName);
                startActivity(LaunchIntent);
            }

            if (!testTime.getText().equals(getString(R.string.timeless))){
                int lg = Integer.parseInt(String.valueOf(testTime.getText()));
                System.out.println(lg*60*60*1000+"  "+Tms);
                if (lg*60*60*1000 <= Tms){
                    stop();
                }
            }

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.start_monitor);
        ints();
        Intent intent = getIntent();
        packageName = intent.getStringExtra("packageName");
        AppName = intent.getStringExtra("APPName");
        PackageManager pm = getPackageManager();
        try {
            ApplicationInfo ai = pm.getApplicationInfo(packageName,PackageManager.GET_ACTIVITIES);
            uid = ai.uid;
            icon = ai.loadIcon(pm);
            PackageInfo packageInfo = pm.getPackageInfo(packageName,0);
            version = packageInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        imageView.setImageDrawable(icon);
        tv.setText(getString(R.string.ApplicationName)+AppName);
        tv2.setText(getString(R.string.packageName)+packageName);
        tv3.setText(getString(R.string.Version)+version);
        try {
            c = createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
            Log.e("000000", String.valueOf(c));
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }


        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (btnStart.getText().equals(getString(R.string.Start))) {
                    tv4.setText(R.string.testing);
                    btnStart.setText(R.string.Stop);
                    timeBar.setEnabled(false);
                    TestTimeBar.setEnabled(false);
                    chkSaveCsv.setClickable(false);
                    Toast.makeText(StartMonitor.this, R.string.startTest, Toast.LENGTH_SHORT).show();
                    if(first){
                        Hcont=1;
                        Qcont=1;
                        cont = 1;
                    }
                    first=true;
                    testEnd=false;
                    Htraf=0;
                    Qtraf=0;
                    tv6.setText(getString(R.string.foreground) + "00:00:00" + getString(R.string.useTraffic) +bytes2kb(Htraf) );
                    tv7.setText(getString(R.string.foreground) + "00:00:00" + getString(R.string.useTraffic) +bytes2kb(Qtraf) );
                    r = TrafficStats.getUidRxBytes(uid) + TrafficStats.getUidTxBytes(uid);
                    handler.postDelayed(runnable, i);// 打开定时器,执行操作
                }else {
                    stop();
                }
            }
        });

    }

    private void stop (){
        handler.removeCallbacks(runnable);
        tv4.setText(R.string.EndTest);
        timeBar.setEnabled(true);
        TestTimeBar.setEnabled(true);
        chkSaveCsv.setClickable(true);
        testEnd=true;
        isTime=true;
        btnStart.setText(getString(R.string.Start));
    }


    private void  ints (){
        imageView = (ImageView) findViewById(R.id.imageView);
        tv = (TextView) findViewById(R.id.textView);
        tv2 = (TextView) findViewById(R.id.textView2);
        tv3 = (TextView) findViewById(R.id.textView3);
        tv5 = (TextView) findViewById(R.id.textView5);
        tv4 = (TextView) findViewById(R.id.textView4);
        tv6 = (TextView) findViewById(R.id.textView6);
        tv7 = (TextView) findViewById(R.id.textView7);
        chkSaveCsv = (CheckBox) findViewById(R.id.SaveCSV);
        chkSaveCsv.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                SaveCSV=isChecked;
            }
        });
        btnStart = (Button) findViewById(R.id.btnStart);
        testEnd=true;

        testTime = (TextView) findViewById(R.id.TestTime);
        testTime.setText(getString(R.string.timeless));
        TestTimeBar = (SeekBar) findViewById(R.id.TestTimeline);
        TestTimeBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (progress==0){
                    testTime.setText(getString(R.string.timeless));
                }else {
                    testTime.setText(Integer.toString(progress));
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        tvTime = (TextView) findViewById(R.id.time);
        tvTime .setText(String.valueOf(interval));
        timeBar = (SeekBar) findViewById(R.id.timeline);
        timeBar.setProgress(interval);
        timeBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
                tvTime.setText(Integer.toString(arg1 + 1));
            }

            @Override
            public void onStartTrackingTouch(SeekBar arg0) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar arg0) {
                // when tracking stoped, update preferences
            }
        });

    }
//单位转换
    public static String bytes2kb(long bytes) {
        BigDecimal filesize = new BigDecimal(bytes);
        BigDecimal megabyte = new BigDecimal(1024 * 1024);
        float returnValue = filesize.divide(megabyte, 2, BigDecimal.ROUND_UP)
                .floatValue();
        if (returnValue > 1)
            return (returnValue + "MB");
        BigDecimal kilobyte = new BigDecimal(1024);
        returnValue = filesize.divide(kilobyte, 2, BigDecimal.ROUND_UP)
                .floatValue();
        return (returnValue + "KB");
    }

    public int isBackground(Context context) {
        ActivityManager activityManager = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);
        List appProcesses = activityManager
                .getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.processName.equals(context.getPackageName())) {

                if (appProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    Log.i(context.getPackageName(), "处于后台"
                            + appProcess.processName);
                    return 1;
                } else {
                    Log.i(context.getPackageName(), "处于前台"
                            + appProcess.processName);
                    return 2;
                }
            }
        }
        return 3;
    }
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (testEnd){
                return super.onKeyDown(keyCode, event);
            }else {

                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    private void writeData(String QorH,String time,String TotalFlow,String Q ,String H){
        if (SaveCSV) {
            if (isTime) {
                SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
                Date curDate = new Date(System.currentTimeMillis());//获取当前时间
                mDateTime = formatter.format(curDate);
                isTime = false;
            }
            write.WriteCSV(QorH, time, TotalFlow, Q, H, mDateTime, AppName, version,getBaseContext());
        }
    }

}

WriteCSV

package com.maple.trafficmonitoring;

import android.content.Context;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;

public class WriteCSV {
    boolean aBoolean=true , bBoolean=true,cBoolean=true,dBoolean=true;
    private String resultFilePath;
    public  void WriteCSV(String QorH, String time, String TotalFlow, String Q , String H, String mDateTime, String appName, String version, Context context){

        try {
            if (android.os.Environment.getExternalStorageState().equals(
                    android.os.Environment.MEDIA_MOUNTED)) {
                // 在4.0以下的低版本上/sdcard连接至/mnt/sdcard,而4.0以上版本则连接至/storage/sdcard0,所以有外接sdcard,/sdcard路径一定存在
                resultFilePath = "/sdcard" + File.separator + "traffic_monitor_"
                        +appName+ mDateTime + ".csv";
                System.out.println("BBB"+resultFilePath);
                // resultFilePath =
                // android.os.Environment.getExternalStorageDirectory() +
                // File.separator + "Emmagee_TestResult_" + mDateTime + ".csv";
            } else {
                resultFilePath = context.getFilesDir().getPath()
                        + File.separator + "traffic_monitor_" + appName+mDateTime
                        + ".csv";
                System.out.println("AAA"+resultFilePath);
            }
            File csv = new File(resultFilePath);
            BufferedWriter bw = new BufferedWriter(new FileWriter(csv, true)); // 附加
            // 添加新的数据行
            if (bBoolean){
                bw.write("应用名称" +","+appName+ "\r\n" + "应用版本" +","+version + "\r\n" + "Android 系统版本" +","+android.os.Build.VERSION.RELEASE+"\r\n" +"手机型号:"+","+android.os.Build.MODEL);
                bw.newLine();
                bBoolean=false;
            }
            if (aBoolean){
                bw.write("运行状态"+ "," + "时间"+ "," + "总流量(B)" + "," + "前台流量(B)" +"," +"后台流量(B)");
                bw.newLine();
                aBoolean=false;
            }
            bw.write(QorH + "," +time + "," + TotalFlow + "," + Q +"," +H);
            bw.newLine();
            bw.close();

        } catch (FileNotFoundException e) {
            // File对象的创建过程中的异常捕获
            e.printStackTrace();
        } catch (IOException e) {
            // BufferedWriter在关闭对象捕捉异常
            e.printStackTrace();
        }
    }
}

start_monitor.xml

"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/light_purple">

    "wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:src="@mipmap/ic_launcher"
        android:id="@+id/imageView"
        android:layout_centerHorizontal="true" />

    "wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/textView"
        android:textSize="@dimen/text_size"
        android:layout_gravity="center_horizontal"
        android:layout_below="@+id/imageView"
        android:layout_centerHorizontal="true" />

    "wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/textView2"
        android:layout_gravity="center_horizontal"
        android:layout_below="@+id/textView"
        android:textSize="@dimen/text_size"
        android:layout_alignLeft="@+id/textView"
        android:layout_alignStart="@+id/textView" />

    "wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/textView3"
        android:textSize="@dimen/text_size"
        android:layout_gravity="center_horizontal"
        android:layout_below="@+id/textView2"
        android:layout_alignLeft="@+id/textView2"
        android:layout_alignStart="@+id/textView2" />


    "vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayout"
        android:background="@color/white"
        android:layout_above="@+id/btnStart"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp"
        android:layout_below="@+id/linearLayout3">
        "wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/textView8"
            android:text="@string/Mark"
            android:layout_marginTop="5dp"
            android:textSize="@dimen/text_size"
            android:layout_marginLeft="15dp"
            android:textColor="@color/red"/>

        "wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/textView4"
            android:textSize="@dimen/text_size"
            android:layout_marginLeft="15dp"
            android:textColor="@color/red"/>

        "wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/textView5"
            android:textSize="@dimen/text_size"
            android:layout_marginLeft="15dp"
            />

        "wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            android:id="@+id/textView6"
            android:textSize="@dimen/text_size"
            android:layout_marginLeft="15dp"/>
        "wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            android:id="@+id/textView7"
            android:textSize="@dimen/text_size"
            android:layout_marginLeft="15dp"/>

    </LinearLayout>

    

你可能感兴趣的:(android-测试)