每个APP的android统计3g流量,怎么样?

时间:2012-09-27 02:53:07

标签: android 3g traffic network-traffic traffic-measurement

对于每个APP的统计网络流量,我现在使用的是Android TrafficStats

我可以获得如下结果:

  • Youtube 50.30 MBytes
  • Facebook 21.39 MBytes
  • Google Play 103.38 MBytes
  • (以及......)

据我所知,“Android Trafficstats”只是一个指向c文件的本机指针。 (也许是.so?)

但它混合了Wifi& 3g流量,有没有办法只获得非WiFi流量统计?

4 个答案:

答案 0 :(得分:8)

晚上,我有办法做到这一点......

首先,我必须创建一个扩展BroadcasrReceiver的类,如下所示:

清单定义:

<receiver android:name=".core.CoreReceiver" android:enabled="true" android:exported="false">
  <intent-filter>
    <action android:name="android.net.ConnectivityManager.CONNECTIVITY_ACTION" />
    <action android:name="android.net.wifi.STATE_CHANGE" />
  </intent-filter>
</receiver>

代码:

/**
 * @author me
 */
public class CoreReceiver extends BroadcastReceiver {
  public void onReceive(Context context, Intent intent) {
    if (Constants.phone == null) {
      // Receive [network] event
      Constants.phone=new PhoneListen(context);
      TelephonyManager telephony=(TelephonyManager) 
      context.getSystemService(Context.TELEPHONY_SERVICE);
      telephony.listen(Constants.phone, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
    }

    WifiManager wifi=(WifiManager)context.getSystemService(Context.WIFI_SERVICE);
    boolean b=wifi.isWifiEnabled();
    if (Constants.STATUS_WIFI != b) {
       // WiFi status changed...
    }
  }
}

下面的电话统计听众......

public class PhoneListen extends PhoneStateListener {
  private Context context;    
  public PhoneListen(Context c) {
     context=c;
  }    
  @Override
  public void onDataConnectionStateChanged(int state) {
    switch(state) {
      case TelephonyManager.DATA_DISCONNECTED:// 3G
        //3G has been turned OFF
      break;
      case TelephonyManager.DATA_CONNECTING:// 3G
        //3G is connecting
      break;
      case TelephonyManager.DATA_CONNECTED:// 3G
        //3G has turned ON
      break;
    }
  }
}

最后,这是我的逻辑

  1. 将计数收集到SQLite DB中。
  2. 仅在3G开启时,每1分钟通过TrafficStats收集所有应用网络使用情况。
  3. 如果3G关闭,则停止收集。
  4. 如果同时兼有3G&amp; WiFi开启,停止收集。
  5. 据我所知,网络流量只会通过WiFi,如果3G和&提供WiFi。

答案 1 :(得分:4)

经过长时间的努力,我能够找到解决方案,通过android中每个安装的应用程序的任何界面获取数据 设备

由于Android提供TrafficStats Apis,但这些API为自设备启动和Even以来的每个应用程序提供编译数据统计信息 API不支持通过特定应用程序的任何接口获取数据。 即使我们依赖TraffiucStates APIS,我们也会为每个应用程序获取新的数据统计信息。

所以我想用隐藏的API来使用它。

这里我提到了通过Android中的任何接口获取每个应用程序的数据统计信息的步骤...

  1. 建立“INetworkStatsSession”会话

    import android.net.INetworkStatsSession;
    INetworkStatsSession mStatsSession = mStatsService.openSession();
    
  2. 根据您要测量的界面创建网络模板..

    import static android.net.NetworkTemplate.buildTemplateEthernet;
    import static android.net.NetworkTemplate.buildTemplateMobile3gLower;
    import static android.net.NetworkTemplate.buildTemplateMobile4g;
    import static android.net.NetworkTemplate.buildTemplateMobileAll;
    import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
    
    import android.net.NetworkTemplate;
    
    private NetworkTemplate mTemplate;
    
    mTemplate = buildTemplateMobileAll(getActiveSubscriberId(this
                .getApplicationContext()));
    
  3. GetActive SubscriberID:

    private static String getActiveSubscriberId(Context context) {
        final TelephonyManager tele = TelephonyManager.from(context);
        final String actualSubscriberId = tele.getSubscriberId();
        return SystemProperties.get(TEST_SUBSCRIBER_PROP, actualSubscriberId);
    }
    
