我的应用正在尝试计算通过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;
我觉得上面的算法是合理的,但是,我不知道如何检查这些计数器的准确性。例如,当我尝试通过WiFi将2.7MB文件上传到Dropbox时,我得到的currentMobileSent
值约为10MB。即使没有浏览网页直到下一次检查,我也会得到非零值,表明我在等待期间确实收到了一些字节数据。
我有办法检查TrafficStats
到达这些数字的方式吗?我知道除了我的浏览器,可能还有其他应用程序在后台运行连接到互联网,但2.7MB到10MB似乎是一个巨大的跳跃 - 我甚至“没有做任何事情”一次“收到”90MB。或者我计算发送和接收的字节的方式有问题吗?
答案 0 :(得分:14)
来自TechRepublic:
在Eclipse中创建一个新的Android项目。请记住使用TrafficStats类,您必须针对Android 2.2(Froyo)或 更高。
在/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>
在我们的布局到位后,我们可以转到/ src文件夹。创建 MainActivity.java通过扩展Activity / AppCompatActivity类。我们也继续吧 声明三个私有类变量。
<强> 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;
}
我们将使用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);
}
}
最后但并非最不重要的是,我们需要更新我们的显示并重新安排 可运行的。
<强> 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);
}
};