Send and receive push messages using Google Cloud Messaging

By

June 16, 2013AndroidNo comments

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:

gcm-example

Installing apps remotely from Play Store is best example for GCM

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

GCM 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

sdk manager

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

Project configuration in eclipse

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;
    }

}
Registration ID

Logcat view of Reg ID

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.

Leave a Reply

*