Android Push Notifications using Google Cloud Messaging GCM

DOWNLOAD CODE

Related Examples

In this example implementing Google Cloud Messaging (GCM) for android. Using Google Cloud Messaging (GCM) sending push notification from web server to registered android devices. Using php as server side language and mysql as database.

Later i will provide example to send push notification from one device to other device.

 

OUTPUT :

 

Example WorkFlow :


Push_notification_Workflow

 

STEPS : We will follow these steps

 

  1.  Register with Google Cloud Messaging from GOOGLE API Console and get Sender ID and API key for Google Cloud Messaging.

  2.  Set Emulator for Google Cloud Messaging helper library.

  3.  Create Android project to register with Google Cloud Messaging(GCM).

  4.  Create server side code to save Google Cloud Messaging registration id in our database and send push notification to device.

 

 

STEP 1 : Register with Google Cloud Messaging from GOOGLE API Console (Create a Google API project)

 

Follow the instrunction from http://developer.android.com/google/gcm/gs.html or follow below steps.


  a.  Open the Google APIs Console page.

  b.  If you haven't created an API project yet, this page will prompt you to do so:

gcm-create-api-project

  c.  After creating project you can see the project id in the url. Note down the project id which will be further used as SENDER ID in android project. (Example: in #project:460866929976 after semicolon 460866778899 is the sender id)

https://code.google.com/apis/console/#project:460866778899


get_gcm_sender_id

  d.   In the main Google APIs Console page, select Services.

  e.  Toggle on Google Cloud Messaging for Android.

Activate_google_cloud_messaging_android

  f.  Click on API Access and note down the API Key. API key will be used when send push notification requests from our server(php script) to GCM server.

get_gcm_api_key

 

/*********************************** STEP1 END ************************************/

 

 

STEP 2 : Set Emulator for Google Cloud Messaging helper library.

 

Before start writing android code we need to install the helper libraries and make required changes to the emulator. Helper library methods we will used to register / unregister with GCM.

  a.  Goto your android SDK folder and open SDK Manager and install Google Cloud Messaging for Android Library under Extras section. (If you don’t see Google Cloud Messaging for Android Library update your SDK manager to latest version)

install_google_cloud_messaging_library_eclipse



download_google_cloud_messaging_android_library_simulator

  b.  After installing the library it will create gcm.jar file in your Andoird_SDK_Folderextrasgooglegcmgcm-clientdist. Later you need to add this .jar file to your android project.





  c.  Now open your AVD Manager and create a new Google API emulator and start the emulator. (Note: To test gcm application in emulator you need to test it on Google API device only)

  d.  After launching emulator press Menu button goto Settings. Select Accounts & Sync. And then press Add Account button and add a Google account.

android_gcm_adding_google_account_simulator_1 android_gcm_signin_google_account_simulator_2
 
android_gcm_account_detail_simulator_3 android_gcm_adding_google_account_simulator_4

 

NOTE :

 

If you will not add google account in your device and run this example you will get gcm error account_missing.see this screenshot

gcm_error_account_missing

 

 

/*********************************** STEP2 END ************************************/

 

STEP3. Create Android project and register with Google Cloud Messaging(GCM)

 

Project Structure :

 

google_push_notification_example_project_sketch

 

AndroidManifest.xml

 

The following permission are required to make your project support gcm.

INTERNET – To make your app use internet services.

ACCESS_NETWORK_STATE – To access network state (used to detect internet status)

GET_ACCOUNTS – Required as GCM needs google account

WAKE_LOCK – Needed if your app need to wake your device when it sleeps

VIBRATE – Needed if your support vibration when receiving notification
Also add some broadcast receivers as mentioned below.

 


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.androidexample.gcm"
    android:versionCode="1"
    android:versionName="1.0" >

    <!-- GCM requires Android SDK version 2.2 (API level 8) or above. -->
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <!-- Main activity. -->
    <application
        android:name="com.androidexample.gcm.Controller"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <!-- Register Activity -->
        <activity
            android:name="com.androidexample.gcm.RegisterActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
			<intent-filter>
				<action android:name="android.intent.action.VIEW" />
				<action android:name="android.intent.action.DELETE" />
				<category android:name="android.intent.category.DEFAULT" />  
				<data android:scheme="com.idrivecare.familypro" />
			</intent-filter>
        </activity>
        
       
        <!-- Main Activity -->
        <activity
            android:name="com.androidexample.gcm.MainActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/app_name" >
        </activity>
        
        <receiver
            android:name="com.google.android.gcm.GCMBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>

                <!-- Receives the actual messages. -->
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <!-- Receives the registration id. -->
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="com.androidexample.gcm" />
            </intent-filter>
        </receiver>

        <service android:name="com.androidexample.gcm.GCMIntentService" />
    </application>

    <!-- GCM connects to Internet Services. -->
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- GCM requires a Google account. -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />

    <!-- Keeps the processor from sleeping when a message is received. -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <!-- Creates a custom permission so only this app can receive its messages. -->
    <permission
        android:name="com.androidexample.gcm.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="com.androidexample.gcm.permission.C2D_MESSAGE" />

    <!-- This app has permission to register and receive data message. -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <!-- Network State Permissions to detect Internet status -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!-- Permission to vibrate -->
    <uses-permission android:name="android.permission.VIBRATE" />
    
</manifest>

 

File : Config.java

 

Model Class to defined configuration values.

YOUR_SERVER_URL : your web server url or localhost.

GOOGLE_SENDER_ID : Google project id you have got from google api console.

 


package com.androidexample.gcm;

public interface Config {

	
	// CONSTANTS
	static final String YOUR_SERVER_URL =  
                          "YOUR_SERVER_URL/gcm_server_files/register.php";
    
    // Google project id
    static final String GOOGLE_SENDER_ID = "9432667788990"; 

    /**
     * Tag used on log messages.
     */
    static final String TAG = "GCM Android Example";

    static final String DISPLAY_MESSAGE_ACTION =
            "com.androidexample.gcm.DISPLAY_MESSAGE";

    static final String EXTRA_MESSAGE = "message";
		
	
}

 

Controller.java

 

Controller class extends with android.app.Application and defined in the application tag in your AndroidManifest.xml file. Android will create an instance of Controller class and make it available for your entire application context. You can get object of your class on any activity / broadcast receiver / service in application context(environment) by Context.getApplicationContext() method.

Controller class to intract with models and provide values to views.

Functions defined in this class:

register() : Creating post request and Store GCM RegID and name / email in database on our web server for later use.

unregister() : Unregister device from GCM server and also creating a post request on server to delete stored RegID from database on our web server.

post() : Create HTTP Post request to server , requested url is defined in Config.java

isConnectingToInternet() : Check internet connectivity

displayMessageOnScreen() : Send broadcast to show message on activity, broadcast receiver mHandleMessageReceiver defined in MainActivity.java.

acquireWakeLock() : Device wakeup when any new push notification received.

 


package com.androidexample.gcm;

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

import com.google.android.gcm.GCMRegistrar; 

import android.app.AlertDialog;
import android.app.Application;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.PowerManager;
import android.util.Log;

public class Controller extends Application{
	
	private  final int MAX_ATTEMPTS = 5;
    private  final int BACKOFF_MILLI_SECONDS = 2000;
    private  final Random random = new Random();
	
    
	 // Register this account with the server.
    void register(final Context context, String name, String email, final String regId) {
    	 
        Log.i(Config.TAG, "registering device (regId = " + regId + ")");
        
        String serverUrl = Config.YOUR_SERVER_URL;
        
        Map<String, String> params = new HashMap<String, String>();
        params.put("regId", regId);
        params.put("name", name);
        params.put("email", email);
        
        long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
        
        // Once GCM returns a registration id, we need to register on our server
        // As the server might be down, we will retry it a couple
        // times.
        for (int i = 1; i <= MAX_ATTEMPTS; i++) {
        	
            Log.d(Config.TAG, "Attempt #" + i + " to register");
            
            try {
            	//Send Broadcast to Show message on screen
            	displayMessageOnScreen(context, context.getString(
                        R.string.server_registering, i, MAX_ATTEMPTS));
                
                // Post registration values to web server
                post(serverUrl, params);
                
                GCMRegistrar.setRegisteredOnServer(context, true);
                
                //Send Broadcast to Show message on screen
                String message = context.getString(R.string.server_registered);
                displayMessageOnScreen(context, message);
                
                return;
            } catch (IOException e) {
            	
                // Here we are simplifying and retrying on any error; in a real
                // application, it should retry only on unrecoverable errors
                // (like HTTP error code 503).
            	
                Log.e(Config.TAG, "Failed to register on attempt " + i + ":" + e);
                
                if (i == MAX_ATTEMPTS) {
                    break;
                }
                try {
                	
                    Log.d(Config.TAG, "Sleeping for " + backoff + " ms before retry");
                    Thread.sleep(backoff);
                    
                } catch (InterruptedException e1) {
                    // Activity finished before we complete - exit.
                    Log.d(Config.TAG, "Thread interrupted: abort remaining retries!");
                    Thread.currentThread().interrupt();
                    return;
                }
                
                // increase backoff exponentially
                backoff *= 2;
            }
        }
        
        String message = context.getString(R.string.server_register_error,
                MAX_ATTEMPTS);
        
        //Send Broadcast to Show message on screen
        displayMessageOnScreen(context, message);
    }

     // Unregister this account/device pair within the server.
     void unregister(final Context context, final String regId) {
    	 
        Log.i(Config.TAG, "unregistering device (regId = " + regId + ")");
        
        String serverUrl = Config.YOUR_SERVER_URL + "/unregister";
        Map<String, String> params = new HashMap<String, String>();
        params.put("regId", regId);
        
        try {
            post(serverUrl, params);
            GCMRegistrar.setRegisteredOnServer(context, false);
            String message = context.getString(R.string.server_unregistered);
            displayMessageOnScreen(context, message);
        } catch (IOException e) {
        	
            // At this point the device is unregistered from GCM, but still
            // registered in the our server.
            // We could try to unregister again, but it is not necessary:
            // if the server tries to send a message to the device, it will get
            // a "NotRegistered" error message and should unregister the device.
        	
            String message = context.getString(R.string.server_unregister_error,
                    e.getMessage());
            displayMessageOnScreen(context, message);
        }
    }

    // Issue a POST request to the server.
    private static void post(String endpoint, Map<String, String> params)
            throws IOException {   	
        
        URL url;
        try {
        	
            url = new URL(endpoint);
            
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException("invalid url: " + endpoint);
        }
        
        StringBuilder bodyBuilder = new StringBuilder();
        Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
        
        // constructs the POST body using the parameters
        while (iterator.hasNext()) {
            Entry<String, String> param = iterator.next();
            bodyBuilder.append(param.getKey()).append('=')
                    .append(param.getValue());
            if (iterator.hasNext()) {
                bodyBuilder.append('&');
            }
        }
        
        String body = bodyBuilder.toString();
        
        Log.v(Config.TAG, "Posting '" + body + "' to " + url);
        
        byte[] bytes = body.getBytes();
        
        HttpURLConnection conn = null;
        try {
        	
        	Log.e("URL", "> " + url);
        	
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setFixedLengthStreamingMode(bytes.length);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded;charset=UTF-8");
            // post the request
            OutputStream out = conn.getOutputStream();
            out.write(bytes);
            out.close();
            
            // handle the response
            int status = conn.getResponseCode();
            
            // If response is not success
            if (status != 200) {
            	
              throw new IOException("Post failed with error code " + status);
            }
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
      }
    
    
    
	// Checking for all possible internet providers
    public boolean isConnectingToInternet(){
    	
        ConnectivityManager connectivity = 
        	                 (ConnectivityManager) getSystemService(
        	                  Context.CONNECTIVITY_SERVICE);
          if (connectivity != null)
          {
              NetworkInfo[] info = connectivity.getAllNetworkInfo();
              if (info != null)
                  for (int i = 0; i < info.length; i++)
                      if (info[i].getState() == NetworkInfo.State.CONNECTED)
                      {
                          return true;
                      }
 
          }
          return false;
    }
	
   // Notifies UI to display a message.
   void displayMessageOnScreen(Context context, String message) {
    	 
        Intent intent = new Intent(Config.DISPLAY_MESSAGE_ACTION);
        intent.putExtra(Config.EXTRA_MESSAGE, message);
        


        // Send Broadcast to Broadcast receiver with message
        context.sendBroadcast(intent);
        
    }
    
    
   //Function to display simple Alert Dialog
   public void showAlertDialog(Context context, String title, String message,
			Boolean status) {
		AlertDialog alertDialog = new AlertDialog.Builder(context).create();

		// Set Dialog Title
		alertDialog.setTitle(title);

		// Set Dialog Message
		alertDialog.setMessage(message);

		if(status != null)
			// Set alert dialog icon
			alertDialog.setIcon((status) ? R.drawable.success : R.drawable.fail);

		// Set OK Button
		alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				
			}
		});

		// Show Alert Message
		alertDialog.show();
	}
    
    private PowerManager.WakeLock wakeLock;
    
    public  void acquireWakeLock(Context context) {
        if (wakeLock != null) wakeLock.release();

        PowerManager pm = (PowerManager) 
                          context.getSystemService(Context.POWER_SERVICE);
        
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
                PowerManager.ACQUIRE_CAUSES_WAKEUP |
                PowerManager.ON_AFTER_RELEASE, "WakeLock");
        
        wakeLock.acquire();
    }

    public  void releaseWakeLock() {
        if (wakeLock != null) wakeLock.release(); wakeLock = null;
    }
   
}

 

