Build a realtime graph in Android with Pusher

Esteban Herrera
AndroidPub
Published in
6 min readMay 6, 2018

--

Despite the hype of serverless architectures and microservices, there are still a lot of applications deployed in servers that need to be managed, and one important part of this task is monitoring resources like CPU, memory, or disk space.

There are a lot of commercial and open source tools for monitoring servers, but what if you just need something simple and specific? Maybe something that can easily show in realtime if things are doing fine, and that you can check on your phone.

In this tutorial, we’ll set up a Node.js process to calculate the memory usage of the system at specified intervals, send this information to a Pusher channel, and show it as a graph in an Android app.

This is how the final app will look:

Setting up your Pusher application

Create a free account at https://pusher.com/signup.

When you create an app, you’ll be asked to enter some configuration options:

Enter a name, choose Android as your front-end tech, and Node.js as the back-end tech. This will give you some sample code to get you started:

But don’t worry, this won’t lock you into this specific set of technologies as you can always change them. With Pusher, you can use any combination of libraries.

Next, copy your cluster ID (next to the app title, in this example mt1), App ID, Key, and Secret information, we’ll need them next. You can also find them in the App Keys tab.

The Node.js process

In Node.js, the os module provides a number of operating system-related utility methods.

After requiring the module:

const os = require('os');

We can use the totalmem() function to get the total amount of system memory in bytes and freemem() to get the amount of free system memory, also in bytes.

This way, we use the setInteval function to get the memory information every ten seconds, for example, calculate the used memory, and publish it to a Pusher channel:

Save this to a file, for example `memory.js`, create a `package.json` file if you haven’t already with:

npm init -y

Install the Pusher dependency with:

npm install --save pusher

And execute it with the command:

node memory.js

You should get the memory information printed in your console. Also, if you go to the Debug Console section of your app in the Pusher dashboard, you should see the events coming up:

Now let’s build the Android app.

Building the Android app

First, make sure to have the latest version of Android Studio. Then, create a new project:

We’re not going to use anything special, so we can safely support a low API level:

Next, create an initial empty activity:

And use the default name of MainActivity with backward compatibility:

Once everything is set up, let’s install the project dependencies. First, add the following repository to your project level build.gradle:

allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}

Next, in the dependencies section of the build.gradle file of your application module add:

dependencies {
...
implementation 'com.android.support:recyclerview-v7:26.1.0'
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
implementation 'com.pusher:pusher-java-client:1.8.0'
implementation 'com.google.code.gson:gson:2.8.2'
...
}

At the time of writing, the latest SDK version is 26, so that’s my target SDK version.

To graph the memory information we’re going to use MPAndroidChart, one of the most popular chart libraries for Android.

Sync the Gradle project so the modules can be installed and the project built.

Don’t forget to add the INTERNET permission to the AndroidManifest.xml file. This is required so we can connect to Pusher and get the events in realtime:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pusher.photofeed">
<uses-permission android:name="android.permission.INTERNET" /> <application>
...
</application>
</manifest>

Now, modify the layout file activity_main.xml to set a line chart that fills all the available space:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.pusher.memorygraph.MainActivity">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>

Next, create the class com.pusher.memorygraph.Stat with the following content:

Open the com.pusher.memorygraph.MainActivity class. Let’s start by defining some constants, like the info we’ll need to instantiate the Pusher object. Also, let’s define the total memory of our server as 16 (gigabytes) and set a maximum limit of 12 to draw a limit line in our chart.

In the next code block, you can see how the job of configuring the chart is divided into four functions, how Pusher is set up, specifying that when an event arrives, the JSON object will be converted to an instance of the class Stat (that just contains the property memory) and this will be added to the chart with the addEntry(stat) method.

Let’s review all the methods defined above. First, setupChart() configures some general options of the chart:

The setupAxes() method configures the options of the X and Y axes and adds the limit line we talked about before:

The setupData method just adds an empty LineData object:

The setLegend() method sets the options of the legend for the data set that will be shown below the chart:

In turn, createSet() will create the data set for the memory data configuring some options for its presentation:

The addEntry(stat) method, the one used when an event arrives, will create a data set if none exists using the above method, add the entry from the Stat instance that is passed as argument, notify the data has changed, and set the options to limit the view to 15 visible entries (to avoid the chart looking crowded):

And finally, we override the method onDestroy to disconnect from Pusher when needed:

And we’re done, let’s test it.

Testing the app

Execute the app, either on a real device or a virtual one:

The following screen will show up:

Make sure the Node.js is running. When new data about the memory is received, it will show up in the graph:

Conclusion

Remember that you can find the final version of the Android app here and the Node.js process here.

Hopefully, this tutorial has shown you how simple it is to build a realtime graph in Android with Pusher and MPAndroidChart. You can improve the app by changing the design or type of graphic (a pie chart will work great to see the used vs the free memory), or show more information.

--

--