Android Push Notifications using Google Cloud Messaging – Part I

I recently implemented push notifications using GCM (Google Cloud Messaging) server for my android app Superjokes – Free Funny Jokes . This tutorial will show you how to make push notifications with images and how to send them to multiple devices through GCM.

There are three parts to this tutorial.

  • Get a device registered in GCM server and send a simple push notification to the device.
  • Send a simple push notification to multiple devices at once.
  • Send a push notification with custom layout containing an image.

As this is the first part I would like you to follow an excellent tutorial by Ravi Tamada. Click here to go there first and complete this. This tutorial is the pre requisite for my tutorial.

In Ravi Tamada’s tutorial , you can see that he has created a database table that takes email and name as user input. I removed those two as they are not necessary for my usage. The new query for creating the SQL query will be like this

[code language=”sql”]
<div class="container">
<div class="line number1 index0 alt2"><code class="sql keyword">CREATE</code> <code class="sql keyword">TABLE</code> <code class="sql plain">IF </code><code class="sql color1">NOT</code> <code class="sql plain">EXISTS `gcm_users` (</code></div>
<div class="line number2 index1 alt1"><code class="sql spaces">  </code><code class="sql plain">`id` </code><code class="sql keyword">int</code><code class="sql plain">(11) </code><code class="sql color1">NOT</code> <code class="sql color1">NULL</code> <code class="sql plain">AUTO_INCREMENT,</code></div>
<div class="line number3 index2 alt2"><code class="sql spaces">  </code><code class="sql plain">`gcm_regid` text,</code></div>
<div class="line number6 index5 alt1"><code class="sql spaces">  </code><code class="sql plain">`created_at` </code><code class="sql keyword">timestamp</code> <code class="sql color1">NOT</code> <code class="sql color1">NULL</code> <code class="sql keyword">DEFAULT</code> <code class="sql color2">CURRENT_TIMESTAMP</code><code class="sql plain">,</code></div>
<div class="line number7 index6 alt2"><code class="sql spaces">  </code><code class="sql keyword">PRIMARY</code> <code class="sql keyword">KEY</code> <code class="sql plain">(`id`)</code></div>
<div class="line number8 index7 alt1"><code class="sql plain">) ENGINE=InnoDB </code><code class="sql keyword">DEFAULT</code> <code class="sql plain">CHARSET=latin1 AUTO_INCREMENT=1 ;</code></div>
<div class="line number8 index7 alt1"></div>
</div>
[/code]

 

Now to store a new user in the database we will change the file db_functions.php. This file has a function named storeUser. We will edit this function to be the following.

[code language=”java”]

public function storeUser($gcm_regid) {

// insert user into database
$result = mysql_query("INSERT INTO gcm_users_new(gcm_regid, created_at) VALUES(‘$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_new 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;
}
}

[/code]

In the tutorial linked above, the client side code given has to be changed as well as it also takes name and email for the device registration purpose. In the tutorial, two activities MainActivity and RegisterActivity are given. In the MainActivity inside mRegisterTask asynctask, a method called ServerUtilities.register is called. We will change this method in the ServerUtilities class to only accept context and registrationId. Similarily for the unregister method, you would remove the name and email parameters. Following is the code for both:

[code language=”java”]

public static void register(final Context context,  final String regId) {
Log.i(TAG, "registering device (regId = " + regId + ")");
String serverUrl = SERVER_URL;
Map<String, String> params = new HashMap<String, String>();
params.put("regId", regId);

long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);

for (int i = 1; i <= MAX_ATTEMPTS; i++) {
Log.d(TAG, "Attempt #" + i + " to register");
try {
displayMessage(context, context.getString(
R.string.server_registering, i, MAX_ATTEMPTS));
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, true);
String message = context.getString(R.string.server_registered);
CommonUtilities.displayMessage(context, message);
return;
} catch (IOException e) {

Log.e(TAG, "Failed to register on attempt " + i + ":" + e);
if (i == MAX_ATTEMPTS) {
break;
}
try {
Log.d(TAG, "Sleeping for " + backoff + " ms before retry");
Thread.sleep(backoff);
} catch (InterruptedException e1) {
// Activity finished before we complete – exit.
Log.d(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);
CommonUtilities.displayMessage(context, message);
}

</div>
&nbsp;

static void unregister(final Context context, final String regId) {
Log.i(TAG, "unregistering device (regId = " + regId + ")");
String serverUrl = 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);
CommonUtilities.displayMessage(context, message);
} catch (IOException e) {

String message = context.getString(R.string.server_unregister_error,
e.getMessage());
CommonUtilities.displayMessage(context, message);
}
}
<div class="line number8 index7 alt1">

[/code]

Leave a Comment