Android Device to Device Messaging using Google Cloud Messaging (GCM) via Http

This Android tutorial will help to learn Android device to device messaging using Google Cloud Messaging (GCM) via a GCM Http server. This is just an improvisation of downstream messaging using GCM server. Communication flow originates from an Android device and the message to be communicated will be sent to GCM application server. From that server the message will be relayed to the Google Cloud Messaging server with the RegId of the device to send the notification. Then this message will be sent to the another Android device by the Google Cloud Messaging server as a notification.

Tutorial for upstream communication from an Android device using Google Cloud Connection Server (XMPP), will be posted soon. When we say device to device messaging immediate chat application comes to our mind. If you are thinking about a chat application or similar cases then XMPP will be the best way to go. If you are looking for simple notifications between Android devices then continue with this Android tutorial. You may even upgrade the example app provided in this tutorial to a chat application.

Device-To-Device-Messaging-using-GCM

If you are just starting with Google Cloud Messaging (GCM), I recommend you to go through the earlier tutorial Google Cloud Messaging GCM for Android and Push Notifications. It gives you more detailed step by step instruction to get started with Google Cloud Messaging. In this tutorial, I am just directly going to jump into the application and code. For the prerequisite like setting up your development environment, getting a Google API server key and all those preliminary steps you need to refer the above linked tutorial.

Device to Device Messaging Flow

Before start of exchanging messages, Android devices should register itself with the Google Cloud Messaging server and get a RegId. Then the Android device will share that regid with the GCM application server. Along with RegId, an identifier name will also be passed. The GCM app server will persist the name and RegId pair. Similarly all the devices that are going to participate should register themselves.

GCM server application which will act as a relay between the Android devices. Device one will send a message to GCM server by invoking a callback URL provided by the server. In the parameter it will send the recipient name. Using the recipient name GCM app sever will pick the respective RegId from its store and send the message along with RegId to the Google Cloud Messaging server. Subsequently Google Cloud messaging server will pass that message as a notification to the corresponding device.

Google Cloud Messaging Client App

RegisterActivity.java

package com.javapapers.android.gcm.devicetodevice;

import java.io.IOException;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

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

public class RegisterActivity extends Activity {

	Button btnGCMRegister;
	Button btnAppShare;
	GoogleCloudMessaging gcm;
	Context context;
	String regId;
	EditText userName;

	public static final String REG_ID = "regId";
	private static final String APP_VERSION = "appVersion";

