转自:http://blog.csdn.net/csxwc/article/details/10110753
前几天想做一个类似于360流量监控悬浮窗的效果,可以实时显示网速。
重要的读取系统的流量文件,文件路径/proc/self/net/dev
下面是复制下来的dev文件
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 5200 48 0 0 0 0 0 0 5200 48 0 0 0 0 0 0
dummy0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet0: 43413730 45920 0 0 0 0 0 0 4447114 39247 0 0 0 0 0 0
rmnet1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet2: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet3: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet4: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet5: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet6: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet7: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
usb0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
tunl0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ip6tnl0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
其中/eth是以太网信息 tiwlan0 是 Wifi rmnet0 是 GPRS
当然,对于不同的机型,文件格式也可能不相同,可自行下载ES文件浏览器查看,并不在sd卡中,在根目录下。
下面我们就来看看是怎么读取跟显示的
首先是悬浮窗,布局文件如下:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="100dp"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
- <RelativeLayout
- android:id="@+id/rl_left"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
- <ImageView
- android:id="@+id/img_float"
- android:layout_width="30dp"
- android:layout_height="30dp"
- android:src="@drawable/ic_launcher" />
- <ImageView
- android:id="@+id/img_close"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@android:drawable/presence_busy"
- android:visibility="gone" />
- </RelativeLayout>
- <TextView
- android:id="@+id/tv_show"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:paddingLeft="5dp"
- android:textColor="#ffff4444"
- android:textSize="15sp" />
- </RelativeLayout>
代码如下:
- public class FloatView extends View {
- WindowManager mWManger;
- WindowManager.LayoutParams mWManParams;
- public View view;
- //初始位置
- private float startX;
- private float startY;
- //坐标
- private float x;
- private float y;
- //
- private float mTouchSatrtX;
- private float mTouchStartY;
- //组件
- public ImageView img_folat,img_close;
- public TextView tv_show;
- Context mContext;
- public FloatView(Context context) {
- super(context);
- this.mContext = context;
- }
- /**
- * 初始化mWManger,mWManParams
- */
- public void show(){
- mWManger = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
- mWManParams = new WindowManager.LayoutParams();
- //设置LayoutParams的参数
- mWManParams.type = 2002;//设置系统级窗口
- mWManParams.flags |= 8;
- //调整悬浮窗到左上角
- mWManParams.gravity = Gravity.TOP|Gravity.LEFT;
- //以屏幕左上角为源点,设置x,y
- mWManParams.x = 0;
- mWManParams.y = 0;
- //悬浮窗的长宽数据
- mWManParams.width = 80;
- mWManParams.height = 40;
- mWManParams.format = -3;//透明
- //加载悬浮窗布局文件
- view = LayoutInflater.from(mContext).inflate(R.layout.traffic_view, null);
- mWManger.addView(view, mWManParams);
- view.setOnTouchListener(new OnTouchListener() {
- /**
- * 改变悬浮窗位置
- */
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- //获取相对屏幕的位置,即以屏幕左上角为原点
- x = event.getRawX();
- y = event.getRawY() - 25;//25为系统状态栏的高度
- //Log.e("初始位置", x+"======="+y);
- switch(event.getAction()){
- case MotionEvent.ACTION_DOWN:
- startX = x;
- startY = y;
- //获取相对View的坐标,以view的左上角为原点
- mTouchSatrtX = event.getX();
- mTouchStartY = event.getY();
- //Log.e("相对view的位置", mTouchSatrtX+"--------"+mTouchStartY);
- break;
- case MotionEvent.ACTION_MOVE:
- updatePosition();
- break;
- case MotionEvent.ACTION_UP:
- updatePosition();
- show_img_close();
- mTouchSatrtX = mTouchStartY =0;
- break;
- }
- return true;
- }
- });
- img_close = (ImageView) view.findViewById(R.id.img_close);
- /**
- * 关闭悬浮窗图标点击事件
- */
- img_close.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(mContext,Traffic_Service.class);
- mContext.stopService(intent);
- view.setVisibility(View.GONE);
- }
- });
- tv_show = (TextView) view.findViewById(R.id.tv_show);
- }
- /**
- * 更新悬浮窗的位置
- *
- */
- public void updatePosition(){
- mWManParams.x = (int) (x - mTouchSatrtX);
- mWManParams.y = (int) (y - mTouchStartY);
- mWManger.updateViewLayout(view, mWManParams);
- }
- /**
- * 控制关闭悬浮窗按钮的显示与隐藏
- */
- public void show_img_close() {
- if (Math.abs(x - startX) < 1.5 && Math.abs(y - startY) < 1.5
- && !img_close.isShown()) {
- img_close.setVisibility(View.VISIBLE);
- } else if (img_close.isShown()) {
- img_close.setVisibility(View.GONE);
- }
- }
- }
下面看看代码:
- public class Traffic_Service extends Service {
- //
- private Handler mHandler;
- // 系统流量文件
- public final String DEV_FILE = "/proc/self/net/dev";
- // 流量数据
- String[] ethData = { "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0",
- "0", "0", "0", "0", "0" };
- String[] gprsData = { "0", "0", "0", "0", "0", "0", "0", "0", "0", "0",
- "0", "0", "0", "0", "0", "0" };
- String[] wifiData = { "0", "0", "0", "0", "0", "0", "0", "0", "0", "0",
- "0", "0", "0", "0", "0", "0" };
- // 用来存储前一个时间点的数据
- String[] data = { "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0",
- "0" };
- // 以太网
- final String ETHLINE = "eth0";
- // wifi
- final String WIFILINE = "wlan0";
- // gprs
- final String GPRSLINE = "rmnet0";
- /**
- * 定义线程周期性地获取网速
- */
- private Runnable mRunnable = new Runnable() {
- // 每3秒钟获取一次数据,求平均,以减少读取系统文件次数,减少资源消耗
- @Override
- public void run() {
- refresh();
- mHandler.postDelayed(mRunnable, 3000);
- }
- };
- /**
- * 启动服务时就开始启动线程获取网速
- */
- @Override
- public void onStart(Intent intent, int startId) {
- mHandler.postDelayed(mRunnable, 0);
- };
- /**
- * 在服务结束时删除消息队列
- */
- @Override
- public void onDestroy() {
- mHandler.removeCallbacks(mRunnable);
- super.onDestroy();
- };
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- final FloatView view = new FloatView(this);
- view.show();
- mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- if (msg.what == 1) {
- // System.out.println((float) (msg.arg1 / 1024) + "kb/s");
- view.tv_show.setText((float) (msg.arg1 / (1024 * 3))
- + "k/s");
- }
- }
- };
- }
- /**
- * 读取系统流量文件
- */
- public void readDev() {
- FileReader fr = null;
- try {
- fr = new FileReader(DEV_FILE);
- } catch (Exception e) {
- e.printStackTrace();
- Toast.makeText(this, "系统流量文件读取失败", Toast.LENGTH_SHORT).show();
- }
- BufferedReader bufr = new BufferedReader(fr, 500);
- String line;
- String[] data_temp;
- String[] netData;
- int k;
- int j;
- // 读取文件,并对读取到的文件进行操作
- try {
- while ((line = bufr.readLine()) != null) {
- data_temp = line.trim().split(":");
- if (line.contains(ETHLINE)) {
- netData = data_temp[1].trim().split(" ");
- for (k = 0, j = 0; k < netData.length; k++) {
- if (netData[k].length() > 0) {
- ethData[j] = netData[k];
- j++;
- }
- }
- } else if (line.contains(GPRSLINE)) {
- netData = data_temp[1].trim().split(" ");
- for (k = 0, j = 0; k < netData.length; k++) {
- if (netData[k].length() > 0) {
- gprsData[j] = netData[k];
- j++;
- }
- }
- } else if (line.contains(WIFILINE)) {
- netData = data_temp[1].trim().split(" ");
- for (k = 0, j = 0; k < netData.length; k++) {
- wifiData[j] = netData[k];
- j++;
- }
- }
- }
- fr.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 实时读取系统流量文件,更新
- */
- public void refresh() {
- // 读取系统流量文件
- readDev();
- // 计算增量
- int[] delta = new int[12];
- delta[0] = Integer.parseInt(ethData[0]) - Integer.parseInt(data[0]);
- delta[1] = Integer.parseInt(ethData[1]) - Integer.parseInt(data[1]);
- delta[2] = Integer.parseInt(ethData[8]) - Integer.parseInt(data[2]);
- delta[3] = Integer.parseInt(ethData[9]) - Integer.parseInt(data[3]);
- delta[4] = Integer.parseInt(gprsData[0]) - Integer.parseInt(data[4]);
- delta[5] = Integer.parseInt(gprsData[1]) - Integer.parseInt(data[5]);
- delta[6] = Integer.parseInt(gprsData[8]) - Integer.parseInt(data[6]);
- delta[7] = Integer.parseInt(gprsData[9]) - Integer.parseInt(data[7]);
- delta[8] = Integer.parseInt(wifiData[0]) - Integer.parseInt(data[8]);
- delta[9] = Integer.parseInt(wifiData[1]) - Integer.parseInt(data[9]);
- delta[10] = Integer.parseInt(wifiData[8]) - Integer.parseInt(data[10]);
- delta[11] = Integer.parseInt(wifiData[9]) - Integer.parseInt(data[11]);
- data[0] = ethData[0];
- data[1] = ethData[1];
- data[2] = ethData[8];
- data[3] = ethData[9];
- data[4] = gprsData[0];
- data[5] = gprsData[1];
- data[6] = gprsData[8];
- data[7] = gprsData[9];
- data[8] = wifiData[0];
- data[9] = wifiData[1];
- data[10] = wifiData[8];
- data[11] = wifiData[9];
- // 每秒下载的字节数
- int traffic_data = delta[0] + delta[4] + delta[8];
- // System.out.println("每秒流量"+traffic_data);
- Message msg = mHandler.obtainMessage();
- msg.what = 1;
- msg.arg1 = traffic_data;
- mHandler.sendMessage(msg);
- }
- }
附源码: 下载源码