Android Multicast Notification using Google Cloud Messaging (GCM)

Google Cloud Messaging for Android (GCM) is a platform provided by Google for developers for sending tiny notification messages to Android applications installed on Android devices. Instead of mobile applications pinging a server for messages, alternately server can notify the application. This will improve the user experience and save resources in mobile devices.

In an earlier tutorial Google Cloud Messaging GCM for Android and Push Notifications, we discussed and worked on an example on how to send a notification message from an application server to an android device. This tutorial is a minor incremental update over that last one. Lets enhance that setup to send Multicast, send message to multiple Android devices simultaneously.

Google-GCM-Multicast-Notification

In the existing tutorial, we need to upgrade the GCM server application only. There is no change in the GCM Android client application. The server application’s

  1. RegId store should be modified to hold multiple RegIds.
  2. Ensure we store and multicast to unique Ids only.
  3. Send multicast message.

This tutorial is a continuation of the previous one. Refer the previous tutorial for,

  1. the GCM Android client.
  2. a general introduction for Google cloud messaging (GCM)
  3. development environment setup and other prerequisite like Google Server API key.
  4. to know about RegId, how and why it is shared.

So in essence, I strongly recommend you to go through the earlier tutorial and then continue with this.

Java GCM Server Application with Multicast

As stated in the previous tutorial, we have used the Helper library for GCM HTTP server operations. This server application has only two files and they are shown below. The complete Eclipse project is given below for download. GCMNotification.java file is modified to store multiple RegId and send multicast message.

GCMNotification.java

package com.javapapers.java.gcm;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Sender;

@WebServlet("/GCMNotification")
public class GCMNotification extends HttpServlet {
	private static final long serialVersionUID = 1L;

	// Put your Google API Server Key here
	private static final String GOOGLE_SERVER_KEY = "AIzaSyDA5dlLInMWVsJEUTIHV0u7maB82MCsZbU";
	static final String MESSAGE_KEY = "message";
	static final String REG_ID_STORE = "GCMRegId.txt";

	public GCMNotification() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);

	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		MulticastResult result = null;

		String share = request.getParameter("shareRegId");

		// GCM RedgId of Android device to send push notification

		if (share != null && !share.isEmpty()) {
			writeToFile(request.getParameter("regId"));
			request.setAttribute("pushStatus", "GCM RegId Received.");
			request.getRequestDispatcher("index.jsp")
					.forward(request, response);
		} else {

			try {

				String userMessage = request.getParameter("message");
				Sender sender = new Sender(GOOGLE_SERVER_KEY);
				Message message = new Message.Builder().timeToLive(30)
						.delayWhileIdle(true).addData(MESSAGE_KEY, userMessage)
						.build();
				Set regIdSet = readFromFile();
				System.out.println("regId: " + regIdSet);
				List regIdList = new ArrayList();
				regIdList.addAll(regIdSet);
				result = sender.send(message, regIdList, 1);
				request.setAttribute("pushStatus", result.toString());
			} catch (IOException ioe) {
				ioe.printStackTrace();
				request.setAttribute("pushStatus",
						"RegId required: " + ioe.toString());
			} catch (Exception e) {
				e.printStackTrace();
				request.setAttribute("pushStatus", e.toString());
			}
			request.getRequestDispatcher("index.jsp")
					.forward(request, response);
		}
	}

	private void writeToFile(String regId) throws IOException {
		Set regIdSet = readFromFile();

		if (!regIdSet.contains(regId)) {
			PrintWriter out = new PrintWriter(new BufferedWriter(
					new FileWriter(REG_ID_STORE, true)));
			out.println(regId);
			out.close();
		}

	}

	private Set readFromFile() throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(REG_ID_STORE));
		String regId = "";
		Set regIdSet = new HashSet();
		while ((regId = br.readLine()) != null) {
			regIdSet.add(regId);
		}
		br.close();
		return regIdSet;
	}
}

index.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<%
	String pushStatus = "";
	Object pushStatusObj = request.getAttribute("pushStatus");

	if (pushStatusObj != null) {
		pushStatus = pushStatusObj.toString();
	}
%>
<head>
<title>Google Cloud Messaging (GCM) Server in PHP</title>
</head>
<body>

	<h1>Google Cloud Messaging (GCM) Server in Java</h1>

	<form action="GCMNotification" method="post">

		<div>
			<textarea rows="2" name="message" cols="23"
				placeholder="Message to transmit via GCM"></textarea>
		</div>
		<div>
			<input type="submit" value="Send Push Notification via GCM" />
		</div>
	</form>
	<p>
		<h3>
			<%=pushStatus%>
		</h3>
	</p>
</body>
</html>

Execute the Google GCM Server and Application

Lets create two AVDs instances and run the same GCM Android client application those two virtual devices.

Multiple-AVDs 

Then register both Android applications with Google cloud messaging server and receive the RegIds.

Register-with-GCM

After registration, share the Regids with the application server. Now the application server will have both RegIds stored in its store. Our store for the example is a text file. At this moment you can open the text file verify if it has got two different RegIds. Now using the application send a multicast message to Google cloud messaging server.

GCM-Multicast

Now the Google cloud messaging server will receive the notification message and the RegIds list to send the message. Then it will broadcast to all the corresponding registered devices. Now both the GCM Android client applications will receive a broadcast notification.

GCM-Broadcast-Notification

On opening the notification, we can see that the same message sent from the server application is sent via the Google cloud messaging server.

GCM-Broadcast-Notification-Message

Download the GCM Server Application

Java GCM Server Web Application Multicast

This Android tutorial was added on 06/03/2014.

