¿Cómo obtener el número correcto de bytes enviados y recibidos en TrafficStats?

Mi aplicación está intentando contar el número de bytes enviados y recibidos a través de WiFi / LAN y conexiones de datos móviles. Para ello, obtengo los valores de los contadores de TrafficStats en un punto en el tiempo y sustraigo de sus valores la próxima vez que compruebo.

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

Siento que el algoritmo anterior es razonable, sin embargo, no estoy seguro de cómo comprobar la exactitud de estos contadores. Por ejemplo, cuando intenté subir un archivo de 2.7MB a Dropbox vía WiFi, el valor de currentMobileSent que obtuve fue alrededor de 10MB. E incluso sin navegar por la web hasta el siguiente chequeo, obtengo valores no nulos que indican que recibí algunos bytes de datos durante el período de espera.

¿Hay alguna forma de comprobar cómo llega TrafficStats a estos números? Soy consciente de que además de mi navegador, puede haber otras aplicaciones que se ejecutan en segundo plano que se conectan a Internet, pero 2.7MB a 10MB sólo parece un gran salto – Incluso "recibió" 90MB una vez sin hacer nada. ¿O hay algo mal con la forma en que estoy computando los bytes enviados y recibidos?

De TechRepublic :

  1. Cree un nuevo proyecto de Android en Eclipse. Recuerde utilizar la clase TrafficStats debe orientar la API para Android 2.2 (Froyo) o superior.

  2. En la carpeta /res/layout crearemos un recurso activity_main.xml. Para este proyecto, estamos usando una serie de vistas de texto en un diseño lineal verticalmente apilado.

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> 

Con nuestro diseño en su lugar podemos pasar a la carpeta / src. Cree MainActivity.java extendiendo la clase Activity / AppCompatActivity. Vamos a seguir adelante y declarar tres variables de clase privadas.

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

Utilizaremos el comando on create override para inicializar nuestras variables privadas, así como programar una devolución de llamada en el subproceso de la interfaz de usuario. Anote la comprobación del enum TrafficStats.UNSUPPORTED. Si bien mi experiencia con la clase TrafficStats ha sido sin problemas, la documentación oficial de Google indica que algunos dispositivos pueden no admitir este tipo de informes y cuando ese es el caso, la llamada devuelve el valor antes mencionado. Por eso es una buena idea escribir su código defensivamente, como he demostrado aquí.

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

Por último, pero no menos importante, tenemos que actualizar nuestra pantalla y reprogramar la ejecución.

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); } }; 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.