blob: 42cebfcbb9046d7c3218a9b4a191f390b4d2c3f5 [file] [log] [blame]
Katie McCormick0ab93262013-11-01 18:10:51 -07001page.title=Implementing GCM Client
kmccormickf788ac12013-05-30 19:06:41 -07002page.tags="cloud","push","messaging"
3@jd:body
4
5<div id="qv-wrapper">
6<div id="qv">
7
Katie McCormick0ab93262013-11-01 18:10:51 -07008
9<h2>In this document</h2>
10
11<ol class="toc">
12<li><a href="#play-services">Set Up Google Play Services</a></li>
13<li><a href="#manifest">Edit Your Application's Manifest</a></li>
14<li><a href="#app">Write Your Application</a>
15 <ol class="toc">
16 <li><a href="#sample-play">Check for Google Play Services APK</a></li>
17 <li><a href="#sample-register">Register for GCM</a></li>
18 <li><a href="#sample-send">Send a message</a></li>
19 <li><a href="#sample-receive">Receive a message</a></li>
20 </ol>
21 <li><a href="#run">Running the Sample</a></li>
22 <li><a href="#stats">Viewing Statistics</a></li>
23</li>
24
25</ol>
26
kmccormickf788ac12013-05-30 19:06:41 -070027<h2>See Also</h2>
28
29<ol class="toc">
30<li><a href="gs.html">Getting Started</a></li>
Katie McCormick0ab93262013-11-01 18:10:51 -070031<li><a href="server.html">Implementing GCM Server</a></li>
kmccormickf788ac12013-05-30 19:06:41 -070032</ol>
33
34</div>
35</div>
36
Katie McCormick0ab93262013-11-01 18:10:51 -070037<p>A GCM client is a GCM-enabled app that runs on an Android device. To write your
38client code, we recommend that you use the
39<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
40{@code GoogleCloudMessaging}</a> APIs.
41The client helper library that was offered in previous versions of GCM still works,
42but it has been superseded by the more efficient
43<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
44{@code GoogleCloudMessaging}</a> APIs.</p>
kmccormickf788ac12013-05-30 19:06:41 -070045
Katie McCormick0ab93262013-11-01 18:10:51 -070046<p>A full GCM implementation requires both a client implementation and a server
47implementation. For more
48information about implementing the server side, see <a href="server.html">
49Implementing GCM Server</a>.</p>
kmccormickf788ac12013-05-30 19:06:41 -070050
Katie McCormick0ab93262013-11-01 18:10:51 -070051<p>The following sections walk you through the steps involved in writing a GCM
52client-side application. Your client app can be arbitrarily complex, but at bare
53minimum, a GCM client app must include code to register (and thereby get a
54registration ID), and a broadcast receiver to receive messages sent by GCM.
55</p>
56
57<h2 id="play-services">Step 1: Set Up Google Play Services</h2>
58
59<p>To write your client application, use the
60<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
61{@code GoogleCloudMessaging}</a> API.
62To use this API, you must set up your project to use the Google Play services SDK,
63as described in <a href="/google/play-services/setup.html">Setup Google Play
64Services SDK</a>.</p>
65
66<p class="note"><strong>Caution:</strong> When you add the Play Services library to
67your project, be sure to add it <em>with resources</em>, as described in
68<a href="{@docRoot}google/play-services/setup.html#Setup">
69Setup Google Play Services SDK</a>. The key point is that you must
70<em>reference</em> the library&mdash;simply adding a {@code .jar} file to
71your Eclipse project will not work. You must follow the directions
72for referencing a library, or your app won't be able to access
73the library's resources, and it won't run properly.
74If you're using Android Studio, this is the string to add to the
75{@code dependency} section of your application's {@code build.gradle} file:</p>
76
77<pre>dependencies {
Katie McCormick63b2b8c2014-02-07 17:36:03 -080078 compile "com.google.android.gms:play-services:3.1.+"
Katie McCormick0ab93262013-11-01 18:10:51 -070079}
80</pre>
81
82
83<h2 id="manifest">Step 2: Edit Your Application's Manifest</h2>
84
85<p>Add the following to your application's manifest:</p>
86<ul>
87 <li>The <code>com.google.android.c2dm.permission.RECEIVE</code> permission so
88the Android application can register and receive messages.</li>
89 <li>The <code>android.permission.INTERNET</code> permission so the Android
90application can send the registration ID to the 3rd party server.</li>
91 <li>The <code>android.permission.GET_ACCOUNTS</code> permission as GCM requires
92a Google account (necessary only if if the device is running a version lower than
93Android 4.0.4)</li>
94 <li>The <code>android.permission.WAKE_LOCK</code> permission so the application
95can keep the processor from sleeping when a message is received. Optional&mdash;use
96only if the app wants to keep the device from sleeping.</li>
97 <li>An <code>applicationPackage + &quot;.permission.C2D_MESSAGE&quot;</code>
98permission to prevent other Android applications from registering and receiving
99the Android application's messages. The permission name must exactly match this
100pattern&mdash;otherwise the Android application will not receive the messages.</li>
101 <li>A receiver for <code>com.google.android.c2dm.intent.RECEIVE</code>, with
102the category set
103as <code>applicationPackage</code>. The receiver should require the
104<code>com.google.android.c2dm.SEND</code> permission, so that only the GCM
105Framework can send a message to it. If your app uses an {@link android.app.IntentService}
106(not required, but a common pattern), this receiver should be an instance of
107{@link android.support.v4.content.WakefulBroadcastReceiver}.
108A {@link android.support.v4.content.WakefulBroadcastReceiver} takes care of
109creating and managing a
110<a href="{@docRoot}reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK">
111partial wake lock</a> for your app.</li>
112
113<li>A {@link android.app.Service} (typically an {@link android.app.IntentService})
114to which the {@link android.support.v4.content.WakefulBroadcastReceiver} passes off
115the work of handling the GCM message, while ensuring that the device does not
116go back to sleep in the process. Including an {@link android.app.IntentService} is
117optional&mdash;you could choose to process your messages in a regular
118{@link android.content.BroadcastReceiver} instead, but realistically, most apps will
119use a {@link android.app.IntentService}.
120</li>
121 <li>If the GCM feature is critical to the Android application's function, be sure to
122set <code>android:minSdkVersion=&quot;8&quot;</code> or higher in the manifest. This
123ensures that the Android application cannot be installed in an environment in which it
124could not run properly. </li>
125</ul>
126
127<p>Here are excerpts from a sample manifest that supports GCM:</p>
128
129<pre class="prettyprint pretty-xml">
130&lt;manifest package="com.example.gcm" ...&gt;
131
132 &lt;uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/&gt;
133 &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
134 &lt;uses-permission android:name="android.permission.GET_ACCOUNTS" /&gt;
135 &lt;uses-permission android:name="android.permission.WAKE_LOCK" /&gt;
136 &lt;uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /&gt;
137
138 &lt;permission android:name="com.example.gcm.permission.C2D_MESSAGE"
139 android:protectionLevel="signature" /&gt;
140 &lt;uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" /&gt;
141
142 &lt;application ...&gt;
143 &lt;receiver
144 android:name=".GcmBroadcastReceiver"
145 android:permission="com.google.android.c2dm.permission.SEND" &gt;
146 &lt;intent-filter&gt;
147 &lt;action android:name="com.google.android.c2dm.intent.RECEIVE" /&gt;
148 &lt;category android:name="com.example.gcm" /&gt;
149 &lt;/intent-filter&gt;
150 &lt;/receiver&gt;
151 &lt;service android:name=".GcmIntentService" /&gt;
152 &lt;/application&gt;
153
154&lt;/manifest&gt;
155</pre>
156
157<h2 id="app"> Step 3: Write Your Application</h2>
158
159<p>Finally, write your application. This section features a sample client
160application that illustrates how to use the
161<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
162{@code GoogleCloudMessaging}</a> APIs. The sample consists of a main activity
163({@code DemoActivity}), a {@link android.support.v4.content.WakefulBroadcastReceiver}
164({@code GcmBroadcastReceiver}), and an {@link android.app.IntentService}
165({@code GcmIntentService}). You can find the complete source code for this sample at the
166<a href="http://code.google.com/p/gcm">open source site</a>.</p>
167
168<p>Note the following:</p>
169
170<ul>
171 <li>Among other things, the sample illustrates registration and upstream
172(device-to-cloud) messaging. Upstream messaging only applies to apps that are running against a
173<a href="ccs.html">CCS</a> (XMPP) server; HTTP-based servers don't support upstream messaging.</li>
174 <li>The <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
175 {@code GoogleCloudMessaging}</a>
176registration APIs replace the old registration process, which was based on the
177now-obsolete client helper library. While the old registration process still works,
178we encourage you to use the newer
179<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
180{@code GoogleCloudMessaging}</a>
181registration APIs, regardless of your underlying server.</li>
182</ul>
183
184<h3 id="sample-play">Check for Google Play Services APK</h3>
185
186<p>As described in <a href="{@docRoot}google/play-services/setup.html">
187Setup Google Play Services SDK</a>, apps that rely on the Play Services SDK
188should always check the device for a compatible Google Play services APK before
189accessing Google Play services features. In the sample app this check is done in
190two places: in the main activity's {@code onCreate()} method, and in its
191{@code onResume()} method. The check in {@code onCreate()} ensures that the app
192can't be used without a successful check. The check in {@code onResume()} ensures
193that if the user returns to the running app through some other means, such as
194through the back button, the check is still performed. If the
195device doesn't have a compatible Google Play services APK, your app can call
196{@code GooglePlayServicesUtil.getErrorDialog()} to allow users to download the
197APK from the Google Play Store or enable it in the device's system settings.
198For example:</p>
199
200<pre>private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
201...
202&#64;Override
203public void onCreate(Bundle savedInstanceState) {
204 super.onCreate(savedInstanceState);
205
206 setContentView(R.layout.main);
207 mDisplay = (TextView) findViewById(R.id.display);
208
209 context = getApplicationContext();
210
211 // Check device for Play Services APK.
212 if (checkPlayServices()) {
213 // If this check succeeds, proceed with normal processing.
214 // Otherwise, prompt user to get valid Play Services APK.
215 ...
216 }
217}
218
219// You need to do the Play Services APK check here too.
220&#64;Override
221protected void onResume() {
222 super.onResume();
223 checkPlayServices();
224}
225
226/**
227 * Check the device to make sure it has the Google Play Services APK. If
228 * it doesn't, display a dialog that allows users to download the APK from
229 * the Google Play Store or enable it in the device's system settings.
230 */
231private boolean checkPlayServices() {
232 int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
233 if (resultCode != ConnectionResult.SUCCESS) {
234 if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
235 GooglePlayServicesUtil.getErrorDialog(resultCode, this,
236 PLAY_SERVICES_RESOLUTION_REQUEST).show();
237 } else {
238 Log.i(TAG, "This device is not supported.");
239 finish();
240 }
241 return false;
242 }
243 return true;
244}</pre>
245
246<h3 id="sample-register">Register for GCM</h3>
247<p>An Android application needs to register with GCM servers before it can receive
248messages. When an app registers, it receives a registration ID, which it can then
249store for future use. In the following snippet the {@code onCreate()} method in the sample app's
250main activity checks to see if the app is already registered with GCM and with
251the server:</p>
252
253<pre>/**
254 * Main UI for the demo app.
255 */
256public class DemoActivity extends Activity {
257
258 public static final String EXTRA_MESSAGE = "message";
259 public static final String PROPERTY_REG_ID = "registration_id";
260 private static final String PROPERTY_APP_VERSION = "appVersion";
261 private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
262
263 /**
264 * Substitute you own sender ID here. This is the project number you got
265 * from the API Console, as described in "Getting Started."
266 */
267 String SENDER_ID = "Your-Sender-ID";
268
269 /**
270 * Tag used on log messages.
271 */
272 static final String TAG = "GCMDemo";
273
274 TextView mDisplay;
275 GoogleCloudMessaging gcm;
276 AtomicInteger msgId = new AtomicInteger();
277 SharedPreferences prefs;
278 Context context;
279
280 String regid;
281
282 &#64;Override
283 public void onCreate(Bundle savedInstanceState) {
284 super.onCreate(savedInstanceState);
285
286 setContentView(R.layout.main);
287 mDisplay = (TextView) findViewById(R.id.display);
288
289 context = getApplicationContext();
290
291 // Check device for Play Services APK. If check succeeds, proceed with
292 // GCM registration.
293 if (checkPlayServices()) {
294 gcm = GoogleCloudMessaging.getInstance(this);
295 regid = getRegistrationId(context);
296
297 if (regid.isEmpty()) {
298 registerInBackground();
299 }
300 } else {
301 Log.i(TAG, "No valid Google Play Services APK found.");
302 }
303 }
304...
305}</pre>
306
307<p>The app calls {@code getRegistrationId()} to see whether there is an existing
308registration ID stored in shared preferences:</p>
309
310<pre>/**
311 * Gets the current registration ID for application on GCM service.
312 * &lt;p&gt;
313 * If result is empty, the app needs to register.
314 *
315 * &#64;return registration ID, or empty string if there is no existing
316 * registration ID.
317 */
318private String getRegistrationId(Context context) {
319 final SharedPreferences prefs = getGCMPreferences(context);
320 String registrationId = prefs.getString(PROPERTY_REG_ID, "");
321 if (registrationId.isEmpty()) {
322 Log.i(TAG, "Registration not found.");
323 return "";
324 }
325 // Check if app was updated; if so, it must clear the registration ID
326 // since the existing regID is not guaranteed to work with the new
327 // app version.
328 int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
329 int currentVersion = getAppVersion(context);
330 if (registeredVersion != currentVersion) {
331 Log.i(TAG, "App version changed.");
332 return "";
333 }
334 return registrationId;
335}
336...
337/**
338 * &#64;return Application's {&#64;code SharedPreferences}.
339 */
340private SharedPreferences getGCMPreferences(Context context) {
341 // This sample app persists the registration ID in shared preferences, but
342 // how you store the regID in your app is up to you.
343 return getSharedPreferences(DemoActivity.class.getSimpleName(),
344 Context.MODE_PRIVATE);
345}</pre>
346
347<p>If the registration ID doesn't exist or the app was updated,
348{@code getRegistrationId()} returns an empty string
349to indicate that the app needs to get a new regID. {@code getRegistrationId()} calls
350the following method to check the app version:</p>
351
352<pre>/**
353 * &#64;return Application's version code from the {&#64;code PackageManager}.
354 */
355private static int getAppVersion(Context context) {
356 try {
357 PackageInfo packageInfo = context.getPackageManager()
358 .getPackageInfo(context.getPackageName(), 0);
359 return packageInfo.versionCode;
360 } catch (NameNotFoundException e) {
361 // should never happen
362 throw new RuntimeException("Could not get package name: " + e);
363 }
364}</pre>
365
366
367<p>If there isn't a valid existing registration ID, {@code DemoActivity} calls the
368following {@code registerInBackground()} method to register. Note that because the GCM
369methods {@code register()} and {@code unregister()} are blocking, this has to
370take place on a background thread. This sample uses {@link android.os.AsyncTask}
371to accomplish this:</p>
372
373<pre>
374/**
375 * Registers the application with GCM servers asynchronously.
376 * &lt;p&gt;
377 * Stores the registration ID and app versionCode in the application's
378 * shared preferences.
379 */
380private void registerInBackground() {
381 new AsyncTask<Void, Void, String>() {
382 &#64;Override
383 protected String doInBackground(Void... params) {
384 String msg = "";
385 try {
386 if (gcm == null) {
387 gcm = GoogleCloudMessaging.getInstance(context);
388 }
389 regid = gcm.register(SENDER_ID);
390 msg = "Device registered, registration ID=" + regid;
391
392 // You should send the registration ID to your server over HTTP,
393 // so it can use GCM/HTTP or CCS to send messages to your app.
394 // The request to your server should be authenticated if your app
395 // is using accounts.
396 sendRegistrationIdToBackend();
397
398 // For this demo: we don't need to send it because the device
399 // will send upstream messages to a server that echo back the
400 // message using the 'from' address in the message.
401
402 // Persist the regID - no need to register again.
403 storeRegistrationId(context, regid);
404 } catch (IOException ex) {
405 msg = "Error :" + ex.getMessage();
406 // If there is an error, don't just keep trying to register.
407 // Require the user to click a button again, or perform
408 // exponential back-off.
409 }
410 return msg;
411 }
412
413 &#64;Override
414 protected void onPostExecute(String msg) {
415 mDisplay.append(msg + "\n");
416 }
417 }.execute(null, null, null);
418 ...
Katie McCormick6b372622013-11-15 16:02:58 -0800419}</pre>
420
421<p>Once you've received your registration ID, send it to your server:</p>
422<pre>
423/**
424 * Sends the registration ID to your server over HTTP, so it can use GCM/HTTP
425 * or CCS to send messages to your app. Not needed for this demo since the
426 * device sends upstream messages to a server that echoes back the message
427 * using the 'from' address in the message.
428 */
429private void sendRegistrationIdToBackend() {
430 // Your implementation here.
Katie McCormick0ab93262013-11-01 18:10:51 -0700431}</pre>
432
433<p>After registering, the app calls {@code storeRegistrationId()} to store the
434registration ID in shared preferences for future use. This is just one way of
435persisting a regID. You might choose to use a different approach in your app:</p>
436
437<pre>/**
438 * Stores the registration ID and app versionCode in the application's
439 * {&#64;code SharedPreferences}.
440 *
441 * &#64;param context application's context.
442 * &#64;param regId registration ID
443 */
444private void storeRegistrationId(Context context, String regId) {
445 final SharedPreferences prefs = getGCMPreferences(context);
446 int appVersion = getAppVersion(context);
447 Log.i(TAG, "Saving regId on app version " + appVersion);
448 SharedPreferences.Editor editor = prefs.edit();
449 editor.putString(PROPERTY_REG_ID, regId);
450 editor.putInt(PROPERTY_APP_VERSION, appVersion);
451 editor.commit();
452}</pre>
453
454<h3 id="sample-send">Send a message</h3>
455<p>When the user clicks the app's <strong>Send</strong> button, the app sends an
456upstream message using the
457<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
458{@code GoogleCloudMessaging}</a> APIs. In order to receive the upstream message,
459your server should be connected to CCS. You can use one of the demo servers in
460<a href="ccs.html#implement">Implementing an XMPP-based App Server</a> to run the sample and connect
461to CCS.</p>
462
463<pre>public void onClick(final View view) {
464 if (view == findViewById(R.id.send)) {
465 new AsyncTask<Void, Void, String>() {
466 &#64;Override
467 protected String doInBackground(Void... params) {
468 String msg = "";
469 try {
470 Bundle data = new Bundle();
471 data.putString("my_message", "Hello World");
472 data.putString("my_action",
473 "com.google.android.gcm.demo.app.ECHO_NOW");
474 String id = Integer.toString(msgId.incrementAndGet());
475 gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data);
476 msg = "Sent message";
477 } catch (IOException ex) {
478 msg = "Error :" + ex.getMessage();
479 }
480 return msg;
481 }
482
483 &#64;Override
484 protected void onPostExecute(String msg) {
485 mDisplay.append(msg + "\n");
486 }
487 }.execute(null, null, null);
488 } else if (view == findViewById(R.id.clear)) {
489 mDisplay.setText("");
490 }
491}</pre>
492
493<h3 id="sample-receive">Receive a message</h3>
494
495<p>As described above in <a href="#manifest">Step 2</a>, the app includes a
496{@link android.support.v4.content.WakefulBroadcastReceiver} for the <code>com.google.android.c2dm.intent.RECEIVE</code>
497intent. A broadcast receiver is the mechanism GCM uses to deliver messages. When {@code onClick()}
498calls {@code gcm.send()}, it triggers the broadcast receiver's {@code onReceive()}
499method, which has the responsibility of making sure that the GCM message gets handled.</p>
500<p>A {@link android.support.v4.content.WakefulBroadcastReceiver} is a special type of
501broadcast receiver that takes care of
502creating and managing a
503<a href="{@docRoot}reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK">
504partial wake lock</a> for your app.
505It passes off the work of processing the GCM message to a
506{@link android.app.Service} (typically an
507{@link android.app.IntentService}), while ensuring that the device does not
508go back to sleep in the transition. If you don't hold a wake lock while transitioning
509the work to a service, you are effectively allowing the device to go back to sleep before
510the work completes. The net result is that the app might not finish processing
511the GCM message until some arbitrary point in the future, which is not what you want.</p>
512
513<p class="note"><strong>Note:</strong> Using {@link android.support.v4.content.WakefulBroadcastReceiver}
514is not a requirement. If you have a relatively simple app that doesn't require
515a service, you can intercept the GCM message in a regular {@link android.content.BroadcastReceiver}
516and do your processing there. Once you get the intent that GCM passes into
517your broadcast receiver's {@code onReceive()} method, what you do with it
518is up to you.</p>
519
520<p>This snippet starts {@code GcmIntentService} with the method
521{@link android.support.v4.content.WakefulBroadcastReceiver#startWakefulService startWakefulService()}.
522This method is comparable to {@link android.content.Context#startService startService()}, except that
523the {@link android.support.v4.content.WakefulBroadcastReceiver} is holding a
524wake lock when the service starts. The intent that is passed with
525{@link android.support.v4.content.WakefulBroadcastReceiver#startWakefulService startWakefulService()}
526holds an extra identifying the wake lock:</p>
527
528
529<pre>public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
530 &#64;Override
531 public void onReceive(Context context, Intent intent) {
532 // Explicitly specify that GcmIntentService will handle the intent.
533 ComponentName comp = new ComponentName(context.getPackageName(),
534 GcmIntentService.class.getName());
535 // Start the service, keeping the device awake while it is launching.
536 startWakefulService(context, (intent.setComponent(comp)));
537 setResultCode(Activity.RESULT_OK);
538 }
539}</pre>
540
541<p>The intent service shown below does the actual work of handling the GCM
542message. When the service is finished, it calls
543{@link android.support.v4.content.WakefulBroadcastReceiver#completeWakefulIntent GcmBroadcastReceiver.completeWakefulIntent()}
544to release the wake lock. The
545{@link android.support.v4.content.WakefulBroadcastReceiver#completeWakefulIntent completeWakefulIntent()}
546method has as its parameter the same intent that was
547passed in from the {@link android.support.v4.content.WakefulBroadcastReceiver}.
548</p>
549
550<p>This snippet processes the GCM message based on message type, and posts the
551result in a notification. But what you do with GCM messages in your app is up to
552you&mdash;the possibilities are endless. For example, the message might be a ping,
553telling the app to sync to a server to retrieve new content, or it might be a
554chat message that you display in the UI.</p>
555
556<pre>
557public class GcmIntentService extends IntentService {
558 public static final int NOTIFICATION_ID = 1;
559 private NotificationManager mNotificationManager;
560 NotificationCompat.Builder builder;
561
562 public GcmIntentService() {
563 super("GcmIntentService");
564 }
565
566 &#64;Override
567 protected void onHandleIntent(Intent intent) {
568 Bundle extras = intent.getExtras();
569 GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
570 // The getMessageType() intent parameter must be the intent you received
571 // in your BroadcastReceiver.
572 String messageType = gcm.getMessageType(intent);
573
574 if (!extras.isEmpty()) { // has effect of unparcelling Bundle
575 /*
576 * Filter messages based on message type. Since it is likely that GCM
577 * will be extended in the future with new message types, just ignore
578 * any message types you're not interested in, or that you don't
579 * recognize.
580 */
581 if (GoogleCloudMessaging.
582 MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
583 sendNotification("Send error: " + extras.toString());
584 } else if (GoogleCloudMessaging.
585 MESSAGE_TYPE_DELETED.equals(messageType)) {
586 sendNotification("Deleted messages on server: " +
587 extras.toString());
588 // If it's a regular GCM message, do some work.
589 } else if (GoogleCloudMessaging.
590 MESSAGE_TYPE_MESSAGE.equals(messageType)) {
591 // This loop represents the service doing some work.
592 for (int i=0; i<5; i++) {
593 Log.i(TAG, "Working... " + (i+1)
594 + "/5 @ " + SystemClock.elapsedRealtime());
595 try {
596 Thread.sleep(5000);
597 } catch (InterruptedException e) {
598 }
599 }
600 Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
601 // Post notification of received message.
602 sendNotification("Received: " + extras.toString());
603 Log.i(TAG, "Received: " + extras.toString());
604 }
605 }
606 // Release the wake lock provided by the WakefulBroadcastReceiver.
607 GcmBroadcastReceiver.completeWakefulIntent(intent);
608 }
609
610 // Put the message into a notification and post it.
611 // This is just one simple example of what you might choose to do with
612 // a GCM message.
613 private void sendNotification(String msg) {
614 mNotificationManager = (NotificationManager)
615 this.getSystemService(Context.NOTIFICATION_SERVICE);
616
617 PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
618 new Intent(this, DemoActivity.class), 0);
619
620 NotificationCompat.Builder mBuilder =
621 new NotificationCompat.Builder(this)
622 .setSmallIcon(R.drawable.ic_stat_gcm)
623 .setContentTitle("GCM Notification")
624 .setStyle(new NotificationCompat.BigTextStyle()
625 .bigText(msg))
626 .setContentText(msg);
627
628 mBuilder.setContentIntent(contentIntent);
629 mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
630 }
631}</pre>
632
633<h2 id="run">Running the Sample</h2>
634
635<p>To run the sample:</p>
636
637<ol>
638 <li>Follow the instructions in <a href="gs.html">Getting Started</a> to get your sender ID and
639 API key.</li>
640 <li>Implement your client app, as described in this document. You can find the complete source
641 code for the client app at the <a href="http://code.google.com/p/gcm">open source site</a>.</li>
642 <li>Run one of the demo servers (Java or Python) provided in
643<a href="ccs.html#implement">Implementing an XMPP-based App Server</a>. Whichever demo server you
644 choose, don't forget to edit its code before running it to supply
645your sender ID and API key.
646</li>
647
648</ol>
649
650<h2 id="stats">Viewing Statistics</h2>
651
652<p>To view statistics and any error messages for your GCM applications:</p>
653<ol>
654 <li> Go to the <code><a href="http://play.google.com/apps/publish">Developer Console</a></code>.</li>
655 <li>Login with your developer account.
656 <p>You will see a page that has a list of all of your apps.</p></li>
657 <li> Click on the &quot;statistics&quot; link next to the app for which you
658want to view GCM stats.
659 <p>Now you are on the statistics page.</p> </li>
660 <li>Go to the drop-down menu and select the GCM metric you want to view.
661 </li>
662</ol>
663<p class="note"><strong>Note:</strong> Stats on the Google API Console are not
664enabled for GCM. You must use the <a href="http://play.google.com/apps/publish">Developer Console</a>.</p>
kmccormickf788ac12013-05-30 19:06:41 -0700665