RegisterActivity.java

 

User registration screen.

 



package com.androidexample.gcm;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class RegisterActivity extends Activity {
	
	// UI elements
	EditText txtName; 
	EditText txtEmail;
	
	// Register button
	Button btnRegister;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_register);
		
		//Get Global Controller Class object (see application tag in AndroidManifest.xml)
		final Controller aController = (Controller) getApplicationContext();
		
		// Check if Internet Connection present
		if (!aController.isConnectingToInternet()) {
			
			// Internet Connection is not present
			aController.showAlertDialog(RegisterActivity.this,
					"Internet Connection Error",
					"Please connect to working Internet connection", false);
			
			// stop executing code by return
			return;
		}

		// Check if GCM configuration is set
		if (Config.YOUR_SERVER_URL == null 
            || Config.GOOGLE_SENDER_ID == null 
            || Config.YOUR_SERVER_URL.length() == 0
		    || Config.GOOGLE_SENDER_ID.length() == 0) {
			
			// GCM sernder id / server url is missing
			aController.showAlertDialog(RegisterActivity.this, "Configuration Error!",
					"Please set your Server URL and GCM Sender ID", false);
			
			// stop executing code by return
			 return;
		}
		
		txtName = (EditText) findViewById(R.id.txtName);
		txtEmail = (EditText) findViewById(R.id.txtEmail);
		btnRegister = (Button) findViewById(R.id.btnRegister);
		
		// Click event on Register button
		btnRegister.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View arg0) {  
				// Get data from EditText 
				String name = txtName.getText().toString(); 
				String email = txtEmail.getText().toString();
				
				// Check if user filled the form
				if(name.trim().length() > 0 && email.trim().length() > 0){
					
					// Launch Main Activity
					Intent i = new Intent(getApplicationContext(), MainActivity.class);
					
					// Registering user on our server					
					// Sending registraiton details to MainActivity
					i.putExtra("name", name);
					i.putExtra("email", email);
					startActivity(i);
					finish();
					
				}else{
					
					// user doen't filled that data
					aController.showAlertDialog(RegisterActivity.this, 
                                                "Registration Error!", 
                                                "Please enter your details", 
                                                false);
				}
			}
		});
	}

}

 

