2012-10-07 19 views
10

我的應用程序正在嘗試計算通過WiFi/LAN和移動數據連接發送和接收的字節數。爲此,我在一個時間點獲得TrafficStats計數器的值,並在下次檢查時從其值中減去該值。如何獲取在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向Dropbox上傳2.7MB文件時,我得到的currentMobileSent值大約爲10MB。即使在下一次檢查之前沒有瀏覽網頁,我也會得到非零值,表示在等待期間我確實收到了一些字節的數據。

有沒有辦法讓我檢查如何TrafficStats到達這些數字?我知道,除了我的瀏覽器,可能還有其他應用程序在後臺運行,可以連接到互聯網,但2.7MB到10MB似乎是一個巨大的跳躍 - 我甚至在沒有做任何事的情況下「收到」90MB。或者我計算髮送和接收的字節的方式有什麼問題嗎?

回答

12

TechRepublic

  1. 在Eclipse中創建一個新的Android項目。請記住使用TrafficStats類,您必須將Android 2.2(Froyo)或 的API更高。

  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。讓我們繼續吧, 聲明三個私有類變量。

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

我們將使用上創建覆蓋初始化我們的私人 變量,以及安排在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); 
    } 
}; 
+0

謝謝。如果它真的能更準確地工作,我會嘗試一下並回到你的答案。 –

+0

是的,它會工作100%,我確定... –

+0

這隻會檢查使用任何連接的字節數,對不對?我需要區分移動數據(3G,4G)使用情況和常規WiFi/LAN使用情況。無論如何,你的方法似乎與我的方法類似,也許驗證我目前的算法是正確的。 –

相關問題