android

How to Setup Multiple Broadcast Receivers for Handling Push Notifications on Android

Broadcast receivers are the handlers for receiving and processing push notifications sent to an android device. Setting up a single broadcast receiver to handle push notifications to your app is a straightforward process.

But what if you need to handle push notifications from disparate sources; from multiple third-party push notification providers and/or from your own servers, for example?

There are two ways to go about doing this.

A. Initialising multiple broadcast receivers in your AndroidManifest.xml

When you initialise two or more broadcast receivers in your app’s AndroidManifest.xml file, each of those receiver’s onReceive methods gets called when your app receives a push notification. Below, I have xml code for how to have a broadcast receiver for CleverTap and a broadcast receiver for my own app LocalBot.



<receiver
  android:name="com.example.LocalBot.MyBroadcastReceiver"
  android:permission="com.google.android.c2dm.permission.SEND">
  <intent-filter>
    <action
      android:name="com.google.android.c2dm.intent.RECEIVE"/>
    <action
      android:name="com.google.android.c2dm.intent.REGISTRATION"/>
      <category android:name="com.example.LocalBot"/>
  </intent-filter>
</receiver>

<receiver
  android:name="com.clevertap.android.sdk.GcmBroadcastReceiver"
  android:permission="com.google.android.c2dm.permission.SEND">
  <intent-filter>
    <action
      android:name="com.google.android.c2dm.intent.RECEIVE"/>
    <action
      android:name="com.google.android.c2dm.intent.REGISTRATION"/>
      <category android:name="com.example.LocalBot"/>
  </intent-filter>
</receiver>

Note that, although both receivers will be invoked on an incoming message, double handling is highly unlikely as third party providers will ignore payloads that don’t contain their unique identifiers.  If you’re sending your own payloads, be sure to include a unique identifier of your own. 

This is the simplest solution, but is somewhat inefficient as both receivers will be invoked for every incoming notification.

Let us now look at the second more efficient strategy.

B. One common broadcast receiver for routing pushes to the relevant broadcast receivers.

In this incrementally more efficient approach, you register only your own custom broadcast receiver. You then route the incoming push notification through your own broadcast receiver either to a specific broadcast receiver or to all the other broadcast receivers. You may use your own discretion to decide the use case for either of the aforementioned approaches.

In the case of Clevertap, we know that the JSON payload from them contains the key “nm”. This can be used to identify a Clevertap push notification and forward the notification to Clevertap’s respective broadcast handler. Similarly, in the case of Parse or Appboy or Localytics, you could go through their API documentation to figure out what would be a way to uniquely identify their push JSON payload.

Below I am going to walk through a small piece of code where I have my own broadcast handler, MyBroadcastReceiver.java. This is the broadcast handler through which all the push notifications pass. I have a condition check to see whether a push came from Clevertap, and if so, pass it onto Clevertap’s broadcast handler. Otherwise, I pass it to my own push JSON payload handler. Assume for the sake of this discussion that I’m only expecting push notifications from Clevertap and my own servers.

First I included my broadcast handler in my AndroidManifest.xml file as follows:-



<receiver
   android:name="com.example.LocalBot.MyBroadcastReceiver"
   android:permission="com.google.android.c2dm.permission.SEND">
   <intent-filter>
     <action
       android:name="com.google.android.c2dm.intent.RECEIVE"/>
     <action
       android:name="com.google.android.c2dm.intent.REGISTRATION"/>
       <category android:name="com.example.LocalBot"/>
   </intent-filter>
</receiver> 

Then I created the MyBroadcastReceiver class as follows:-


package com.example.LocalBot;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
import com.clevertap.android.sdk.CleverTapAPI;
import com.clevertap.android.sdk.GcmBroadcastReceiver;
import com.google.android.gms.gcm.GoogleCloudMessaging;

public class MyBroadcastReceiver extends WakefulBroadcastReceiver {
  public void onReceive(Context context, Intent intent) {
    Bundle extras = intent.getExtras();
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
    String messageType = gcm.getMessageType(intent);
    if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
      String ctpn = extras.getString(CleverTapAPI.NOTIFICATION_TAG);
      if(ctpn!=null && ctpn.equals("true")) {
        GcmBroadcastReceiver obj = new GcmBroadcastReceiver();
        obj.onReceive(context, intent);
      }
    } else {
        MyHandler obj = new MyHandler();
        obj.handlePush(intent);
    }
 }
}

Now all push notifications will pass through my broadcast receiver, MyBroadcastReceiver.java and will get routed to the respective broadcast handler accordingly.

In case you would like to pass a notification to all your broadcast receivers, you could remove the if else checks and make a call to all your broadcast receivers, as shown below:-

public class MyBroadcastReceiver extends WakefulBroadcastReceiver {
  public void onReceive(Context context, Intent intent) {
    Bundle extras = intent.getExtras();
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
    String messageType = gcm.getMessageType(intent);
    if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
      new com.clevertap.android.sdk.GcmBroadcastReceiver().onReceive(context, intent);
      new MyNotificaitonHandler().handleReq(intent);
   }
}

 

Hope you enjoyed reading this blog post and developed a fairly good understanding of how to setup multiple broadcast receivers for your android app.

Author: Anand Jain

Anand is the co-founder of CleverTap. He works out of CleverTap's Mumbai office.