MainActivity.java

 

Call GCMRegistrar.register method with GOOGLE_SENDER_ID defined in config.java to register device for Google Cloud Messaging Server. if device is registered then using AsyncTask to store GCM RegID in our web database, Later we will use this RegID to send push notification from web server to this device..

Create broadcast receiver mHandleMessageReceiver to print messages. when we call displayMessageOnScreen() from controller class it will send broadcast to broadcast receiver mHandleMessageReceiver  and it will print message on activity.

 



package com.androidexample.gcm;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gcm.GCMRegistrar;

public class MainActivity extends Activity {
	// label to display gcm messages
	TextView lblMessage;
	Controller aController;
	
	// Asyntask
	AsyncTask<Void, Void, Void> mRegisterTask;
	
	public static String name;
	public static String email;

	@Override
	public void onCreate(Bundle savedInstanceState) { 
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//Get Global Controller Class object (see application tag in AndroidManifest.xml)
		aController = (Controller) getApplicationContext();
		
		
		// Check if Internet present
		if (!aController.isConnectingToInternet()) {
			
			// Internet Connection is not present
			aController.showAlertDialog(MainActivity.this,
					"Internet Connection Error",
					"Please connect to Internet connection", false);
			// stop executing code by return
			return;
		}
		
		// Getting name, email from intent
		Intent i = getIntent();
		
		name = i.getStringExtra("name");
		email = i.getStringExtra("email");		
		
		// Make sure the device has the proper dependencies.
		GCMRegistrar.checkDevice(this);

		// Make sure the manifest permissions was properly set 
		GCMRegistrar.checkManifest(this);

		lblMessage = (TextView) findViewById(R.id.lblMessage);
		
		// Register custom Broadcast receiver to show messages on activity
		registerReceiver(mHandleMessageReceiver, new IntentFilter(
				Config.DISPLAY_MESSAGE_ACTION));
		
		// Get GCM registration id
		final String regId = GCMRegistrar.getRegistrationId(this);

		// Check if regid already presents
		if (regId.equals("")) {
			
			// Register with GCM			
			GCMRegistrar.register(this, Config.GOOGLE_SENDER_ID);
			
		} else {
			
			// Device is already registered on GCM Server
			if (GCMRegistrar.isRegisteredOnServer(this)) {
				
				// Skips registration.				
				Toast.makeText(getApplicationContext(), 
                              "Already registered with GCM Server", 
                              Toast.LENGTH_LONG).
                              show();
			
			} else {
				
				// Try to register again, but not in the UI thread.
				// It's also necessary to cancel the thread onDestroy(),
				// hence the use of AsyncTask instead of a raw thread.
				
				final Context context = this;
				mRegisterTask = new AsyncTask<Void, Void, Void>() {

					@Override
					protected Void doInBackground(Void... params) {
						
						// Register on our server
						// On server creates a new user
						aController.register(context, name, email, regId);
						
						return null;
					}

					@Override
					protected void onPostExecute(Void result) {
						mRegisterTask = null;
					}

				};
				
				// execute AsyncTask
				mRegisterTask.execute(null, null, null);
			}
		}
	}		