  4. 通过传递应用程序UID来收集相应应用程序的网络HIStory ......

    private NetworkStatsHistory collectHistoryForUid(NetworkTemplate template,
        int uid, int set) throws RemoteException {
        final NetworkStatsHistory history = mStatsSession.getHistoryForUid(
                template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
        return history;
    
    }
    
  5. 获取总消费数据:

    public void showConsuption(int UID){
        NetworkStatsHistory history = collectHistoryForUid(mTemplate, UID,
                SET_DEFAULT);
    
        Log.i(DEBUG_TAG, "load:::::SET_DEFAULT:.getTotalBytes:"+ Formatter.formatFileSize(context, history.getTotalBytes()));
    
        history = collectHistoryForUid(mTemplate, 10093,
                SET_FOREGROUND);
        Log.i(DEBUG_TAG, "load::::SET_FOREGROUND::.getTotalBytes:"+ Formatter.formatFileSize(context, history.getTotalBytes()));
    
        history = collectHistoryForUid(mTemplate, 10093,
                SET_ALL);
        Log.i(DEBUG_TAG, "load::::SET_ALL::.getTotalBytes:"+ Formatter.formatFileSize(context, history.getTotalBytes()));
    
    }
    

答案 2 :(得分:2)

我找到了获得唯一无线流量的方法

long totalbyte = Trafficstats.getTotalRxBytes();
long mobilenetworkbyte = Trafficstats.getMobileRxBytes();
String total = Long.toString(totalbyte);
String mobile = Long.toString(mobilenetworkbyte);
String wifibyte = total - mobile + "kb";

现在wifibyte字符串显示wifi总字节数 它的工作对我来说,我希望为你工作

答案 3 :(得分:-2)

请尝试以下代码并关闭“WIFI”并仅使用“3G”进行检查

  1. 在Eclipse中创建一个新的Android项目。请记住使用TrafficStats类,您必须针对Android 2.2(Froyo)或更高版本的API。

  2. 在/ res / layout文件夹中,我们将创建一个main.xml资源。对于这个项目,我们只是在垂直堆叠的线性布局中使用一系列文本视图。

          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:textSize="16sp"
    
         android:textStyle="bold"
    
         android:gravity="center"
    
         android:paddingBottom="20dip"
    
         android:text="Traffic Stats Demo" />
    
         <TextView
    
         android:layout_width="fill_parent"
    
         android:layout_height="wrap_content"
    
         android:textSize="14sp"
    
         android:textColor="#00ff00"
    
         android:gravity="center"
    
         android:text="Transmit Bytes" />
    
         <TextView
    
         android:layout_width="fill_parent"
    
         android:layout_height="wrap_content"
    
         android:textSize="14sp"
    
         android:gravity="center"
    
         android:text="0"
    
         android:id="@+id/TX"/>
    
        <TextView
    
        android:layout_width="fill_parent"
    
        android:layout_height="wrap_content"
    
        android:textSize="14sp"
    
        android:textColor="#ff0000"
    
        android:gravity="center"
    
        android:text="Receive Bytes" />
    
        <TextView
    
        android:layout_width="fill_parent"
    
        android:layout_height="wrap_content"
    
        android:textSize="14sp"
    
        android:gravity="center"
    
        android:text="0"
    
        android:id="@+id/RX"/>
    
        </LinearLayout>
    
  3. 我们的布局到位后,我们可以转到/ src文件夹。通过扩展Activity类来创建Main.java。让我们继续并声明三个私有类变量。

  4. Main.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;
    
          }
    
    1. 我们将使用on create override来初始化我们的私有变量,以及在UI线程上安排回调。记下枚举TrafficStats.UNSUPPORTED的检查。虽然我对TrafficStats类的使用经验毫无障碍,但Google官方文档指出某些设备可能不支持此类报告,在这种情况下,调用会返回上述值。因此,正如我在此处演示的那样,以防御性方式编写代码是个好主意。

            Main.java
      
           @Override
      
           public void onCreate(Bundle savedInstanceState) {
      
           super.onCreate(savedInstanceState);
      
           setContentView(R.layout.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);
      
           }
      
             }
      
    2. 最后但并非最不重要的是,我们需要更新我们的显示并重新安排runnable。

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