	static final String TAG = "Register Activity";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_register);

		context = getApplicationContext();

		// to register with Google GCM Server
		btnGCMRegister = (Button) findViewById(R.id.btnGCMRegister);
		btnGCMRegister.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {
				if (TextUtils.isEmpty(regId)) {
					regId = registerGCM();
					Log.d("RegisterActivity", "GCM RegId: " + regId);
				} else {
					Toast.makeText(getApplicationContext(),
							"Already Registered with GCM Server!",
							Toast.LENGTH_LONG).show();
				}
			}
		});

		// to share regid to our custom GCM application server
		btnAppShare = (Button) findViewById(R.id.btnAppShare);
		btnAppShare.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {

				userName = (EditText) findViewById(R.id.userName);
				String name = userName.getText().toString();

				if (TextUtils.isEmpty(regId)) {
					Toast.makeText(getApplicationContext(), "RegId is empty!",
							Toast.LENGTH_LONG).show();
				} else if (TextUtils.isEmpty(name)) {
					Toast.makeText(getApplicationContext(), "Name is empty!",
							Toast.LENGTH_LONG).show();
				} else {
					Intent i = new Intent(getApplicationContext(),
							MainActivity.class);
					i.putExtra(Config.REGISTER_NAME, name);
					i.putExtra("regId", regId);
					Log.d("RegisterActivity",
							"onClick of Share: Before starting main activity.");
					startActivity(i);
					finish();
					Log.d("RegisterActivity", "onClick of Share: After finish.");
				}
			}
		});
	}

	public String registerGCM() {

		gcm = GoogleCloudMessaging.getInstance(this);
		regId = getRegistrationId(context);
		if (TextUtils.isEmpty(regId)) {
			registerInBackground();
			Log.d("RegisterActivity",
					"registerGCM - successfully registered with GCM server - regId: "
							+ regId);
		} else {
			Toast.makeText(getApplicationContext(),
					"RegId already available. RegId: " + regId,
					Toast.LENGTH_LONG).show();
		}
		return regId;
	}

	private String getRegistrationId(Context context) {
		final SharedPreferences prefs = getSharedPreferences(
				MainActivity.class.getSimpleName(), Context.MODE_PRIVATE);
		String registrationId = prefs.getString(REG_ID, "");
		if (registrationId.isEmpty()) {
			Log.i(TAG, "Registration not found.");
			return "";
		}
		int registeredVersion = prefs.getInt(APP_VERSION, Integer.MIN_VALUE);
		int currentVersion = getAppVersion(context);
		if (registeredVersion != currentVersion) {
			Log.i(TAG, "App version changed.");
			return "";
		}
		return registrationId;
	}

	private static int getAppVersion(Context context) {
		try {
			PackageInfo packageInfo = context.getPackageManager()
					.getPackageInfo(context.getPackageName(), 0);
			return packageInfo.versionCode;
		} catch (NameNotFoundException e) {
			Log.d("RegisterActivity",
					"I never expected this! Going down, going down!" + e);
			throw new RuntimeException(e);
		}
	}

	private void registerInBackground() {
		new AsyncTask() {
			@Override
			protected String doInBackground(Void... params) {
				String msg = "";
				try {
					if (gcm == null) {
						gcm = GoogleCloudMessaging.getInstance(context);
					}
					regId = gcm.register(Config.GOOGLE_PROJECT_ID);
					Log.d("RegisterActivity", "registerInBackground - regId: "
							+ regId);
					msg = "Device registered, registration ID=" + regId;

					storeRegistrationId(context, regId);
				} catch (IOException ex) {
					msg = "Error :" + ex.getMessage();
					Log.d("RegisterActivity", "Error: " + msg);
				}
				Log.d("RegisterActivity", "AsyncTask completed: " + msg);
				return msg;
			}

			@Override
			protected void onPostExecute(String msg) {
				Toast.makeText(getApplicationContext(),
						"Registered with GCM Server." + msg, Toast.LENGTH_LONG)
						.show();
			}
		}.execute(null, null, null);
	}

	private void storeRegistrationId(Context context, String regId) {
		final SharedPreferences prefs = getSharedPreferences(
				MainActivity.class.getSimpleName(), Context.MODE_PRIVATE);
		int appVersion = getAppVersion(context);
		Log.i(TAG, "Saving regId on app version " + appVersion);
		SharedPreferences.Editor editor = prefs.edit();
		editor.putString(REG_ID, regId);
		editor.putInt(APP_VERSION, appVersion);
		editor.commit();
	}
}

activity_register.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="20dp"
        android:src="@drawable/gcm_logo" />

    <Button
        android:id="@+id/btnGCMRegister"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        android:text="Register Device with Google GCM Server" />

    <View
        android:layout_width="fill_parent"
        android:layout_height="2dp"
        android:layout_margin="10dp"
        android:background="@android:color/darker_gray" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:text="Enter name and register with GCM app server."
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textStyle="italic" />

    <EditText
        android:id="@+id/userName"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:singleLine="true" />

    <Button
        android:id="@+id/btnAppShare"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginBottom="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:text="Share GCM-RegId with App Server" />

</LinearLayout>

Android-Google-GCM-Device-To-Device-Communication-Register

MainActivity.java