	// Create a broadcast receiver to get message and show on screen 
	private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
		
		@Override
		public void onReceive(Context context, Intent intent) {
			
			String newMessage = intent.getExtras().getString(Config.EXTRA_MESSAGE);
			
			// Waking up mobile if it is sleeping
			aController.acquireWakeLock(getApplicationContext());
			
			// Display message on the screen
			lblMessage.append(newMessage + "
");			
			
			Toast.makeText(getApplicationContext(), 
                           "Got Message: " + newMessage, 
                           Toast.LENGTH_LONG).show();
			
			// Releasing wake lock
			aController.releaseWakeLock();
		}
	};
	
	@Override
	protected void onDestroy() {
		// Cancel AsyncTask
		if (mRegisterTask != null) {
			mRegisterTask.cancel(true);
		}
		try {
			// Unregister Broadcast Receiver
			unregisterReceiver(mHandleMessageReceiver);
			
			//Clear internal resources.
			GCMRegistrar.onDestroy(this);
			
		} catch (Exception e) {
			Log.e("UnRegister Receiver Error", 
                      "> " + e.getMessage());
		}
		super.onDestroy();
	}

}

 

GCMIntentService.java

 

This class is defined as broadcast receiver in AndroidManifest.xml file.
extending class GCMBaseIntentService and overriding methods.
GCMBaseIntentService class methods automatically call when device is registering to GCM, unregistering to GCM , New push notification received from GCM or any error occoured.

