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. 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>

