12

私のアプリは、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でした。そして、次のチェックまでWebを閲覧しなくても、待機期間中に数バイトのデータを受信したことを示すゼロ以外の値を取得します。

TrafficStatsこれらの番号にどのように到達するかを確認する方法はありますか?私のブラウザ以外にも、インターネットに接続するバックグラウンドで実行されている他のアプリケーションがあるかもしれないことを知っていますが、2.7MBから10MBは、大きなジャンプのように思えます。または、送受信されたバイトの計算方法に何か問題がありますか?

4

1 に答える 1

15

TechRepublicから:

  1. Eclipseで新しいAndroidプロジェクトを作成します。Android 2.2(Froyo)以降のAPIをターゲットにする必要があるTrafficStatsクラスを使用することを忘れないでください。

  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>

レイアウトが整ったら、/srcフォルダーに移動できます。Activity / AppCompatActivityクラスを拡張して、MainActivity.javaを作成します。また、先に進んで、3つのプライベートクラス変数を宣言しましょう。

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オーバーライドを使用して、プライベート変数を初期化し、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);
    }
};
于 2012-10-07T04:15:24.880 に答える