| page.title=Implementing GCM Client |
| page.tags="cloud","push","messaging" |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| |
| |
| <h2>In this document</h2> |
| |
| <ol class="toc"> |
| <li><a href="#play-services">Set Up Google Play Services</a></li> |
| <li><a href="#manifest">Edit Your Application's Manifest</a></li> |
| <li><a href="#app">Write Your Application</a> |
| <ol class="toc"> |
| <li><a href="#sample-play">Check for Google Play Services APK</a></li> |
| <li><a href="#sample-register">Register for GCM</a></li> |
| <li><a href="#sample-send">Send a message</a></li> |
| <li><a href="#sample-receive">Receive a message</a></li> |
| </ol> |
| <li><a href="#run">Running the Sample</a></li> |
| <li><a href="#stats">Viewing Statistics</a></li> |
| </li> |
| |
| </ol> |
| |
| <h2>See Also</h2> |
| |
| <ol class="toc"> |
| <li><a href="gs.html">Getting Started</a></li> |
| <li><a href="server.html">Implementing GCM Server</a></li> |
| </ol> |
| |
| </div> |
| </div> |
| |
| <p>A GCM client is a GCM-enabled app that runs on an Android device. To write your |
| client code, we recommend that you use the |
| <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"> |
| {@code GoogleCloudMessaging}</a> APIs. |
| The client helper library that was offered in previous versions of GCM still works, |
| but it has been superseded by the more efficient |
| <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"> |
| {@code GoogleCloudMessaging}</a> APIs.</p> |
| |
| <p>A full GCM implementation requires both a client implementation and a server |
| implementation. For more |
| information about implementing the server side, see <a href="server.html"> |
| Implementing GCM Server</a>.</p> |
| |
| <p>The following sections walk you through the steps involved in writing a GCM |
| client-side application. Your client app can be arbitrarily complex, but at bare |
| minimum, a GCM client app must include code to register (and thereby get a |
| registration ID), and a broadcast receiver to receive messages sent by GCM. |
| </p> |
| |
| <h2 id="play-services">Step 1: Set Up Google Play Services</h2> |
| |
| <p>To write your client application, use the |
| <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"> |
| {@code GoogleCloudMessaging}</a> API. |
| To use this API, you must set up your project to use the Google Play services SDK, |
| as described in <a href="/google/play-services/setup.html">Setup Google Play |
| Services SDK</a>.</p> |
| |
| <p class="note"><strong>Caution:</strong> When you add the Play Services library to |
| your project, be sure to add it <em>with resources</em>, as described in |
| <a href="{@docRoot}google/play-services/setup.html#Setup"> |
| Setup Google Play Services SDK</a>. The key point is that you must |
| <em>reference</em> the library—simply adding a {@code .jar} file to |
| your Eclipse project will not work. You must follow the directions |
| for referencing a library, or your app won't be able to access |
| the library's resources, and it won't run properly. |
| If you're using Android Studio, this is the string to add to the |
| {@code dependency} section of your application's {@code build.gradle} file:</p> |
| |
| <pre>dependencies { |
| compile "com.google.android.gms:play-services:3.1.+" |
| } |
| </pre> |
| |
| |
| <h2 id="manifest">Step 2: Edit Your Application's Manifest</h2> |
| |
| <p>Add the following to your application's manifest:</p> |
| <ul> |
| <li>The <code>com.google.android.c2dm.permission.RECEIVE</code> permission so |
| the Android application can register and receive messages.</li> |
| <li>The <code>android.permission.INTERNET</code> permission so the Android |
| application can send the registration ID to the 3rd party server.</li> |
| <li>The <code>android.permission.GET_ACCOUNTS</code> permission as GCM requires |
| a Google account (necessary only if if the device is running a version lower than |
| Android 4.0.4)</li> |
| <li>The <code>android.permission.WAKE_LOCK</code> permission so the application |
| can keep the processor from sleeping when a message is received. Optional—use |
| only if the app wants to keep the device from sleeping.</li> |
| <li>An <code>applicationPackage + ".permission.C2D_MESSAGE"</code> |
| permission to prevent other Android applications from registering and receiving |
| the Android application's messages. The permission name must exactly match this |
| pattern—otherwise the Android application will not receive the messages.</li> |
| <li>A receiver for <code>com.google.android.c2dm.intent.RECEIVE</code>, with |
| the category set |
| as <code>applicationPackage</code>. The receiver should require the |
| <code>com.google.android.c2dm.SEND</code> permission, so that only the GCM |
| Framework can send a message to it. If your app uses an {@link android.app.IntentService} |
| (not required, but a common pattern), this receiver should be an instance of |
| {@link android.support.v4.content.WakefulBroadcastReceiver}. |
| A {@link android.support.v4.content.WakefulBroadcastReceiver} takes care of |
| creating and managing a |
| <a href="{@docRoot}reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK"> |
| partial wake lock</a> for your app.</li> |
| |
| <li>A {@link android.app.Service} (typically an {@link android.app.IntentService}) |
| to which the {@link android.support.v4.content.WakefulBroadcastReceiver} passes off |
| the work of handling the GCM message, while ensuring that the device does not |
| go back to sleep in the process. Including an {@link android.app.IntentService} is |
| optional—you could choose to process your messages in a regular |
| {@link android.content.BroadcastReceiver} instead, but realistically, most apps will |
| use a {@link android.app.IntentService}. |
| </li> |
| <li>If the GCM feature is critical to the Android application's function, be sure to |
| set <code>android:minSdkVersion="8"</code> or higher in the manifest. This |
| ensures that the Android application cannot be installed in an environment in which it |
| could not run properly. </li> |
| </ul> |
| |
| <p>Here are excerpts from a sample manifest that supports GCM:</p> |
| |
| <pre class="prettyprint pretty-xml"> |
| <manifest package="com.example.gcm" ...> |
| |
| <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/> |
| <uses-permission android:name="android.permission.INTERNET" /> |
| <uses-permission android:name="android.permission.GET_ACCOUNTS" /> |
| <uses-permission android:name="android.permission.WAKE_LOCK" /> |
| <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> |
| |
| <permission android:name="com.example.gcm.permission.C2D_MESSAGE" |
| android:protectionLevel="signature" /> |
| <uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" /> |
| |
| <application ...> |
| <receiver |
| android:name=".GcmBroadcastReceiver" |
| android:permission="com.google.android.c2dm.permission.SEND" > |
| <intent-filter> |
| <action android:name="com.google.android.c2dm.intent.RECEIVE" /> |
| <category android:name="com.example.gcm" /> |
| </intent-filter> |
| </receiver> |
| <service android:name=".GcmIntentService" /> |
| </application> |
| |
| </manifest> |
| </pre> |
| |
| <h2 id="app"> Step 3: Write Your Application</h2> |
| |
| <p>Finally, write your application. This section features a sample client |
| application that illustrates how to use the |
| <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"> |
| {@code GoogleCloudMessaging}</a> APIs. The sample consists of a main activity |
| ({@code DemoActivity}), a {@link android.support.v4.content.WakefulBroadcastReceiver} |
| ({@code GcmBroadcastReceiver}), and an {@link android.app.IntentService} |
| ({@code GcmIntentService}). You can find the complete source code for this sample at the |
| <a href="http://code.google.com/p/gcm">open source site</a>.</p> |
| |
| <p>Note the following:</p> |
| |
| <ul> |
| <li>Among other things, the sample illustrates registration and upstream |
| (device-to-cloud) messaging. Upstream messaging only applies to apps that are running against a |
| <a href="ccs.html">CCS</a> (XMPP) server; HTTP-based servers don't support upstream messaging.</li> |
| <li>The <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"> |
| {@code GoogleCloudMessaging}</a> |
| registration APIs replace the old registration process, which was based on the |
| now-obsolete client helper library. While the old registration process still works, |
| we encourage you to use the newer |
| <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"> |
| {@code GoogleCloudMessaging}</a> |
| registration APIs, regardless of your underlying server.</li> |
| </ul> |
| |
| <h3 id="sample-play">Check for Google Play Services APK</h3> |
| |
| <p>As described in <a href="{@docRoot}google/play-services/setup.html"> |
| Setup Google Play Services SDK</a>, apps that rely on the Play Services SDK |
| should always check the device for a compatible Google Play services APK before |
| accessing Google Play services features. In the sample app this check is done in |
| two places: in the main activity's {@code onCreate()} method, and in its |
| {@code onResume()} method. The check in {@code onCreate()} ensures that the app |
| can't be used without a successful check. The check in {@code onResume()} ensures |
| that if the user returns to the running app through some other means, such as |
| through the back button, the check is still performed. If the |
| device doesn't have a compatible Google Play services APK, your app can call |
| {@code GooglePlayServicesUtil.getErrorDialog()} to allow users to download the |
| APK from the Google Play Store or enable it in the device's system settings. |
| For example:</p> |
| |
| <pre>private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; |
| ... |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| setContentView(R.layout.main); |
| mDisplay = (TextView) findViewById(R.id.display); |
| |
| context = getApplicationContext(); |
| |
| // Check device for Play Services APK. |
| if (checkPlayServices()) { |
| // If this check succeeds, proceed with normal processing. |
| // Otherwise, prompt user to get valid Play Services APK. |
| ... |
| } |
| } |
| |
| // You need to do the Play Services APK check here too. |
| @Override |
| protected void onResume() { |
| super.onResume(); |
| checkPlayServices(); |
| } |
| |
| /** |
| * Check the device to make sure it has the Google Play Services APK. If |
| * it doesn't, display a dialog that allows users to download the APK from |
| * the Google Play Store or enable it in the device's system settings. |
| */ |
| 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; |
| }</pre> |
| |
| <h3 id="sample-register">Register for GCM</h3> |
| <p>An Android application needs to register with GCM servers before it can receive |
| messages. When an app registers, it receives a registration ID, which it can then |
| store for future use. In the following snippet the {@code onCreate()} method in the sample app's |
| main activity checks to see if the app is already registered with GCM and with |
| the server:</p> |
| |
| <pre>/** |
| * Main UI for the demo app. |
| */ |
| public class DemoActivity 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; |
| |
| /** |
| * Substitute you own sender ID here. This is the project number you got |
| * from the API Console, as described in "Getting Started." |
| */ |
| String SENDER_ID = "Your-Sender-ID"; |
| |
| /** |
| * Tag used on log messages. |
| */ |
| static final String TAG = "GCMDemo"; |
| |
| TextView mDisplay; |
| GoogleCloudMessaging gcm; |
| AtomicInteger msgId = new AtomicInteger(); |
| SharedPreferences prefs; |
| Context context; |
| |
| String regid; |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| setContentView(R.layout.main); |
| mDisplay = (TextView) findViewById(R.id.display); |
| |
| context = getApplicationContext(); |
| |
| // Check device for Play Services APK. If check succeeds, proceed with |
| // GCM registration. |
| if (checkPlayServices()) { |
| gcm = GoogleCloudMessaging.getInstance(this); |
| regid = getRegistrationId(context); |
| |
| if (regid.isEmpty()) { |
| registerInBackground(); |
| } |
| } else { |
| Log.i(TAG, "No valid Google Play Services APK found."); |
| } |
| } |
| ... |
| }</pre> |
| |
| <p>The app calls {@code getRegistrationId()} to see whether there is an existing |
| registration ID stored in shared preferences:</p> |
| |
| <pre>/** |
| * Gets the current registration ID for application on GCM service. |
| * <p> |
| * If result is empty, the app needs to register. |
| * |
| * @return registration ID, or empty string if there is no existing |
| * registration ID. |
| */ |
| 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 ""; |
| } |
| // Check if app was updated; if so, it must clear the registration ID |
| // since the existing regID is not guaranteed to work with the new |
| // app version. |
| 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; |
| } |
| ... |
| /** |
| * @return Application's {@code SharedPreferences}. |
| */ |
| private SharedPreferences getGCMPreferences(Context context) { |
| // This sample app persists the registration ID in shared preferences, but |
| // how you store the regID in your app is up to you. |
| return getSharedPreferences(DemoActivity.class.getSimpleName(), |
| Context.MODE_PRIVATE); |
| }</pre> |
| |
| <p>If the registration ID doesn't exist or the app was updated, |
| {@code getRegistrationId()} returns an empty string |
| to indicate that the app needs to get a new regID. {@code getRegistrationId()} calls |
| the following method to check the app version:</p> |
| |
| <pre>/** |
| * @return Application's version code from the {@code PackageManager}. |
| */ |
| 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); |
| } |
| }</pre> |
| |
| |
| <p>If there isn't a valid existing registration ID, {@code DemoActivity} calls the |
| following {@code registerInBackground()} method to register. Note that because the GCM |
| methods {@code register()} and {@code unregister()} are blocking, this has to |
| take place on a background thread. This sample uses {@link android.os.AsyncTask} |
| to accomplish this:</p> |
| |
| <pre> |
| /** |
| * Registers the application with GCM servers asynchronously. |
| * <p> |
| * Stores the registration ID and app versionCode in the application's |
| * shared preferences. |
| */ |
| private void registerInBackground() { |
| new AsyncTask<Void, Void, String>() { |
| @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; |
| |
| // You should send the registration ID to your server over HTTP, |
| // so it can use GCM/HTTP or CCS to send messages to your app. |
| // The request to your server should be authenticated if your app |
| // is using accounts. |
| sendRegistrationIdToBackend(); |
| |
| // For this demo: we don't need to send it because the device |
| // will send upstream messages to a server that echo back the |
| // message using the 'from' address in the message. |
| |
| // Persist the regID - no need to register again. |
| storeRegistrationId(context, regid); |
| } catch (IOException ex) { |
| msg = "Error :" + ex.getMessage(); |
| // If there is an error, don't just keep trying to register. |
| // Require the user to click a button again, or perform |
| // exponential back-off. |
| } |
| return msg; |
| } |
| |
| @Override |
| protected void onPostExecute(String msg) { |
| mDisplay.append(msg + "\n"); |
| } |
| }.execute(null, null, null); |
| ... |
| }</pre> |
| |
| <p>Once you've received your registration ID, send it to your server:</p> |
| <pre> |
| /** |
| * Sends the registration ID to your server over HTTP, so it can use GCM/HTTP |
| * or CCS to send messages to your app. Not needed for this demo since the |
| * device sends upstream messages to a server that echoes back the message |
| * using the 'from' address in the message. |
| */ |
| private void sendRegistrationIdToBackend() { |
| // Your implementation here. |
| }</pre> |
| |
| <p>After registering, the app calls {@code storeRegistrationId()} to store the |
| registration ID in shared preferences for future use. This is just one way of |
| persisting a regID. You might choose to use a different approach in your app:</p> |
| |
| <pre>/** |
| * Stores the registration ID and app versionCode in the application's |
| * {@code SharedPreferences}. |
| * |
| * @param context application's context. |
| * @param regId registration ID |
| */ |
| 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(); |
| }</pre> |
| |
| <h3 id="sample-send">Send a message</h3> |
| <p>When the user clicks the app's <strong>Send</strong> button, the app sends an |
| upstream message using the |
| <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"> |
| {@code GoogleCloudMessaging}</a> APIs. In order to receive the upstream message, |
| your server should be connected to CCS. You can use one of the demo servers in |
| <a href="ccs.html#implement">Implementing an XMPP-based App Server</a> to run the sample and connect |
| to CCS.</p> |
| |
| <pre>public void onClick(final View view) { |
| if (view == findViewById(R.id.send)) { |
| new AsyncTask<Void, Void, String>() { |
| @Override |
| protected String doInBackground(Void... params) { |
| String msg = ""; |
| try { |
| Bundle data = new Bundle(); |
| data.putString("my_message", "Hello World"); |
| data.putString("my_action", |
| "com.google.android.gcm.demo.app.ECHO_NOW"); |
| String id = Integer.toString(msgId.incrementAndGet()); |
| gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data); |
| msg = "Sent message"; |
| } catch (IOException ex) { |
| msg = "Error :" + ex.getMessage(); |
| } |
| return msg; |
| } |
| |
| @Override |
| protected void onPostExecute(String msg) { |
| mDisplay.append(msg + "\n"); |
| } |
| }.execute(null, null, null); |
| } else if (view == findViewById(R.id.clear)) { |
| mDisplay.setText(""); |
| } |
| }</pre> |
| |
| <h3 id="sample-receive">Receive a message</h3> |
| |
| <p>As described above in <a href="#manifest">Step 2</a>, the app includes a |
| {@link android.support.v4.content.WakefulBroadcastReceiver} for the <code>com.google.android.c2dm.intent.RECEIVE</code> |
| intent. A broadcast receiver is the mechanism GCM uses to deliver messages. When {@code onClick()} |
| calls {@code gcm.send()}, it triggers the broadcast receiver's {@code onReceive()} |
| method, which has the responsibility of making sure that the GCM message gets handled.</p> |
| <p>A {@link android.support.v4.content.WakefulBroadcastReceiver} is a special type of |
| broadcast receiver that takes care of |
| creating and managing a |
| <a href="{@docRoot}reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK"> |
| partial wake lock</a> for your app. |
| It passes off the work of processing the GCM message to a |
| {@link android.app.Service} (typically an |
| {@link android.app.IntentService}), while ensuring that the device does not |
| go back to sleep in the transition. If you don't hold a wake lock while transitioning |
| the work to a service, you are effectively allowing the device to go back to sleep before |
| the work completes. The net result is that the app might not finish processing |
| the GCM message until some arbitrary point in the future, which is not what you want.</p> |
| |
| <p class="note"><strong>Note:</strong> Using {@link android.support.v4.content.WakefulBroadcastReceiver} |
| is not a requirement. If you have a relatively simple app that doesn't require |
| a service, you can intercept the GCM message in a regular {@link android.content.BroadcastReceiver} |
| and do your processing there. Once you get the intent that GCM passes into |
| your broadcast receiver's {@code onReceive()} method, what you do with it |
| is up to you.</p> |
| |
| <p>This snippet starts {@code GcmIntentService} with the method |
| {@link android.support.v4.content.WakefulBroadcastReceiver#startWakefulService startWakefulService()}. |
| This method is comparable to {@link android.content.Context#startService startService()}, except that |
| the {@link android.support.v4.content.WakefulBroadcastReceiver} is holding a |
| wake lock when the service starts. The intent that is passed with |
| {@link android.support.v4.content.WakefulBroadcastReceiver#startWakefulService startWakefulService()} |
| holds an extra identifying the wake lock:</p> |
| |
| |
| <pre>public class GcmBroadcastReceiver extends WakefulBroadcastReceiver { |
| @Override |
| public void onReceive(Context context, Intent intent) { |
| // Explicitly specify that GcmIntentService will handle the intent. |
| ComponentName comp = new ComponentName(context.getPackageName(), |
| GcmIntentService.class.getName()); |
| // Start the service, keeping the device awake while it is launching. |
| startWakefulService(context, (intent.setComponent(comp))); |
| setResultCode(Activity.RESULT_OK); |
| } |
| }</pre> |
| |
| <p>The intent service shown below does the actual work of handling the GCM |
| message. When the service is finished, it calls |
| {@link android.support.v4.content.WakefulBroadcastReceiver#completeWakefulIntent GcmBroadcastReceiver.completeWakefulIntent()} |
| to release the wake lock. The |
| {@link android.support.v4.content.WakefulBroadcastReceiver#completeWakefulIntent completeWakefulIntent()} |
| method has as its parameter the same intent that was |
| passed in from the {@link android.support.v4.content.WakefulBroadcastReceiver}. |
| </p> |
| |
| <p>This snippet processes the GCM message based on message type, and posts the |
| result in a notification. But what you do with GCM messages in your app is up to |
| you—the possibilities are endless. For example, the message might be a ping, |
| telling the app to sync to a server to retrieve new content, or it might be a |
| chat message that you display in the UI.</p> |
| |
| <pre> |
| public class GcmIntentService extends IntentService { |
| public static final int NOTIFICATION_ID = 1; |
| private NotificationManager mNotificationManager; |
| NotificationCompat.Builder builder; |
| |
| public GcmIntentService() { |
| super("GcmIntentService"); |
| } |
| |
| @Override |
| protected void onHandleIntent(Intent intent) { |
| Bundle extras = intent.getExtras(); |
| GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); |
| // The getMessageType() intent parameter must be the intent you received |
| // in your BroadcastReceiver. |
| String messageType = gcm.getMessageType(intent); |
| |
| if (!extras.isEmpty()) { // has effect of unparcelling Bundle |
| /* |
| * Filter messages based on message type. Since it is likely that GCM |
| * will be extended in the future with new message types, just ignore |
| * any message types you're not interested in, or that you don't |
| * recognize. |
| */ |
| 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(TAG, "Working... " + (i+1) |
| + "/5 @ " + SystemClock.elapsedRealtime()); |
| try { |
| Thread.sleep(5000); |
| } catch (InterruptedException e) { |
| } |
| } |
| Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime()); |
| // Post notification of received message. |
| sendNotification("Received: " + extras.toString()); |
| Log.i(TAG, "Received: " + extras.toString()); |
| } |
| } |
| // Release the wake lock provided by the WakefulBroadcastReceiver. |
| GcmBroadcastReceiver.completeWakefulIntent(intent); |
| } |
| |
| // Put the message into a notification and post it. |
| // This is just one simple example of what you might choose to do with |
| // a GCM message. |
| private void sendNotification(String msg) { |
| mNotificationManager = (NotificationManager) |
| this.getSystemService(Context.NOTIFICATION_SERVICE); |
| |
| PendingIntent contentIntent = PendingIntent.getActivity(this, 0, |
| new Intent(this, DemoActivity.class), 0); |
| |
| NotificationCompat.Builder mBuilder = |
| new NotificationCompat.Builder(this) |
| .setSmallIcon(R.drawable.ic_stat_gcm) |
| .setContentTitle("GCM Notification") |
| .setStyle(new NotificationCompat.BigTextStyle() |
| .bigText(msg)) |
| .setContentText(msg); |
| |
| mBuilder.setContentIntent(contentIntent); |
| mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build()); |
| } |
| }</pre> |
| |
| <h2 id="run">Running the Sample</h2> |
| |
| <p>To run the sample:</p> |
| |
| <ol> |
| <li>Follow the instructions in <a href="gs.html">Getting Started</a> to get your sender ID and |
| API key.</li> |
| <li>Implement your client app, as described in this document. You can find the complete source |
| code for the client app at the <a href="http://code.google.com/p/gcm">open source site</a>.</li> |
| <li>Run one of the demo servers (Java or Python) provided in |
| <a href="ccs.html#implement">Implementing an XMPP-based App Server</a>. Whichever demo server you |
| choose, don't forget to edit its code before running it to supply |
| your sender ID and API key. |
| </li> |
| |
| </ol> |
| |
| <h2 id="stats">Viewing Statistics</h2> |
| |
| <p>To view statistics and any error messages for your GCM applications:</p> |
| <ol> |
| <li> Go to the <code><a href="http://play.google.com/apps/publish">Developer Console</a></code>.</li> |
| <li>Login with your developer account. |
| <p>You will see a page that has a list of all of your apps.</p></li> |
| <li> Click on the "statistics" link next to the app for which you |
| want to view GCM stats. |
| <p>Now you are on the statistics page.</p> </li> |
| <li>Go to the drop-down menu and select the GCM metric you want to view. |
| </li> |
| </ol> |
| <p class="note"><strong>Note:</strong> Stats on the Google API Console are not |
| enabled for GCM. You must use the <a href="http://play.google.com/apps/publish">Developer Console</a>.</p> |
| |