How to use GCM in Android
Posted By : Chandan Wadhwa | 27-Mar-2015
Google cloud messaging is a free service provided by Google which allows you to send data from server to Android device and also from android device to server. This could be a lightweight message telling the client app that there is new data to be fetched from the server (for instance, a "new email" notification informing the app that it is out of sync with the back end), or it could be a message. The GCM service handles all aspects of queueing of messages and delivery to and from the target client app.
Overview of architecture
-
GCM Connection Servers which is provided by google take messages from a 3rd-party app server and send these messages to a GCM-enabled client app.
-
The 3rd-Party App Server is a component that you implement to work with your chosen GCM connection server and messages to a GCM connection server.
-
The Client App is a GCM-enabled client app to receive GCM messages.
Steps to create client app for Android
-
Open Google Developers Console(https://console.developers.google.com/) and create Api project.
-
After creating project a page appears that displays your project ID and project number copy down your project number you will use it later.
Enabling the GCM Service
In the sidebar select APIs & auth and turn on the Google Cloud Messaging for Android from the list of API's.
Obtaining an API Key
-
select APIs & auth > Credentials and under Public API access, click create new key >Server key.
-
In Dialog box supply your server's IP address. For testing purposes, you can use 0.0.0.0/0 and click create.
-
Copy the API key you will use it later for authentication with server.
Set Up Google Play Services SDK
Open SDK Manager and install Google play services if not already and add to your IDE projects as a library project(sdk/extras/google/google_play_services) after this add to your GCM app project as a library project.
Add the following to your Application's Manifest
Add this inside manifest tag
Add this inside application tag
Now add the following broadcast receiver to receive GCM messages
Add the following service for checking GCM messages in background
Create class for BroadcastReceiver (GcmBroadcastReceiver) and add code for receiver
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
Create class for Service(GcmIntentService) and following code
public class GcmIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public static final String SENDER_ID ="write sender id which you have generate earlier";
public GcmIntentService() {
super(SENDER_ID);
}
// intent come in in your onReceive method of your BroadcastReceiver:
public void onReceive(Context context, Intent intent) {
// check to see if it is a message
if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
String id = intent.getExtras().getString("id");
String other_key = intent.getExtras().getString("other_key");
// if your key/value is a JSON string, just extract it and parse it using JSONObject
String json_info = intent.getExtras().getString("json_info");
//JSONObject jsonObj = new JSONObject(json_info);
Log.d("Message Respinse --->",json_info);
}
}
@Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
if (GoogleCloudMessaging.
MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_DELETED.equals(messageType)) {
sendNotification("Deleted messages on server: " +
extras.toString());
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_MESSAGE.equals(messageType)) {
// This loop represents the service doing some work.
for (int i=0; i<5; i++) {
Log.i("Msg", "Working... " + (i+1)
+ "/5 @ " + SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
Log.i("Msg", "Completed work @ " + SystemClock.elapsedRealtime());
// Post notification of received message.
sendNotification("Received: " + extras.toString());
Log.i("Msg", "Received: " + extras.toString());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
MainActivity
public class MainActivity extends Activity { public static final String EXTRA_MESSAGE = "message"; public static final String PROPERTY_REG_ID = "registration_id"; private static final String PROPERTY_APP_VERSION = "appVersion"; private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; String SENDER_ID = "project number you got from the API Console"; static final String TAG = "GCMDemo"; GoogleCloudMessaging gcm; AtomicInteger msgId = new AtomicInteger(); SharedPreferences prefs; Context context; String regid; @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = getApplicationContext(); // Check device for Play Services APK. If check succeeds, proceed with // GCM registration. if (checkPlayServices()) { gcm = GoogleCloudMessaging.getInstance(this); regid = getRegistrationId(context); Log.d("Registration ID ",regid+""); if (regid.isEmpty()) { registerInBackground(); } } else { Log.d(TAG, "No valid Google Play Services APK found."); } } private boolean checkPlayServices() { int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (resultCode != ConnectionResult.SUCCESS) { if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) { GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_RESOLUTION_REQUEST).show(); } else { Log.i(TAG, "This device is not supported."); finish(); } return false; } return true; } @SuppressLint("NewApi") private String getRegistrationId(Context context) { final SharedPreferences prefs = getGCMPreferences(context); String registrationId = prefs.getString(PROPERTY_REG_ID, ""); if (registrationId.isEmpty()) { Log.i(TAG, "Registration not found."); return ""; } int registeredVersion = prefs.getInt(PROPERTY_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) { // should never happen throw new RuntimeException("Could not get package name: " + e); } } private SharedPreferences getGCMPreferences(Context context) { return getSharedPreferences(MainActivity.class.getSimpleName(), Context.MODE_PRIVATE); } private void registerInBackground() { new AsyncTask() { @Override protected String doInBackground(Void... params) { String msg = ""; try { if (gcm == null) { gcm = GoogleCloudMessaging.getInstance(context); } regid = gcm.register(SENDER_ID); msg = "Device registered, registration ID=" + regid; Log.d("Device Reg ID",regid); storeRegistrationId(context, regid); } catch (IOException ex) { msg = "Error :" + ex.getMessage(); } return msg; } @Override protected void onPostExecute(String msg) { Toast.makeText(getApplicationContext(), msg,Toast.LENGTH_SHORT).show(); } }.execute(null, null, null); } private void storeRegistrationId(Context context, String regId) { final SharedPreferences prefs = getGCMPreferences(context); int appVersion = getAppVersion(context); Log.i(TAG, "Saving regId on app version " + appVersion); SharedPreferences.Editor editor = prefs.edit(); editor.putString(PROPERTY_REG_ID, regId); editor.putInt(PROPERTY_APP_VERSION, appVersion); editor.commit(); } /** * Receiving push messages * */ private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String newMessage = intent.getExtras().getString(EXTRA_MESSAGE); Toast.makeText(getApplicationContext(), "New Message: " + newMessage, Toast.LENGTH_LONG).show(); } };
Thanks
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Chandan Wadhwa
Chandan is an Android Apps developer with good experience in building native Android applications.