When new push notification received on device overrided method onMessage() called and display message on screen and also create a notification.

 



package com.androidexample.gcm;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.google.android.gcm.GCMBaseIntentService;

public class GCMIntentService extends GCMBaseIntentService {

	private static final String TAG = "GCMIntentService";
	
	private Controller aController = null;

    public GCMIntentService() {
    	// Call extended class Constructor GCMBaseIntentService
        super(Config.GOOGLE_SENDER_ID);
    }

    /**
     * Method called on device registered
     **/
    @Override
    protected void onRegistered(Context context, String registrationId) {
    	
    	//Get Global Controller Class object (see application tag in AndroidManifest.xml)
    	if(aController == null)
           aController = (Controller) getApplicationContext();
    	
        Log.i(TAG, "Device registered: regId = " + registrationId);
        aController.displayMessageOnScreen(context, 
                                           "Your device registred with GCM");
        Log.d("NAME", MainActivity.name);
        aController.register(context, MainActivity.name, 
                               MainActivity.email, registrationId);
    }

    /**
     * Method called on device unregistred
     * */
    @Override
    protected void onUnregistered(Context context, String registrationId) {
    	if(aController == null)
            aController = (Controller) getApplicationContext();
        Log.i(TAG, "Device unregistered");
        aController.displayMessageOnScreen(context, 
                                            getString(R.string.gcm_unregistered));
        aController.unregister(context, registrationId);
    }