package com.javapapers.android.gcm.devicetodevice;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

	ShareExternalServer appUtil;
	String regId;
	String userName;
	AsyncTask shareRegidTask;

	EditText toUser;
	EditText message;
	Button btnSendMessage;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		appUtil = new ShareExternalServer();

		regId = getIntent().getStringExtra("regId");
		Log.d("MainActivity", "regId: " + regId);

		userName = getIntent().getStringExtra(Config.REGISTER_NAME);
		Log.d("MainActivity", "userName: " + userName);

		shareRegidTask = new AsyncTask() {
			@Override
			protected String doInBackground(Void... params) {
				String result = appUtil
						.shareRegIdWithAppServer(regId, userName);
				return result;
			}

			@Override
			protected void onPostExecute(String result) {
				shareRegidTask = null;
				Toast.makeText(getApplicationContext(), result,
						Toast.LENGTH_LONG).show();
			}

		};

		// to send message to another device via Google GCM
		btnSendMessage = (Button) findViewById(R.id.sendMessage);
		btnSendMessage.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {

				toUser = (EditText) findViewById(R.id.toUser);
				String toUserName = toUser.getText().toString();

				message = (EditText) findViewById(R.id.message);
				String messageToSend = message.getText().toString();

				if (TextUtils.isEmpty(toUserName)) {
					Toast.makeText(getApplicationContext(),
							"To User is empty!", Toast.LENGTH_LONG).show();
				} else if (TextUtils.isEmpty(messageToSend)) {
					Toast.makeText(getApplicationContext(),
							"Message is empty!", Toast.LENGTH_LONG).show();
				} else {
					Log.d("MainActivity", "Sending message to user: "
							+ toUserName);
					sendMessageToGCMAppServer(toUserName, messageToSend);

				}
			}
		});

		shareRegidTask.execute(null, null, null);
	}

	private void sendMessageToGCMAppServer(final String toUserName,
			final String messageToSend) {
		new AsyncTask() {
			@Override
			protected String doInBackground(Void... params) {

				String result = appUtil.sendMessage(userName, toUserName,
						messageToSend);
				Log.d("MainActivity", "Result: " + result);
				return result;
			}

			@Override
			protected void onPostExecute(String msg) {
				Log.d("MainActivity", "Result: " + msg);
				Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG)
						.show();
			}
		}.execute(null, null, null);
	}
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/lblMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="20dp"
        android:text="Send Message to other Device"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="50dp"
        android:text="To User:"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <EditText
        android:id="@+id/toUser"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:singleLine="true" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="10dp"
        android:text="Message:"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <EditText
        android:id="@+id/message"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:singleLine="true" />

    <Button
        android:id="@+id/sendMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="20dp"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:text="Send Message" />

</LinearLayout>

Android-Google-GCM-Device-To-Device-Send-Message

ShareExternalServer.java

package com.javapapers.android.gcm.devicetodevice;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import android.util.Log;

public class ShareExternalServer {

	public String shareRegIdWithAppServer(final String regId,
			final String userName) {
		String result = "";
		Map paramsMap = new HashMap();
		paramsMap.put("action", "shareRegId");
		paramsMap.put("regId", regId);
		paramsMap.put(Config.REGISTER_NAME, userName);
		result = request(paramsMap);
		if ("success".equalsIgnoreCase(result)) {
			result = "RegId shared with GCM application server successfully. Regid: "
					+ regId + ". Username: " + userName;
		}
		Log.d("ShareExternalServer", "Result: " + result);
		return result;
	}

	public String sendMessage(final String fromUserName,
			final String toUserName, final String messageToSend) {

		String result = "";
		Map paramsMap = new HashMap();
		paramsMap.put("action", "sendMessage");
		paramsMap.put(Config.REGISTER_NAME, fromUserName);
		paramsMap.put(Config.TO_NAME, toUserName);
		paramsMap.put(Config.MESSAGE_KEY, messageToSend);
		result = request(paramsMap);
		if ("success".equalsIgnoreCase(result)) {
			result = "Message " + messageToSend + " sent to user " + toUserName
					+ " successfully.";
		}
		Log.d("ShareExternalServer", "Result: " + result);
		return result;
	}

