如何获取TrafficStats中发送和接收的正确字节数?

Mat*_*ros 11 android traffic network-traffic traffic-measurement

我的应用程序试图计算通过WiFi/LAN和移动数据连接发送和接收的字节数.为此,我TrafficStats在一个时间点获取计数器的值,并在下次检查时从其值中减去该值.

// get current values of counters
long currentMobileTxBytes = TrafficStats.getMobileTxBytes();
long currentMobileRxBytes = TrafficStats.getMobileRxBytes();
long totalTxBytes = TrafficStats.getTotalTxBytes();
long totalRxBytes = TrafficStats.getTotalRxBytes();

// to get mobile data count, subtract old from current
long currentMobileSent = currentMobileTxBytes - oldMobileTxBytes;
long currentMobileReceived = currentMobileRxBytes - oldMobileRxBytes;

// to get WiFi/LAN data count, subtract total from mobile
long currentNetworkSent = totalTxBytes - currentMobileTxBytes;
long currentNetworkReceived = totalRxBytes - currentMobileRxBytes;
Run Code Online (Sandbox Code Playgroud)

我觉得上面的算法是合理的,但是,我不知道如何检查这些计数器的准确性.例如,当我尝试通过WiFi将2.7MB文件上传到Dropbox时,currentMobileSent我得到的值大约是10MB.即使没有浏览网页直到下一次检查,我得到非零值,表明我在等待期间确实收到了一些字节的数据.

有没有办法让我检查TrafficStats这些数字是如何到达的?我知道除了我的浏览器,可能还有其他应用程序在后台运行连接到互联网,但2.7MB到10MB似乎是一个巨大的跳跃 - 我甚至"没有做任何事情"一次"收到"90MB.或者我计算发送和接收的字节的方式有问题吗?

G M*_*esh 14

来自TechRepublic:

  1. 在Eclipse中创建一个新的Android项目.请记住使用TrafficStats类,您必须针对Android 2.2(Froyo)或更高版本的API.

  2. 在该/res/layout文件夹中,我们将创建一个activity_main.xml资源.对于这个项目,我们只是在垂直堆叠的线性布局中使用一系列文本视图.

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical">

   <TextView
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:gravity="center"
       android:paddingBottom="20dip"
       android:text="Traffic Stats Demo"
       android:textSize="16sp"
       android:textStyle="bold" />

   <TextView
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:gravity="center"
       android:text="Transmit Bytes"
       android:textColor="#00ff00"
       android:textSize="14sp" />

   <TextView
       android:id="@+id/TX"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:gravity="center"
       android:text="0"
       android:textSize="14sp" />

   <TextView
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:gravity="center"
       android:text="Receive Bytes"
       android:textColor="#ff0000"
       android:textSize="14sp" />

   <TextView
       android:id="@+id/RX"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:gravity="center"
       android:text="0"
       android:textSize="14sp" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

在我们的布局到位后,我们可以转到/ src文件夹.通过扩展Activity/AppCompatActivity类来创建MainActivity.java.让我们继续并声明三个私有类变量.

MainActivity.java

package com.authorwjf;

import android.app.Activity;
import android.app.AlertDialog;
import android.net.TrafficStats;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;

public class Main extends Activity {
    private Handler mHandler = new Handler();
    private long mStartRX = 0;
    private long mStartTX = 0;
}
Run Code Online (Sandbox Code Playgroud)

我们将使用on create override来初始化我们的私有变量,以及在UI线程上安排回调.记下枚举TrafficStats.UNSUPPORTED的检查.虽然我对TrafficStats类的使用经验毫无障碍,但Google官方文档指出某些设备可能不支持此类报告,在这种情况下,调用会返回上述值.因此,正如我在此演示的那样,以防御性方式编写代码是个好主意.

MainActivity.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mStartRX = TrafficStats.getTotalRxBytes();
    mStartTX = TrafficStats.getTotalTxBytes();

    if (mStartRX == TrafficStats.UNSUPPORTED || mStartTX == TrafficStats.UNSUPPORTED) {
        AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle("Uh Oh!");
        alert.setMessage("Your device does not support traffic stat monitoring.");
        alert.show();
    } else {
        mHandler.postDelayed(mRunnable, 1000);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的是,我们需要更新我们的显示并重新安排runnable.

MainActivity.java

private final Runnable mRunnable = new Runnable() {
    public void run() {
        TextView RX = (TextView) findViewById(R.id.RX);
        TextView TX = (TextView) findViewById(R.id.TX);
        long rxBytes = TrafficStats.getTotalRxBytes() - mStartRX;
        RX.setText(Long.toString(rxBytes));
        long txBytes = TrafficStats.getTotalTxBytes() - mStartTX;
        TX.setText(Long.toString(txBytes));
        mHandler.postDelayed(mRunnable, 1000);
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 引用非您自己的内容时需要归属.我不是立即删除你的答案,因为它是问题的唯一答案,但如果你故意删除归属链接,从而拒绝承认你的来源,我将删除你的答案. (5认同)