GCM or Google Cloud Messaging service is offered by google for the android platform to send and receive data using google’s cloud infrastructure.Earlier it is better known an C2DM or Cloud to Device messaging that is used to install the applications from playstore website directly to the android device remotely.
Using this service you can send and receive data up to 4kb to any number of android devices at blazing speed.
Example:
How GCM Works?
By default every android device will have the Google cloud messaging services installed.Any application can use the service in order to receive the push notifications.
In this tutorial we will show you how to send a message using Google cloud messaging,
We need a Client application and server application.Whenever a new push message is sent from the server to cloud the client application will receive the message.But you cannot send a message simply to a client because the phone/tablet should be registered first with the specific GCM instance where the server application pushes data.
Registering GCM in your google Account
1.Register the cloud messaging service here
2.Click Create new project
3.Note Down the projectid on the URL after creating the project.For example #project 457017530933
4.Click on the service tab in the left menu and enable the “Google Cloud Messaging”
5.Click the API access and generate a new server key.
So now we registered for the service we can start building the application.Before that you make sure to check the ADT version in eclipse is updated to latest version.
Open the SDK manager and install the library files.Extras->Google Cloud Messaging for Android Library
Create a new project
In Eclipse two project has to be created one for client and one for server.Server app will send the GCM message to the client devices.
GCMClient
Setup project with the below configuration
Client application performs two important functions
1.Register the device with the GCM
2.Receive and process the messages sent by server application.
Layout
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <textview android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/hello_world"></textview> </relativelayout> |
When the main activity is loaded the device will be registered to the google cloud.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package com.example.gcmclient; import com.google.android.gcm.GCMRegistrar; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.Menu; import android.widget.TextView; public class MainActivity extends Activity { private String TAG = "** GCMClientAndroidActivity **"; private TextView mDisplay; private String sender_id = "457017530933"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GCMRegistrar.checkDevice(this); GCMRegistrar.checkManifest(this); setContentView(R.layout.activity_main); mDisplay = (TextView) findViewById(R.id.textView2); String regId = GCMRegistrar.getRegistrationId(this); Log.i(TAG, "registration id ===== " + regId); if (regId.equals("")) { GCMRegistrar.register(this, sender_id); } else { // send data to server to store regid of all the device installed Senddata task = new Senddata(); task.execute(regId.toString()); Log.v(TAG, "Already registered"); } mDisplay.setText("Reg ID: " + regId); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } } |
Replace the Sender_id with the 457017530933 which the project id generated earlier.
Once the device is successfully registered it will return the registration id which has to be stored for the server to send messages.
Create a new activity extending the class GCMBaseIntentService which will be the backbone for the receiving and registering the device.
GCMIntentService.Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | package com.example.gcmclient; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.support.v4.app.NotificationCompat; import android.util.Log; import com.google.android.gcm.GCMBaseIntentService; /** * IntentService responsible for handling GCM messages. */ public class GCMIntentService extends GCMBaseIntentService { @Override protected void onError(Context arg0, String arg1) { // TODO Auto-generated method stub } @Override protected void onMessage(Context arg0, Intent arg1) { // TODO Auto-generated method stub Log.d("GCM", "RECIEVED A MESSAGE"); // Get the data from intent and send to notificaion bar //generateNotification(arg0, arg1.getStringExtra("message")); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("GCM Server") .setContentText(arg1.getStringExtra("message")); NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // mId allows you to update the notification later on. mNotificationManager.notify(12, mBuilder.build()); } @Override protected void onRegistered(Context arg0, String arg1) { // TODO Auto-generated method stub Log.i(TAG, "Device registered: regId = " + arg1); } @Override protected void onUnregistered(Context arg0, String arg1) { // TODO Auto-generated method stub } } |
GCMServer
Server application sends the message to the registered devices using the device specific ID.
Layout
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="134dp" android:text="Send"></button> <edittext android:id="@+id/editText1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="79dp" android:ems="10" android:inputType="textPostalAddress"></edittext> </relativelayout> |
Create a new class to send the message in background.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package com.example.gcmexample; import android.os.Bundle; import android.app.Activity; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnsend = (Button) findViewById(R.id.button1); final EditText txtmsg = (EditText) findViewById(R.id.editText1); btnsend.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub SendMessage task = new SendMessage(); task.execute(txtmsg.getText().toString()); } }); } } |
SendMessage.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | package com.example.gcmexample; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.google.android.gcm.server.Message; import com.google.android.gcm.server.MulticastResult; import com.google.android.gcm.server.Sender; import android.os.AsyncTask; public class SendMessage extends AsyncTask<string , Void, String> { ArrayList</string><string> stringList = new ArrayList</string><string>(); protected String doInBackground(String... params) { // TODO Auto-generated method stub // request tokens from server HttpClient httpClient = new DefaultHttpClient(); HttpPost httppost = new HttpPost( "http://projects.devlup.com/PRS/Notify/read.php"); // httppost.setHeader("Content-type", "application/json"); try { // Execute HTTP Post Request HttpResponse response = httpClient.execute(httppost); HttpEntity entity = response.getEntity(); InputStream is = entity.getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader( is, "iso-8859-1"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); JSONArray jArray = new JSONArray(sb.toString()); for (int i = 0; i < jArray.length(); i++) { JSONObject json_data = jArray.getJSONObject(i); stringList.add(json_data.getString("device_token")); } } catch (ClientProtocolException e) { // TODO Auto-generated catch block } catch (IOException e) { // TODO Auto-generated catch block } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } MulticastResult result = null; Sender sender = new Sender("AIzaSyAVrnN8hVlXt4G1mW8cghtJxsAhAmwn2Lw"); Message message = new Message.Builder().collapseKey("145675") .timeToLive(3).delayWhileIdle(true) .addData("message", params[0].toString()).build(); try { // return result; for (int i = 0; i < stringList.size(); i++) { // result = sender.send(message, stringList, 1); sender.send(message, stringList.get(i).toString(), 1); } // result = sender.send(message,stringList.get(i).toString(), 5); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } |
This is a simple example for a single device but for a large scale application GCM messages will be sent out to thousands of devices.In those cases the device registration IDs can be stored in database and accessed through a simple webservice in PHP.
Additional Information
Usually the device registration is not instant it happens if the internet connection is active.
Messages are delivered to devices so fast since every android phone has the cloud service which listens for the push messages.
If the application is uninstalled the device will be de registered automatically.
If you like this tutorial you can read more at android category.