Статистика 3g-трафика Android для каждого приложения, как?

Для статистики сетевого трафика по приложениям сейчас я использую Android TrafficStats.

Что я могу получить результат следующим образом:

  • Ютуб 50,30 МБ
  • Facebook 21,39 МБ
  • Google Play 103,38 МБ
  • (и больше...)

Насколько я знаю, "Android Trafficstats" просто нативный указатель на файл c. (может быть .so ?)

Но это смешанный трафик Wi-Fi и 3g, есть ли способ получить статистику трафика только без WiFi?


person RRTW    schedule 27.09.2012    source источник
comment
Какую систему вы используете? по крайней мере, начиная с ICS, вы можете видеть использование данных 3g / mobile; интернет; или все вместе.   -  person SunnySonic    schedule 27.09.2012


Ответы (4)


Добрый вечер, у меня есть способ сделать это...

Сначала мне нужно создать класс, который расширяет 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.
  2. Собирайте данные об использовании сети всеми приложениями с помощью TrafficStats каждую минуту, только когда 3G включен.
  3. Если 3G выключен, то прекратите сбор.
  4. Если и 3G, и WiFi включены, прекратите сбор.

Насколько я знаю, сетевой трафик будет проходить только через WiFi, если доступны и 3G, и WiFi.

person RRTW    schedule 11.10.2012

После долгой борьбы я могу найти решение для получения данных через любой интерфейс для каждого установленного приложения на устройстве Android.

Поскольку Android предоставляет API TrafficStats, эти API-интерфейсы предоставляют статистику компиляции данных для каждого uid приложения с момента загрузки устройства, а даже 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. Получить активный идентификатор подписчика:

    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. Соберите сетевую HIStory соответствующего приложения, передавая UID приложения...

    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()));
    
    }
    
person Anshuman    schedule 20.04.2015
comment
У вас есть ссылка на эти внутренние классы? Нужно ли его компилировать или просто скопировать и вставить? - person M. Reza Nasirloo; 15.08.2015
comment
@Pedram Как я уже упоминал в этом решении ... Для этого мы используем внутренние API-интерфейсы, поэтому нам нужно создать приложение как системное приложение, и при компиляции требуется весь связанный импорт пакетов ... - person Anshuman; 21.08.2015

я нашел способ получить только трафик Wi-Fi

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

теперь строка wifibyte показывает общий байт Wi-Fi, это работает для меня, я надеюсь, что это сработает для вас

person er reflex    schedule 25.12.2014

Попробуйте следующий код и отключите «WIFI» и проверьте только «3G».

  1. Создайте новый проект Android в Eclipse. Помните, что для использования класса TrafficStats вы должны ориентироваться на API для Android 2.2 (Froyo) или выше.

  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. Создайте Main.java, расширив класс Activity. Давайте также продолжим и объявим три частные переменные класса.

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. Мы будем использовать переопределение при создании для инициализации наших частных переменных, а также для планирования обратного вызова в потоке пользовательского интерфейса. Запишите проверку перечисления 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);
    
               }
    
               };
    
person G M Ramesh    schedule 27.09.2012
comment
Спасибо, но чтобы узнать об использовании сетевого трафика, отличного от WiFi, я могу просто использовать TrafficStats.getMobileTxBytes() и TrafficStats.getMobileRxBytes(). Кроме того, это не может получить каждое приложение для использования 3G, и это то, что мне действительно нужно. - person RRTW; 27.09.2012
comment
на самом деле требуется вся статистика телефонного трафика, для использования приложений я все еще пытаюсь найти решение, если я получу, то я опубликую для вас - person G M Ramesh; 27.09.2012
comment
Для этого я пробую другое решение, а именно: 1) Обнаружение включения 3G 2) Начать подсчет трафика для каждого приложения с помощью TrafficStats 3) Остановить подсчет трафика при включении WiFi........... Другая проблема заключается в том, что если 3G и WiFi включены? До сих пор разбираюсь...... - person RRTW; 01.10.2012
comment
Вы можете получить TrafficStats для каждого приложения? - person G M Ramesh; 01.10.2012
comment
Да, но возвращаемое значение представляло собой сводку по подсчету 3G и WiFi. Поэтому я решаю считать себя, когда 3G включен, и прекращаю считать, когда 3G выключен. Но до сих пор не знаю, как прослушать событие 3G ON/OFF... - person RRTW; 02.10.2012
comment
@RRTW: На самом деле, когда включены и 3G, и WiFi, устройство будет предпочитать WiFi. Таким образом, вы можете просто изменить свою логику: если WiFi включен, то getUidRxBytes(...) и getUidTxBytes(...) вернут трафик WiFi, иначе 3G. - person Paolo Rovelli; 13.12.2013
comment
Это заслуга techrepublic. com/blog/software-engineer/: Уильям Дж. Фрэнсис - person Franklin Hirata; 17.06.2016