Monitoring Network Bandwidth Usage in the Doubtnut app.

How we build a Dashboard to Display Network Bandwidth in the Doubtnut app.

Raghav Aggarwal
Doubtnut
6 min readMar 1, 2022

--

What led us to think about it?

Doubtnut is a complete package for students of class 6th to 12th and for those who are preparing for various competitive exams such as IIT-JEE, NEET or different government exams as it offers Doubt resolution by clicking images and providing video solutions, exam preparation resources to offering Competitive Exam preparation courses with very affordable prices.

But here is the issue that most of the students in India have a limited Internet bandwidth everyday specially those coming from tier 2–3 cities. As they share their parent’s phone, they have to manage their network bandwidth usage from daily allotted 1–3 Gigabytes.

What we wanted to build?

We decided to build a screen which displays the Internet Data consumed by different components in the app such as Image Loading, Video Streaming, Api Requests etc. We took inspiration from WhatsApp’s Android app which provides these statistics for Calls, Media, Messages etc.

After some discussion we realised that the highest amount of data is consumed by Images and Videos in the app hence for the v1 version of the feature let’s target Images and Videos.

What’s already available?

The Android ecosystem is huge and the probability of what you want to build is already being implemented is big. This was indeed the case here, if you search the Internet about how to show Internet Data Usage of your app you will find two ways.

  1. TrafficStats
  2. NetworkStats Manager
TrafficStats vs NetworkStats Manager

Pros of TrafficStats

  1. TrafficStats is a very simple and easy to implement, so easy that you can just have to write TrafficStats.getUidRxBytes(uid)and TrafficStats.getUidTxBytes(uid) and you will have the Data bytes received (downloaded) and transmitted (uploaded) by your app since boot.

Here uid is the app’s unique id which is assigned to it by Android OS as soon as it’s installed on the device. It can be accessed with the help of package manager api easily from within the code.

Cons of TrafficStats

  1. The Network data is reset to zero every-time the device shuts down or reboots.

2. The bytes transmitted and received given by Traffic Stats are not accurate. To find the measure of error we validated the Network bytes given by TrafficStats and by a third party app from Playstore called My Data Manager (over 10 million downloads). This app provides the internet used by various apps in your device.

The results from both TrafficStats and My Data Manager coincided! Then where is the error?

So what happens is that data is always transferred in compressed form over the Internet specially when dealing with Mobile Platforms as to wisely use the limited resources and reduce overhead. For eg. an Image of 5 Kilobytes may be compressed to 500 Bytes and this file is decompressed again after being downloaded on the device before getting displayed.
So TrafficStats is not giving the network bytes consumed while transferring the data but the bytes which is taken by the application to load data after decompression, in the above the example TrafficStats will give 5120 Bytes (5 * 1024) if you calculate received Bytes. But the actual transfer over the Internet was only 500 Bytes.

Let’s move to NetworkStats Manager Then.

Pros of NetworkStats Manager

The useful method for our use-case was queryDetailsForUid which gives accurate network usage data and also this data is not reset after the device is rebooted as per documentation.

Cons of NetworkStats Manager

The queryDetailsForUid() method requires the subscriberId as a parameter which can be accessed by using Telephony Manager. But to access subscriber id the app must have the READ_PRIVILEGED_PHONE_STATE permission which cannot be accessed the third party apps. There are ways by which this permission could be accessed by the app but our app being an educational app with most users being students, it would have required certain policy changes which certainly didn’t looked appropriate.

Hence both of these couldn’t be used and Therefore, we needed a custom implementation!
For the v1 version we decided to show Internet Data used by the images and Videos streamed in the app as they account for most of the data usage.

Internet Data Consumed by Images

We use the popular Image loading library Glide to load images in the Doubtnut app. To get the data consumed by the images we needed two things.

1. A central place from where all the images loaded in the app can be monitored. As Images may be coupled with Json responses or in some cases sent individually by the server as per requirement.
2. We need to get the size of the transferred image from the server which is in compressed form and not the actual size as we want the network bandwidth used not the storage used by the image.

To accomplish first point we used AppGlideModule class provided by the Glide library itself. As developers we can add dependencies or options to modify Glide’s behaviour in the app from this class.

Now to get the size we used the Response header content-length which is sent by the server giving the size of the compressed image transferred. We registered a OkHttp Interceptor in the app’s AppGlideModule class. Programmed the Interceptor to store the value of response header content-length for every image loaded in the app.

Here is my blog on How to Intercept Network Requests with an OkHttp Interceptor

Logic about storing the values in Database and implementing other business logic to make it presentable is not in the scope of this blog.

Internet Data Consumed by Videos

To stream videos in the app we use Google’s ExoPlayer library, To get Network Data consumed by videos we used Exoplayer’s Analytics Listener which gives which gives methods to get analytics about different playbacks. We overrode methods onLoadStarted(), onLoadCanceled(), onLoadError() and LoadCompleted() with slight modifications to get required network data.

Just to be sure about the accuracy of the above implementation we crosschecked the findings with Charles which is again a very popular and reliable tool for monitoring network requests while debugging.
The Data from Exoplayer Analytics Listener coincided with Charles, hence the data was accurate.

Here the core logic is being discussed that how Network Usage Data can be fetched and not the business logic to deliver it as a feature because it will depend upon the use-case.

Hence we were able to show the accurate Internet data consumed by Images and Videos in the Doubtnut app!
Here is a screenshot for reference purposes

Future Plans

Though Internet data consumed by Images and Videos accounts for most the data used by the Doubtnut app, we aim to show more metrics such as data consumed by network requests and display information in a more appealing way by using graphs and tables with other useful data points.

Conclusion and Learnings

Frontend Engineering is not about consuming the provided apis by the given framework but it’s about engineering a way out of them by making them work in tandem with others and writing code to build features which are very general for eg. in our case but in a specific way that can be achieved be with current architecture of the app with robustness.

Thanks for reading the Blog, we will keep sharing and improving!

--

--

Raghav Aggarwal
Doubtnut

Android Developer at Mutual Mobile | Ex- Doubtnut