How to Get Started With Push Notifications On Android

Introduction

Getting users to install your app is only half the battle. Getting them to use it regularly is the other half. It is quite possible that your users completely forget about your app after using it only once or twice. What with all the other new apps competing for their attention.

By using push notifications, you can remind users about your app every now and then, improving the chances of your app staying installed on their devices.

Google Cloud Messaging, GCM for short, is a free service you can use to send push notifications to your users. In this tutorial, you learn how to use it to create an Android app that can receive push notifications, and a simple server-side Python script that can generate and send them.

Why Use Google Cloud Messaging?

For most client-server communications, the client initiates requests to receive data from the server. In other words, the client pulls data from the server. In the case of push notifications, however, it is the server initiating the data transfer.

This is usually accomplished by maintaining a persistent TCP/IP connection—a connection that stays open indefinitely—between the server and the client. That might sound great, but if you have a popular app, maintaining thousands of persistent connections between your server and the devices of your users can be very expensive.

Google Cloud Messaging is a service that solves this problem by acting as an intermediary between your server and your user’s device. With GCM, Google’s Cloud Connection Server, often referred to as CCS, manages the persistent connections for you. It also makes sure that your push notifications are delivered securely and reliably.

Prerequisites

To follow along with me, you need:

1. Setting Up the Android Studio Project

Fire up Android Studio and create a new project with an empty Activity. If you used the defaults, the project should include a Java class in MainActivity.java.

Step 1: Add the Dependencies

In this project, we will be using the Google Services gradle plugin to configure GCM. Include it in the project by adding the following line in the dependencies section of the project’s build.gradle:

Next, apply the plugin in the app module’s build.gradle:

To be able to use the GCM API, add com.google.android.gms:play-services as a compile dependency in the same file:

If you click the Sync Now button, you should see the following error:

Install Repository and sync project

Click the Install Repository and sync project link to fix the error.

Step 2: Update the Manifest

Inside the project’s AndroidManifest.xml file, create and use a custom C2D_MESSAGE permission based on your project’s package name. Make sure that the protectionLevel of the permission is set to signature.

The notifications are received in the form of broadcasts. To handle those broadcasts, our app needs a BroadcastReceiver. However, we don’t have to create it manually. We can instead use the GcmReceiver class as the BroadcastReceiver.

The BroadcastReceiver must have an intent-filter that responds to the com.google.android.c2dm.intent.RECEIVE action and the name of its category must match your project’s package name. Add the following code to the manifest:

2. Get a Server API Key and a Sender ID

While communicating with the Cloud Connection Server, we need to identify ourselves using an API key on the server side and a sender ID on the client side. To get the API key and the sender ID, create a new project in the developers console.

Welcome screen

Start by clicking the Pick a platform button. Next, click the Enable services for my Android App button. When you do so, you will be asked to provide a name and an Android package name for your app. Make sure that the Android package name you provide matches the package name you entered when you created the Android Studio project.

Project details

Next, click the Choose and configure services button at the bottom. You can now select the Google services you want to add to the app.

Available Google Services

For now, click the Cloud Messaging button and then click Enable Google Cloud Messaging. After a few seconds, you will be presented with your server API key and sender ID. Make a note of the server API key and press Close.

Server API key and sender ID

The Google Services plugin we added earlier needs a configuration file to work correctly. Generate the file by clicking the Generate configuration files button.

Once the file has been generated, download it and place it inside your Android Studio project’s app directory.

3. Registering the Client

GCM identifies Android devices using registration tokens. Therefore, our app must be able to register itself from every Android device on which it is installed.

Step 1: Create a Registration Service

The registration must be done on a background thread because the process might take a while depending on network connectivity. Because the registration doesn’t need any inputs from the user, an IntentService is ideal for this task.

Create a new Java class called RegistrationService.java, make it a subclass of IntentService, and override its onHandleIntent method.

Inside the onHandleIntent method, we can use the Instance ID API to generate or fetch the registration token. First, create an instance of the InstanceID class, using its getInstance method.

We can now use the getToken method of the InstanceID object to get the registration token in the form of a String. getToken expects the sender ID as one of its arguments. Because we’ve added the google-services.json file to our project, we can pass the sender ID to the method using R.string.gcm_defaultSenderID.

If you want to see the contents of the registration token for debugging purposes, you can log it as a debug message using the Log.d method.

At this point, you could send the registration token to your web server and store it in a database there. However, you don’t have to do this if you don’t plan to address your users individually. If you plan to send the same message to every user, you should follow the publish-subscribe approach.

I’ll now be showing you how to subscribe to a topic called my_little_topic. It takes just two lines of code. First, create a new instance of the GcmPubSub class using its getInstance method. Next, call its subscribe method and pass the registration token to it, along with the name of the topic.