Comments on "Android Multicast Notification using Google Cloud Messaging (GCM)" Tutorial:

  1. Destiny says:

    How about implementing Java GCM Server Application with Multicast in php?

  2. Pratik says:

    Hi Joe ,
    Any suggestion for Game Development for Android.

  3. Nick Halden says:

    hello joe..
    no code for PHP server???tell me what string ,character should i append in text file in which we stored 1 reg id in previous tutorial.so i can use FILLE_APPEND in php..

    something like this?.. asdasd24234fsdf1&asdasd24234fsdf2
    asdasd24234fsdf1+asdasd24234fsdf2
    where asdasd24234fsdf1 is our first reg id and asdasd24234fsdf2 is our 2nd reg id

  4. udit says:

    Hi Joe

    This is very use full Android push notification example for fresher please tell me what kind of we add in Server side php code for multicast message push notification .

  5. Shardool says:

    Hi Joe,
    Thanks a lot for the GCM messaging tutorials, helped me a lot. For the Php end server code , i was able to achieve sending multiple messages by appending the regid in the text file and then calling the pushnotification depending upon the file. Let me know if you see any concern with this approach.

    Appending in Txt file:
    gcmRegID .= “\r\n”;
    file_put_contents(“GCMRegId.txt”,$gcmRegID,FILE_APPEND);

    Calling pushnotification:

    $file = fopen(“GCMRegId.txt”,r) or exit(“Unable to open file!”);
    while (!feof($file))
    {
    $gcmRegID = fgets($file);
    if (isset($gcmRegID) && isset($pushMessage)) {
    $gcmRegIds = array($gcmRegID);
    $message = array(“message” => $pushMessage);
    $pushStatus .= sendPushNotificationToGCM($gcmRegIds, $message);
    }

  6. saksi says:

    hey Shardool can you please share your gcm.php codes

  7. Amol Suryawanshi says:

    Hii…Everything is working fine..go step by step. But remember one thing please give proper server url and application key..

  8. Anonymous says:

    Hello Joe,

    thank you for sharing this, very helpful.
    I do have some problems with the Android part on your article “Google Cloud Messaging GCM for Android and Push Notifications”. I get an error “Cannot resolve symbol gsm” at the import of GoogleCloudMessaging.

    import com.google.android.gms.gcm.GoogleCloudMessaging;

    I do have imported Google Play Services from SDK Manager.

    Thank you

  9. Akis says:

    sorry forgot to add my details for contact. Thanks again.

  10. Keith says:

    Hi Joe, May i know why i import import com.google.android.gms.gcm.GoogleCloudMessaging;
    It prompt out the error with “the import com.google cannot be solved”?
    Pease help me, thanks

  11. Chayan says:

    Hi,
    I get error that “ECONNREFUSED” (cant connect to localhost).

    Please give me any solution.

  12. santosh says:

    hello sir
    i am getting this error,
    javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
    please help me .

  13. R. Eder Weiss says:

    Hi joe:

    i am getting this, but not receive notifications push on android devices:

    MulticastResult(multicast_id=5694705687530102897,total=2,success=2,failure=0,canonical_ids=0,results: [[ messageId=0:1416865928485520%4b30447ef9fd7ecd ], [ messageId=0:1416865928485521%4b30447ef9fd7ecd ]]

  14. Vickie says:

    I Have followed the previous link @ http://javapapers.com/android/google-cloud-messaging-gcm-for-android-and-push-notifications/

    and successfully received the GCM reg id but the notifications are receiving and the following error… could you please help me out

    12-18 14:58:19.430: E/AndroidRuntime(3429): java.lang.RuntimeException: Unable to instantiate receiver com.javapapers.android.GcmBroadcastReceiver: java.lang.ClassNotFoundException: Didn’t find class “com.javapapers.android.GcmBroadcastReceiver” on path: DexPathList[[zip file “/data/app/com.javapapers.android-2/base.apk”],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]

    ———————-
    Used the standalone java to send the notifications to GCM and pls find below the log info.

    MulticastResult(multicast_id=6510119295849904776,total=1,success=1,failure=0,canonical_ids=0,results: [[ messageId=0:1418896686488639%31e4cc1700000031 ]]

  15. Vickie says:

    Notifications are not receiving due to the error… pls help me

    12-18 14:58:19.430: E/AndroidRuntime(3429): java.lang.RuntimeException: Unable to instantiate receiver com.javapapers.android.GcmBroadcastReceiver: java.lang.ClassNotFoundException: Didn’t find class “com.javapapers.android.GcmBroadcastReceiver” on path: DexPathList[[zip file “/data/app/com.javapapers.android-2/base.apk”],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]

  16. Vickie says:

    The problem has been resolved by adding the android-support-v4.jar in eclipse project Java Build Path and in “Order and Export”. Thanks

  17. Fuougy says:

    Unauthorized

    Unauthorized
    Error 401

    I have followed all step as per guid line but I still got same error please do needful.

  18. Edwin Jose says:

    Hi, Thanks for the Tutorial, I was wondering how would I be able to use this to customize the Notification Icon. If yes, How would I able to do this, Do I just customize the php to send like an icon link and on the client side do i just make a receiver class which would download the icon then do i make a layout class to attach this icon to the notification. If no, Can you tell me any other way to achieve this?

  19. Vinod Kumar says:

    The problem her is I’m able to get the Push Notification on to the Mobile Device but, On clicking on that push notification it is displaying message as null. Could you please help me out.

  20. karl says:

    Hello joe, how can i make the android multicast notification using php?

Comments are closed for this "Android Multicast Notification using Google Cloud Messaging (GCM)" tutorial.