	public String request(Map paramsMap) {
		String result = "";
		URL serverUrl = null;
		OutputStream out = null;
		HttpURLConnection httpCon = null;
		try {
			serverUrl = new URL(Config.APP_SERVER_URL);
			StringBuilder postBody = new StringBuilder();
			Iterator> iterator = paramsMap.entrySet()
					.iterator();
			while (iterator.hasNext()) {
				Entry param = iterator.next();
				postBody.append(param.getKey()).append('=')
						.append(param.getValue());
				if (iterator.hasNext()) {
					postBody.append('&');
				}
			}
			String body = postBody.toString();
			byte[] bytes = body.getBytes();
			httpCon = (HttpURLConnection) serverUrl.openConnection();
			httpCon.setDoOutput(true);
			httpCon.setUseCaches(false);
			httpCon.setFixedLengthStreamingMode(bytes.length);
			httpCon.setRequestMethod("POST");
			httpCon.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded;charset=UTF-8");
			Log.d("ShareExternalServer", "Just before getting output stream.");
			out = httpCon.getOutputStream();
			out.write(bytes);
			int status = httpCon.getResponseCode();
			Log.d("ShareExternalServer", "HTTP Connection Status: " + status);
			if (status == 200) {
				result = "success";
			} else {
				result = "Post Failure." + " Status: " + status;
			}

		} catch (MalformedURLException e) {
			Log.e("ShareExternalServer", "Unable to Connect. Invalid URL: "
					+ Config.APP_SERVER_URL, e);
			result = "Invalid URL: " + Config.APP_SERVER_URL;
		} catch (IOException e) {
			Log.e("ShareExternalServer",
					"Unable to Connect. Communication Error: " + e);
			result = "Unable to Connect GCM App Server.";
		} finally {
			if (httpCon != null) {
				httpCon.disconnect();
			}
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					// do nothing
				}
			}
		}
		return result;
	}

}

I have not displayed the source of GCMNotificationIntentService.java, GcmBroadcastReceiver.java, Config.java and AndroidManifest.xml files. As they are same as given the previous tutorial. Either you may refer the previous tutorial or you can download the project below to get the complete files.

Download Android GCM Client for Device to Device Messaging

Google Cloud Messaging Server Application

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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

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.Result;
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 = "AIzaSyA9DQTcggUtfqABClnV_XYZVE8QiKBEaP4";
	static final String REGISTER_NAME = "name";
	static final String MESSAGE_KEY = "message";
	static final String TO_NAME = "toName";
	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 {

		String action = request.getParameter("action");

		if ("shareRegId".equalsIgnoreCase(action)) {

			writeToFile(request.getParameter("name"),
					request.getParameter("regId"));
			request.setAttribute("pushStatus",
					"GCM Name and corresponding RegId Received.");
			request.getRequestDispatcher("index.jsp")
					.forward(request, response);

		} else if ("sendMessage".equalsIgnoreCase(action)) {

			try {
				String fromName = request.getParameter(REGISTER_NAME);
				String toName = request.getParameter(TO_NAME);
				String userMessage = request.getParameter(MESSAGE_KEY);
				Sender sender = new Sender(GOOGLE_SERVER_KEY);
				Message message = new Message.Builder().timeToLive(30)
						.delayWhileIdle(true).addData(MESSAGE_KEY, userMessage)
						.addData(REGISTER_NAME, fromName).build();
				Map regIdMap = readFromFile();
				String regId = regIdMap.get(toName);
				Result result = sender.send(message, regId, 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);
		} else if ("multicast".equalsIgnoreCase(action)) {

			try {
				String fromName = request.getParameter(REGISTER_NAME);
				String userMessage = request.getParameter(MESSAGE_KEY);
				Sender sender = new Sender(GOOGLE_SERVER_KEY);
				Message message = new Message.Builder().timeToLive(30)
						.delayWhileIdle(true).addData(MESSAGE_KEY, userMessage)
						.addData(REGISTER_NAME, fromName).build();
				Map regIdMap = readFromFile();

				List regIdList = new ArrayList();

				for (Entry entry : regIdMap.entrySet()) {
					regIdList.add(entry.getValue());
				}

				MulticastResult multiResult = sender
						.send(message, regIdList, 1);
				request.setAttribute("pushStatus", multiResult.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 name, String regId) throws IOException {
		Map regIdMap = readFromFile();
		regIdMap.put(name, regId);
		PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(
				REG_ID_STORE, false)));
		for (Map.Entry entry : regIdMap.entrySet()) {
			out.println(entry.getKey() + "," + entry.getValue());
		}
		out.println(name + "," + regId);
		out.close();

	}

	private Map readFromFile() throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(REG_ID_STORE));
		String regIdLine = "";
		Map regIdMap = new HashMap();
		while ((regIdLine = br.readLine()) != null) {
			String[] regArr = regIdLine.split(",");
			regIdMap.put(regArr[0], regArr[1]);
		}
		br.close();
		return regIdMap;
	}
}

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 Java</title>
</head>
<body>

	<h1>Google Cloud Messaging (GCM) Server in Java: Device to Device
		Communication</h1>

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

		<div>
			<input type="hidden" name="name" value="Admin" />
			<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>

