Old Answer (Mostly work for devices below Api level 23)
First, get a list of all running apps' process info:
List<RunningAppProcessInfo>
Then get the UID of every app and get then send and receive traffic of the app:
// Get running processes
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningApps = manager.getRunningAppProcesses();
for (RunningAppProcessInfo runningApp : runningApps) {
// Get UID of the selected process
int uid = ((RunningAppProcessInfo)getListAdapter().getItem(position)).uid;
// Get traffic data
long received = TrafficStats.getUidRxBytes(uid);
long send = TrafficStats.getUidTxBytes(uid);
Log.v("" + uid , "Send :" + send + ", Received :" + received);
}
Edited Answer
There are some more options to get network usage :
- NetworkStatsManager - So NetworkStatsManager is an option which is also provides required info but it has a drawback i.e. This API is available only on Marshmallow(API level 23) or higher. For the devices below to api 23 the my old answer can be used.
According to the official documentation:
[NetworkStatsManager] provides network traffic statistics. These
statistics include bytes transmitted and received and network packets
transmitted and received, over all interfaces, over the mobile
interface, and on a per-UID basis.
So to use NetworkStatsManager :
Declare required permissions in AndroidManifest file :
<uses-permission android:name="android.permission.READ_PHONE_STATE" / >
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" / >
Since “android.permission.PACKAGE_USAGE_STATS” is a system level
permission we will need to handle the request in a different manner.
In order to check, whether the permission has been granted, check:
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;
}
This permission can be granted from the Settings -> Security -> Apps with usage access screen. To ask for this permission, simply start an activity with Settings.ACTION_USAGE_ACCESS_SETTINGS Intent to help the user to get there:
startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
Once everything has been set up you can get an instance of NetworkStatsManager which we will need to fetch network usage data:
NetworkStatsManager networkStatsManager = (NetworkStatsManager) context.getSystemService(Context.NETWORK_STATS_SERVICE);
Whatever query you will perform, you will get as a result a NetworkStats.Bucket or a NetworkStats (which is basically a container for multiple buckets with methods hasNextBucket() and getNextBucket() to access the real data (also remember to use close() before the object is out of scope).
In every query you will have to specify the network type (ConnectivityManager.TYPE_WIFI or ConnectivityManager.TYPE_MOBILE).
Subscriber Id required to make query and it remains same unless the user switches SIM card or carrier. To get that
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String subscriberId = manager.getSubscriberId();
- To access an individual app stats you will need the uid of that app, which is an int value assigned by the system to each app at install time.
PackageManager packageManager = context.getPackageManager();
ApplicationInfo info = packageManager.getApplicationInfo("com.example.app", 0);
int uid = info.uid;
UIDs used for the network usage caused by :
- Unistalled apps : UID_REMOVED
- Tethering : UID_TETHERING
- Android OS : SYSTEM_UID
- To get stats for all apps : UID_ALL
Some example queries:
To get all Rx and Tx bytes of Mobile :
NetworkStats.Bucket bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE, getSubscriberId(context, ConnectivityManager.TYPE_MOBILE), 0, System.currentTimeMillis());
bucket.getRxBytes();
bucket.getTxBytes();
To get all Rx and Tx bytes of Wifi :
NetworkStats.Bucket bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI, ””, 0, System.currentTimeMillis());
bucket.getRxBytes();
bucket.getTxBytes();
To get all Rx and Tx bytes of Mobile for package :
NetworkStats.Bucket bucket = networkStatsManager.queryDetailsForUid(ConnectivityManager.TYPE_MOBILE, getSubscriberId(context, ConnectivityManager.TYPE_MOBILE), 0, System.currentTimeMillis(),packageUid);
long rxBytes = 0L;
long txBytes = 0L;
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
while (networkStats.hasNextBucket()) {
networkStats.getNextBucket(bucket);
rxBytes += bucket.getRxBytes();
txBytes += bucket.getTxBytes();
}
networkStats.close();
To get all Rx and Tx bytes of Wifi for package :
NetworkStats.Bucket bucket = networkStatsManager.queryDetailsForUid(ConnectivityManager.TYPE_WIFI, “”, 0, System.currentTimeMillis(),packageUid);
long rxBytes = 0L;
long txBytes = 0L;
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
while (networkStats.hasNextBucket()) {
networkStats.getNextBucket(bucket);
rxBytes += bucket.getRxBytes();
txBytes += bucket.getTxBytes();
}
networkStats.close();
Note :
- Those queries should never be performed on the main thread or
they will cause your app to drop frame.
- NetworkStatsManager.query* throws RemoteException
- Roaming and tag were added in API level 24 (Android 7.0 Nougat) so if you’re targeting Marshmallow (API level 23) you won’t be able to use those.
- Since API level 24 (Android 7.0 Nougat) you can use NetworkStatsManager without the PACKAGE_USAGE_STATS permission if you only want to get your app data. You’d still need it if your goal is to access other apps’ stats.
2. TrafficStats : It also provides required info but there are some drawbacks which makes it unreliable at least :
- Data resets after every reboot
- It may also be unsupported on some devices.
Some example methods of TrafficStats:
- To get Total Rx bytes - TrafficStats.getTotalRxBytes();
- To get Total Tx bytes - TrafficStats.getTotalTxBytes();
- To get all Mobile Rx bytes - TrafficStats.getMobileRxBytes();
- To get all Mobile Tx bytes - TrafficStats.getMobileTxBytes();
- To get all Wifi Rx bytes - TrafficStats.getTotalRxBytes() - TrafficStats.getMobileRxBytes();
- To get all Wifi Tx bytes - TrafficStats.getTotalTxBytes() - TrafficStats.getMobileTxBytes();
- To get Package Rx Bytes : - TrafficStats.getUidRxBytes(packageUid);
- To get Package Tx Bytes : - TrafficStats.getUidTxBytes(packageUid);