2012-10-07 6 views
10

Meine App versucht, die Anzahl der über WiFi/LAN und mobile Datenverbindungen gesendeten und empfangenen Bytes zu zählen. Um dies zu tun, bekomme ich die Werte von TrafficStats Zähler zu einem Zeitpunkt und subtrahiere das von seinen Werten das nächste Mal, wenn ich überprüfe.Wie bekomme ich die korrekte Anzahl an Bytes, die in TrafficStats gesendet und empfangen wurden?

// 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; 

Ich glaube, dass der obige Algorithmus sinnvoll ist, aber ich bin mir nicht sicher, wie die Genauigkeit dieser Zähler zu überprüfen. Als ich beispielsweise versuchte, eine 2,7-MB-Datei über WiFi auf Dropbox hochzuladen, betrug der Wert currentMobileSent, den ich bekam, etwa 10 MB. Und selbst ohne das Internet bis zur nächsten Überprüfung zu durchforsten, erhalte ich Werte ungleich Null, die anzeigen, dass ich während der Wartezeit einige Datenbytes erhalten habe.

Gibt es eine Möglichkeit für mich zu überprüfen, wie TrafficStats bei diesen Nummern ankommt? Mir ist bewusst, dass neben meinem Browser noch andere Anwendungen im Hintergrund laufen, die mit dem Internet verbunden sind, aber 2.7MB bis 10MB scheint nur ein riesiger Sprung - ich habe sogar einmal 90MB "empfangen", ohne etwas zu tun. Oder stimmt etwas nicht damit, wie ich die gesendeten und empfangenen Bytes berechne?

Antwort

12

Von TechRepublic:

  1. ein neues Android-Projekt in Eclipse erstellen. Denken Sie daran, die TrafficStats-Klasse zu verwenden, auf die Sie die API für Android 2.2 (Froyo) oder höher ausrichten müssen.

  2. Im Ordner /res/layout erstellen wir die Ressource activity_main.xml. Für dieses Projekt verwenden wir nur eine Reihe von Textansichten in einem vertikal gestapelten linearen Layout.

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> 

Mit unserem Layout an Ort und Stelle können wir in das Verzeichnis/src Ordner verschieben auf. Erstellen Sie MainActivity.java, indem Sie die Activity/AppCompatActivity-Klasse erweitern. Lassen Sie uns auch voran gehen und deklarieren drei private Klassenvariablen.

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; 
} 

Wir werden die auf Überschreibung erstellen verwenden unsere privaten Variablen zu initialisieren, sowie Zeitplan ein Rückruf auf dem UI-Thread. Machen Sie eine Notiz der Prüfung für die enum TrafficStats.UNSUPPORTED. Meine Erfahrung mit der TrafficStats-Klasse war problemlos, die offizielle Google-Dokumentation besagt jedoch, dass einige Geräte diese Art der Berichterstattung nicht unterstützen und wenn dies der Fall ist, gibt der Aufruf den zuvor genannten Wert zurück. Aus diesem Grund ist es eine gute Idee, Ihren Code defensiv zu schreiben, wie ich hier gezeigt habe.

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); 
    } 
} 

Last but not least müssen wir unsere Anzeige aktualisieren und die runnable neu planen.

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); 
    } 
}; 
+0

Danke. Ich werde das ausprobieren und auf Ihre Antwort zurückkommen, wenn es wirklich genauer funktioniert. –

+0

ja, es wird für 100% funktionieren, ich bin sicher ... –

+0

Dies überprüft nur die Anzahl der Bytes, die unabhängig von der Verbindung verwendet werden, richtig? Ich muss zwischen der Nutzung von mobilen Daten (3G, 4G) und der normalen WLAN/LAN-Nutzung unterscheiden. In jedem Fall scheint Ihr Ansatz mir ähnlich zu sein und bestätigt vielleicht, dass mein aktueller Algorithmus richtig ist. –