I am writing an application that integrates with Smooch and Carnival. Both these libraries receive GCM push messages using the standard approach of defining a GCM Intent Service to receive messages.
When I use only Smooch, everything works great. When I use only Carnival, everything works great. The problem comes in when I try to use both. What I have found is that the GCM receiver will simply start the first service listed in the manifest that defines intent com.google.android.c2dm.intent.RECEIVE
.
In fact, I found that the order the libraries are listed in my build.gradle
affects in which order their manifests are merged into the application manifest. So, if I put smooch first, it works (but Carnival doesn't receive anything). And if I put Carnival first, it works (but Smooch never receives anything).
How can I handle multiple GCM intent services when I don't control either one? In general, how should applications define and manage multiple GCM intent services?
The IntentService is a subclass of the Service class that provides an Android specific implementation of this pattern. It will manage queueing work, starting up a worker thread to service the queue, and pulling requests off the queue to be run on the worker thread.
The GCM service handles all aspects of queueing of messages and delivery to client applications running on target devices, and it is completely free. To get this service from Google, however, you will need to do certain things: Enable GCM for that project. Get the SENDER_ID of the project or create a configuration file.
Implement an Android Client app to register with GCM, send the registration id to your push notification server and manage the notifications sent from your server via GCM. Implement a server side API to get and store registration ids from the client app and optionally provide an Admin panel to send push notification from.
MyGcmListenerService: It's an intent service which runs in the background (always) for the project and responsible for getting the notification and triggering different events accordingly.
The reason you can't get push to work in both Carnival and Smooch is that both libraries are registering their own GcmListenerService, and in Android the first GcmListenerService defined in your manifest will receive all GCM messages.
I have a solution for you based primarily off the following SO article: Multiple GCM listeners using GcmListenerService
The best solution would be to just have one GcmListenerService implementation, and have this handle messages for both.
In order to specify your own GcmListenerService, follow the instructions from Google's Cloud Messaging Documentation.
Smooch provides the tools necessary for you to disable their internal GCM registration when you have your own.
To do so, simply call setGoogleCloudMessagingAutoRegistrationEnabled
while initializing Smooch:
Settings settings = new Settings("<your_app_token>");
settings.setGoogleCloudMessagingAutoRegistrationEnabled(false);
Smooch.init(this, settings);
And in your own GcmRegistrationIntentService
, call Smooch.setGoogleCloudMessagingToken(token);
with your token.
Once that is complete, you'll be able to pass the GCM message on to any GCM Receiver that you'd like.
@Override
public void onMessageReceived(String from, Bundle data) {
final String smoochNotification = data.getString("smoochNotification");
if (smoochNotification != null && smoochNotification.equals("true")) {
data.putString("from", from);
Intent intent = new Intent();
intent.putExtras(data);
intent.setAction("com.google.android.c2dm.intent.RECEIVE");
intent.setComponent(new ComponentName(getPackageName(), "io.smooch.core.GcmService"));
GcmReceiver.startWakefulService(getApplicationContext(), intent);
}
}
EDIT
As of Smooch version 3.2.0, you can now more easily trigger Smooch’s notification by calling GcmService.triggerSmoochGcm
in your onMessageReceived.
@Override
public void onMessageReceived(String from, Bundle data) {
final String smoochNotification = data.getString("smoochNotification");
if (smoochNotification != null && smoochNotification.equals("true")) {
GcmService.triggerSmoochGcm(data, this);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With