2010-10-27 4 views
6

Ho scritto una simpatica app per Android per controllare l'utilizzo dei dati, sfortunatamente si basa molto su android.net.TrafficStats che è stato introdotto con Froyo (Android 2.2).Qualcuno può spiegare come TrafficStats funzioni nel suo sistema operativo Android?

Sto tentando di back-port questa classe per i miei utenti non Froyo, e quello che sono in grado di determinare dal Android source è:

  1. TrafficStats.java è solo un puntatore nativo di ac il file
  2. Il file c apre due file (vedi sotto) e legge il contenuto
  3. Se uno dei due contiene un valore numerico che sputa indietro come i "byte utilizzati" contare

Ecco la mia challeng e ... quando chiamo TrafficStats tramite l'API sul mio dispositivo, ottengo una lettura (es. 1113853 byte). Quando apro i due file e ne controllo il contenuto, un file non esiste e l'altro file è 0 byte.

Così chiaramente ho capito male cosa sta facendo TrafficStats. Qualcuno può far luce su come funziona è magica?

Grazie per l'aiuto.

(qui è il mio tentativo di porta il file c per java)

package com.suttco.net; 

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.IOException; 

import com.suttco.IOUtils; 
import com.suttco.StringUtils; 

import android.util.Log; 

public class TrafficStatsFile { 

private static final String mobileRxFile_1 = "/sys/class/net/rmnet0/statistics/rx_bytes"; 
private static final String mobileRxFile_2 = "/sys/class/net/ppp0/statistics/rx_bytes"; 
private static final String mobileTxFile_1 = "/sys/class/net/rmnet0/statistics/tx_bytes"; 
private static final String mobileTxFile_2 = "/sys/class/net/ppp0/statistics/tx_bytes"; 

private static final String LOGGING_TAG = TrafficStatsFile.class.getSimpleName(); 

public long getMobileRxBytes() { 
    return tryBoth(mobileRxFile_1, mobileRxFile_2); 
} 

public long getMobileTxBytes() { 
    return tryBoth(mobileTxFile_1, mobileTxFile_2); 
} 

// Return the number from the first file which exists and contains data 
private static long tryBoth(String a, String b) { 
    long num = readNumber(a); 
    return num >= 0 ? num : readNumber(b); 
} 

// Returns an ASCII decimal number read from the specified file, -1 on error. 
private static long readNumber(String filename) { 
    File f = new File(filename); 
    if(f.exists()) { 
    if(f.canRead()) { 
    try { 
    Log.d(LOGGING_TAG, "f.length() = " + f.length()); 
    String contents = IOUtils.readFileAsString(f); 
    if(StringUtils.IsNotNullOrEmpty(contents)) { 
     try { 
     return Long.parseLong(contents); 
     } 
     catch(NumberFormatException nfex) { 
     Log.w(LOGGING_TAG, "File contents are not numeric: " + filename); 
     } 
    } 
    else { 
     Log.w(LOGGING_TAG, "File contents are empty: " + filename); 
    } 
    } 
    catch (FileNotFoundException fnfex) { 
    Log.w(LOGGING_TAG, "File not found: " + filename, fnfex); 
    } 
    catch(IOException ioex) { 
    Log.w(LOGGING_TAG, "IOException: " + filename, ioex); 
    } 
    } 
    else { 
    Log.w(LOGGING_TAG, "Unable to read file: " + filename); 
    } 
    } 
    else { 
    Log.w(LOGGING_TAG, "File does not exist: " + filename); 
    } 
    return -1; 
} 
} 
+0

Link alla fonte ha maciullato, provate questo: http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/jni/android_net_TrafficStats .cpp; h = ff46bdd2ba39380a0a673cbf8aadfc5a3529156c; hb = refs/heads/master –

+0

Oppure una copia cache qui: http://google.com/codesearch#uX1GffpyOZk/core/jni/android_net_TrafficStats.cpp&q=TrafficStats.cpp – Idolon

+0

Il collegamento è interrotto, e anche se trovi Android_net_TrafficStats.cpp, il codice che tratta quei contatori è stato spostato da lì all'ultima revisione. Quindi, il link alla revisione giusta è qui: https://github.com/android/platform_frameworks_base/blob/3762c311729fe9f3af085c14c5c1fb471d994c03/core/jni/android_net_TrafficStats.cpp – Eduardo

risposta

11

Ecco una versione funzionante e modificata del codice sopra. Questo utilizza RandomAccessFile e non si basa su personalizzato imports ma utilizza solo le funzioni integrate String con il loro Exceptions.

import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.RandomAccessFile; 

import android.util.Log; 

public class TrafficStatsFile { 

private static final String mobileRxFile_1 = "/sys/class/net/rmnet0/statistics/rx_bytes"; 
private static final String mobileRxFile_2 = "/sys/class/net/ppp0/statistics/rx_bytes"; 
private static final String mobileTxFile_1 = "/sys/class/net/rmnet0/statistics/tx_bytes"; 
private static final String mobileTxFile_2 = "/sys/class/net/ppp0/statistics/tx_bytes"; 

private static final String LOGGING_TAG = TrafficStatsFile.class.getSimpleName(); 

public long getMobileRxBytes() { 
    return tryBoth(mobileRxFile_1, mobileRxFile_2); 
} 

public long getMobileTxBytes() { 
    return tryBoth(mobileTxFile_1, mobileTxFile_2); 
} 

// Return the number from the first file which exists and contains data 
private static long tryBoth(String a, String b) { 
    long num = readNumber(a); 
    return num >= 0 ? num : readNumber(b); 
} 

// Returns an ASCII decimal number read from the specified file, -1 on error. 
private static long readNumber(String filename) { 
    try { 
     RandomAccessFile f = new RandomAccessFile(filename, "r"); 
     try { 
      Log.d(LOGGING_TAG, "f.length() = " + f.length()); 
      String contents = f.readLine(); 
      if(!contents.isEmpty() && contents!=null) { 
       try { 
        return Long.parseLong(contents); 
       } 
       catch(NumberFormatException nfex) { 
        Log.w(LOGGING_TAG, "File contents are not numeric: " + filename); 
       } 
      } 
      else { 
       Log.w(LOGGING_TAG, "File contents are empty: " + filename); 
      } 
     } 
     catch (FileNotFoundException fnfex) { 
      Log.w(LOGGING_TAG, "File not found: " + filename, fnfex); 
     } 
     catch(IOException ioex) { 
      Log.w(LOGGING_TAG, "IOException: " + filename, ioex); 
     } 
    }catch(FileNotFoundException ffe){ 
     Log.w(LOGGING_TAG, "File not found: " + filename, ffe); 
    } 
    return -1; 
} 

} 
+1

grazie per avermi dato -1 per nulla ... – IBoS

+0

Nessuno dei le seguenti directory sono presenti nel mio dispositivo: rmnet0, ppp0, rmnet0 e ppp0. Sto usando Samsung SM-T111. Questo dispositivo è dipendente? – Gem

4

Cambiare ad un RandomAccessFile invece di file ha funzionato.

Modifica: vedere la risposta di IBoS per codice di lavoro. Cambiando la risposta accettata alla sua.

Problemi correlati