Download Android GCM Server for Device to Device Messaging

Android Device to Device Messaging Output

Device To Device Message Sent:

Android-Google-GCM-Device-To-Device-Message-Sent

Device To Device Message Received:

Android-Google-GCM-Device-To-Device-Message-Received

Device To Device Reply Message Sent:

Android-Google-GCM-Device-To-Device-Reply-Sent

Device To Device Reply Message Received:

Android-Google-GCM-Device-To-Device-Reply-Received

Device To Device both Messages:

Android-Google-GCM-Device-To-Device-Messages

Google Cloud Messaging Multicast Messages

Following output showcases the multicast messaging to devices using Google cloud messaging. From the GCM server application we can send messages to multiple Android devices. In this tutorial example we are sending message to all registered Android devices.

Multicast-Message-from-GCM-Server

Google-GCM-Multicast-message-sent

Google-GCM-multicast-message-received

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

Comments on "Android Device to Device Messaging using Google Cloud Messaging (GCM) via Http" Tutorial:

  1. Akash says:

    Hi, Will this GCM cloud device to device msging service scalable for more number of users?

  2. Joe says:

    Yes GCM is a scalable service by Google. Check their service cost before you use it heavily.

  3. sai says:

    hi joe,
    how to convert android gcm server device to device into war file & upload into apache tomcat….

  4. Kaustubh says:

    Hi Joe, this is what I was looking for, many thanks. But I have one doubt, when we receive a notification, the contents of notification are “GCM Notification”
    “Message via Google GCM Server … message…”
    I want to change these contents of the push notification, along with the notification icon. How can I do that?

  5. Kaustubh says:

    Also I wanted to do the same in PHP :(
    What changes do I have to make for PHP

  6. Tony says:

    Hi Joe,
    I’m new at Android app programming. Can you provide more step by step detail on the server side setup using XMPP (phpmyadmin) for example. When do you plan on publishing the Android Device to Device Messaging using Google Cloud Messaging (GCM) using XMPP?

  7. swati says:

    i also need php codes..provide me if u have it.

  8. Alan says:

    Hi, I made the deploy on tomcat of the server part but when i’m trying to acces via device to web http://SERVERIP/GCM…/GCMNotification? like the config.java file said i’m getting a 404 not found

    Anyone else with the same problem?

  9. Anonymous says:

    i have a problem. Config.REGISTER_NAME cannot be resolved

  10. vicio says:

    i have a problem. Config.REGISTER_NAME cannot be resolved

  11. RI says:

    Sir where should i put server side code?

  12. Lykos Fatsopoulos says:

    Although it is a little late for a response on this, but maybe someone else has the same problem.

    The notification – icon and message – is generated in GCMNotificationIntentService.java, so just change it to whatever you like.

  13. sathish says:

    hi Joe,

    how to communicate local server(apache tomcat server)& SQLyog with Android application through mobile.

  14. Dipali says:

    Hello Joe,
    I tested your the GCM push Notifications Project from server to device. and it ran perfectly. But now I am trying Device to device.. and I am getting POST ERROR 500 while sharing register id with Server. and on the same time I am getting error on server saying “Servlet.service() for servlet [com.javapapers.java.gcm.GCMNotification] in context with path [/GCM-Server-Device-To-Device]”.. Can you please help me on this?

  15. dipali says:

    Hi Joe,
    I am able to send and recieve messages now.. I just added some jar files.
    Thank you

  16. Davvy says:

    friend please tell me how to import this project in eclipse and how to use this in step by step…..

  17. dexterx says:

    Hello joe , excellent work you do!

    Can you tell me how is the code to a php server ?

  18. alexis says:

    Hi joe Help me, in this part of the server code,WHen DEBUG I get error.
    this occurs when the client FIRST sends its ID and name the server:
    enter –> if (“shareRegId”.equalsIgnoreCase(action)) {…..}
    enter –>
    private void writeToFile(String name, String regId) throws IOException {
    Map regIdMap = readFromFile();
    //In THIS PART I GET ERROR (READFROMFILE)

    }

    private Map readFromFile() throws IOException {…}

    I defined this way the Map:()
    Map regIdMap = new HashMap();
    BUT in the .TXT the data is repeating.

  19. Jignesh Patel says:

    Thanx for tutorial but can you please share php server code to me?

  20. Tony jaa says:

    i couldn’t get the exact process… when i click send message .. toast says the mesg xx is send to yy. but the other device is not receiving it. can you pls help me for it

  21. Tony jaa says:

    Even i included all the jar files … still i couldn’t get it…. pls reply for it joe

  22. Tony jaa says:

    in server side i get this error… REGID REQUIRED: JAVA.IO.FILENOTFOUNDEXCEPRION:GCMREGID.TXT(THE SYSTEM CANNOT FIND THE FILE SPECIFIED)

  23. Rajesh says:

    I tried your application its superb but one problem for when i click the “send push Notification Via GCM” button it shows
    RegId required: java.io.FileNotFoundException:GCMRegId.txt (The system cannot find the file specified).In mobile it runs fine but i cant send message to another mobile.i waiting for your answer

  24. Ranjith says:

    Hi Joe, your example is nice but while clicking “send push notification via GCM” button in web server it shows an error message like “RegId required: java.io.FileNotFoundException: GCMRegId.txt (No such file or directory) “. How to resolve this??? I need this urgent…. pls reply to ma mail

  25. Jan says:

    I keep getting the same exception. What are the .jar files you added?

  26. Chirag nahar says:

    Thanks a lot for this ..Am trying from last 15 days to do this bt now today i completed this task and feeling too much happy..Its a Superb Material..Love u:)

  27. jeeva says:

    Nice tutorial ,But when i press send push notification button,i faced the following error

    RegId required: java.io.FileNotFoundException: GCMRegId.txt (The system cannot find the file specified)

    How can i fix this error(jeeva2k10@gmail.com)

    Thanks

  28. jeeva says:

    Hi, Nice tutorial ,Its working well,I can able to send notification from server to multiple device and Device to device.How can i send from device to cloud,any one help me.

    Thanks

  29. harisha says:

    hello same error like most of them.. i m getting
    WHen DEBUG I get error.
    this occurs when the client FIRST sends its ID and name the server:
    enter –> if (“shareRegId”.equalsIgnoreCase(action)) {…..}
    enter –>
    private void writeToFile(String name, String regId) throws IOException {
    Map regIdMap = readFromFile();
    //In THIS PART I GET ERROR (READFROMFILE)

    please sir.. i m extremely in need of this code.. my project marks are depended on this.. please give solution to this

Comments are closed for this "Android Device to Device Messaging using Google Cloud Messaging (GCM) via Http" tutorial.