    /**
     * Method called on Receiving a new message from GCM server
     * */
    @Override
    protected void onMessage(Context context, Intent intent) {
    	
    	if(aController == null)
            aController = (Controller) getApplicationContext();
    	
        Log.i(TAG, "Received message");
        String message = intent.getExtras().getString("price");
        
        aController.displayMessageOnScreen(context, message);
        // notifies user
        generateNotification(context, message);
    }

    /**
     * Method called on receiving a deleted message
     * */
    @Override
    protected void onDeletedMessages(Context context, int total) {
    	
    	if(aController == null)
            aController = (Controller) getApplicationContext();
    	
        Log.i(TAG, "Received deleted messages notification");
        String message = getString(R.string.gcm_deleted, total);
        aController.displayMessageOnScreen(context, message);
        // notifies user
        generateNotification(context, message);
    }

    /**
     * Method called on Error
     * */
    @Override
    public void onError(Context context, String errorId) {
    	
    	if(aController == null)
            aController = (Controller) getApplicationContext();
    	
        Log.i(TAG, "Received error: " + errorId);
        aController.displayMessageOnScreen(context, 
                                   getString(R.string.gcm_error, errorId));
    }

    @Override
    protected boolean onRecoverableError(Context context, String errorId) {
    	
    	if(aController == null)
            aController = (Controller) getApplicationContext();
    	
        // log message
        Log.i(TAG, "Received recoverable error: " + errorId);
        aController.displayMessageOnScreen(context, 
                        getString(R.string.gcm_recoverable_error,
                        errorId));
        return super.onRecoverableError(context, errorId);
    }

    /**
     * Create a notification to inform the user that server has sent a message.
     */
    private static void generateNotification(Context context, String message) {
    
        int icon = R.drawable.ic_launcher;
        long when = System.currentTimeMillis();
        
        NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = new Notification(icon, message, when);
        
        String title = context.getString(R.string.app_name);
        
        Intent notificationIntent = new Intent(context, MainActivity.class);
        // set intent so it does not start a new activity
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
                Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent =
                PendingIntent.getActivity(context, 0, notificationIntent, 0);
        notification.setLatestEventInfo(context, title, message, intent);
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        
        // Play default notification sound
        notification.defaults |= Notification.DEFAULT_SOUND;
        
        //notification.sound = Uri.parse(
                               "android.resource://" 
                               + context.getPackageName() 
                               + "your_sound_file_name.mp3");
        
        // Vibrate if vibrate is enabled
        notification.defaults |= Notification.DEFAULT_VIBRATE;
        notificationManager.notify(0, notification);      

    }

}


 

 

 

/*************************** STEP3 END ***************************/

 

 

Step 4. Create server side code to save Google Cloud Messaging registration id in our database and send push notification to device.

 

a. Creating MySQL Database :

 

  

