javaandroidpush-notificationgoogle-cloud-messaginggcmlistenerservice

How do I route GCM messages from a GcmListenerService to their relevant handlers?


The app that I am working on has two services (Pushwoosh and Helpshift) that use GCM for push notifications. I am attempting to implement the functionality shown here, in the Pushwoosh documentation, to allow both systems to function; https://docs.pushwoosh.com/v1.0/docs/gcm-integration-legacy. However my Android knowledge is failing me for how I actually route the bundle recieved to the relevant handlers. The project is dones in Unity but this is very much Android territory.

Here is the GcmListenerService class I have created that is very similar to the example;

import android.os.Bundle;
import android.content.Intent;
import android.util.Log;
import com.google.android.gms.gcm.*;
import android.content.ComponentName;

public class GCMListenerRouterService extends GcmListenerService
{
    public GCMListenerRouterService()
    {
        super();
        Log.i("Unity", "GCMListener - Constuctor");
    }

    private void dispatchMessage(String component, Bundle data)
    {
        Log.i("Unity", "GCMListener - dispatchMessage: " + (data != null ? data.toString() : "<null>") + " component: " + component);

        Intent intent = new Intent();
        intent.putExtras(data);
        intent.setAction("com.google.android.c2dm.intent.RECEIVE");
        intent.setComponent(new ComponentName(getPackageName(), component));

        GcmReceiver.startWakefulService(getApplicationContext(), intent);
    }

    @Override
    public void onMessageReceived(String from, Bundle data)
    {
        Log.i("Unity", "GCMListener - onMessageReceived: " + (data != null ? data.toString() : "<null>") + " from: " + from);

        // Base GCM listener service removes this extra before calling onMessageReceived
        // Need to set it again to pass intent to another service
        //data.putString("from", from);

        //if (TextUtils.equals(from, getString(R.string.PUSHWOOSH_PROJECT_ID)))
        //{
        //    dispatchMessage(PushGcmIntentService.class.getName(), data);
        //}
        //else if (TextUtils.equals(from, getString(R.string.PRIVATE_PROJECT_ID)))
        //{
        //    dispatchMessage(PrivateGCMListenerService.class.getName(), data);
        //}
    }
}

I am able to confirm that the push notification came from the correct messaging service, and I can determine if a push notifications came from one plugin or another. How do I route these bundle objects to the correct handler? I do not understand the following sample code;

if (TextUtils.equals(from, getString(R.string.PUSHWOOSH_PROJECT_ID)))
{
    dispatchMessage(PushGcmIntentService.class.getName(), data);
}
else if (TextUtils.equals(from, getString(R.string.PRIVATE_PROJECT_ID)))
{
    dispatchMessage(PrivateGCMListenerService.class.getName(), data);
}

I appreciate that this is example code but I can't find any functions in the Android documentation with the same signature as dispatchMessage. Do I need to make an intent service for each different type of message that is needed?

I know that for Helpshift I need to call a function with the signature handlePush(Context context, Bundle data) but I'm not sure what the Context object is. For Pushwoosh, i'm not sure what the handler is. While I am talking about two particular services I am assuming that this setup is a standard method for receiving messages and handling them.


Solution

  • Turns out that, for that for GCM, Bundle objects are the raw push details that you need to be handled. No further processing is needed and plugins/frameworks that support GCM should have a function that handles this, e.g. For helpshift that function is in com.helpshift.Core called handlePush(Context context, Bundle data).

    Note that GCM is actually deprecated and Firebase Cloud Messenger is the new system going forward. This service has a different way of dealing with multiple push handlers and you should check your plugins for documentation on this.