AndroidのTrafficStatsの2つのメソッド getUidTxBytes(int uid)とgetUidRxBytes(int uid)について混乱してください。これらの2つのメソッドは、このUIDのネットワークを介して送受信されたバイト数を返します。しかし、それの時間単位は何ですか、それは毎秒ですか?アプリごとに1日あたりに送受信されるデータを計算したい場合はどうすればよいですか。SQLにデータを格納し、テーブルにデータを追加し続けるという1つの方法を考えました。それは適切な方法ですか?
4 に答える
これらは、「インターフェースが起動してから」または「このUIDを持つアプリケーションが開始されてから」のカウンターです。つまり、携帯電話が「機内モード」になってから戻った場合、カウンターは再びゼロから始まる可能性があります。1秒あたりの値が必要な場合は、これらの関数を1秒ごとに呼び出してから、最後の呼び出しからのデルタを使用する必要があります。デルタが負の場合は、値をそのまま使用します。これは、カウンターが再びゼロから開始されたことを意味します。
もう1つ、私が知る限り、これらのカウンターはTCP/IPのみをカウントします。UDPではありません。したがって、非常に正確なアカウンティングが必要であり、問題のアプリケーションがUDP / IPまたはTCP以外の他のプロトコルを使用している場合、これらのカウンターは間違っています。
この関数がどのように機能するかについては、無料で入手できるAndroidのソースを参照してください。問題のファイルは./frameworks/base/core/jni/android_net_TrafficStats.cpp
この関数はからデータを取得します/proc/uid_stat/[uid]/tcp_snd
。それについてさらに情報が必要な場合は、Linuxカーネルに飛び込む必要があります...
これらのカウンタには、最後の再起動以降のバイト数が含まれています。一部の電話では、これらのカウンターが定期的にリセットされる場合がありますが、ほとんどの場合、再起動後にのみリセットされます。機内モードに入ったり、モバイルとWi-Fiを切り替えたりしても、これらのカウンターはリセットされません。
重要な点の1つは、これらのカウンターにはパケットオーバーヘッドは含まれず、ペイロードサイズのみが含まれることです。したがって、通常、これはデータの3〜4%が考慮されていない可能性があることを意味します。ただし、パケットペイロードが小さいストリーミング、トレント、またはVoIPアプリの場合は、考慮されていないデータ量がはるかに多くなる可能性があります。
興味深いことに、getTotalRxBytes(モバイルとWi-Fiを組み合わせた場合を除く、すべてのインターフェイスで受信されたバイト)とgetMobileRxBytes(モバイルインターフェイスでのみ受信されたバイト)には、オーバーヘッドを含むすべてのバイトが含まれます。したがって、基本的に、アプリのバイト数の合計は、インターフェースのバイト数の合計よりも少なくなります。したがって、ネットワークオペレーターが請求するデータの量よりも少なくなります。
最後に、ほとんどのストリーミングアプリは、独自のUIDでデータを考慮していません。それらはsystem.mediaUIDの下で会計処理されます。したがって、YouTubeのデータ使用量を監視している場合、そのアプリの下に実際に表示されるデータはごくわずかです。残りはメディアUID(1013)の下にあります。
ここでは、インターネットの権限を持つアプリを取得しています。権限名を変更して、必要に応じてアプリを取得できます。
ArrayList<AppObject> listApps;
public void getAllAppList() {
listApps = new ArrayList<AppObject>();
PackageManager p = getPackageManager();
List<ApplicationInfo> packages = p.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo applicationInfo : packages) {
try {
PackageInfo packageInfo = p.getPackageInfo(applicationInfo.packageName, PackageManager.GET_PERMISSIONS);
String[] permissions = packageInfo.requestedPermissions;
for (String permissionName : permissions) {
if (permissionName.equals("android.permission.INTERNET")) {
ApplicationInfo appInfo = packageInfo.applicationInfo;
AppObject appObject = new AppObject();
appObject.appDrawable = getPackageManager().getApplicationIcon(appInfo);
appObject.appName = (String) getPackageManager().getApplicationLabel(appInfo);
appObject.dataUsage = getDataUsage(appInfo);
listApps.add(appObject);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
Debug.e("APP_SIZE", ":" + listApps.size());
appsAdapter.addAll(listApps);
}
public String getDataUsage(ApplicationInfo appInfo) {
int uid = appInfo.uid;
double received = (double) TrafficStats.getUidRxBytes(uid) / (1024 * 1024);
double sent = (double) TrafficStats.getUidTxBytes(uid) / (1024 * 1024);
double total = received + sent;
return String.format("%.2f", total) + " MB";
}
getUidRxBytes()とgetUidTxBytes()は、基本的にそれぞれ受信バイトと送信バイトに使用されます。各アプリのデータを監視するには、各プロセスのuidを見つけ、各プロセスに対応するデータを見つけます。これが各アプリのデータになり、このコードを計算に使用できます。
TextView totData = (TextView)findViewById(R.id.totData);
TextView wifiTot = (TextView)findViewById(R.id.wifitotData);
TextView wifiTX = (TextView)findViewById(R.id.wifiUpData);
TextView wifiRX = (TextView)findViewById(R.id.wifiDownData);
TextView mobileTot = (TextView)findViewById(R.id.mobtotData);
TextView mobTX = (TextView)findViewById(R.id.mobUpData);
TextView mobRX = (TextView)findViewById(R.id.mobDownData);
/*
* Converting bytes to MB
*/
long rxBytes = TrafficStats.getTotalRxBytes()/1048576;
long txBytes = TrafficStats.getTotalTxBytes()/1048576;
long mobUpload = TrafficStats.getMobileTxBytes()/1048576;
long mobDown = TrafficStats.getMobileRxBytes()/1048576;
long wifiUpload = txBytes-(mobUpload);
long wifiDown = rxBytes-(mobDown);
wifiRX.setText(Long.toString(wifiDown));
wifiTX.setText(Long.toString(wifiUpload));
long wifitot = wifiUpload+wifiDown;
wifiTot.setText(Long.toString(wifitot));
mobTX.setText(Long.toString(mobUpload));
mobRX.setText(Long.toString(mobDown));
long mobTot = mobUpload+mobDown;
mobileTot.setText(Long.toString(mobTot));
totData.setText(Long.toString(wifitot+mobTot));