Our app can now receive every push notification published to my_little_topic.

Finally, define the service in AndroidManifest.xml.

The registration service is complete.

Step 2: Create an InstanceIDListenerService

Registration tokens are refreshed periodically. Consequently, every Android app that uses GCM must have an InstanceIDListenerService that can handle those refreshes. Therefore, create a new Java file called TokenRefreshListenerService.java and make it a subclass of InstanceIDListenerService. Inside the onTokenRefresh method of the class, all we need to do is simply start the registration process again by starting the registration service using an Intent and the startService method.

Add the following code to TokenRefreshListenerService.java:

This service must be able to respond to the com.google.android.gms.iid.InstanceID action. Therefore, while defining the service in AndroidManifest.xml, add the appropriate intent-filter.

Step 3: Starting the Registration Service

To make sure that the registration process begins as soon as the app starts, we must start the RegistrationService class inside the onCreate method of MainActivity. To do so, create an Intent for it and use the startService method.

4. Displaying Push Notifications

GCM automatically displays push notifications in the notification tray as soon as they are received. However, it does so only if the associated app contains a GCMListenerService.

Create a new Java class called NotificationsListenerService and make it a subclass of GCMListenerService. Unless you want to handle the pushed data yourself, you don’t have to write any code inside this class. We can leave this class empty for now.

While defining the service in AndroidManifest.xml, make sure that you add an intent-filter that allows it to respond to the com.google.android.c2dm.intent.RECEIVE action.

5. Adding Push Notification Icons

Every push notification must have an icon associated with it. If you don’t have one handy, you can get one from Google’s Material Design Icons Library.

Material design icons library

Once you download the icon, place it inside the res folder of your project. I’ll be using ic_cloud_white_48dp as the icon.

6. Running the Android App

Our Android app is now complete. Once you compile it and run it on an Android device, you will be able to see the registration token in the logcat logs.

Registration token in logcat

Press the back button on your device to exit the app. This is necessary because GCM will display push notifications automatically only if the user is not using the app. If you want the notifications to be shown even when the app is running, you will have to create the notifications yourself inside NotificationsListenerService using the Notification.Builder class.

7. Sending Push Notifications

In the final part of this tutorial, we will create a simple Python script that can generate and send push notifications to all the Android devices on which our app is installed.

You can run this script from your local computer or from a remote web server to which you have SSH access.

Step 1: Creating the Script

Create a new file called send.py and open it using your favorite text editor.

At the top of the file, import the urllib2 and urllib modules. We will use these modules to send data to Google’s Cloud Connection Server. Import the json module as well because the data we send must be valid JSON. Lastly, to access command line arguments, import the sys module.

Next, create a variable that stores the server API key you took note of earlier. The key needs to be part of every HTTP request we make to the CCS.

Every notification must have a title and a body. Instead of hard-coding them in our script, let’s accept the title and body as command line arguments using the argv array.

Create a new Python dictionary object to represent the data that should be sent to the CCS. For our Android app to be able to receive the notification, it must be published to a topic called my_little_topic. Therefore, add a key called to to the dictionary and set its value to /topics/my_little_topic.

To represent the contents of the notification, add a key called notification to the dictionary and set its value to another dictionary object containing three keys:

  • body
  • title
  • icon

Make sure that the value of the icon key matches the name of the icon drawable in your Android project.

Convert the dictionary to a JSON string using the dumps function of the json module:

All we need to do now is send the JSON string to https://gcm-http.googleapis.com/gcm/send. To do so, create a new Request object and set dataAsJSON as its data. Next, set the Authorization header to MY_API_KEY and the Content-type header to application/json.

Finally, to execute the request and fetch the response, pass the request object to the urlopen function and call its read method.

The Python script is now complete and ready to use.

Step 2: Running the Script

At this point, we are ready to send push notifications to all the devices on which our app is installed. Open a terminal and enter the directory in which you created send.py.

Pass the name of the script to the python executable along with a string for the title of the notification and one for the notification’s body. Here’s an example you can use:

If there are no errors, you should get a response that looks like this:

If you check your Android device, you should see a new notification in the notification tray.

Push notification in notification tray

Conclusion

You now know how to send push notifications to your users. In this lesson, you learned how to create an Android app capable of registering itself, and receiving notifications that are published to a specific topic. You also learned how to create a Python script that can publish notifications.

Even though push notifications may feel like a great way to communicate with your users, I suggest that you use them sparingly and only if you have something useful to say, because sending too many of them too often is perhaps the quickest way to get your app uninstalled.

To learn more about Google Cloud Messaging, refer to the Cloud Messaging Guide.

Tags:

Comments

Related Articles