Андроид статистика 3g трафика для каждого приложения, как?
Для статистики сетевого трафика по приложению я использую Android TrafficStats
Что я могу получить результат, как следующий:
- Youtube 50,30 МБайт
- Facebook 21,39 МБ
- Google Play 103,38 МБайт
- (и больше...)
Как я знаю, "Android Trafficstats" просто родной указатель на AC-файл. (может быть.so?)
Но это смешало трафик Wi-Fi и 3G, есть ли способ получить только статистику трафика не-WiFi?
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;
}
}
}
Наконец, вот моя логика
- Соберите счет в БД SQLite.
- Соберите все использование сети приложения через TrafficStats каждую 1 минуту, только когда 3G включен.
- Если 3G выключен, то прекратить сбор.
- Если включены 3G и WiFi, прекратите сбор.
Как я знаю, сетевой трафик будет проходить только через WiFi, если доступны как 3G, так и WiFi.
После долгой борьбы я смог найти решение для получения данных через любой интерфейс для каждого установленного приложения на устройстве Android.
Android предоставляет TrafficStats Apis, но эти API предоставляют статистику данных компиляции для каждого идентификатора приложения, поскольку загрузка устройства и API-интерфейсы Even не поддерживают получение данных через какой-либо интерфейс для конкретного приложения. Даже если мы полагаемся на TraffiucStates APIS, мы получаем новую статистику данных для каждого приложения.
Поэтому я подумал использовать скрытые API, чтобы использовать это..
Здесь я упоминаю шаги для получения статистики данных для каждого приложения через любой интерфейс в Android...
Установить сеанс "INetworkStatsSession"
import android.net.INetworkStatsSession; INetworkStatsSession mStatsSession = mStatsService.openSession();
Создайте шаблон сети в соответствии с интерфейсом, который вы хотите измерить.
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()));
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); }
Соберите сетевую 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; }
Получить данные общего потребления:
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())); }
Я нашел способ получить только трафик 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 string show wifi total byte его работа для меня, я надеюсь, что работа для вас
Попробуйте следующий код и выключите ваш "WIFI" и проверьте только с "3G"
Создайте новый проект Android в Eclipse. Не забудьте использовать класс TrafficStats, вы должны использовать API для Android 2.2 (Froyo) или выше.
В папке /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>
С нашим макетом мы можем перейти к папке /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;
}
Мы будем использовать переопределение при создании для инициализации наших личных переменных, а также запланировать обратный вызов в потоке пользовательского интерфейса. Запишите проверку для перечисления 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); } }
И последнее, но не менее важное: нам нужно обновить наш дисплей и перепланировать работоспособность.
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); } };