1.  Open phpmyadmin panel by open to http://localhost/phpmyadmin and create a database called gcm. (if your localhost is running on port number add port number to url)
  

2.   After creating the database, select the database and execute following query in SQL tab to create gcm_users table.



CREATE TABLE IF NOT EXISTS `gcm_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `gcm_regid` text,
  `name` varchar(50) NOT NULL,
  `email` varchar(255) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;


 

b. Creating PHP Files :

 

config.php

 

Define database connection and GOOGLE_API_KEY values.

 


<?php

// Database config variables
define("DB_HOST", "localhost");
define("DB_USER", "xxxxxxxxx");
define("DB_PASSWORD", "xxxxxxx");
define("DB_DATABASE", "gcm");

// Google Cloud Messaging API Key
// Place your Google API Key
define("GOOGLE_API_KEY", "AIzaSyA81yS1VSj1WZXY_T"); 
                          
?>

 

function.php

 

This file contains functions :

  storeUser() : Storing new registered user detail in our database.

  getAllUsers() : Get all registered users in database.

  isUserExisted() : Check user data is already is our database or not.

  send_push_notification() : Using curl sending request to https://android.googleapis.com/gcm/send with GCM registration ID and message.

NOTE :

 

curl is php extension , Enable this extension for php open configuration file php.ini(C:wampinapacheApache2.2.17in) and search for php_curl.dll , and remove semicolon (;) before extension=php_curl.dll line and restart wamp server.

 


<?php

   //Storing new user and returns user details
   
   function storeUser($name, $email, $gcm_regid) {
	   
        // insert user into database
        $result = mysql_query(
                      "INSERT INTO gcm_users
                            (name, email, gcm_regid, created_at) 
                            VALUES
                            ('$name', 
                             '$email', 
                             '$gcm_regid', 
                             NOW())");
		
        // check for successful store
        if ($result) {
			
            // get user details
            $id = mysql_insert_id(); // last inserted id
            $result = mysql_query(
                               "SELECT * 
                                     FROM gcm_users 
                                     WHERE id = $id") or die(mysql_error());
            // return user details 
            if (mysql_num_rows($result) > 0) { 
                return mysql_fetch_array($result);
            } else {
                return false;
            }
			
        } else {
            return false;
        }
    }

    /**
     * Get user by email
     */
   function getUserByEmail($email) {
        $result = mysql_query("SELECT * 
                                    FROM gcm_users 
                                    WHERE email = '$email' 
                                    LIMIT 1");
        return $result;
    }

    // Getting all registered users
  function getAllUsers() {
        $result = mysql_query("select * 
                                    FROM gcm_users");
        return $result;
    }

    // Validate user
  function isUserExisted($email) {
        $result    = mysql_query("SELECT email 
                                       from gcm_users 
                                       WHERE email = '$email'");
                                       
        $NumOfRows = mysql_num_rows($result);
        if ($NumOfRows > 0) {
            // user existed
            return true;
        } else {
            // user not existed
            return false;
        }
    }
	
	//Sending Push Notification
   function send_push_notification($registatoin_ids, $message) {
        

        // Set POST variables
        $url = 'https://android.googleapis.com/gcm/send';

        $fields = array(
            'registration_ids' => $registatoin_ids,
            'data' => $message,
        );

        $headers = array(
            'Authorization: key=' . GOOGLE_API_KEY,
            'Content-Type: application/json'
        );
		//print_r($headers);
        // Open connection
        $ch = curl_init();

        // Set the url, number of POST vars, POST data
        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        // Disabling SSL Certificate support temporarly
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

        // Execute post
        $result = curl_exec($ch);
        if ($result === FALSE) {
            die('Curl failed: ' . curl_error($ch));
        }

        // Close connection
        curl_close($ch);
        echo $result;
    }
?>

 

loader.php

 

include function and config file and create database connection.

 


<?php
require_once('config.php');
require_once('function.php');

// connecting to mysql
$conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
// selecting database
if(!mysql_select_db(DB_DATABASE))
  print "Not connected with database.";
?>

 

register.php

 

Store new device GCM registration details to database on our web server.

 


<?php
require_once('loader.php');

// return json response 
$json = array();

$nameUser  = $_POST["name"];
$nameEmail = $_POST["email"];

// GCM Registration ID got from device
$gcmRegID  = $_POST["regId"]; 

/**
 * Registering a user device in database
 * Store reg id in users table
 */
if (isset($nameUser) 
     && isset($nameEmail) 
     && isset($gcmRegID)) {
    
	// Store user details in db
    $res = storeUser($nameUser, $nameEmail, $gcmRegID);

    $registatoin_ids = array($gcmRegID);
    $message = array("product" => "shirt");

    $result = send_push_notification($registatoin_ids, $message);

    echo $result;
} else {
    // user details not found
}
?>

 

index.php

 

Create page to show all registered user , and forms to send push notification on devices.

File index.php code output screensshot


server_number_of_devices_registered

 


<?php
   require_once('loader.php');
   
    $resultUsers =  getAllUsers();
	if ($resultUsers != false)
		$NumOfUsers = mysql_num_rows($resultUsers);
	else
		$NumOfUsers = 0;
?>
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function(){
               
            });
            function sendPushNotification(id){
                var data = $('form#'+id).serialize();
                $('form#'+id).unbind('submit');                
                $.ajax({
                    url: "send_push_notification_message.php",
                    type: 'GET',
                    data: data,
                    beforeSend: function() {
                        
                    },
                    success: function(data, textStatus, xhr) {
                          $('.push_message').val("");
                    },
                    error: function(xhr, textStatus, errorThrown) {
                        
                    }
                });
                return false;
            }
        </script>
        <style type="text/css">
            
            h1{
                font-family:Helvetica, Arial, sans-serif;
                font-size: 24px;
                color: #777;
            }
            div.clear{
                clear: both;
            }
            
            textarea{
                float: left;
                resize: none;
            }
            
        </style>
    </head>
    <body>
        
        
        <table  width="910" cellpadding="1" cellspacing="1" style="padding-left:10px;">
         <tr>
           <td align="left">
              <h1>No of Devices Registered: <?php echo $NumOfUsers; ?></h1>
              <hr/>
           </td>
          </tr> 
          <tr>
            <td align="center">
              <table width="100%" cellpadding="1" 
                        cellspacing="1" 
                        style="border:1px solid #CCC;" bgcolor="#f4f4f4">
                <tr>
                  
       <?php
        if ($NumOfUsers > 0) {
            $i=1;
            while ($rowUsers = mysql_fetch_array($resultUsers)) {
                if($i%3==0)
                  print "</tr><tr><td colspan='2'> </td></tr><tr>";
         ?>
                <td align="left">
                     <form id="<?php echo $rowUsers["id"] ?>" 
                           name="" method="post" 
                           onSubmit="return sendPushNotification('<?php echo $rowUsers["id"] ?>')">
                        <label><b>Name:</b> </label> <span><?php echo $rowUsers["name"] ?></span>
                        <div class="clear"></div>
                        <label><b>Email:</b></label> <span><?php echo $rowUsers["email"] ?></span>
                        <div class="clear"></div>
                        <div class="send_container">                                
                            <textarea rows="3" 
                                   name="message" 
                                   cols="25" class="push_message" 
                                   placeholder="Type push message here"></textarea>
                            <input type="hidden" name="regId" 
                                      value="<?php echo $rowUsers["gcm_regid"] ?>"/>
                            <input type="submit"  
                                      value="Send Push Notification" onClick=""/>
                        </div>
                    </form>
                 </td>
            <?php }
        } else { ?> 
              <td>
                User not exist.
               </td>
        <?php } ?>
                    
                </tr>
                </table>
            </td>
          </tr>  
        </table>
        
        
    </body>
</html>

 

send_push_notification_message.php

 

Call send_push_notification function defined in function.php

 


<?php

 require_once('loader.php');

	$gcmRegID    = $_GET["regId"]; // GCM Registration ID got from device
	$pushMessage = $_GET["message"];
	
	if (isset($gcmRegID) && isset($pushMessage)) {
		
		
		$registatoin_ids = array($gcmRegID);
		$message = array("price" => $pushMessage);
	
		$result = send_push_notification($registatoin_ids, $message);
	
		echo $result;
	}
?>