Retrieving Network Usage Details — Part 1

Akshay Kumar S
2 min readDec 6, 2020

A detailed explanation with examples is in part 2. You can find it here.

Problem: To get the network usage details for a particular time interval.

Here I will introduce Android API to collect data usage of each application and the overall device.

Expected output: For each application

Expected output: For the whole device

Solution:

API used: NetworkStatsManager (Added in API level 23)

Introduction to API:

(1) querySummary(int, String, long, long)

Syntax:

NetworkStats data = querySummary(networkType, subscriberId, startTime, endTime)

· Query network usage statistics summaries.

· Result filtered to include only UID’s belonging to the calling user.

· Result is aggregated over time.

· This means buckets’ start and end timestamps are going to be the same as the ‘startTime’ and ‘endTime’ parameters.

(2) querySummaryForDevice(int, String, long, long)

Syntax:

NetworkStats.Bucket bucket = querySummaryForDevice(networkType, subscriberId, startTime, endTime)

· Result is summarized data usage for the whole device.

· Result is a single Bucket aggregated over time, state, UID, tag and roaming.

· This means the bucket’s start and end timestamp are going to be the same as the ‘startTime’ and ‘endTime’ parameters.

Retrieving network usage of each application in the specified time interval.

Logic:

· Using querySummary() we get the network usage of each application till the current time.

· Keep the start time fixed for each function call.

· Call this function to find data usage at regular time intervals.

· To find the usage for a specified interval [startTime, endTime], retrieve the previously stored data for the startTime and endTime.

· Finding their difference gives the required solution.

Code in Java:

public long getAppNetworkUsage(long startTime, long endTime) {NetworkStatsManager networkStatsManager =(NetworkStatsManager)getApplicationContext().getSystemService(Context.NETWORK_STATS_SERVICE);
NetworkStats networkStatsByApp;
long currentAppUsage = 0L;
try {
networkStatsByApp = networkStatsManager.querySummary(ConnectivityManager.TYPE_WIFI,subscriberId: “”,startTime: startTime,endTime: endTime);
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
do {
networkStatsByApp.getNextBucket(bucket);
if (bucket.getUid() == packageUid) {
currentAppUsage = (bucket.getRxBytes() +bucket.getTxBytes());
}
} while (networkStatsByApp.hasNextBucket());

} catch (RemoteException e) {
e.printStackTrace();
}
return currentAppUsage;
}

Code in Kotlin:

private fun getAppUsage(startTime:Long, endTime:Long):Long{val uid=getUid("com.google.android.youtube")
val networkStatsManager = applicationContext.getSystemService(NETWORK_STATS_SERVICE)as NetworkStatsManager
val networkStats:NetworkStats
var totalUsage=0L
try{
networkStats = networkStatsManager.querySummary( ConnectivityManager.TYPE_WIFI,"",startTime,endTime)
val bucket = NetworkStats.Bucket()
while(networkStats.hasNextBucket()){
networkStats.getNextBucket(bucket)
if(bucket.uid==uid){
totalUsage+=bucket.txBytes + bucket.rxBytes
}
}
}catch(e:RemoteException){
Log.d(TAG,"getUsage: RemoteException")
}
return totalUsage
}

Note:

  1. To get Mobile data Usage, use ConnectivityManager.TYPE_MOBILE instead of ConnectivityManager.TYPE_WIFI in the above code.

2. packageUid is the unique id for each application.

Retrieving network usage of the whole device in the specified time interval

Logic:

Using querySummaryForDevice(), we can get the network usage details for any specific time interval by assigning the start time and end time as per the user's needs to the function.

Code in Java:

public long getDeviceNetworkUsage(long startTime,long endTime) {NetworkStatsManager networkStatsManager =   (NetworkStatsManager)getApplicationContext().getSystemService(Context.NETWORK_STATS_SERVICE);
NetworkStats.Bucket bucket;
try {
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI,“”,startTime,endTime );
} catch (RemoteException e) {
return -1;
}
currentAppUsage = (bucket.getRxBytes() + bucket.getTxBytes());
return currentAppUsage;}

Code in Kotlin:

private fun getDeviceUsage(startTime:Long,endTime:Long):Long{
val networkStatsManager = applicationContext.getSystemService(NETWORK_STATS_SERVICE)as NetworkStatsManager
val bucket:NetworkStats.Bucket
var totalUsage = 0L
try{
bucket = networkStatsManager.querySummaryForDevice( ConnectivityManager.TYPE_WIFI, "",startTime, endTime)
totalUsage += bucket.txBytes + bucket.rxBytes
}catch(e:RemoteException){
Log.d(TAG,"getUsage: RemoteException")
}
return totalUsage
}

Find the sample project here and the next part of this article here.

--

--

Akshay Kumar S

Android | Java | Kotlin | Flutter | Dart | .Net Core