タイトルが言うように。特定のアプリが特定の時間に使用する1秒あたりのバイト数を知りたいです。
たぶん私は " netstat "コマンドを使用できますか?しかし、そうであれば、特定のアプリ/プロセスにフィルタリングするにはどうすればよいですか?
また、それを行うには何らかの許可が必要ですか?
現在、人々はTrafficStats.getUidRxBytes(packageInfo.uid)を使用すると言いますが、ここから: https://developer.Android.com/reference/Android/net/TrafficStats.html#getUidRxBytes(int) 、Nからはサポートされていないため、代わりにNetworkStatsManagerを使用する必要があると表示されます。それを使用する例はありますか?
多分マージされたソリューション?
編集:Android NでNetworkStatsManagerを使用しようとしましたが、失敗しました。使用方法のサンプルが見つかりません。また、stackOverflowに関するすべての質問は、そうでないという点で類似しています。うまく使えます。使い方を知っている人がいたら、書いてください。
NetworkStats
の使用法は複雑ではありません。
デバイスAPIレベルは23以上である必要があります。NetworkStatsManager
の使用を開始する前に必要ないくつかの手順を次に示します。
AndroidManifest.xml
で必要な権限を宣言します。
<uses-permission Android:name="Android.permission.READ_PHONE_STATE"/>
<uses-permission
Android:name="Android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions"/>
Activity
で許可を求める
Android.permission.PACKAGE_USAGE_STATS
は通常の権限ではないため、単純に要求することはできません。許可が与えられているかどうかを確認するには、以下を確認してください。
AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
Android.os.Process.myUid(), getPackageName());
if (mode == AppOpsManager.MODE_ALLOWED) {
return true;
}
この許可を求めるには、Intent
に電話するだけです。
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
別の許可も必要です:Manifest.permission.READ_PHONE_STATE
。ただし、これは通常の権限であるため、 他の権限として要求される
NetworkStatsManager
を使用します:
参照を取得するには、次のように呼び出します。
NetworkStatsManager networkStatsManager = (NetworkStatsManager) getApplicationContext().getSystemService(Context.NETWORK_STATS_SERVICE);
NetworkStatsManager
から取得されたものはすべて、 Buckets
にパックされます。これは、データを保持する単純なPOJOです。
グローバル:
WiFiの全体的な使用状況を取得するには:
NetworkStats.Bucket bucket;
try {
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI,
"",
0,
System.currentTimeMillis());
} catch (RemoteException e) {
return -1;
}
NetworkStats.Bucket
から、2つのメソッドを呼び出して使用量(Bps単位)を取得できます。
bucket.getRxBytes();
bucket.getTxBytes();
モバイルネットワークのデータを取得するのは困難です。 Bucket
呼び出しを取得するには、次のようにします。
public long getAllRxBytesMobile(Context context) {
NetworkStats.Bucket bucket;
try {
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE,
getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
0,
System.currentTimeMillis());
} catch (RemoteException e) {
return -1;
}
return bucket.getRxBytes();
}
//Here Manifest.permission.READ_PHONE_STATS is needed
private String getSubscriberId(Context context, int networkType) {
if (ConnectivityManager.TYPE_MOBILE == networkType) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.getSubscriberId();
}
return "";
}
アプリケーション:
特定のアプリケーションのデータを取得するには、 queryDetailsForUID のドキュメントをお読みください。
WiFiのパッケージ使用量を取得するには:
NetworkStats networkStats = null;
try {
networkStats = networkStatsManager.queryDetailsForUid(
ConnectivityManager.TYPE_WIFI,
"",
0,
System.currentTimeMillis(),
packageUid);
} catch (RemoteException e) {
return -1;
}
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
networkStats.getNextBucket(bucket);
Mobileのパッケージ使用量を取得するには:
NetworkStats networkStats = null;
try {
networkStats = networkStatsManager.queryDetailsForUid(
ConnectivityManager.TYPE_MOBILE,
getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
0,
System.currentTimeMillis(),
packageUid);
} catch (RemoteException e) {
return -1;
}
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
networkStats.getNextBucket(bucket);
残念ながら、 このコード によると、統計の取得はConnectivityManager.TYPE_MOBILE
とConnectivityManager.TYPE_WIFI
でのみ可能です。
サンプルを作成しました Githubリポジトリ 使用法のデモ。
統計を取得する複雑な方法もありますが、これはすべてのアダプターで機能するはずです:(ただし、ファイルを継続的に読み取る必要があるため、コストがかかります)、
cat /proc/net/dev
cat /sys/class/net/**wlan0**/statistics/**rx**_bytes
wlanはすべてのアダプターである可能性がありますが、アダプターをオフ/オンにすると値が再び0になるため、アプリで値を維持する必要があります。 (RXとTXの値を持つことができます)
cat /proc/net/**tcp6**
これは、tcp、tcp6、pd、pd6でも実行できます。
ここに、インストールされているアプリのUIDである「uid」列があります。 (そのアプリは現在ネットワークを使用しています)
このファイルから、接続エンドポイントも確認できます。
cat /proc/uid_stat/**10348**/tcp_snd
idここにアプリケーションUIDがあります。送信済み:tcp_sndと受信済み:tcp_rcvファイルもあります。
cat /proc/**17621**/status
ここでのIDは、たとえば、から取得できるプロセスIDです。 topコマンド。 statusファイルには、インストール済み/システムアプリのUIDであるUIDがあります。
+1。このファイルも確認できます。TrafficStatsAPIはこれを使用します。
cat /proc/net/xt_qtaguid/stats
ヘッダー:
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
値:
6 eth0 0x0 10005 0 0 0 80 2 0 0 0 0 0 0 80 2 0 0 0 0
7 eth0 0x0 10005 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
8 eth0 0x0 10007 0 11133 25 4751 24 11133 25 0 0 0 0 4751 24 0 0 0 0
9 eth0 0x0 10007 1 5965514 4358 102028 2327 5965514 4358 0 0 0 0 102028 2327 0 0 0 0
10 eth0 0x0 10014 0 95 1 40 1 95 1 0 0 0 0 40 1 0 0 0 0
したがって、最初の答えとこの知識を組み合わせると、より多くのより良い統計を得ることができます。
/ proc/net/devを介して全体的なネットワーク使用量を取得するために、簡略化された関数を追加します。
一意の許可は必要ありません。
public static long[] getNetworkUsageKb() {
BufferedReader reader;
String line;
String[] values;
long[] totalBytes = new long[2];//rx,tx
try {
reader = new BufferedReader(new FileReader("/proc/net/dev"));
while ((line = reader.readLine()) != null) {
if (line.contains("eth") || line.contains("wlan")){
values = line.trim().split("\\s+");
totalBytes[0] +=Long.parseLong(values[1]);//rx
totalBytes[1] +=Long.parseLong(values[9]);//tx
}
}
reader.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
//transfer to kb
totalBytes[0] = totalBytes[0] / 1024;
totalBytes[1] = totalBytes[1] / 1024;
return totalBytes;
}