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&mdash;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&mdash;use
only if the app wants to keep the device from sleeping.</li>
  <li>An <code>applicationPackage + &quot;.permission.C2D_MESSAGE&quot;</code>
permission to prevent other Android applications from registering and receiving
the Android application's messages. The permission name must exactly match this
pattern&mdash;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&mdash;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=&quot;8&quot;</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">
&lt;manifest package="com.example.gcm" ...&gt;

    &lt;uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/&gt;
    &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
    &lt;uses-permission android:name="android.permission.GET_ACCOUNTS" /&gt;
    &lt;uses-permission android:name="android.permission.WAKE_LOCK" /&gt;
    &lt;uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /&gt;

    &lt;permission android:name="com.example.gcm.permission.C2D_MESSAGE"
        android:protectionLevel="signature" /&gt;
    &lt;uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" /&gt;

    &lt;application ...&gt;
        &lt;receiver
            android:name=".GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" &gt;
            &lt;intent-filter&gt;
                &lt;action android:name="com.google.android.c2dm.intent.RECEIVE" /&gt;
                &lt;category android:name="com.example.gcm" /&gt;
            &lt;/intent-filter&gt;
        &lt;/receiver&gt;
        &lt;service android:name=".GcmIntentService" /&gt;
    &lt;/application&gt;

&lt;/manifest&gt;
</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;
...
&#64;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.
&#64;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 (note that registration IDs must be kept secret). 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;

    &#64;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.
 * &lt;p&gt;
 * If result is empty, the app needs to register.
 *
 * &#64;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;
}
...
/**
 * &#64;return Application's {&#64;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>/**
 * &#64;return Application's version code from the {&#64;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.
 * &lt;p&gt;
 * Stores the registration ID and app versionCode in the application's
 * shared preferences.
 */
private void registerInBackground() {
    new AsyncTask<Void, Void, String>() {
        &#64;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;
        }

        &#64;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
 * {&#64;code SharedPreferences}.
 *
 * &#64;param context application's context.
 * &#64;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>() {
            &#64;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;
            }

            &#64;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 {
    &#64;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&mdash;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");
    }

    &#64;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 &quot;statistics&quot; 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>

