2014년 8월 10일 일요일

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

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

댓글 없음:

댓글 쓰기