summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Fernandez <joefernandez@google.com>2015-05-14 19:43:49 -0700
committerJoe Fernandez <joefernandez@google.com>2015-05-15 13:12:41 -0700
commit6b4c3fed885db4341076159dc549d6bdae4df02e (patch)
tree0acf10db828e2a2c0a3445c95a87493032b524f7
parentefd254b2f9246d4c259be7885ef344be745bc8bc (diff)
downloadframeworks_base-6b4c3fed885db4341076159dc549d6bdae4df02e.zip
frameworks_base-6b4c3fed885db4341076159dc549d6bdae4df02e.tar.gz
frameworks_base-6b4c3fed885db4341076159dc549d6bdae4df02e.tar.bz2
docs: Refactor Google Services pages for site redesign
b/18225342 - removed outdated advertising ux recommendations Redirects Change-Id: I669b2c7f216be28603594ae3f2909f50e7eaf60d Change-Id: I50eada1885156c2abfcc0b1c2bd1f61bfc790e72
-rw-r--r--docs/html/google/gcm/c2dm.jd119
-rw-r--r--docs/html/google/gcm/ccs.jd963
-rw-r--r--docs/html/google/gcm/client.jd689
-rw-r--r--docs/html/google/gcm/demo.jd277
-rw-r--r--docs/html/google/gcm/gcm.jd307
-rw-r--r--docs/html/google/gcm/gs.jd94
-rw-r--r--docs/html/google/gcm/helper.jd199
-rw-r--r--docs/html/google/gcm/http.jd445
-rw-r--r--docs/html/google/gcm/index.jd70
-rw-r--r--docs/html/google/gcm/notifications.jd308
-rw-r--r--docs/html/google/gcm/server-ref.jd764
-rw-r--r--docs/html/google/gcm/server.jd440
-rw-r--r--docs/html/google/gcs/gcs-signup.jd10
-rw-r--r--docs/html/google/gcs/index.jd30
-rw-r--r--docs/html/google/play-services/ads.jd110
-rw-r--r--docs/html/google/play-services/cast.jd92
-rw-r--r--docs/html/google/play-services/drive.jd141
-rw-r--r--docs/html/google/play-services/games.jd94
-rw-r--r--docs/html/google/play-services/id.jd211
-rw-r--r--docs/html/google/play-services/location.jd125
-rw-r--r--docs/html/google/play-services/maps.jd97
-rw-r--r--docs/html/google/play-services/plus.jd90
-rw-r--r--docs/html/google/play-services/wallet.jd87
-rw-r--r--docs/html/google/play/safetynet/index.jd82
-rw-r--r--docs/html/training/building-location.jd11
-rw-r--r--docs/html/training/maps/index.jd70
-rw-r--r--docs/html/training/monetization/ads-and-ux.jd250
-rw-r--r--docs/html/training/monetization/index.jd44
-rw-r--r--docs/html/training/safetynet/index.jd (renamed from docs/html/google/play/safetynet/start.jd)21
-rw-r--r--docs/html/training/sign-in/index.jd68
-rw-r--r--docs/html/training/training_toc.cs123
31 files changed, 225 insertions, 6206 deletions
diff --git a/docs/html/google/gcm/c2dm.jd b/docs/html/google/gcm/c2dm.jd
deleted file mode 100644
index bc58e66..0000000
--- a/docs/html/google/gcm/c2dm.jd
+++ /dev/null
@@ -1,119 +0,0 @@
-page.title=Migration
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>Quickview</h2>
-
-<ul>
-<li>Understand the differences between GCM and C2DM.</li>
-<li>Learn how to migrate an app from C2DM to GCM.</li>
-
-</ul>
-
-
-<h2>In this document</h2>
-
-<ol>
-<li><a href="#history">Historical Overview</a></li>
-<li><a href="#diffs">How is GCM Different from C2DM?</a>
- <ol>
- <li><a href="#interop">Relationship between C2DM and GCM</a></li>
- </ol>
-</li>
-<li><a href="#migrating">Migrating Your Apps</a>
- <ol>
- <li><a href="#client">Client changes</a></li>
- <li><a href="#server">Server changes</a></li>
- </ol>
-</li>
-</ol>
-
-</div>
-</div>
-
-<p>Android Cloud to Device Messaging (C2DM) was officially deprecated on June 26, 2012, and will be
- shut down completely as of July 30, 2015. <strong>C2DM developers are strongly encouraged to move
- to Google Cloud Messaging (GCM)</strong>. GCM is the next generation of C2DM.</p>
-
-<p>This document is addressed to C2DM developers who are moving to GCM. It describes the differences between GCM and C2DM, and explains how to migrate existing C2DM apps to GCM.</p>
-
-
-<h2 id="history">Historical Overview</h2>
-<p>C2DM was launched in 2010 to help Android apps send data from servers to their applications. Servers can tell apps to contact the server directly, to fetch updated application or user data. The C2DM service handles all aspects of queueing of messages and delivery to the target application running on the target device.</p>
-<p>GCM replaces C2DM. The focus of GCM is as follows:</p>
-<ul>
- <li> Ease of use. No sign-up forms.</li>
- <li>No quotas.</li>
- <li>GCM and C2DM stats are available through the <a href="http://play.google.com/apps/publish">Developer Console</a>.</li>
- <li>Battery efficiency.</li>
- <li>Rich set of new APIs.</li>
-</ul>
-<h2 id="diffs">How is GCM Different from C2DM?</h2>
-<p>GCM builds on the core foundation of C2DM. Here is what's different:</p>
-
-<dl>
-<dt><strong>Simple API Key</strong></dt>
-<dd>To use the GCM service, you need to obtain a Simple API Key from Google APIs console page. For more information, see <a href="gs.html">Getting Started</a>. Note that GCM <em>only</em> accepts Simple API Key&mdash;using ClientLogin or OAuth2 tokens will not work.
-</dd>
-<dt><strong>Sender ID</strong></dt>
-<dd>In C2DM, the Sender ID is an email address. In GCM, the Sender ID is a project number that you acquire from the API console, as described in <a href="gs.html#create-proj">Getting Started</a>. </dd>
-
-<dt><strong>JSON format</strong></dt>
-<dd>GCM HTTP requests support JSON format in addition to plain text. For more information, see the <a href="gcm.html#send-msg">Architectural Overview</a>.</dd>
-
-<dt><strong>Multicast messages</strong></dt>
-<dd>In GCM you can send the same message to multiple devices simultaneously. For example, a sports app wanting to deliver a score update to fans can now send the message to up to 1000 registration IDs in the same request (requires JSON). For more information, see the <a href="gcm.html#send-msg">Architectural Overview</a>.</dd>
-
-<dt><strong>Multiple senders</strong></dt>
-<dd>Multiple parties can send messages to the same app with one common registration ID. For more information, see <a href="adv.html#multi-senders">Advanced Topics</a>.</dd>
-
-<dt><strong>Time-to-live messages</strong></dt>
-<dd>Apps like video chat and calendar apps can send expiring invitation events with a time-to-live value between 0 and 4 weeks. GCM will store the messages until they expire. A message with a time-to-live value of 0 will not be stored on the GCM server, nor will it be throttled. For more information, see <a href="adv.html#ttl">Advanced Topics</a>.</dd>
-
-<dt><strong>Messages with payload</strong></dt>
-<dd>Apps can use &quot;messages with payload&quot; to deliver messages of up to 4 Kb. This would be useful in a chat application, for example. To use this feature, simply omit the <code>collapse_key</code> parameter and messages will not be collapsed. GCM will store up to 100 messages. If you exceed that number, all messages will be discarded but you will receive a special message. If an application receives this message, it needs to sync with the server. For more information, see <a href="adv.html#collapsible">Advanced Topics</a>.</dd>
-
-<dt><strong>Canonical registration ID</strong></dt>
-<dd>There may be situations where the server ends up with 2 registration IDs for the same device. If the GCM response contains a registration ID, simply replace the registration ID you have with the one provided. With this feature your application doesn't need to send the device ID to your server anymore. For more information, see <a href="adv.html#canonical">Advanced Topics</a>.</dd>
-</dl>
-
-<h3 id="interop">Relationship between C2DM and GCM</h3>
-
-<p>C2DM and GCM are not interoperable. For example, you cannot post notifications from GCM to C2DM registration IDs, nor can you use C2DM registration IDs as GCM registration IDs. From your server-side application, you must keep track of whether a registration ID is from C2DM or GCM and use the proper endpoint. </p>
-
-<p>As you transition from C2DM to GCM, your server needs to be aware of whether a given registration ID
-contains an old C2DM sender or a new GCM project number. This is the approach we recommend: have the new app version (the one that uses GCM) send a bit along with the registration ID. This bit tells your server that this registration ID is for GCM. If you don't get the extra bit, you mark the registration ID as C2DM. Once no more valid registration IDs are marked as C2DM, you can complete the migration.</p>
-
-<h2 id="migrating">Migrating Your Apps</h2>
-<p>This section describes how to move existing C2DM apps to GCM.</p>
-<h3 id="client">Client changes</h3>
-<p>Migration is simple! Just re-register the client app for your target GCM-enabled platform. For
- example, see <a href="{@docRoot}google/gcm/client.html#sample-register">Register for GCM</a></p>
-
-<p>After receiving a response from GCM, the registration ID obtained must be sent to the application server. When doing this, the application should indicate that it is sending a GCM registration ID so that the server can distinguish it from existing C2DM registrations.</p>
-
-<h3 id="server">Server changes</h3>
-<p>When the application server receives a GCM registration ID, it should store it and mark it as such.</p>
-<p>Sending messages to GCM devices requires a few changes:</p>
-<ul>
- <li> The request should be sent to a new endpoint: <code>https://android.googleapis.com/gcm/send</code>.</li>
- <li>The Authorization header of the request should contain the API key generated during sign up. This key replaces the deprecated ClientLogin Auth token.</li>
-</ul>
-<p>For example:
-</p>
-<pre>Content-Type:application/json
-Authorization:key=AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA
-
-{
- "registration_id" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
- "data" : {
- "Team" : "Portugal",
- "Score" : "3",
- "Player" : "Varela",
- },
-}</pre>
-<p>For a detailed discussion of this topic and more examples, see the <a href="gcm.html#send-msg">Architectural Overview</a>.</p>
-<p>Eventually, once enough users of your application have migrated to the new service, you might want to take advantage of the new <a href="gcm.html#send-msg">JSON-formatted</a> requests that give access to the full set of features provided by GCM.</p>
-
diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd
deleted file mode 100644
index c4d1b1d..0000000
--- a/docs/html/google/gcm/ccs.jd
+++ /dev/null
@@ -1,963 +0,0 @@
-page.title=GCM Cloud Connection Server (XMPP)
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-
-<h2>In this document</h2>
-
-<ol class="toc">
- <li><a href="#connecting">Establishing a Connection</a>
- <ol class="toc">
- <li><a href="#auth">Authentication</a></li>
- </ol>
- </li>
- <li><a href="#format">Downstream Messages</a>
- <ol class="toc">
- <li><a href="#request">Request format</a></li>
- <li><a href="#response">Response format</a></li>
- <li><a href="#receipts">Receive delivery receipts</a></li>
- </ol>
- </li>
- <li><a href="#upstream">Upstream Messages</a>
- </li>
- <li><a href="#flow">Flow Control</a> </li>
- <li><a href="#implement">Implementing an XMPP-based App Server</a>
- <ol class="toc">
- <li><a href="#smack">Java sample using the Smack library</a></li>
- <li><a href="#python">Python sample</a></li>
- </ol>
- </li>
-</ol>
-
-<h2>See Also</h2>
-
-<ol class="toc">
-<li><a href="server-ref.html">Server Reference</a></li>
-<li><a href="{@docRoot}google/gcm/http.html">HTTP</a></li>
-<li><a href="{@docRoot}google/gcm/gs.html">Getting Started</a></li>
-<li><a href="{@docRoot}google/gcm/server.html">Implementing GCM Server</a></li>
-<li><a href="{@docRoot}google/gcm/client.html">Implementing GCM Client</a></li>
-</ol>
-
-</div>
-</div>
-
-<p>The Google Cloud Messaging (GCM) Cloud Connection Server (CCS) is an XMPP endpoint that provides a
-persistent, asynchronous, bidirectional connection to Google servers. The
-connection can be used to send and receive messages between your server and
-your users' GCM-connected devices.</p>
-
-<p class="note"><strong>Note:</strong> The content in this document
-applies to <a href="http://developer.chrome.com/apps/cloudMessaging">
-GCM with Chrome apps</a> as well as Android.
-
-<p>You can continue to use the HTTP request mechanism to send messages to GCM
-servers, side-by-side with CCS which uses XMPP. Some of the benefits of CCS include:</p>
-
-<ul>
- <li>The asynchronous nature of XMPP allows you to send more messages with fewer
-resources.</li>
- <li>Communication is bidirectional&mdash;not only can your server send messages
-to the device, but the device can send messages back to your server.</li>
- <li>The device can send messages back using the same connection used for receiving,
-thereby improving battery life.</li>
-</ul>
-
-<p>The upstream messaging (device-to-cloud) feature of CCS is part of the Google
-Play services platform. Upstream messaging is available through the
-<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
-{@code GoogleCloudMessaging}</a>
-APIs. For examples, see
-<a href="#implement">Implementing an XMPP-based App Server</a>.</p>
-
-<p class="note"><strong>Note:</strong> See the
-<a href="server-ref.html">Server Reference</a> for a list of all the message
-parameters and which connection server(s) supports them.</p>
-
-<h2 id="connecting">Establishing a Connection</h2>
-
-<p>CCS just uses XMPP as an authenticated transport layer, so you can use most
-XMPP libraries to manage the connection. For an example, see <a href="#smack">
-Java sample using the Smack library</a>.</p>
-
-<p>The CCS XMPP endpoint runs at {@code gcm.googleapis.com:5235}. When testing
-functionality (with non-production users), you should instead connect to
-{@code gcm-preprod.googleapis.com:5236} (note the different port). Regular
-testing on preprod (a smaller environment where the latest CCS builds run) is
-beneficial both for isolating real users from test code, as well as for early
-detection of unexpected behavior changes. Note that a connection receives upstream
-messages destined for its GCM sender ID, regardless of which environment (gcm or
-gcm-preprod) it is connected to. Therefore, test code connecting to
-{@code gcm-preprod.googleapis.com:5236} should use a different GCM sender ID to
-avoid upstream messages from production traffic being sent over test connections.</p>
-
-<p>The connection has two important requirements:</p>
-
-<ul>
- <li>You must initiate a Transport Layer Security (TLS) connection. Note that
- CCS doesn't currently support the <a href="http://xmpp.org/rfcs/rfc3920.html"
- class="external-link" target="_android">STARTTLS extension</a>.</li>
- <li>CCS requires a SASL PLAIN authentication mechanism using
- {@code &lt;your_GCM_Sender_Id&gt;&#64;gcm.googleapis.com} (GCM sender ID)
- and the API key as the password, where the sender ID and API key are the same
- as described in <a href="gs.html">Getting Started</a>.</li>
-</ul>
-
-<p>If at any point the connection fails, you should immediately reconnect.
-There is no need to back off after a disconnect that happens after
-authentication.</p>
-
-<h3 id="auth">Authentication</h3>
-
-<p>The following snippets illustrate how to perform authentication in CCS.</p>
-<h4>Client</h4>
-<pre>&lt;stream:stream to=&quot;gcm.googleapis.com&quot;
- version=&quot;1.0&quot; xmlns=&quot;jabber:client&quot;
- xmlns:stream=&quot;http://etherx.jabber.org/streams&quot;/&gt;
-</pre>
-<h4>Server</h4>
-<pre>&lt;str:features xmlns:str=&quot;http://etherx.jabber.org/streams&quot;&gt;
- &lt;mechanisms xmlns=&quot;urn:ietf:params:xml:ns:xmpp-sasl&quot;&gt;
- &lt;mechanism&gt;X-OAUTH2&lt;/mechanism&gt;
- &lt;mechanism&gt;X-GOOGLE-TOKEN&lt;/mechanism&gt;
- &lt;mechanism&gt;PLAIN&lt;/mechanism&gt;
- &lt;/mechanisms&gt;
-&lt;/str:features&gt;
-</pre>
-
-<h4>Client</h4>
-<pre>&lt;auth mechanism=&quot;PLAIN&quot;
-xmlns=&quot;urn:ietf:params:xml:ns:xmpp-sasl&quot;&gt;MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
-mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==&lt;/auth&gt;
-</pre>
-
-<h4>Server</h4>
-<pre>&lt;success xmlns=&quot;urn:ietf:params:xml:ns:xmpp-sasl&quot;/&gt;</pre>
-
-<h2 id="format">Downstream Messages</h2>
-<p>Once the XMPP connection is established, CCS and your server use normal XMPP
-<code>&lt;message&gt;</code> stanzas to send JSON-encoded messages back and
-forth. The body of the <code>&lt;message&gt;</code> must be:</p>
-<pre>
-&lt;gcm xmlns:google:mobile:data&gt;
- <em>JSON payload</em>
-&lt;/gcm&gt;
-</pre>
-
-<p>The JSON payload for regular GCM messages is similar to
-<a href="http.html#request">what the GCM http endpoint uses</a>, with these
-exceptions:</p>
-<ul>
- <li>There is no support for multiple recipients.</li>
- <li>{@code to} is used instead of {@code registration_ids}.</li>
- <li>CCS adds the field {@code message_id}, which is required. This ID uniquely
-identifies the message in an XMPP connection. The ACK or NACK from CCS uses the
-{@code message_id} to identify a message sent from 3rd-party app servers to CCS.
-Therefore, it's important that this {@code message_id} not only be unique (per
-sender ID), but always present.</li>
-</ul>
-
-<p>In addition to regular GCM messages, control messages are sent, indicated by
-the {@code message_type} field in the JSON object. The value can be either
-'ack' or 'nack', or 'control' (see formats below). Any GCM message with an
-unknown {@code message_type} can be ignored by your server.</p>
-
-<p>For each device message your app server receives from CCS, it needs to send
-an ACK message.
-It never needs to send a NACK message. If you don't send an ACK for a message,
-CCS resends it the next time a new XMPP connection is established, unless the
-message expires first.
-</p>
-<p>CCS also sends an ACK or NACK for each server-to-device message. If you do not
-receive either, it means that the TCP connection was closed in the middle of the
-operation and your server needs to resend the messages. See
-<a href="#flow">Flow Control</a> for details.
-</p>
-
-<p class="note"><strong>Note:</strong> See the
-<a href="server-ref.html">Server Reference</a> for a list of all the message
-parameters and which connection server(s) supports them.</p>
-
-<h3 id="request">Request format</h3>
-
-<p>Here is an XMPP stanza containing the JSON message from a 3rd-party app server to CCS:
-
-</p>
-<pre>&lt;message id=&quot;&quot;&gt;
- &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
- {
- &quot;to&quot;:&quot;REGISTRATION_ID&quot;, // &quot;to&quot; replaces &quot;registration_ids&quot;
- &quot;message_id&quot;:&quot;m-1366082849205&quot; // new required field
- &quot;data&quot;:
- {
- &quot;hello&quot;:&quot;world&quot;,
- }
- &quot;time_to_live&quot;:&quot;600&quot;,
- &quot;delay_while_idle&quot;: true/false,
- &quot;delivery_receipt_requested&quot;: true/false
- }
- &lt;/gcm&gt;
-&lt;/message&gt;
-</pre>
-
-<h3 id="response">Response format</h3>
-
-<p>A CCS response can have 3 possible forms. The first one is a regular 'ack'
-message. But when the response contains an error, there are 2
-different forms the message can take, described below.</p>
-
-<h4 id="ack">ACK message</h4>
-
-<p>Here is an XMPP stanza containing the ACK/NACK message from CCS to 3rd-party app server:
-</p>
-<pre>&lt;message id=&quot;&quot;&gt;
- &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
- {
- &quot;from&quot;:&quot;REGID&quot;,
- &quot;message_id&quot;:&quot;m-1366082849205&quot;
- &quot;message_type&quot;:&quot;ack&quot;
- }
- &lt;/gcm&gt;
-&lt;/message&gt;
-</pre>
-
-<h4 id="nack">NACK message</h4>
-
-<p>A NACK error is a regular XMPP message in which the {@code message_type} status
-message is &quot;nack&quot;. A NACK message contains:</p>
-<ul>
-<li>Nack error code.</li>
-<li>Nack error description.</li>
-</ul>
-
-<p>Below are some examples.</p>
-
-<p>Bad registration:</p>
-
-<pre>&lt;message&gt;
- &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
- {
- &quot;message_type&quot;:&quot;nack&quot;,
- &quot;message_id&quot;:&quot;msgId1&quot;,
- &quot;from&quot;:&quot;SomeInvalidRegistrationId&quot;,
- &quot;error&quot;:&quot;BAD_REGISTRATION&quot;,
- &quot;error_description&quot;:&quot;Invalid token on 'to' field: SomeInvalidRegistrationId&quot;
- }
- &lt;/gcm&gt;
-&lt;/message&gt;</pre>
-
-<p>Invalid JSON:</p>
-
-<pre>&lt;message&gt;
- &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
- {
- &quot;message_type&quot;:&quot;nack&quot;,
- &quot;message_id&quot;:&quot;msgId1&quot;,
- &quot;from&quot;:&quot;APA91bHFOtaQGSwupt5l1og&quot;,
- &quot;error&quot;:&quot;INVALID_JSON&quot;,
- &quot;error_description&quot;:&quot;InvalidJson: JSON_TYPE_ERROR : Field \&quot;time_to_live\&quot; must be a JSON java.lang.Number: abc&quot;
- }
- &lt;/gcm&gt;
-&lt;/message&gt;
-</pre>
-
-<p>Device Message Rate Exceeded:</p>
-
-<pre>&lt;message id=&quot;...&quot;&gt;
- &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
- {
- &quot;message_type&quot;:&quot;nack&quot;,
- &quot;message_id&quot;:&quot;msgId1&quot;,
- &quot;from&quot;:&quot;REGID&quot;,
- &quot;error&quot;:&quot;DEVICE_MESSAGE_RATE_EXCEEDED&quot;,
- &quot;error_description&quot;:&quot;Downstream message rate exceeded for this registration id&quot;
- }
- &lt;/gcm&gt;
-&lt;/message&gt;
-</pre>
-
-<p>See the <a href="server-ref.html#table11">Server Reference</a> for a complete list of the
-NACK error codes. Unless otherwise
-indicated, a NACKed message should not be retried. Unexpected NACK error codes
-should be treated the same as {@code INTERNAL_SERVER_ERROR}.</p>
-
-<h4 id="stanza">Stanza error</h4>
-
-<p>You can also get a stanza error in certain cases.
-A stanza error contains:</p>
-<ul>
-<li>Stanza error code.</li>
-<li>Stanza error description (free text).</li>
-</ul>
-<p>For example:</p>
-
-<pre>&lt;message id=&quot;3&quot; type=&quot;error&quot; to=&quot;123456789@gcm.googleapis.com/ABC&quot;&gt;
- &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
- {&quot;random&quot;: &quot;text&quot;}
- &lt;/gcm&gt;
- &lt;error code=&quot;400&quot; type=&quot;modify&quot;&gt;
- &lt;bad-request xmlns=&quot;urn:ietf:params:xml:ns:xmpp-stanzas&quot;/&gt;
- &lt;text xmlns=&quot;urn:ietf:params:xml:ns:xmpp-stanzas&quot;&gt;
- InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
- &lt;/text&gt;
- &lt;/error&gt;
-&lt;/message&gt;
-</pre>
-
-<h4 id="control">Control messages</h4>
-
-<p>Periodically, CCS needs to close down a connection to perform load balancing. Before it
-closes the connection, CCS sends a {@code CONNECTION_DRAINING} message to indicate that the connection is being drained
-and will be closed soon. "Draining" refers to shutting off the flow of messages coming into a
-connection, but allowing whatever is already in the pipeline to continue. When you receive
-a {@code CONNECTION_DRAINING} message, you should immediately begin sending messages to another CCS
-connection, opening a new connection if necessary. You should, however, keep the original
-connection open and continue receiving messages that may come over the connection (and
-ACKing them)&mdash;CCS handles initiating a connection close when it is ready.</p>
-
-<p>The {@code CONNECTION_DRAINING} message looks like this:</p>
-<pre>&lt;message&gt;
- &lt;data:gcm xmlns:data=&quot;google:mobile:data&quot;&gt;
- {
- &quot;message_type&quot;:&quot;control&quot;
- &quot;control_type&quot;:&quot;CONNECTION_DRAINING&quot;
- }
- &lt;/data:gcm&gt;
-&lt;/message&gt;</pre>
-
-<p>{@code CONNECTION_DRAINING} is currently the only {@code control_type} supported.</p>
-
-<!--Delivery receipts section-->
-
-<h3 id="receipts">Receive delivery receipts</h3>
-
-<p>You can get delivery receipts (sent from CCS to
-your 3rd party app server) when
-a device confirms that it received a message sent by CCS.</p>
-
-<p>To enable this feature, the message your 3rd-party app server sends to CCS must include
-a field called <code>&quot;delivery_receipt_requested&quot;</code>. When this field is set to
-<code>true</code>, CCS sends a delivery receipt when a device confirms that it received a particular message.</p>
-
-<p>Here is an XMPP stanza containing a JSON
-message with <code>&quot;delivery_receipt_requested&quot;</code> set to <code>true</code>:</p>
-
-<pre>&lt;message id=&quot;&quot;&gt;
- &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
- {
- &quot;to&quot;:&quot;REGISTRATION_ID&quot;,
- &quot;message_id&quot;:&quot;m-1366082849205&quot;
- &quot;data&quot;:
- {
- &quot;hello&quot;:&quot;world&quot;,
- }
- &quot;time_to_live&quot;:&quot;600&quot;,
- &quot;delay_while_idle&quot;: true,
- <strong>&quot;delivery_receipt_requested&quot;: true</strong>
- }
- &lt;/gcm&gt;
-&lt;/message&gt;
-</pre>
-
-
-
-<p>Here is an example of the delivery receipt that CCS sends to tell your 3rd-party
-app server that a device received a message that CCS sent it:</p>
-
-</p>
-<pre>&lt;message id=&quot;&quot;&gt;
- &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
- {
- &quot;category&quot;:&quot;com.example.yourapp&quot;, // to know which app sent it
- &quot;data&quot;:
- {
- &#x201c;message_status&quot;:&quot;MESSAGE_SENT_TO_DEVICE&quot;,
- &#x201c;original_message_id&#x201d;:&#x201d;m-1366082849205&#x201d;
- &#x201c;device_registration_id&#x201d;: &#x201c;REGISTRATION_ID&#x201d;
- },
- &quot;message_id&quot;:&quot;dr2:m-1366082849205&quot;,
- &quot;message_type&quot;:&quot;receipt&quot;,
- &quot;from&quot;:&quot;gcm.googleapis.com&quot;
- }
- &lt;/gcm&gt;
-&lt;/message&gt;</pre>
-
-<p>Note the following:</p>
-
-<ul>
- <li>The {@code &quot;message_type&quot;} is set to {@code &quot;receipt&quot;}.
- <li>The {@code &quot;message_status&quot;} is set to {@code &quot;MESSAGE_SENT_TO_DEVICE&quot;},
- indicating that the device received the message. Notice that in this case,
-{@code &quot;message_status&quot;} is not a field but rather part of the data payload.</li>
- <li>The receipt message ID consists of the original message ID, but with a
-<code>dr2:</code> prefix. Your 3rd-party app server must send an ACK back with this ID,
-which in this example is {@code dr2:m-1366082849205}.</li>
- <li>The original message ID, the device registration ID, and the status are inside the
-{@code &quot;data&quot;} field.</li>
-<li>If the connection between CCS and the device is poor, GCM may send multiple, duplicate delivery
- receipts. You can safely ignore such duplicates.</li>
-</ul>
-
-<h2 id="upstream">Upstream Messages</h2>
-
-<p>Using CCS and the
-<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
-{@code GoogleCloudMessaging}</a>
-API, you can send messages from a user's device to the cloud.</p>
-
-<p>Here is how you send an upstream message using the
-<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
-{@code GoogleCloudMessaging}</a>
-API. For a complete example, see <a href="client.html">Implementing GCM Client</a>:</p>
-
-<pre>GoogleCloudMessaging gcm = GoogleCloudMessaging.get(context);
-String GCM_SENDER_ID = "Your-Sender-ID";
-AtomicInteger msgId = new AtomicInteger();
-String id = Integer.toString(msgId.incrementAndGet());
-Bundle data = new Bundle();
-// Bundle data consists of a key-value pair
-data.putString("hello", "world");
-// "time to live" parameter
-// This is optional. It specifies a value in seconds up to 24 hours.
-int ttl = [0 seconds, 24 hours]
-
-gcm.send(GCM_SENDER_ID + "&#64;gcm.googleapis.com", id, ttl, data);
-</pre>
-
-<p>This call generates the necessary XMPP stanza for sending the upstream message.
-The message goes from the app on the device to CCS to the 3rd-party app server.
-The stanza has the following format:</p>
-
-<pre>&lt;message id=&quot;&quot;&gt;
- &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
- {
- &quot;category&quot;:&quot;com.example.yourapp&quot;, // to know which app sent it
- &quot;data&quot;:
- {
- &quot;hello&quot;:&quot;world&quot;,
- },
- &quot;message_id&quot;:&quot;m-123&quot;,
- &quot;from&quot;:&quot;REGID&quot;
- }
- &lt;/gcm&gt;
-&lt;/message&gt;</pre>
-
-<p>Here is the format of the ACK expected by CCS from 3rd-party app servers in
-response to the above message:</p>
-
-<pre>&lt;message id=&quot;&quot;&gt;
- &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
- {
- &quot;to&quot;:&quot;REGID&quot;,
- &quot;message_id&quot;:&quot;m-123&quot;
- &quot;message_type&quot;:&quot;ack&quot;
- }
- &lt;/gcm&gt;
-&lt;/message&gt;</pre>
-
-
-<h2 id="flow">Flow Control</h2>
-
-<p>Every message sent to CCS receives either an ACK or a NACK response. Messages
-that haven't received one of these responses are considered pending. If the pending
-message count reaches 100, the 3rd-party app server should stop sending new messages
-and wait for CCS to acknowledge some of the existing pending messages as illustrated in
-figure 1:</p>
-
-<img src="{@docRoot}images/gcm/CCS-ack.png">
-
-<p class="img-caption">
- <strong>Figure 1.</strong> Message/ack flow.
-</p>
-
-<p>Conversely, to avoid overloading the 3rd-party app server, CCS stops sending
-if there are too many unacknowledged messages. Therefore, the 3rd-party app server
-should "ACK" upstream messages, received from the client application via CCS, as soon as possible
-to maintain a constant flow of incoming messages. The aforementioned pending message limit doesn't
-apply to these ACKs. Even if the pending message count reaches 100, the 3rd-party app server
-should continue sending ACKs for messages received from CCS to avoid blocking delivery of new
-upstream messages.</p>
-
-<p>ACKs are only valid within the context of one connection. If the connection is
-closed before a message can be ACKed, the 3rd-party app server should wait for CCS
-to resend the upstream message before ACKing it again. Similarly, all pending messages for which an
-ACK/NACK was not received from CCS before the connection was closed should be sent again.
-</p>
-
-<h2 id="implement">Implementing an XMPP-based App Server</h2>
-
-<p>This section gives examples of implementing an app server that works with CCS.
-Note that a full GCM implementation requires a client-side implementation, in
-addition to the server. For more information, see <a href="client.html">
-Implementing GCM Client</a>.</a>
-
-<h3 id="smack">Java sample using the Smack library</h3>
-
-<p>Here is a sample app server written in Java, using the
-<a href="http://www.igniterealtime.org/projects/smack/">Smack</a> library.</p>
-
-<pre>import org.jivesoftware.smack.ConnectionConfiguration;
-import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
-import org.jivesoftware.smack.ConnectionListener;
-import org.jivesoftware.smack.PacketInterceptor;
-import org.jivesoftware.smack.PacketListener;
-import org.jivesoftware.smack.SmackException;
-import org.jivesoftware.smack.SmackException.NotConnectedException;
-import org.jivesoftware.smack.XMPPConnection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.PacketTypeFilter;
-import org.jivesoftware.smack.packet.DefaultPacketExtension;
-import org.jivesoftware.smack.packet.Message;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.PacketExtension;
-import org.jivesoftware.smack.provider.PacketExtensionProvider;
-import org.jivesoftware.smack.provider.ProviderManager;
-import org.jivesoftware.smack.tcp.XMPPTCPConnection;
-import org.jivesoftware.smack.util.StringUtils;
-import org.json.simple.JSONValue;
-import org.json.simple.parser.ParseException;
-import org.xmlpull.v1.XmlPullParser;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.net.ssl.SSLSocketFactory;
-
-/**
- * Sample Smack implementation of a client for GCM Cloud Connection Server. This
- * code can be run as a standalone CCS client.
- *
- * &lt;p&gt;For illustration purposes only.
- */
-public class SmackCcsClient {
-
- private static final Logger logger = Logger.getLogger(&quot;SmackCcsClient&quot;);
-
- private static final String GCM_SERVER = &quot;gcm.googleapis.com&quot;;
- private static final int GCM_PORT = 5235;
-
- private static final String GCM_ELEMENT_NAME = &quot;gcm&quot;;
- private static final String GCM_NAMESPACE = &quot;google:mobile:data&quot;;
-
- static {
-
- ProviderManager.addExtensionProvider(GCM_ELEMENT_NAME, GCM_NAMESPACE,
- new PacketExtensionProvider() {
- &#64;Override
- public PacketExtension parseExtension(XmlPullParser parser) throws
- Exception {
- String json = parser.nextText();
- return new GcmPacketExtension(json);
- }
- });
- }
-
- private XMPPConnection connection;
-
- /**
- * Indicates whether the connection is in draining state, which means that it
- * will not accept any new downstream messages.
- */
- protected volatile boolean connectionDraining = false;
-
- /**
- * Sends a downstream message to GCM.
- *
- * &#64;return true if the message has been successfully sent.
- */
- public boolean sendDownstreamMessage(String jsonRequest) throws
- NotConnectedException {
- if (!connectionDraining) {
- send(jsonRequest);
- return true;
- }
- logger.info(&quot;Dropping downstream message since the connection is draining&quot;);
- return false;
- }
-
- /**
- * Returns a random message id to uniquely identify a message.
- *
- * &lt;p&gt;Note: This is generated by a pseudo random number generator for
- * illustration purpose, and is not guaranteed to be unique.
- */
- public String nextMessageId() {
- return &quot;m-&quot; + UUID.randomUUID().toString();
- }
-
- /**
- * Sends a packet with contents provided.
- */
- protected void send(String jsonRequest) throws NotConnectedException {
- Packet request = new GcmPacketExtension(jsonRequest).toPacket();
- connection.sendPacket(request);
- }
-
- /**
- * Handles an upstream data message from a device application.
- *
- * &lt;p&gt;This sample echo server sends an echo message back to the device.
- * Subclasses should override this method to properly process upstream messages.
- */
- protected void handleUpstreamMessage(Map&lt;String, Object&gt; jsonObject) {
- // PackageName of the application that sent this message.
- String category = (String) jsonObject.get(&quot;category&quot;);
- String from = (String) jsonObject.get(&quot;from&quot;);
- &#64;SuppressWarnings(&quot;unchecked&quot;)
- Map&lt;String, String&gt; payload = (Map&lt;String, String&gt;) jsonObject.get(&quot;data&quot;);
- payload.put(&quot;ECHO&quot;, &quot;Application: &quot; + category);
-
- // Send an ECHO response back
- String echo = createJsonMessage(from, nextMessageId(), payload,
- &quot;echo:CollapseKey&quot;, null, false);
-
- try {
- sendDownstreamMessage(echo);
- } catch (NotConnectedException e) {
- logger.log(Level.WARNING, &quot;Not connected anymore, echo message is
- not sent&quot;, e);
- }
- }
-
- /**
- * Handles an ACK.
- *
- * &lt;p&gt;Logs a {@code INFO} message, but subclasses could override it to
- * properly handle ACKs.
- */
- protected void handleAckReceipt(Map&lt;String, Object&gt; jsonObject) {
- String messageId = (String) jsonObject.get(&quot;message_id&quot;);
- String from = (String) jsonObject.get(&quot;from&quot;);
- logger.log(Level.INFO, &quot;handleAckReceipt() from: &quot; + from + &quot;,
- messageId: &quot; + messageId);
- }
-
- /**
- * Handles a NACK.
- *
- * &lt;p&gt;Logs a {@code INFO} message, but subclasses could override it to
- * properly handle NACKs.
- */
- protected void handleNackReceipt(Map&lt;String, Object&gt; jsonObject) {
- String messageId = (String) jsonObject.get(&quot;message_id&quot;);
- String from = (String) jsonObject.get(&quot;from&quot;);
- logger.log(Level.INFO, &quot;handleNackReceipt() from: &quot; + from + &quot;,
- messageId: &quot; + messageId);
- }
-
- protected void handleControlMessage(Map&lt;String, Object&gt; jsonObject) {
- logger.log(Level.INFO, &quot;handleControlMessage(): &quot; + jsonObject);
- String controlType = (String) jsonObject.get(&quot;control_type&quot;);
- if (&quot;CONNECTION_DRAINING&quot;.equals(controlType)) {
- connectionDraining = true;
- } else {
- logger.log(Level.INFO, &quot;Unrecognized control type: %s. This could
- happen if new features are &quot; + &quot;added to the CCS protocol.&quot;,
- controlType);
- }
- }
-
- /**
- * Creates a JSON encoded GCM message.
- *
- * &#64;param to RegistrationId of the target device (Required).
- * &#64;param messageId Unique messageId for which CCS sends an
- * &quot;ack/nack&quot; (Required).
- * &#64;param payload Message content intended for the application. (Optional).
- * &#64;param collapseKey GCM collapse_key parameter (Optional).
- * &#64;param timeToLive GCM time_to_live parameter (Optional).
- * &#64;param delayWhileIdle GCM delay_while_idle parameter (Optional).
- * &#64;return JSON encoded GCM message.
- */
- public static String createJsonMessage(String to, String messageId,
- Map&lt;String, String&gt; payload, String collapseKey, Long timeToLive,
- Boolean delayWhileIdle) {
- Map&lt;String, Object&gt; message = new HashMap&lt;String, Object&gt;();
- message.put(&quot;to&quot;, to);
- if (collapseKey != null) {
- message.put(&quot;collapse_key&quot;, collapseKey);
- }
- if (timeToLive != null) {
- message.put(&quot;time_to_live&quot;, timeToLive);
- }
- if (delayWhileIdle != null &amp;&amp; delayWhileIdle) {
- message.put(&quot;delay_while_idle&quot;, true);
- }
- message.put(&quot;message_id&quot;, messageId);
- message.put(&quot;data&quot;, payload);
- return JSONValue.toJSONString(message);
- }
-
- /**
- * Creates a JSON encoded ACK message for an upstream message received
- * from an application.
- *
- * &#64;param to RegistrationId of the device who sent the upstream message.
- * &#64;param messageId messageId of the upstream message to be acknowledged to CCS.
- * &#64;return JSON encoded ack.
- */
- protected static String createJsonAck(String to, String messageId) {
- Map&lt;String, Object&gt; message = new HashMap&lt;String, Object&gt;();
- message.put(&quot;message_type&quot;, &quot;ack&quot;);
- message.put(&quot;to&quot;, to);
- message.put(&quot;message_id&quot;, messageId);
- return JSONValue.toJSONString(message);
- }
-
- /**
- * Connects to GCM Cloud Connection Server using the supplied credentials.
- *
- * &#64;param senderId Your GCM project number
- * &#64;param apiKey API Key of your project
- */
- public void connect(long senderId, String apiKey)
- throws XMPPException, IOException, SmackException {
- ConnectionConfiguration config =
- new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
- config.setSecurityMode(SecurityMode.enabled);
- config.setReconnectionAllowed(true);
- config.setRosterLoadedAtLogin(false);
- config.setSendPresence(false);
- config.setSocketFactory(SSLSocketFactory.getDefault());
-
- connection = new XMPPTCPConnection(config);
- connection.connect();
-
- connection.addConnectionListener(new LoggingConnectionListener());
-
- // Handle incoming packets
- connection.addPacketListener(new PacketListener() {
-
- &#64;Override
- public void processPacket(Packet packet) {
- logger.log(Level.INFO, &quot;Received: &quot; + packet.toXML());
- Message incomingMessage = (Message) packet;
- GcmPacketExtension gcmPacket =
- (GcmPacketExtension) incomingMessage.
- getExtension(GCM_NAMESPACE);
- String json = gcmPacket.getJson();
- try {
- &#64;SuppressWarnings(&quot;unchecked&quot;)
- Map&lt;String, Object&gt; jsonObject =
- (Map&lt;String, Object&gt;) JSONValue.
- parseWithException(json);
-
- // present for &quot;ack&quot;/&quot;nack&quot;, null otherwise
- Object messageType = jsonObject.get(&quot;message_type&quot;);
-
- if (messageType == null) {
- // Normal upstream data message
- handleUpstreamMessage(jsonObject);
-
- // Send ACK to CCS
- String messageId = (String) jsonObject.get(&quot;message_id&quot;);
- String from = (String) jsonObject.get(&quot;from&quot;);
- String ack = createJsonAck(from, messageId);
- send(ack);
- } else if (&quot;ack&quot;.equals(messageType.toString())) {
- // Process Ack
- handleAckReceipt(jsonObject);
- } else if (&quot;nack&quot;.equals(messageType.toString())) {
- // Process Nack
- handleNackReceipt(jsonObject);
- } else if (&quot;control&quot;.equals(messageType.toString())) {
- // Process control message
- handleControlMessage(jsonObject);
- } else {
- logger.log(Level.WARNING,
- &quot;Unrecognized message type (%s)&quot;,
- messageType.toString());
- }
- } catch (ParseException e) {
- logger.log(Level.SEVERE, &quot;Error parsing JSON &quot; + json, e);
- } catch (Exception e) {
- logger.log(Level.SEVERE, &quot;Failed to process packet&quot;, e);
- }
- }
- }, new PacketTypeFilter(Message.class));
-
- // Log all outgoing packets
- connection.addPacketInterceptor(new PacketInterceptor() {
- &#64;Override
- public void interceptPacket(Packet packet) {
- logger.log(Level.INFO, &quot;Sent: {0}&quot;, packet.toXML());
- }
- }, new PacketTypeFilter(Message.class));
-
- connection.login(senderId + &quot;&#64;gcm.googleapis.com&quot;, apiKey);
- }
-
- public static void main(String[] args) throws Exception {
- final long senderId = 1234567890L; // your GCM sender id
- final String password = &quot;Your API key&quot;;
-
- SmackCcsClient ccsClient = new SmackCcsClient();
-
- ccsClient.connect(senderId, password);
-
- // Send a sample hello downstream message to a device.
- String toRegId = &quot;RegistrationIdOfTheTargetDevice&quot;;
- String messageId = ccsClient.nextMessageId();
- Map&lt;String, String&gt; payload = new HashMap&lt;String, String&gt;();
- payload.put(&quot;Hello&quot;, &quot;World&quot;);
- payload.put(&quot;CCS&quot;, &quot;Dummy Message&quot;);
- payload.put(&quot;EmbeddedMessageId&quot;, messageId);
- String collapseKey = &quot;sample&quot;;
- Long timeToLive = 10000L;
- String message = createJsonMessage(toRegId, messageId, payload,
- collapseKey, timeToLive, true);
-
- ccsClient.sendDownstreamMessage(message);
- }
-
- /**
- * XMPP Packet Extension for GCM Cloud Connection Server.
- */
- private static final class GcmPacketExtension extends DefaultPacketExtension {
-
- private final String json;
-
- public GcmPacketExtension(String json) {
- super(GCM_ELEMENT_NAME, GCM_NAMESPACE);
- this.json = json;
- }
-
- public String getJson() {
- return json;
- }
-
- &#64;Override
- public String toXML() {
- return String.format(&quot;&lt;%s xmlns=\&quot;%s\&quot;&gt;%s&lt;/%s&gt;&quot;,
- GCM_ELEMENT_NAME, GCM_NAMESPACE,
- StringUtils.escapeForXML(json), GCM_ELEMENT_NAME);
- }
-
- public Packet toPacket() {
- Message message = new Message();
- message.addExtension(this);
- return message;
- }
- }
-
- private static final class LoggingConnectionListener
- implements ConnectionListener {
-
- &#64;Override
- public void connected(XMPPConnection xmppConnection) {
- logger.info(&quot;Connected.&quot;);
- }
-
- &#64;Override
- public void authenticated(XMPPConnection xmppConnection) {
- logger.info(&quot;Authenticated.&quot;);
- }
-
- &#64;Override
- public void reconnectionSuccessful() {
- logger.info(&quot;Reconnecting..&quot;);
- }
-
- &#64;Override
- public void reconnectionFailed(Exception e) {
- logger.log(Level.INFO, &quot;Reconnection failed.. &quot;, e);
- }
-
- &#64;Override
- public void reconnectingIn(int seconds) {
- logger.log(Level.INFO, &quot;Reconnecting in %d secs&quot;, seconds);
- }
-
- &#64;Override
- public void connectionClosedOnError(Exception e) {
- logger.info(&quot;Connection closed on error.&quot;);
- }
-
- &#64;Override
- public void connectionClosed() {
- logger.info(&quot;Connection closed.&quot;);
- }
- }
-}</pre>
-
-<h3 id="python">Python sample</h3>
-
-<p>Here is an example of a CCS app server written in Python. This sample echo
-server sends an initial message, and for every upstream message received, it sends
-a dummy response back to the application that sent the upstream message. This
-example illustrates how to connect, send, and receive GCM messages using XMPP. It
-shouldn't be used as-is on a production deployment.</p>
-
-<pre>
-#!/usr/bin/python
-import sys, json, xmpp, random, string
-
-SERVER = 'gcm.googleapis.com'
-PORT = 5235
-USERNAME = "Your GCM Sender Id"
-PASSWORD = "API Key"
-REGISTRATION_ID = "Registration Id of the target device"
-
-unacked_messages_quota = 100
-send_queue = []
-
-# Return a random alphanumerical id
-def random_id():
- rid = ''
- for x in range(8): rid += random.choice(string.ascii_letters + string.digits)
- return rid
-
-def message_callback(session, message):
- global unacked_messages_quota
- gcm = message.getTags('gcm')
- if gcm:
- gcm_json = gcm[0].getData()
- msg = json.loads(gcm_json)
- if not msg.has_key('message_type'):
- # Acknowledge the incoming message immediately.
- send({'to': msg['from'],
- 'message_type': 'ack',
- 'message_id': msg['message_id']})
- # Queue a response back to the server.
- if msg.has_key('from'):
- # Send a dummy echo response back to the app that sent the upstream message.
- send_queue.append({'to': msg['from'],
- 'message_id': random_id(),
- 'data': {'pong': 1}})
- elif msg['message_type'] == 'ack' or msg['message_type'] == 'nack':
- unacked_messages_quota += 1
-
-def send(json_dict):
- template = (&quot;&lt;message&gt;&lt;gcm xmlns='google:mobile:data'&gt;{1}&lt;/gcm&gt;&lt;/message&gt;&quot;)
- client.send(xmpp.protocol.Message(
- node=template.format(client.Bind.bound[0], json.dumps(json_dict))))
-
-def flush_queued_messages():
- global unacked_messages_quota
- while len(send_queue) and unacked_messages_quota &gt; 0:
- send(send_queue.pop(0))
- unacked_messages_quota -= 1
-
-client = xmpp.Client('gcm.googleapis.com', debug=['socket'])
-client.connect(server=(SERVER,PORT), secure=1, use_srv=False)
-auth = client.auth(USERNAME, PASSWORD)
-if not auth:
- print 'Authentication failed!'
- sys.exit(1)
-
-client.RegisterHandler('message', message_callback)
-
-send_queue.append({'to': REGISTRATION_ID,
- 'message_id': 'reg_id',
- 'data': {'message_destination': 'RegId',
- 'message_id': random_id()}})
-
-while True:
- client.Process(1)
- flush_queued_messages()</pre>
diff --git a/docs/html/google/gcm/client.jd b/docs/html/google/gcm/client.jd
deleted file mode 100644
index 9cb3f84..0000000
--- a/docs/html/google/gcm/client.jd
+++ /dev/null
@@ -1,689 +0,0 @@
-page.title=Implementing GCM Client on Android
-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-receive">Receive a downstream message</a></li>
- <li><a href="#sample-send">Send an upstream 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 Google Cloud Messaging (GCM) Android 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/package-summary.html">
-{@code GoogleCloudMessaging}</a> API.</p>
-
-<p>Here are the requirements for running a GCM Android client:</p>
-
-<ul>
- <li>At a bare minimum, GCM requires devices running Android 2.2 or higher that also have the
-Google Play Store application installed, or an emulator running Android 2.2
-with Google APIs. Note that you are not limited to deploying your
-Android applications through Google Play Store.</li>
- <li>However, if you want to continue to use new GCM features that are distributed
-through Google Play Services, the device must be running Android 2.3 or higher, or
-you can use an emulator running Android 2.3 with Google APIs.</li>
-<li>On Android devices, GCM uses an existing connection for Google services. For
-pre-3.0 devices, this requires users to set up their Google accounts on their mobile
-devices. A Google account is not a requirement on devices running Android 4.0.4 or higher.</li>
-
-</ul>
-
-<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/package-summary.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.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.permission.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> API. 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 registration ID 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 registration ID 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 registration ID. {@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 registration ID - 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 registration ID. 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>
-
-<h4 id="reg-errors">Handle registration errors</h4>
-
-<p>As stated above, an Android app must register with GCM servers and get a registration ID
-before it can receive messages. A given registration ID is not guaranteed to last indefinitely,
-so the first thing your app should always do is check to make sure it has a valid
-registration ID (as shown in the code snippets above).</p>
-
-<p>In addition to confirming that it has a valid registration ID, your app should be prepared to handle
-the registration error {@code TOO_MANY_REGISTRATIONS}. This error indicates that the device
-has too many apps registered with GCM. The error only occurs in cases where there are
-extreme numbers of apps, so it should not affect the average user. The remedy is to prompt
-the user to delete some of the other client apps from the device to make
-room for the new one.</p>
-
-<h3 id="sample-receive">Receive a downstream 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. </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>
-
-
-<h3 id="sample-send">Send an upstream 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> API. 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>
-
-<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 <a href="http://play.google.com/apps/publish">Developer Console</a>.</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>
-
diff --git a/docs/html/google/gcm/demo.jd b/docs/html/google/gcm/demo.jd
deleted file mode 100644
index 012eb9a..0000000
--- a/docs/html/google/gcm/demo.jd
+++ /dev/null
@@ -1,277 +0,0 @@
-page.title=GCM Demo Application
-@jd:body
-
-<div id="deprecatedSticker">
- <a href="#"
- onclick="$('#naMessage').show();$('#deprecatedSticker').hide();return false">
- <strong>This doc is deprecated</strong></a>
-</div>
-
-
-<div id="naMessage" style="display:block">
-<div><p><strong>The information in this document has been superseded by <a href="server.html">GCM Server</a> and <a href="client.html">GCM Client</a></strong>. Please use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> API instead of the GCM client helper library. The GCM server helper library is still valid.</p>
-
- <input style="margin-top:1em;padding:5px" type="button"
- value="That's nice, but I still want to read this document"
-onclick="$('#naMessage').hide();$('#deprecatedSticker').show()" />
-</div>
-</div>
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>Quickview</h2>
-
-<ul>
-<li>Build and run the GCM demo app.</li>
-<li>Understand how to set up both the client and server sides of a GCM app.</li>
-<li>Become familiar with the GCM helper libraries.</li>
-</ul>
-
-
-<h2>In this document</h2>
-
-<ol>
- <li><a href="#requirements">Requirements</a> </li>
- <li><a href="#gcm-setup">Setting Up GCM</a></li>
- <li><a href="#server-setup">Setting Up the Server</a>
- <ol>
- <li><a href="#webserver-setup">Using a standard web server</a></li>
- <li><a href="#appengine-setup">Using App Engine for Java</a></li>
- </ol>
- </li>
- <li><a href="#device-setup">Setting Up the Device</a></li>
-</ol>
-
-</div>
-</div>
-
-<p class="note"><strong>Note:</strong> This tutorial describes how to develop GCM-enabled apps using the helper libraries. This is just one approach. For a more comprehensive discussion of the available APIs and development paths, see <a href="gs.html">Getting Started</a>.
-
-<p>The Google Cloud Messaging (GCM) Demo demonstrates how to use the Google Cloud Messaging framework in your Android application. This tutorial walks you through setting up and running the demo.</p>
-
-
-<p>This demo consists of the following pieces: </p>
-<ul>
- <li>A web server containing a page where you can send messages.</li>
- <li>An Android application that receives and displays such messages.</li>
-</ul>
-<p>See the <a href="{@docRoot}reference/com/google/android/gcm/package-summary.html">reference</a> for the client and server helper libraries used in this demo.</p>
-
-<p>The sections below describe how to download the demo code and helper libraries from the SDK Manager. The demo code and helper libraries are also available at the <a href="http://code.google.com/p/gcm">open source site</a>.
-
-<h2 id="requirements">Requirements</h2>
-<p>For the web server:</p>
-<ul>
- <li> <a href="http://ant.apache.org/">Ant 1.8</a> (it might work with earlier versions, but it's not guaranteed).</li>
- <li>One of the following:
- <ul>
- <li>A running web server compatible with Servlets API version 2.5, such as <a href="http://tomcat.apache.org/">Tomcat 6</a> or <a href="http://jetty.codehaus.org/">Jetty</a>, or</li>
- <li><a href="http://code.google.com/appengine/">Java App Engine SDK</a> version 1.6 or later.</li>
- </ul>
- </li>
- <li>A Google account registered to use GCM.</li>
- <li>The API key for that account.</li>
-</ul>
-<p>For the Android application:</p>
-<ul>
- <li>Emulator (or device) running Android 2.2 with Google APIs.</li>
- <li>The Google API project number of the account registered to use GCM.</li>
-</ul>
-<h2 id="gcm-setup">Setting Up GCM</h2>
-<p>Before proceeding with the server and client setup, it's necessary to register a Google account with the Google API Console, enable Google Cloud Messaging in GCM, and obtain an API key from the <a href="https://code.google.com/apis/console">Google API Console</a>.</p>
-<p>For instructions on how to set up GCM, see <a href="gs.html">Getting Started</a>.</p>
-
-
-<h2 id="server-setup">Setting Up the Server</h2>
-<p>This section describes the different options for setting up a server.</p>
-<h3 id="webserver-setup">Using a standard web server</h3>
-<p>To set up the server using a standard, servlet-compliant web server:</p>
-<ol>
- <li> From the SDK Manager, install <strong>Extras &gt; Google Cloud Messaging for Android Library</strong>.
-
-
- <p>This creates a <code>gcm</code> directory under <code><em>YOUR_SDK_ROOT</em>/extras/google/</code> containing these subdirectories: <code>gcm-client</code>, <code>gcm-server</code>, <code>samples/gcm-demo-client</code>, <code>samples/gcm-demo-server</code>, and <code>samples/gcm-demo-appengine</code>.</p>
-
-<p class="note"><strong>Note:</strong> If you don't see <strong>Extras &gt; Google Cloud Messaging for Android Library</strong> in the SDK Manager, make sure you are running version 20 or higher. Be sure to restart the SDK Manager after updating it.</p>
- </li>
-
- <li>In a text editor, edit the <code>samples/gcm-demo-server/WebContent/WEB-INF/classes/api.key</code> and replace the existing text with the API key obtained above.</li>
- <li>In a shell window, go to the <code>samples/gcm-demo-server</code> directory.</li>
- <li>Generate the server's WAR file by running <code>ant war</code>:</li>
-
- <pre class="prettyprint">$ ant war
-
-Buildfile:build.xml
-
-init:
- [mkdir] Created dir: build/classes
- [mkdir] Created dir: dist
-
-compile:
- [javac] Compiling 6 source files to build/classes
-
-war:
- [war] Building war: <strong>dist/gcm-demo.war</strong>
-
-BUILD SUCCESSFUL
-Total time: 0 seconds
-</pre>
-
- <li>Deploy the <code>dist/gcm-demo.war</code> to your running server. For instance, if you're using Jetty, copy <code>gcm-demo.war</code> to the <code>webapps</code> directory of the Jetty installation.</li>
- <li>Open the server's main page in a browser. The URL depends on the server you're using and your machine's IP address, but it will be something like <code>http://192.168.1.10:8080/gcm-demo/home</code>, where <code>gcm-demo</code> is the application context and <code>/home</code> is the path of the main servlet.
-
- </li>
-</ol>
-<p class="note"><strong>Note:</strong> You can get the IP by running <code>ifconfig</code> on Linux or MacOS, or <code>ipconfig</code> on Windows. </p>
-
-<p> You server is now ready.</p>
-<h3 id="appengine-setup">Using App Engine for Java</h3>
-
-<p>To set up the server using a standard App Engine for Java:</p>
-<ol>
- <li> From the SDK Manager, install <strong>Extras &gt; Google Cloud Messaging for Android Library</strong>.
- <p>This creates a <code>gcm</code> directory under <code><em>YOUR_SDK_ROOT</em>/extras/google/</code> containing these subdirectories: <code>gcm-client</code>, <code>gcm-server</code>, <code>samples/gcm-demo-client</code>, <code>samples/gcm-demo-server</code>, and <code>samples/gcm-demo-appengine</code>.</p>
- </li>
- <li>In a text editor, edit <code>samples/gcm-demo-appengine/src/com/google/android/gcm/demo/server/ApiKeyInitializer.java</code> and replace the existing text with the API key obtained above.
- <p class="note"><strong>Note:</strong> The API key value set in that class will be used just once to create a persistent entity on App Engine. If you deploy the application, you can use App Engine's <code>Datastore Viewer</code> to change it later.</p>
-
- </li>
- <li>In a shell window, go to the <code>samples/gcm-demo-appengine</code> directory.</li>
- <li>Start the development App Engine server by <code>ant runserver</code>, using the <code>-Dsdk.dir</code> to indicate the location of the App Engine SDK and <code>-Dserver.host</code> to set your server's hostname or IP address:</li>
-
-<pre class="prettyprint">
-$ ant -Dsdk.dir=/opt/google/appengine-java-sdk runserver -Dserver.host=192.168.1.10
-Buildfile: gcm-demo-appengine/build.xml
-
-init:
- [mkdir] Created dir: gcm-demo-appengine/dist
-
-copyjars:
-
-compile:
-
-datanucleusenhance:
- [enhance] DataNucleus Enhancer (version 1.1.4) : Enhancement of classes
- [enhance] DataNucleus Enhancer completed with success for 0 classes. Timings : input=28 ms, enhance=0 ms, total=28 ms. Consult the log for full details
- [enhance] DataNucleus Enhancer completed and no classes were enhanced. Consult the log for full details
-
-runserver:
- [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.jetty.JettyLogger info
- [java] INFO: Logging to JettyLogger(null) via com.google.apphosting.utils.jetty.JettyLogger
- [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml
- [java] INFO: Successfully processed gcm-demo-appengine/WebContent/WEB-INF/appengine-web.xml
- [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml
- [java] INFO: Successfully processed gcm-demo-appengine/WebContent/WEB-INF/web.xml
- [java] Jun 15, 2012 8:46:09 PM com.google.android.gcm.demo.server.ApiKeyInitializer contextInitialized
- [java] SEVERE: Created fake key. Please go to App Engine admin console, change its value to your API Key (the entity type is 'Settings' and its field to be changed is 'ApiKey'), then restart the server!
- [java] Jun 15, 2012 8:46:09 PM com.google.appengine.tools.development.DevAppServerImpl start
- [java] INFO: The server is running at http://192.168.1.10:8080/
- [java] Jun 15, 2012 8:46:09 PM com.google.appengine.tools.development.DevAppServerImpl start
- [java] INFO: The admin console is running at http://192.168.1.10:8080/_ah/admin
-</pre>
-
- <li>Open the server's main page in a browser. The URL depends on the server you're using and your machine's IP address, but it will be something like <code>http://192.168.1.10:8080/home</code>, where <code>/home</code> is the path of the main servlet.</li>
-
- <p class="note"><strong>Note:</strong> You can get the IP by running <code>ifconfig</code> on Linux or MacOS, or <code>ipconfig</code> on Windows.</p>
-
-</ol>
-<p> You server is now ready.</p>
-<h2 id="device-setup">Setting Up the Device</h2>
-<p>To set up the device:</p>
-<ol>
- <li> From the SDK Manager, install <strong>Extras &gt; Google Cloud Messaging for Android Library</strong>.
- <p>This creates a <code>gcm</code> directory under <code><em>YOUR_SDK_ROOT</em>/extras/google</code> containing these subdirectories: <code>gcm-client</code>, <code>gcm-server</code>, <code>samples/gcm-demo-client</code>, <code>samples/gcm-demo-server</code>, and <code>samples/gcm-demo-appengine</code>.</p>
- </li>
- <li>Using a text editor, open <code>samples/gcm-demo-client/src/com/google/android/gcm/demo/app/CommonUtilities.java</code> and set the proper values for the <code>SENDER_ID</code> and <code>SERVER_URL</code> constants. For example:</li>
-
-<pre class="prettyprint pretty-java">
-static final String SERVER_URL = &quot;http://192.168.1.10:8080/gcm-demo&quot;;
-static final String SENDER_ID = &quot;4815162342&quot;;</pre>
-<p>Note that the <code>SERVER_URL</code> is the URL for the server and the application's context (or just server, if you are using App Engine), and it does not include the forward slash (<code>/</code>). Also note that <code>SENDER_ID</code> is the Google API project number you obtained in the server setup steps above.</p>
-
- <li>In a shell window, go to the <code>gcm-demo-client</code> directory.</li>
- <li>Use the SDK's <code>android</code> tool to generate the <code>ant</code> build files:</li>
-
-<pre class="prettyprint">
-$ android update project --name GCMDemo -p . --target android-16
-Updated project.properties
-Updated local.properties
-Updated file ./build.xml
-Updated file ./proguard-project.txt
-</pre>
-<p>If this command fails becase <code>android-16</code> is not recognized, try a different target (as long as it is at least <code>android-15</code>).</p>
-
-<li>Use <code>ant</code> to build the application's APK file:</li>
-
- <pre class="prettyprint">
-$ ant clean debug
-Buildfile: build.xml
-
-...
-
-
--do-debug:
-[zipalign] Running zip align on final apk...
- [echo] Debug Package: bin/GCMDemo-debug.apk
-[propertyfile] Creating new property file: <strong>bin/build.prop</strong>
-[propertyfile] Updating property file: bin/build.prop
-[propertyfile] Updating property file: bin/build.prop
-[propertyfile] Updating property file: bin/build.prop
-
--post-build:
-
-debug:
-
-BUILD SUCCESSFUL
-Total time: 3 seconds
- </pre>
-
-<li>Start the Android emulator:</li>
-<pre class="prettyprint">$emulator -avd my_avd
-</pre>
-
-<p> This example assumes there is an AVD (Android Virtual Device) named <code>my_avd</code> previously configured with Android 2.2 and Google APIs level 8. For more information on how to run an Android emulator, see <a href="{@docRoot}tools/devices/index.html">Managing Virtual Devices</a> in the Android Developers Guide.</p>
-
-<li>Make sure there is a Google account added to the emulator. It doesn't have to be any account (like the <code>senderId</code>) in particular. </li>
-
-<p> If the emulator is running Android 4.0.4 or later, this step is optional as GCM does not require an account from this version on.</p>
-
-<li>Install the application in the emulator:</li>
-
-<pre class="prettyprint">
-$ ant installd
-Buildfile: gcm-demo-client/build.xml
-
--set-mode-check:
-
--set-debug-files:
-
-install:
- [echo] Installing gcm-demo-client/bin/GCMDemo-debug.apk onto default emulator or device...
- [exec] 1719 KB/s (47158 bytes in 0.026s)
- [exec] pkg: /data/local/tmp/GCMDemo-debug.apk
- [exec] Success
-
-installd:
-
-BUILD SUCCESSFUL
-Total time: 3 seconds
-</pre>
- <li>In the emulator, launch the GCM Demo app. The initial screen should look like this:</li>
- <p><img src="{@docRoot}images/gcm/gcm-avd-home-auto-reg.png" class="screenshot" /></p>
-<p class="note"><strong>Note:</strong> What happened? When the device received a registration callback intent from GCM, it contacted the server to register itself, using the register servlet and passing the registration ID received from GCM; the server then saved the registration ID to use it to send messages to the phone.</p>
-<li> Now go back to your browser and refresh the page. It will show that there is one device registered:</li>
-
-<p><img src="{@docRoot}images/gcm/gcm-device-reg.png" class="screenshot" /></p>
-
-<li>Click on <strong>Send Message</strong>. The browser should show:</li>
-<p><img src="{@docRoot}images/gcm/gcm-sent-server.png" class="screenshot" /></p>
-
-<p>And in your emulator:</p>
-
-<p><img src="{@docRoot}images/gcm/gcm-avd-first-msg.png" class="screenshot" /></p>
-
-<p class="note"><strong>Note:</strong> What happened? When you clicked the button, the web server sent a message to GCM addressed to your device (more specifically, to the registration ID returned by GCM during the registration step). The device then received the message and displayed in the main activity; it also issued a system notification so the user would be notified even if the demo application was not running.</p>
-</ol>
-
diff --git a/docs/html/google/gcm/gcm.jd b/docs/html/google/gcm/gcm.jd
deleted file mode 100644
index d4bb45e..0000000
--- a/docs/html/google/gcm/gcm.jd
+++ /dev/null
@@ -1,307 +0,0 @@
-page.title=Overview
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>In this document</h2>
-
-<ol class="toc">
- <li><a href="#key">Key Concepts</a></li>
- <li><a href="#arch">Architectural Overview</a></li>
- <li><a href="#lifecycle">Lifecycle Flow</a></li>
- <li><a href="#reg">Register to enable GCM</a></li>
-</ol>
-
-</div>
-</div>
-
-<p>Google Cloud Messaging (GCM) is a free service that enables developers
-to send downstream messages (from servers to GCM-enabled client apps), and
-upstream messages (from the GCM-enabled client apps to servers).
-This could be a lightweight message telling the client app
-that there is new data to be fetched from the server (for instance, a "new email"
-notification informing the app that it is out of sync with the back end),
-or it could be a message containing up to 4kb of payload
-data (so apps like instant messaging can consume the message directly). The GCM
-service handles all aspects of queueing of messages and delivery to and from
-the target client app.</p>
-
-
-<h2 id="key">Key Concepts</h2>
-
-<p>This table summarizes the key terms and concepts involved in GCM. It is
-divided into these categories:</p>
-<ul>
- <li><strong>Components</strong> &mdash; The entities that play a primary role in
-GCM.</li>
- <li><strong>Credentials</strong> &mdash; The IDs and tokens that are used in
-GCM to ensure that all parties have been authenticated, and
-that the message is going to the correct place.</li>
-</ul>
-
-<p class="table-caption" id="table1">
- <strong>Table 1.</strong> GCM components and credentials.</p>
-
-<table>
- <tr>
- <th colspan="2">Components</th>
- </tr>
-<tr>
- <td><strong>GCM Connection Servers</strong></td>
- <td>The Google-provided servers involved in sending messages between the
-3rd-party app server and the client app.</td>
- </tr>
- <tr>
- <td><strong>Client App</strong></td>
- <td>A GCM-enabled client app that communicates with a 3rd-party app server.</td>
- </tr>
- <tr>
- <td><strong>3rd-party App Server</strong></td>
- <td>An app server that you write as part of implementing
-GCM. The 3rd-party app server sends data to a client app via
-the GCM connection server.</td>
- </tr>
- <tr>
- <th colspan="2">Credentials</th>
- </tr>
- <tr>
- <td id="senderid"><strong>Sender ID</strong></td>
- <td>A project number you acquire from the API console, as described in
-<a href="gs.html#create-proj">Getting Started</a>. The sender
-ID is used in the <a href="#register">registration process</a> to identify a
-3rd-party app server that is permitted to send messages to the client app.</td>
- </tr>
- <tr>
- <td id="apikey"><strong>Sender Auth Token</strong></td>
- <td>An API key that is saved on the 3rd-party app
-server that gives the app server authorized access to Google services.
-The API key is included in the header of POST requests.
-</td>
- </tr>
- <tr>
- <td><strong>Application ID</strong></td>
- <td>The client app that is registering to receive messages. How this is implemented
-is platform-dependent. For example, an Android app
-is identified by the package name from the <a href="client.html#manifest">manifest</a>.
-This ensures that the messages are targeted to the correct Android app.</td>
- </tr>
- <tr>
- <td><strong>Registration ID</strong></td>
- <td>An ID issued by the GCM servers to the client app that allows
-it to receive messages. Note that registration IDs must be kept secret.
-
-</td>
- </tr>
-
-</table>
-
-<h2 id="arch">Architectural Overview</h2>
-
-<p>A GCM implementation includes a Google-provided
-connection server, a 3rd-party app server that interacts with the connection
-server, and a GCM-enabled client app. For example, this diagram shows GCM
-communicating with a client app on an Android device:</p>
-
-<img src="{@docRoot}images/gcm/GCM-arch.png">
-
-<p class="img-caption">
- <strong>Figure 1.</strong> GCM Architecture.
-</p>
-
-<p>This is how these components interact:</p>
-<ul>
- <li>Google-provided <strong>GCM Connection Servers</strong> take messages from
-a 3rd-party app server and send these messages to a
-GCM-enabled client app (the &quot;client app&quot;).
-Currently Google provides connection servers for <a href="http.html">HTTP</a>
-and <a href="ccs.html">XMPP</a>.</li>
- <li>The <strong>3rd-Party App Server</strong> is a component that you
-implement to work with your chosen GCM connection server(s). App servers send
-messages to a GCM connection server; the connection server enqueues and stores the
-message, and then sends it to the client app.
-For more information, see <a href="server.html">Implementing GCM Server</a>.</li>
- <li>The <strong>Client App</strong> is a GCM-enabled client app.
-To receive GCM messages, this app must register with GCM and get a
-registration ID. If you are using the <a href="ccs.html">XMPP</a> (CCS) connection
-server, the client app can send "upstream" messages back to the 3rd-party app server.
-For more information on how to implement the client app, see
-the documentation for your platform.</li>
-</ul>
-
-<h2 id="lifecycle">Lifecycle Flow</h2>
-
-<ul>
- <li><strong>Register to enable GCM</strong>. A client app registers to receive messages.
-For more discussion, see <a href="#register">Register to enable GCM</a>.</li>
- <li><strong>Send and receive downstream messages</strong>.
- <ul>
- <li>Send a message. A 3rd-party app server sends messages to the client app:
- <ol>
- <li>The 3rd-party app server <a href="server.html#send-msg">sends a message</a>
-to GCM connection servers.</li>
- <li>The GCM connection server enqueues and stores the message if the device is offline.</li>
- <li>When the device is online, the GCM connection server sends the message to the device. </li>
- <li>On the device, the client app receives the message according to the platform-specific implementation.
-See your platform-specific documentation for details.</li>
- </ol>
- </li>
- <li>Receive a message. A client app
-receives a message from a GCM server. See your platform-specific documentation for details
-on how a client app in that environment processes the messages it receives.</li>
- </ul>
-</li>
-
- <li><strong>Send and receive upstream messages</strong>. This feature is only available if
-you're using the <a href="ccs.html">XMPP Cloud Connection Server</a> (CCS).
-<ul>
- <li>Send a message. A client app sends messages to the 3rd-party app server:
- <ol>
- <li>On the device, the client app sends messages to XMPP (CCS).See your platform-specific
- documentation for details on how a client app can send a message to XMPP (CCS).</li>
- <li>XMPP (CCS) enqueues and stores the message if the server is disconnected.</li>
- <li>When the 3rd-party app server is re-connected, XMPP (CCS) sends the message to the 3rd-party app server.</li>
- </ol>
- </li>
- <li>Receive a message. A 3rd-party app server receives a message from XMPP (CCS) and then does the following:
- <ol>
- <li>Parses the message header to verify client app sender information.
- <li>Sends "ack" to GCM XMPP connection server to acknowledge receiving the message.
- <li>Optionally parses the message payload, as defined by the client app.
- </ol>
-</li>
-</ul>
-
-</li>
-
-
-</ul>
-
-<h2 id="reg">Register to enable GCM</h2>
-
-<p>Regardless of the platform you're developing on, the first step
-a client app must do is register with GCM. This section covers some of the general
-best practices for registration and unregistration. See your platform-specific docs for
-details on writing a GCM-enabled client app on that platform.</p>
-
-<h3 id="reg-state">Keeping the Registration State in Sync</h3>
-<p>Whenever the app registers as described in
-<a href="{@docRoot}google/gcm/client.html">Implementing GCM Client</a>,
-it should save the registration ID for future use, pass it to the
-3rd-party server to complete the registration, and keep track of
-whether the server completed the registration. If the server fails
-to complete the registration, the client app should retry passing the
-registration ID to 3rd-party app server to complete the registration.
-If this continues to fail, the client app should unregister from GCM.</p>
-
-<p>There are also two other scenarios that require special care:</p>
-<ul>
- <li>Client app update</li>
- <li>Backup and restore
- </li>
-</ul>
-<p><bold>Client app update:</bold> When a client app is updated, it should invalidate its existing registration
-ID, as it is not guaranteed to work with the new version. The recommended way to achieve
-this validation is by storing the current app version when a registration
-ID is stored. Then when the app starts, compare the stored value with
-the current app version. If they do not match, invalidate the stored data
-and start the registration process again.</p>
-
-<p><bold>Backup and restore: </bold> You should not save the registration ID when an app is
-backed up. This is because the registration ID could become invalid by the time
-the app is restored, which would put the app in an invalid state
-(that is, the app thinks it is registered, but the server and GCM do not
-store that registration ID anymore&mdash;thus the app will not get more
-messages). The best practice is to initiate the registration process as if the app has been
-installed for the first time.</p>
-
-<h4 id="canonical">Canonical IDs</h4>
-<p>If a bug in the app triggers multiple
-registrations for the same device, it can be hard to reconcile state and you might
-end up with duplicate messages.</p>
-<p>GCM provides a facility called &quot;canonical registration IDs&quot; to easily
-recover from these situations. A canonical registration ID is defined to be the ID
-of the last registration requested by your app. This is the ID that the
-server should use when sending messages to the device.</p>
-<p>If later on you try to send a message using a different registration ID, GCM
-will process the request as usual, but it will include the canonical registration
-ID in the <code>registration_id</code> field of the response. Make sure to replace
-the registration ID stored in your server with this canonical ID, as eventually
-the ID you're using will stop working.</p>
-
-<h3 id="retry">Automatic Retry Using Exponential Back-Off</h3>
-
-<p>When registration or unregistration fails, the app should retry the failed operation.</p>
-<p>In the simplest case, if your app attempts to register and GCM is not a
-fundamental part of the app, the app could simply ignore the error
-and try to register again the next time it starts. Otherwise, it should retry the
-previous operation using exponential back-off. In exponential back-off, each time
-there is a failure, it should wait twice the previous amount of time before trying
-again.
-</p>
-
-<h3 id="unreg">Unregistration</h3>
-
-<p>This section explains when you should unregister in GCM and what happens
-when you do.</p>
-
-<h4 id="unreg-why">Why you should rarely unregister</h4>
-
-<p>You should only need to unregister in rare cases, such as
-if you want an app to stop receiving messages, or if you suspect that the registration ID has
-been compromised. In general, once an app has a registration ID, you shouldn't need
-to change it.</p>
-
-<p>In particular, you should never unregister your app as a mechanism for
-logout or for switching between users, for the following reasons:</p>
-
-<ul>
- <li>A registration ID isn't associated with a particular
- logged in user. If you unregister and then re-register, GCM may return the same
- ID or a different ID&mdash;there's no guarantee either way.</li>
-
- <li>Unregistration may take up to 5 minutes to propagate.</li>
- <li>After unregistration, re-registration may again take up to 5 minutes to
-propagate. During this time messages may be rejected due to the state of being
-unregistered, and after all this, messages may still go to the wrong user.</li>
-</ul>
-
-
-<p>To make sure that messages go to the intended user:</p>
-
-<ul>
- <li>Your app server can maintain a mapping between the current user
-and the registration ID.</li>
- <li>The app can then check to ensure that messages it
-receives match the logged in user.</li>
-</ul>
-
-
-<h4 id="unreg-how">How unregistration works</h4>
-
-<p>A client app can be automatically unregistered after it is uninstalled.
-However, this process does not happen right away. What happens in
-this scenario is as follows:</p>
-<ol>
- <li>The end user uninstalls the client app.</li>
- <li>The 3rd-party app server sends a message to GCM server.</li>
- <li>The GCM server sends the message to the GCM client on the device.</li>
- <li>The GCM client on the device receives the message and detects that the client app has been
- uninstalled; the detection details depend on the platform on which the client app is running.
-</li>
- <li>The GCM client on the device informs the GCM server that the client app was uninstalled.</li>
- <li>The GCM server marks the registration ID for deletion.</li>
- <li>The 3rd-party app server sends a message to GCM.</li>
- <li>The GCM returns a <code>NotRegistered</code> error message to the 3rd-party app server.</li>
- <li>The 3rd-party app server deletes the registration ID.
- </li>
-</ol>
-
-<p>Note that it might take a while for the registration ID be completely removed
-from GCM. Thus it is possible that messages sent during step 7 above gets a valid
-message ID as response, even though the message will not be delivered to the client app.
-Eventually, the registration ID will be removed and the server will get a
-<code>NotRegistered</code> error, without any further action being required from
-the 3rd-party server (this scenario happens frequently while an app is
-being developed and tested).</p>
-
diff --git a/docs/html/google/gcm/gs.jd b/docs/html/google/gcm/gs.jd
deleted file mode 100644
index 2331292..0000000
--- a/docs/html/google/gcm/gs.jd
+++ /dev/null
@@ -1,94 +0,0 @@
-page.title=Getting Started on Android
-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="#create-proj">Creating a Google API Project</a></li>
-<li><a href="#gcm-service">Enabling the GCM Service</a></li>
-<li><a href="#access-key">Obtaining an API Key</a></li>
-<li><a href="#next">Next Steps</a></li>
-</ol>
-
-<h2>See Also</h2>
-
-<ol class="toc">
-<li><a href="https://cloud.google.com/console">Google Cloud Console</a></li>
-<li><a href="https://developers.google.com/console/help/new/">Google Cloud Console Help</a></li>
-</ol>
-
-</div>
-</div>
-
-<p>This document tells you how to get started setting up a Google Cloud Messaging
-(GCM) implementation.
-Before you begin, make sure to <a href="/google/play-services/setup.html">set up
-the Google Play Services SDK</a>. You need this SDK to use the
-<a href="{@docRoot}reference/com/google/android/gms/gcm/package-summary.html">
-GCM APIs</a>.</p>
-
-<h2 id="create-proj">Creating a Google API project</h2>
-<p>To create a Google API project:</p>
-<ol>
- <li>Open the <a href="https://cloud.google.com/console">Google Developers Console</a>.
- </li>
- <li>If you haven't created an API project yet, click <strong>Create Project</strong>.</li>
-
- <li>Supply a project name and click <strong>Create</strong>.
-
-<p>Once the project has been created, a page appears that displays your project ID and
-project number. For example, <strong>Project Number: 670330094152</strong>.</p></li>
-
- <li>Copy down your project number. You will use it later on as the
- <a href="{@docRoot}google/gcm/gcm.html#senderid">GCM sender ID</a>.</li>
-
-</ol>
-<h2 id="gcm-service">Enabling the GCM Service</h2>
-<p>To enable the GCM service:</p>
-<ol>
- <li>In the sidebar on the left, select <strong>APIs &amp; auth</strong>. </li>
- <li>In the displayed list of APIs, turn the <strong>Google Cloud Messaging for Android
- </strong> toggle to ON.</li>
-
-</ol>
-<h2 id="access-key">Obtaining an API Key</h2>
-<p>To obtain an API key:</p>
-<ol>
- <li>In the sidebar on the left, select <strong>APIs &amp; auth > Credentials</strong>.</li>
-
- <li>Under <strong>Public API access</strong>, click <strong>Create new key</strong>.</li>
-
-<li>In the <strong>Create a new key</strong> dialog, click <strong>Server key</strong>.</li>
-
-<li>In the resulting configuration dialog, supply your server's IP address. For testing
-purposes, you can use {@code 0.0.0.0/0}.</p></li>
-<li>Click <strong>Create</strong>.</li>
-
-<li>In the refreshed page, copy the
-<a href="{@docRoot}google/gcm/gcm.html#apikey">API key</a>.
-You will need the API key later on to perform authentication in your app server.</li>
-
-<p class="note"><strong>Note:</strong> If you need to rotate the key, click
-<strong>Regenerate key</strong>. A new key will be created. If you think the key has been
-compromised and you want to delete it immediately, click <strong>Delete</strong>.</p>
-</ol>
-
-<h2 id="next">Next Steps</h2>
-
-<p>Once you've finished the tasks listed above, you're ready to start
-implementing GCM. Here is an overview of the basic steps:</p>
-
-<ol>
- <li>Implement an app server (the "3rd-party app server") to interact
-with your chosen GCM connection server. The app server sends data to a
-GCM-enabled Android client app via the GCM connection server. For more
-information about implementing the server side, see <a href="server.html">
-Implementing GCM Server</a>.</li>
-<li>Write your client app. This is the GCM-enabled Android app that runs
-on a device. See <a href="client.html">Implementing GCM Client</a> for more information.</li>
-</ol>
diff --git a/docs/html/google/gcm/helper.jd b/docs/html/google/gcm/helper.jd
deleted file mode 100644
index 19dcdc5..0000000
--- a/docs/html/google/gcm/helper.jd
+++ /dev/null
@@ -1,199 +0,0 @@
-page.title=Using the GCM Helper Libraries
-page.tags=cloud,push,messaging
-@jd:body
-
-<div id="deprecatedSticker">
- <a href="#"
- onclick="$('#naMessage').show();$('#deprecatedSticker').hide();return false">
- <strong>This doc is deprecated</strong></a>
-</div>
-
-
-<div id="naMessage" style="display:block">
-<div><p><strong>The information in this document has been superseded by <a href="server.html">GCM Server</a> and <a href="client.html">GCM Client</a></strong>. Please use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> API instead of the GCM client helper library. The GCM server helper library is still valid.</p>
-
- <input style="margin-top:1em;padding:5px" type="button"
- value="That's nice, but I still want to read this document"
-onclick="$('#naMessage').hide();$('#deprecatedSticker').show()" />
-</div>
-</div>
-
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>Quickview</h2>
-
-<ul>
-<li>Walk through the steps of creating a GCM app.</li>
-</ul>
-
-
-<h2>In this document</h2>
-
-<ol class="toc">
-<li><a href="#libs">Installing the Helper Libraries</a></li>
-<li><a href="#android-app">Writing the Android Application</a>
-<li><a href="#server-app">Writing the Server-side Application</a> </li>
-</ol>
-
-<h2>See Also</h2>
-
-<ol class="toc">
-<li><a href="{@docRoot}google/play-services/gcm/gs.html">Getting Started with GCM Extensions</a></li>
-<li><a href="https://services.google.com/fb/forms/gcm/" class="external-link" target="_android">CCS and User Notifications Signup Form</a></li>
-</ol>
-
-</div>
-</div>
-
-<p>This document describes how to write an Android application and the server-side logic, using the client and server <a href="{@docRoot}reference/com/google/android/gcm/package-summary.html">helper libraries</a> provided by GCM.</p>
-
-<p>The helper libraries are one option for creating an Android application that uses GCM. You can alternatively use the approach described in the <a href="{@docRoot}google/gcm/gcm.html#writing_apps">GCM Architectural Overview</a>. If you need to perform upstream messaging, you must use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> APIs, and <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> also provides a streamlined registration process.</p>
-
-<p>For information on how to get started creating an Android GCM application and an example of how to use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> APIs, see <a href="{@docRoot}google/gcm/gs.html">Getting Started</a>.</p>
-
-<h2 id="libs">Installing the Helper Libraries</h2>
-<p>To perform the steps described in the following sections, you must first install the
-<a href="{@docRoot}reference/com/google/android/gcm/package-summary.html">helper libraries</a>. Note that while using the helper libraries is recommended, it is not required. See the <a href="gcm.html#writing_apps">GCM Architectural Overview</a> for a description of how to write apps without using the helper libraries.
-
-<p>To install the helper libraries, choose
-<strong>Extras &gt; Google Cloud Messaging for Android Library</strong>
-from the SDK Manager. This creates a <code>gcm</code> directory under
-<code><em>YOUR_SDK_ROOT</em>/extras/google/</code> containing these
-subdirectories: <code>gcm-client</code>, <code>gcm-server</code>,
-<code>samples/gcm-demo-client</code>, <code>samples/gcm-demo-server</code>,
-and <code>samples/gcm-demo-appengine</code>.</p>
-
-<p class="note"><strong>Note:</strong> If you don't see <strong>Extras &gt; Google Cloud Messaging for Android Library</strong> in the SDK Manager, make sure you are running version 20 or higher. Be sure to restart the SDK Manager after updating it.</p>
-
-<h2 id="android-app">Writing the Android Application</h2>
-<p>This section describes the steps involved in writing an Android application that uses GCM.</p>
-<h4>Step 1: Copy the gcm.jar file into your application classpath</h4>
-<p> To write your Android application, first copy the <code>gcm.jar</code> file from the SDK's <code>gcm-client/dist</code> directory to your application classpath.</p>
-<h4>Step 2: Make the following changes in the application's Android manifest</h4>
-<ol>
- <li>GCM requires Android 2.2 or later, so if your application cannot work without GCM, add the following line, where <em>xx</em> is the latest target SDK version:</li>
-
-<pre class="prettyprint pretty-xml">&lt;uses-sdk android:minSdkVersion=&quot;8&quot; android:targetSdkVersion=&quot;xx&quot;/&gt;</pre>
-
- <li>Declare and use a custom permission so only this application can receive GCM messages:<br>
- </li>
-
-<pre class="prettyprint pretty-xml">&lt;permission android:name=&quot;my_app_package.permission.C2D_MESSAGE&quot; android:protectionLevel=&quot;signature&quot; /&gt;
-&lt;uses-permission android:name=&quot;my_app_package.permission.C2D_MESSAGE&quot; /&gt; </pre>
-<p> This permission must be called <code>my_app_package.permission.C2D_MESSAGE</code> (where <code>my_app_package</code> is the package name of your app as defined by the manifest tag), otherwise it will not work.</p>
-<p class="note"><strong>Note:</strong> This permission is not required if you are targeting your application to 4.1 or above (i.e., minSdkVersion 16)</p>
-
- <li>Add the following permissions:</li>
-
-<pre class="prettyprint pretty-xml">&lt;!-- App receives GCM messages. --&gt;
-&lt;uses-permission android:name=&quot;com.google.android.c2dm.permission.RECEIVE&quot; /&gt;
-&lt;!-- GCM connects to Google Services. --&gt;
-&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
-&lt;!-- GCM requires a Google account. --&gt;
-&lt;uses-permission android:name=&quot;android.permission.GET_ACCOUNTS&quot; /&gt;
-&lt;!-- Keeps the processor from sleeping when a message is received. --&gt;
-&lt;uses-permission android:name=&quot;android.permission.WAKE_LOCK&quot; /&gt;</pre>
-
- <li>Add the following broadcast receiver:</li>
-
-<pre class="prettyprint pretty-xml">&lt;receiver android:name=&quot;com.google.android.gcm.GCMBroadcastReceiver&quot; android:permission=&quot;com.google.android.c2dm.permission.SEND&quot; &gt;
- &lt;intent-filter&gt;
- &lt;action android:name=&quot;com.google.android.c2dm.intent.RECEIVE&quot; /&gt;
- &lt;action android:name=&quot;com.google.android.c2dm.intent.REGISTRATION&quot; /&gt;
- &lt;category android:name=&quot;my_app_package&quot; /&gt;
- &lt;/intent-filter&gt;
-&lt;/receiver&gt;</pre>
-<p> This broadcast receiver is responsible for handling the 2 intents that can be sent by GCM (<code>com.google.android.c2dm.intent.RECEIVE</code> and <code>com.google.android.c2dm.intent.REGISTRATION</code>) and should be defined in the manifest (rather than programmatically) so that these intents can be received even if the application is not running. By setting the <code>com.google.android.c2dm.permission.SEND</code> permission, you are ensuring that only intents sent by the GCM system framework are sent to the receiver (a regular application cannot issue intents with that permission).</p>
-<p> Notice that <code>android:name</code> in the category tag must be replaced by your application's package name (and the category tag is not required for applications targeted to minSdkVersion 16 and higher).<br>
- </p>
-
- <li>Add the following intent service:</li>
-
-
- <pre class="prettyprint pretty-xml">&lt;service android:name=&quot;.GCMIntentService&quot; /&gt;</pre>
-
-</ol>
-<p>This intent service will be called by the <code>GCMBroadcastReceiver</code> (which is provided by the GCM library), as shown in the next step. It must be a subclass of <code>com.google.android.gcm.GCMBaseIntentService</code>, must contain a public constructor, and should be named <code>my_app_package.GCMIntentService</code> (unless you use a subclass of <code>GCMBroadcastReceiver</code> that overrides the method used to name the service).</p>
-
-<p>The intent service must also define its sender ID(s). It does this as follows:</p>
-<ul>
- <li>If the value is static, the service's default constructor should call <code>super(senderIds)</code>.</li>
- <li>If the value is dynamic, the service should override the <code>getSenderIds()</code> method.</li>
-</ul>
-
-
-<h4>Step 3: Write the my_app_package.GCMIntentService class</h4>
-
-<p>Next write the <code>my_app_package.GCMIntentService</code> class, overriding the following callback methods (which are called by <code>GCMBroadcastReceiver</code>):<br>
-</p>
-<ul>
- <li><code>onRegistered(Context context, String regId)</code>: Called after a registration intent is received, passes the registration ID assigned by GCM to that device/application pair as parameter. Typically, you should send the <code>regid</code> to your server so it can use it to send messages to this device.</li>
- <li><code>onUnregistered(Context context, String regId)</code>: Called after the device has been unregistered from GCM. Typically, you should send the <code>regid</code> to the server so it unregisters the device.</li>
- <li><code>onMessage(Context context, Intent intent)</code>: Called when your server sends a message to GCM, and GCM delivers it to the device. If the message has a payload, its contents are available as extras in the intent.</li>
- <li><code>onError(Context context, String errorId)</code>: Called when the device tries to register or unregister, but GCM returned an error. Typically, there is nothing to be done other than evaluating the error (returned by errorId) and trying to fix the problem.</li>
- <li> <code>onRecoverableError(Context context, String errorId)</code>: Called when the device tries to register or unregister, but the GCM servers are unavailable. The GCM library will retry the operation using exponential backup, unless this method is overridden and returns false. This method is optional and should be overridden only if you want to display the message to the user or cancel the retry attempts.
- </li>
-</ul>
-
-<p class="note"><strong>Note:</strong> The methods above run in the intent service's thread and hence are free to make network calls without the risk of blocking the UI thread.</p>
-
-<h4> Step 4: Write your application's main activity</h4>
-Add the following import statement in your application's main activity:
-<pre class="prettyprint pretty-java">import com.google.android.gcm.GCMRegistrar;</pre>
-<p> In the <code>onCreate()</code> method, add the following code:</p>
-<pre class="prettyprint pretty-java">GCMRegistrar.checkDevice(this);
-GCMRegistrar.checkManifest(this);
-final String regId = GCMRegistrar.getRegistrationId(this);
-if (regId.equals("")) {
- GCMRegistrar.register(this, SENDER_ID);
-} else {
- Log.v(TAG, "Already registered");
-}</pre>
-<p>The <code>checkDevice()</code> method verifies that the device supports GCM and throws an exception if it does not (for instance, if it is an emulator that does not contain the Google APIs). Similarly, the <code>checkManifest()</code> method verifies that the application manifest contains meets all the requirements described in <a href="#android-app">Writing the Android Application</a> (this method is only necessary when you are developing the application; once the application is ready to be published, you can remove it).</p>
-
-<p>Once the sanity checks are done, the device calls <code>GCMRegsistrar.register()</code> to register the device, passing the <code>SENDER_ID</code> you got when you signed up for GCM. But since the <code>GCMRegistrar</code> singleton keeps track of the registration ID upon the arrival of registration intents, you can call <code>GCMRegistrar.getRegistrationId()</code> first to check if the device is already registered.</p>
-<p class="note"><strong>Note:</strong> It is possible that the device was successfully registered to GCM but failed to send the registration ID to your server, in which case you should retry. See <a href="adv.html#reg-state">Advanced Topics</a> for more details on how to handle this scenario.</p>
-
-<h2 id="server-app">Writing the Server-side Application</h2>
-
-<p>To write the server-side application:</p>
-<ol>
- <li> Copy the <code>gcm-server.jar</code> file from the SDK's <code>gcm-server/dist</code> directory to your server classpath.</li>
- <li>Create a servlet (or other server-side mechanism) that can be used by the Android application to send the registration ID received by GCM . The application might also need to send other information&mdash;such as the user's email address or username&mdash;so that the server can associate the registration ID with the user owning the device.</li>
- <li>Similarly, create a servlet used to unregister registration IDs.<br>
- </li>
-<li>When the server needs to send a message to the registration ID, it can use the <code>com.google.android.gcm.server.Sender</code> helper class from the GCM library. For example:</li>
-</ol>
-
-<pre class="prettyprint pretty-java">import com.google.android.gcm.server.*;
-
-Sender sender = new Sender(myApiKey);
-Message message = new Message.Builder().build();
-MulticastResult result = sender.send(message, devices, 5);</pre>
-
-<p> The snippet above does the following:
-<ul>
-<li>Creates a <code>Sender</code> object using your project's API key.</li>
-<li>Creates a message using a given registration ID (the message builder also has methods to set all message parameters such as the collapse key and payload data).</li>
-<li>Sends the message with a maximum of 5 retry attempts (in case the GCM servers are unavailable), and stores the response on result. </li>
-</ul>
-<p>It's now necessary to parse the result and take the proper action in the following cases:</p>
-<ul>
- <li>If the message was created but the result returned a canonical registration ID, it's necessary to replace the current registration ID with the canonical one.</li>
- <li>If the returned error is <code>NotRegistered</code>, it's necessary to remove that registration ID, because the application was uninstalled from the device.</li>
-</ul>
-<p> Here's a code snippet that handles these 2 conditions:</p>
-<pre class="prettyprint pretty-java">
-if (result.getMessageId() != null) {
- String canonicalRegId = result.getCanonicalRegistrationId();
- if (canonicalRegId != null) {
- // same device has more than on registration ID: update database
- }
-} else {
- String error = result.getErrorCodeName();
- if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
- // application has been removed from device - unregister database
- }
-}</pre>
diff --git a/docs/html/google/gcm/http.jd b/docs/html/google/gcm/http.jd
deleted file mode 100644
index e36440a..0000000
--- a/docs/html/google/gcm/http.jd
+++ /dev/null
@@ -1,445 +0,0 @@
-page.title=GCM HTTP Connection Server
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-
-<h2>In this document</h2>
-
-<ol class="toc">
- <li><a href="#auth">Authentication</a> </li>
- <li><a href="#request">Request Format</a> </li>
- <li><a href="#response">Response Format</a>
- <ol class="toc">
- <li><a href="#success">Interpreting a success response</a>
- <li><a href="#error_codes">Interpreting an error response</a>
- <li><a href="#example-responses">Example responses</a>
- </ol>
- </li>
- <li><a href="#app-server">Implementing an HTTP-Based App Server</a>
-</ol>
-
-<h2>See Also</h2>
-
-<ol class="toc">
-<li><a href="server-ref.html">Server Reference</a></li>
-<li><a href="gs.html">Getting Started</a></li>
-<li><a href="client.html">Implementing GCM Client</a></li>
-<li><a href="ccs.html">Cloud Connection Server</a></li>
-
-
-</ol>
-
-</div>
-</div>
-
-<p>This document describes the Google Cloud Messaging (GCM) HTTP
-connection server. Connection servers
-are the Google-provided servers that take messages from the 3rd-party
-application server and sending them to the device.</p>
-
-<p class="note"><strong>Note:</strong> The content in this document
-applies to <a href="http://developer.chrome.com/apps/cloudMessaging">
-GCM with Chrome apps</a> as well as Android.</p>
-
-<p>See the
-<a href="server-ref.html">Server Reference</a> for a list of all the message
-parameters and which connection server(s) supports them.</p>
-
-
-<h2 id="auth">Authentication</h2>
-
-<p>To send a message, the application server issues a POST request. For example:</p>
-<pre>https://android.googleapis.com/gcm/send</pre>
-<p>A message request is made of 2 parts: HTTP header and HTTP body.</p>
-
-<p>The HTTP header must contain the following headers:</p>
-<ul>
- <li><code>Authorization</code>: key=YOUR_API_KEY</li>
- <li><code>Content-Type</code>: <code>application/json</code> for JSON;
-<code>application/x-www-form-urlencoded;charset=UTF-8</code> for plain text.
-If <code>Content-Type</code> is omitted, the format
-is assumed to be plain text.
- </li>
-</ul>
-
-<p>For example:
-</p>
-
-<pre>Content-Type:application/json
-Authorization:key=AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA
-
-{
- "registration_ids" : ["APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx..."],
- "data" : {
- ...
- },
-}</pre>
-
-
-<p>The HTTP body content depends on whether you're using JSON or plain text.
-See
-<a href="server-ref.html#params">the Server Reference</a> for a list of all the
-parameters your JSON or plain text message can contain.</p>
-
-<h3 id="checkAPIkey">Checking the validity of an API key</h3>
-
-<p>If you receive authentication errors when sending messages, check the validity
-of your API key. For example, on Android, run the following command:</p>
-
-<pre># api_key=YOUR_API_KEY
-
-# curl --header "Authorization: key=$api_key" \
- --header Content-Type:"application/json" \
- https://android.googleapis.com/gcm/send \
- -d "{\"registration_ids\":[\"ABC\"]}"</pre>
-
-<p>
-If you receive a 401 HTTP status code, your API key is not valid. Otherwise you
-should see something like this:</p>
-
-<pre>
-{"multicast_id":6782339717028231855,"success":0,"failure":1,
-"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
-</pre>
-
-<p>
-If you want to confirm the validity of a registration ID, you can do so by
-replacing "ABC" with the registration ID.
-</p>
-
-
- <h2 id="request">Request Format</h2>
-
-<p>This section shows you how to format a request for both JSON and plain text. See
-the <a href="server-ref.html#table1">Server Reference</a> for a complete
-list of the fields you can include in a request.</p>
-
- <p>Here is the smallest possible request (a message without any parameters and
-just one recipient) using JSON:</p>
-
- <pre class="prettyprint pretty-json">{ &quot;registration_ids&quot;: [ &quot;42&quot; ] }</pre>
-
- <p>And here the same example using plain text:</p>
- <pre class="prettyprint">registration_id=42</pre>
-
- <p> Here is a message with a payload and 6 recipients:</p>
-
- <pre class="prettyprint pretty-HTML">{ "data": {
- "score": "5x1",
- "time": "15:10"
- },
- "registration_ids": ["4", "8", "15", "16", "23", "42"]
-}</pre>
- <p>Here is a message with all optional fields set and 6 recipients:</p>
- <pre class="prettyprint pretty-json">{ "collapse_key": "score_update",
- "time_to_live": 108,
- "delay_while_idle": true,
- "data": {
- "score": "4x8",
- "time": "15:16.2342"
- },
- "registration_ids":["4", "8", "15", "16", "23", "42"]
-}</pre>
- <p>And here is the same message using plain-text format (but just 1 recipient): </p>
-
- <pre class="prettyprint">collapse_key=score_update&amp;time_to_live=108&amp;delay_while_idle=1&amp;data.score=4x8&amp;data.time=15:16.2342&amp;registration_id=42
- </pre>
-
-<p>Here is a message that includes a notification key and payload:</p>
-
-<pre>
-{
- "data": {
- "message": "ciao"
- },
- "notification_key":"aUniqueKey"
-}
-</pre>
-
-<p>For more information about notifications and how to use them, see
-<a href="{@docRoot}google/gcm/notifications.html">User Notifications</a>.</p>
-
-
-<p class="note"><strong>Note:</strong> If your organization has a firewall
-that restricts the traffic to or
-from the Internet, you need to configure it to allow connectivity with GCM in order for
-your GCM client apps to receive messages.
-The ports to open are: 5228, 5229, and 5230. GCM typically only uses 5228, but
-it sometimes uses 5229 and 5230. GCM doesn't provide specific IPs, so you should allow
-your firewall to accept outgoing connections to all IP addresses
-contained in the IP blocks listed in Google's ASN of 15169.</p>
-
-
-
-<h2 id="response">Response format</h2>
-
-<p>There are two possible outcomes when trying to send a message:</p>
-<ul>
- <li>The message is processed successfully. The HTTP response has a 200 status, and
-the body contains more information about the status of the message (including possible errors).</li>
- <li>The GCM server rejects the request. The HTTP response contains a
-non-200 status code (such as 400, 401 or 5xx).</li>
-</ul>
-
-<p>When a JSON request is successful (HTTP status code 200), the JSON object returned
-contains the <a href="{@docRoot}google/gcm/server-ref.html#table4">
-Downstream HTTP message response body</a>.</p>
-
-<p>If the value of <code>failure</code> and <code>canonical_ids</code> is 0, it's
-not necessary to parse the remainder of the response. Otherwise, we recommend
-that you iterate through the results field and do the following for each object
-in that list:</p>
-<ul>
- <li>If <code>message_id</code> is set, check for <code>registration_id</code>:
- <ul>
- <li>If <code>registration_id</code> is set, replace the original ID with
-the new value (canonical ID) in your server database. Note that the original ID
-is not part of the result, so you need to obtain it from the list of
-code>registration_ids</code> passed in the request (using the same index).</li>
- </ul>
- </li>
- <li>Otherwise, get the value of <code>error</code>:
- <ul>
- <li>If it is <code>Unavailable</code>, you could retry to send it in another
-request.</li>
- <li>If it is <code>NotRegistered</code>, you should remove the registration
-ID from your server database because the application was uninstalled from the
-device, or the client app isn't configured to receive
-messages.</li>
- <li>Otherwise, there is something wrong in the registration ID passed in
-the request; it is probably a non-recoverable error that will also require removing
-the registration from the server database. See
-<a href="{@docRoot}google/gcm/server-ref.html#error-codes">Downstream message error response
- codes</a> for all possible error values.</li>
- </ul>
- </li>
-</ul>
-
-<p>When a plain-text request is successful (HTTP status code 200), the response
-body contains 1 or 2 lines in the form of key/value pairs.
-The first line is always available and its content is either <code>id=<em>ID of
-sent message</em></code> or <code>Error=<em>GCM error code</em></code>. The second
-line, if available,
-has the format of <code>registration_id=<em>canonical ID</em></code>. The second
-line is optional, and it can only be sent if the first line is not an error. We
-recommend handling the plain-text response in a similar way as handling the
-JSON response:</p>
-<ul>
- <li>If first line starts with <code>id</code>, check second line:
- <ul>
- <li>If second line starts with <code>registration_id</code>, gets its value
-and replace the registration IDs in your server database.</li>
- </ul>
- </li>
- <li>Otherwise, get the value of <code>Error</code>:
- <ul>
- <li>If it is <code>NotRegistered</code>, remove the registration ID from
-your server database.</li>
- <li>Otherwise, there is probably a non-recoverable error (<strong>Note:
-</strong>Plain-text requests will never return <code>Unavailable</code> as the
-error code, they would have returned a 500 HTTP status instead).</li>
- </ul>
- </li>
-</ul>
-
-
-<h3 id="example-responses">Example responses</h3>
-<p>This section shows a few examples of responses indicating messages that were
-processed successfully. See <a href="#request">Request Format</a> for
-the requests these responses are based on.</p>
-<p> Here is a simple case of a JSON message successfully sent to one recipient
-without canonical IDs in the response:</p>
-<pre class="prettyprint pretty-json">{ "multicast_id": 108,
- "success": 1,
- "failure": 0,
- "canonical_ids": 0,
- "results": [
- { "message_id": "1:08" }
- ]
-}</pre>
-
-<p>Or if the request was in plain-text format:</p>
-<pre class="prettyprint">id=1:08
-</pre>
-
-<p>Here are JSON results for 6 recipients (IDs 4, 8, 15, 16, 23, and 42 respectively)
-with 3 messages successfully processed, 1 canonical registration ID returned,
-and 3 errors:</p>
-<pre class="prettyprint pretty-json">{ "multicast_id": 216,
- "success": 3,
- "failure": 3,
- "canonical_ids": 1,
- "results": [
- { "message_id": "1:0408" },
- { "error": "Unavailable" },
- { "error": "InvalidRegistration" },
- { "message_id": "1:1516" },
- { "message_id": "1:2342", "registration_id": "32" },
- { "error": "NotRegistered"}
- ]
-}
-</pre>
-<p> In this example:</p>
-<ul>
- <li>First message: success, not required.</li>
- <li>Second message: should be resent (to registration ID 8).</li>
- <li>Third message: had an unrecoverable error (maybe the value got corrupted
-in the database).</li>
- <li>Fourth message: success, nothing required.</li>
- <li>Fifth message: success, but the registration ID should be updated in the
-server database (from 23 to 32).</li>
- <li>Sixth message: registration ID (42) should be removed from the server database
-because the application was uninstalled from the device.</li>
-</ul>
-<p>Or if just the 4th message above was sent using plain-text format:</p>
-<pre class="prettyprint">Error=InvalidRegistration
-</pre>
-<p>If the 5th message above was also sent using plain-text format:</p>
-<pre class="prettyprint">id=1:2342
-registration_id=32
-</pre>
-
-
-<h2 id="app-server">Implementing an HTTP-Based App Server</h2>
-
-<p>This section gives examples of implementing an app server that works with the
-GCM HTTP connection server. Note that a full GCM implementation requires a
-client-side implementation, in addition to the server. This example is based on Android.</a>
-
-
-<p>Requirements</p>
-<p>For the web server:</p>
-<ul>
- <li> <a href="http://ant.apache.org/">Ant 1.8</a> (it might work with earlier versions, but it's not guaranteed).</li>
- <li>One of the following:
- <ul>
- <li>A running web server compatible with Servlets API version 2.5, such as
-<a href="http://tomcat.apache.org/">Tomcat 6</a> or <a href="http://jetty.codehaus.org/">Jetty</a>, or</li>
- <li><a href="http://code.google.com/appengine/">Java App Engine SDK</a>
-version 1.6 or later.</li>
- </ul>
- </li>
- <li>A Google account registered to use GCM.</li>
- <li>The API key for that account.</li>
-</ul>
-<p>For the Android application:</p>
-<ul>
- <li>Emulator (or device) running Android 2.2 (ideally, 2.3 or above) with Google APIs.</li>
- <li>The Google API project number of the account registered to use GCM.</li>
-</ul>
-
-<h3 id="gcm-setup">Setting Up GCM</h3>
-<p>Before proceeding with the server and client setup, it's necessary to register
-a Google account with the Google API Console, enable Google Cloud Messaging in GCM,
-and obtain an API key from the <a href="https://code.google.com/apis/console">
-Google API Console</a>.</p>
-<p>For instructions on how to set up GCM, see <a href="gs.html">Getting Started</a>.</p>
-
-
-<h3 id="server-setup">Setting Up an HTTP Server</h3>
-<p>This section describes the different options for setting up an HTTP server.</p>
-
-<h4 id="webserver-setup">Using a standard web server</h4>
-<p>To set up the server using a standard, servlet-compliant web server:</p>
-<ol>
- <li>From the <a href="http://code.google.com/p/gcm">open source site</a>,
-download the following directories: <code>gcm-server</code>,
-<code>samples/gcm-demo-server</code>, and <code>samples/gcm-demo-appengine</code>.</p>
-
-
- <li>In a text editor, edit the <code>samples/gcm-demo-server/WebContent/WEB-INF/classes/api.key</code> and replace the existing text with the API key obtained above.</li>
- <li>In a shell window, go to the <code>samples/gcm-demo-server</code> directory.</li>
- <li>Generate the server's WAR file by running <code>ant war</code>:</li>
-
- <pre class="prettyprint">$ ant war
-
-Buildfile:build.xml
-
-init:
- [mkdir] Created dir: build/classes
- [mkdir] Created dir: dist
-
-compile:
- [javac] Compiling 6 source files to build/classes
-
-war:
- [war] Building war: <strong>dist/gcm-demo.war</strong>
-
-BUILD SUCCESSFUL
-Total time: 0 seconds
-</pre>
-
- <li>Deploy the <code>dist/gcm-demo.war</code> to your running server. For instance, if you're using Jetty, copy <code>gcm-demo.war</code> to the <code>webapps</code> directory of the Jetty installation.</li>
- <li>Open the server's main page in a browser. The URL depends on the server you're using and your machine's IP address, but it will be something like <code>http://192.168.1.10:8080/gcm-demo/home</code>, where <code>gcm-demo</code> is the application context and <code>/home</code> is the path of the main servlet.
-
- </li>
-</ol>
-<p class="note"><strong>Note:</strong> You can get the IP by running <code>ifconfig</code> on Linux or MacOS, or <code>ipconfig</code> on Windows. </p>
-
-<p> You server is now ready.</p>
-
-<h4 id="appengine-setup">Using App Engine for Java</h4>
-
-<p>To set up the server using a standard App Engine for Java:</p>
-<ol>
- <li>Get the files from the <a href="http://code.google.com/p/gcm">open source
-site</a>, as described above.</p>
- </li>
- <li>In a text editor, edit
-<code>samples/gcm-demo-appengine/src/com/google/android/gcm/demo/server/ApiKeyInitializer.java</code>
-and replace the existing text with the API key obtained above.
-
- <p class="note"><strong>Note:</strong> The API key value set in that class will
-be used just once to create a persistent entity on App Engine. If you deploy
-the application, you can use App Engine's <code>Datastore Viewer</code> to change
-it later.</p>
-
- </li>
- <li>In a shell window, go to the <code>samples/gcm-demo-appengine</code> directory.</li>
- <li>Start the development App Engine server by <code>ant runserver</code>,
-using the <code>-Dsdk.dir</code> to indicate the location of the App Engine SDK
-and <code>-Dserver.host</code> to set your server's hostname or IP address:</li>
-
-<pre class="prettyprint">
-$ ant -Dsdk.dir=/opt/google/appengine-java-sdk runserver -Dserver.host=192.168.1.10
-Buildfile: gcm-demo-appengine/build.xml
-
-init:
- [mkdir] Created dir: gcm-demo-appengine/dist
-
-copyjars:
-
-compile:
-
-datanucleusenhance:
- [enhance] DataNucleus Enhancer (version 1.1.4) : Enhancement of classes
- [enhance] DataNucleus Enhancer completed with success for 0 classes. Timings : input=28 ms, enhance=0 ms, total=28 ms. Consult the log for full details
- [enhance] DataNucleus Enhancer completed and no classes were enhanced. Consult the log for full details
-
-runserver:
- [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.jetty.JettyLogger info
- [java] INFO: Logging to JettyLogger(null) via com.google.apphosting.utils.jetty.JettyLogger
- [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml
- [java] INFO: Successfully processed gcm-demo-appengine/WebContent/WEB-INF/appengine-web.xml
- [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml
- [java] INFO: Successfully processed gcm-demo-appengine/WebContent/WEB-INF/web.xml
- [java] Jun 15, 2012 8:46:09 PM com.google.android.gcm.demo.server.ApiKeyInitializer contextInitialized
- [java] SEVERE: Created fake key. Please go to App Engine admin console, change its value to your API Key (the entity type is 'Settings' and its field to be changed is 'ApiKey'), then restart the server!
- [java] Jun 15, 2012 8:46:09 PM com.google.appengine.tools.development.DevAppServerImpl start
- [java] INFO: The server is running at http://192.168.1.10:8080/
- [java] Jun 15, 2012 8:46:09 PM com.google.appengine.tools.development.DevAppServerImpl start
- [java] INFO: The admin console is running at http://192.168.1.10:8080/_ah/admin
-</pre>
-
- <li>Open the server's main page in a browser. The URL depends on the server
-you're using and your machine's IP address, but it will be something like
-<code>http://192.168.1.10:8080/home</code>, where <code>/home</code>
-is the path of the main servlet.</li>
-
- <p class="note"><strong>Note:</strong> You can get the IP by running <code>ifconfig</code>
-on Linux or MacOS, or <code>ipconfig</code> on Windows.</p>
-
-</ol>
-<p> You server is now ready.</p>
diff --git a/docs/html/google/gcm/index.jd b/docs/html/google/gcm/index.jd
deleted file mode 100644
index af5d741..0000000
--- a/docs/html/google/gcm/index.jd
+++ /dev/null
@@ -1,70 +0,0 @@
-page.title=Google Cloud Messaging for Android
-page.tags=gcm
-header.hide=1
-@jd:body
-
-
-<div class="landing-banner">
-
-<div class="col-5" style="min-height:100px">
- <img src="{@docRoot}images/gcm/gcm-logo.png" />
-</div>
-<div class="col-7">
-
- <h1 itemprop="name" style="margin-bottom:0;">Google Cloud Messaging for Android</h1>
- <p itemprop="description">
- Google Cloud Messaging (GCM) for Android is a service that allows you to send data
-from your server to your users' Android-powered device, and also to receive messages from
-devices on the same connection. The GCM service handles all aspects of queueing of messages
-and delivery to the target Android application running on the target device, and it is
-completely free.
-</p>
-
-</div>
-</div>
-
-<div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">Key Developer Features</h3>
- <h4>Send data from your server to users' Android-powered devices</h4>
- <p>This could be a lightweight
-message telling your app there is new data to be fetched from the
-server (for instance, a movie uploaded by a friend), or it could be a message containing
-up to 4kb of payload data (so apps like instant messaging can consume the message directly).
-<a href="{@docRoot}google/gcm/gcm.html">GCM Architectural Overview.</a></p>
-
- <h4>Send "send-to-sync" messages</h4>
- <p>A send-to-sync (collapsible) message is often a "tickle" that tells a mobile
- application to sync data from the server. For example, suppose you have an email
- application. When a user receives new email on the server, the server pings the mobile
- application with a "New mail" message. This tells the application to sync to the server
- to pick up the new email.
- <a href="{@docRoot}google/gcm/adv.html#s2s">Learn more &raquo;</a></p>
-
- <h4>Send messages with payload</h4>
- <p>Unlike a send-to-sync message, every "message with payload" (non-collapsible message)
- is delivered. The payload the message contains can be up to 4kb.
- <a href="{@docRoot}google/gcm/adv.html#payload">Learn more &raquo;</a></p>
- </div>
-
-
- <div class="col-6 normal-links">
- <h3 style="clear:left">New Features</h3>
-
-
-
- <h4>Return Receipts</h4>
- <p>You can use upstream messaging to get receipt notifications, confirming that a given
- message was sent to a device. Your 3rd-party app server receives the receipt notification
- from CCS once the message has been sent to the device.
- <a href="{@docRoot}google/gcm/ccs.html#receipts">Learn more &raquo;</a></p>
-
-
- <h4>Get Started</h4>
- <p>Get started with a tutorial that walks you through creating a GCM app.
- <a href="{@docRoot}google/gcm/gs.html">Learn more &raquo;</a></p>
- </div>
-
-</div>
-
-
diff --git a/docs/html/google/gcm/notifications.jd b/docs/html/google/gcm/notifications.jd
deleted file mode 100644
index 333d4b6..0000000
--- a/docs/html/google/gcm/notifications.jd
+++ /dev/null
@@ -1,308 +0,0 @@
-page.title=User Notifications
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>Quickview</h2>
-
-<ul>
-<li>Learn how to send a single message to multiple devices owned by a single user.</li>
-</ul>
-
-
-<h2>In this document</h2>
-
-<ol class="toc">
- <li><a href="#gen-server">Generate a Notification Key on the Server</a></li>
- <li><a href="#gen-client">Generate a Notification Key on the Client</a></li>
- <li><a href="#add">Add Registration IDs</a></li>
- <li><a href="#remove">Remove Registration IDs</a></li>
- <li><a href="#upstream">Send Upstream Messages</a></li>
- <li><a href="#response">Response Formats</a>
- <ol class="toc">
- <li><a href="#response-create">Create/add/remove operations</a>
- <li><a href="#response-send">Send operations</a>
- </ol>
- </li>
-</ol>
-
-<h2>See Also</h2>
-
-<ol class="toc">
-<li><a href="{@docRoot}google/gcm/gs.html">Getting Started</a></li>
-</ol>
-
-</div>
-</div>
-
-<p>With user notifications, 3rd-party app servers can send a single message to
-multiple instance of an app running on devices owned by a single user. This feature
-is called <em>user notifications</em>. User notifications make it possible for every
-app instance that a user owns to reflect the latest messaging state. For example:</p>
-
- <ul>
- <li>If a message has been handled on one device, the GCM message on the other
-devices are dismissed. For example, if a user has handled a calendar notification
-on one device, the notification will go away on the user's other devices.</li>
-
- <li>If a message has not been delivered yet to a device and but it has been handled,
-the GCM server removes it from the unsent queue for the other devices.</li>
-
- <li>Likewise, a device can send messages to the {@code notification_key}, which
-is the token that GCM uses to fan out notifications to all devices whose
-registration IDs are associated with the key.</li>
-</ul>
-
-<p>The way this works is that during registration, the 3rd-party server requests
-a {@code notification_key}. The {@code notification_key} maps a particular user
-to all of the user's associated registration IDs (a regID represents a particular
-Android application running on a particular device). Then instead of sending one
-message to one regID at a time, the 3rd-party server can send a message to to the
-{@code notification_key}, which then sends the message to all of the user's regIDs.</p>
-
-<p class="note"><strong>Note:</strong> A notification dismissal message is like any
-other upstream message, meaning that it will be delivered to the other devices that
-belong to the specified {@code notification_key}. You should design your app to
-handle cases where the app receives a dismissal message, but has not yet displayed
-the notification that is being dismissed. You can solve this by caching the dismissal
-and then reconciling it with the corresponding notification.
-</p>
-
-<p>You can use this feature with either the <a href="ccs.html">XMPP</a> (CCS) or
-<a href="http.html">HTTP</a> connection server.</p>
-
-<p>You can generate notification keys in two different ways: on the server, and on
-the client, if the user has a Google account. All of the associated registration IDs
-can be mapped to a single user.</p>
-
-<p>The examples below show you how to perform generate/add/remove operations,
-and how to send upstream messages. For generate/add/remove operations, the
-message body is JSON.</p>
-
-<h2 id="gen-server">Generate a Notification Key on the Server</h2>
-
-<p>To generate a notification key on the server, you create a new
-<code>notification_key</code> and map it to a
-<code>notification_key_name</code>.</p>
-
-<p>This example shows how to create a new <code>notification_key</code> for a
-<code>notification_key_name</code> called <code>appUser-Chris</code>.
-The {@code notification_key_name} is a name or identifier (it can be a username for
-a 3rd-party app) that is unique to a given user. It is used by third parties to
-group together registration IDs for a single user. Note that <code>notification_key_name</code>
-and <code>notification_key</code> are unique to a group of registration IDs. It is also
-important that <code>notification_key_name</code> be uniquely named per app in case
-you have multiple apps for the same project ID. This ensures that notifications
-only go to the intended target app.</p>
-
-
-<p>A create operation returns a token (<code>notification_key</code>). Third parties
-must save this token (as well as its mapping to the <code>notification_key_name</code>)
-to use in subsequent operations:</p>
-
-<pre>request:
-{
- &quot;operation&quot;: &quot;create&quot;,
- &quot;notification_key_name&quot;: &quot;appUser-Chris&quot;,
- &quot;registration_ids&quot;: [&quot;4&quot;, &quot;8&quot;, &quot;15&quot;, &quot;16&quot;, &quot;23&quot;, &quot;42&quot;]
-}</pre>
-
-<h3 id="request-server">Request format</h3>
-
-<p>To send a message in cases where your notification key is generated on the server,
-the application server issues a POST request to
-<code>https://android.googleapis.com/gcm/notification</code>.</p>
-
-<p>Here is the HTTP request header you should use for all server side create/add/remove operations:</p>
-
-<pre>content-type: "application/json"
-Header : "project_id": &lt;projectID&gt;
-Header: "Authorization", "key=API_KEY"
-</pre>
-
-
-<h2 id="gen-client">Generate a Notification Key on the Client</h2>
-
-<p>Generating a notification key on the client is useful for cases where a server is unavailable.
-To generate a notification key on the client, the device must have at least one
-Google account. Note that the process for generating a notification key on the client is significantly
-different from the server process described above.</p>
-
-<p>To generate a notification key on the client:</p>
-
-<ol>
- <li>Open your project in the <a href="https://cloud.google.com/console">Google Developers Console</a>.</li>
- <li>Click <strong>APIS &amp; AUTH &gt; Credentials</strong>.</li>
- <li>Under OAuth, click <strong>Create new Client ID</strong>.</li>
- <li>In the <strong>Create Client ID</strong> dialog, select <strong>Web Application</strong> as
-the application type, and click <strong>Create Client ID</strong>.</li>
- <li>Copy the value from <strong>Client ID for web application &gt; Client ID</strong>.
-This client ID represents a Google account "scope" that you will use to generate an {@code id_token}.</li>
-</ol>
-
-<p>Once you've followed the above steps and gotten a client ID from Google Developers Console,
- you're ready to add this feature to your app. First check the device for the presence of a Google
-account. For example:</p>
-
-<pre>// This snippet takes the simple approach of using the first returned Google account,
-// but you can pick any Google account on the device.
-public String getAccount() {
- Account[] accounts = AccountManager.get(getActivity()).
- getAccountsByType(&quot;com.google&quot;);
- if (accounts.length == 0) {
- return null;
- }
- return accounts[0].name;
-}</pre>
-
-<p>Next, get an authentication token ({@code id_token}) by using the <code><a href=
-"http://developer.android.com/reference/com/google/android/gms/auth/GoogleAuthUtil.html">GoogleAuthUtil</a></code>
-class. For example:</p>
-
-<pre>String accountName = getAccount();
-
-// Initialize the scope using the client ID you got from the Console.
-final String scope = &quot;audience:server:client_id:&quot;
- + &quot;1262xxx48712-9qs6n32447mcj9dirtnkyrejt82saa52.apps.googleusercontent.com&quot;;
-String id_token = null;
-try {
- id_token = GoogleAuthUtil.getToken(context, accountName, scope);
-} catch (Exception e) {
- log(&quot;exception while getting id_token: &quot; + e);
-}
-...</pre>
-
-<p>Now use <code>id_token</code> to authenticate your request.
-This add operation returns a {@code notification_key}.
-Third parties must save this {@code notification_key} (as well as its mapping to the
-<code>notification_key_name</code>)
-to use in subsequent operations. Note that a client request only takes a single regID.
-The only operations supported on the client side are add/remove.</p>
-
-<pre>request:
-{
- &quot;operation&quot;: &quot;add&quot;,
- &quot;notification_key_name&quot;: &quot;appUser-Chris&quot;,
- &quot;registration_ids&quot;: [&quot;4&quot;]
- &quot;id_token&quot;: &quot;id_token&quot;
-}</pre>
-
-<h3 id="request-client">Request format</h3>
-
-<p>To send a message in cases where your notification key is generated on the client,
-the application server issues a POST request to
-<code>https://android.googleapis.com/gcm/googlenotification</code>.</p>
-
-<p>Here is the HTTP request header you should use for all add/remove operations. The
-client side doesn't support the create operation;
-the add operation has the effect of creating the notification key if it doesn't already
-exist:</p>
-
-<pre>content-type: "application/json"
-Header : "project_id": &lt;projectID&gt;
-</pre>
-
-<p>Note that the authentication token is passed in the JSON body as shown above, not the header.
-This is different from the server case.</p>
-
-
-<h2 id="add">Add Registration IDs</h2>
-
-<p>This example shows how to add registration IDs for a given notification key.
-The maximum number of members allowed for a {@code notification_key} is 20.</p>
-
-<p>Note that the <code>notification_key_name</code> is not strictly required for
-adding/removing regIDs. But including it protects you against accidentally using
-the incorrect <code>notification_key</code>.</p>
-
-<pre>request:
-{
- &quot;operation&quot;: &quot;add&quot;,
- &quot;notification_key_name&quot;: &quot;appUser-Chris&quot;,
- &quot;notification_key&quot;: &quot;aUniqueKey&quot;
- &quot;registration_ids&quot;: [&quot;4&quot;, &quot;8&quot;, &quot;15&quot;, &quot;16&quot;, &quot;23&quot;, &quot;42&quot;]
-}</pre>
-
-<h2 id="remove">Remove Registration IDs</h2>
-
-<p>This example shows how to remove registration IDs for a given notification key:</p>
-<pre>request:
-{
- &quot;operation&quot;: &quot;remove&quot;,
- &quot;notification_key_name&quot;: &quot;appUser-Chris&quot;,
- &quot;notification_key&quot;: &quot;aUniqueKey&quot;
- &quot;registration_ids&quot;: [&quot;4&quot;, &quot;8&quot;, &quot;15&quot;, &quot;16&quot;, &quot;23&quot;, &quot;42&quot;]
-}</pre>
-
-<h2 id="upstream">Send Upstream Messages</h2>
-
-<p>To send an upstream (device-to-cloud) message, you must use the
-<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
-{@code GoogleCloudMessaging}</a> API. Specifying a {@code notification_key} as the target
-for an upstream message allows a user on one device to send a message to other
-devices in the notification group&mdash;for example, to dismiss a notification.
-Here is an example that shows targeting a {@code notification_key}:</p>
-
-<pre>GoogleCloudMessaging gcm = GoogleCloudMessaging.get(context);
-String to = NOTIFICATION_KEY;
-AtomicInteger msgId = new AtomicInteger();
-String id = Integer.toString(msgId.incrementAndGet());
-Bundle data = new Bundle();
-data.putString("hello", "world");
-
-gcm.send(to, id, data);
-</pre>
-
-<p>This call generates the necessary XMPP stanza for sending the message. The
-Bundle data consists of a key-value pair.</p>
-
-<p>For a complete example, see <a href="client.html">Implementing GCM Client</a>.
-
-<h2 id="response">Response Formats</h2>
-
-<p>This section shows examples of the responses that can be returned for
-notification key operations.</p>
-
-<h3 id="response-create">Create/add/remove operations</h3>
-
-<p>When you make a request to create a {@code notification_key} or to add/remove its
-regIDs, a successful response always returns the <code>notification_key</code>.
-Use the returned {@code notification_key} for sending messages:</p>
-
-<pre>HTTP status: 200
-{
- &quot;notification_key&quot;: &quot;aUniqueKey&quot;, // to be used for sending
-}</pre>
-
-
-<h3 id="response-send">Send operations</h3>
-
-<p>For a send operation that has a {@code notification_key} as its target, the
-possible responses are success, partial success, and failure.</p>
-
-<p>Here is an example of "success"&mdash;the {@code notification_key} has 2 regIDs
-associated with it, and the message was successfully sent to both of them:</p>
-
-<pre>{
- "success": 2,
- "failure": 0
-}</pre>
-
-<p>Here is an example of "partial success"&mdash;the {@code notification_key} has
-3 regIDs associated with it. The message was successfully send to 1 of the regIDs,
-but not to the other 2. The response message lists the regIDs that failed to
-receive the message:</p>
-
-<pre>{
- "success":1,
- "failure":2,
- "failed_registration_ids":[
- "regId1",
- "regId2"
- ]
-}</pre>
-
-<p>In the case of failure, the response has HTTP code 503 and no JSON. When a message
-fails to be delivered to one or more of the regIDs associated with a {@code notification_key},
-the 3rd-party server should retry.</p>
diff --git a/docs/html/google/gcm/server-ref.jd b/docs/html/google/gcm/server-ref.jd
deleted file mode 100644
index 2a41e58..0000000
--- a/docs/html/google/gcm/server-ref.jd
+++ /dev/null
@@ -1,764 +0,0 @@
-page.title=Server Reference
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>In this document</h2>
-
-<ol class="toc">
- <li><a href="#downstream">Downstream Messages</a></li>
-<ol class="toc">
- <li><a href="#send-downstream">Sending a downstream message</a></li>
- <li><a href="#interpret-downstream">Interpreting a downstream message response</a></li>
- </ol>
- <li><a href="#upstream">Upstream Messages (XMPP)</a>
- <ol class="toc">
- <li><a href="#interpret-upstream">Interpreting an upstream XMPP message</a></li>
- <li><a href="#upstream-response">Sending an upstream XMPP message response</a></li>
- </ol>
- </li>
-<li><a href="#ccs">Cloud Connection Server Messages (XMPP)</a></li>
-<li><a href="#error-codes">Downstream message error response codes (HTTP and XMPP)</a></li>
-</ol>
-
-</div>
-</div>
-
-<p>This document provides a reference for the syntax used to pass
-messages back and forth in GCM. These messages fall into
-the following broad categories:</p>
-
-<ul>
- <li><a href="#downstream">Downstream messages</a></li>
- <li><a href="#upstream">Upstream messages</a></li>
- <li><a href="#ccs">Cloud Connection Server messages (XMPP)</a></li>
- <li><a href="#error-codes">Downstream message error response codes (HTTP and XMPP)</a></li>
-</ul>
-
-<p>The following sections describe the basic requirements for
-sending messages.</p>
-
-<h2 id="downstream">Downstream Messages</h2>
-<p>This is the message that a 3rd-party app server sends to a client app.
-</p>
-<p>A downstream message includes the following components:</p>
-<ul>
- <li>Target: specifies the recipient of the message.</li>
- <li>Options: specifies attributes of the message.</li>
- <li>Payload: specifies additional content to be included in the message. Optional.</li>
-</ul>
-
-<p>The syntax for each of these components is described in the tables below. </p>
-
-<h3 id="send-downstream">Sending a downstream message</h3>
-
-<p>This section gives the syntax for sending a downstream messages. For JSON,
-these messages can be either HTTP or XMPP. For plain text, these messages can only be HTTP.</p>
-
-<h4>Downstream HTTP or XMPP messages (JSON)</h4>
-
-<p>The following table lists the targets, options, and payload for HTTP or XMPP JSON messages.</p>
-<p class="table-caption" id="table1">
- <strong>Table 1.</strong> Targets, options, and payload for downstream HTTP or XMPP message (JSON).</p>
-<table border="1">
- <tr>
- <th>Parameter</th>
- <th>Protocol</th>
- <th>Usage</th>
- <th>Description</th>
- </tr>
-<tr>
- <td colspan="4"><strong>Targets</strong></td>
- </tr>
- <tr>
- <td><code>to</code></td>
- <td>XMPP</td>
- <td>Required, string</td>
- <td><p>This parameter specifies the recipient of a message. </p>
- <p>The value must be a registration ID or notification key.</p>
- <p>This parameter is used in XMPP in place of {@code registration_ids} or {@code notification_key} in HTTP.</p></td>
- </tr>
- <tr>
- <td><code>registration_ids</code></td>
- <td>HTTP</td>
- <td>Required if {@code notification_key} not present, string array</td>
- <td><p>This parameter specifies the list of devices (registration IDs)
-receiving the message. It must contain at least 1 and at most 1000 registration IDs.</p>
- <p>Multicast messages (sending to more than 1 registration IDs) are allowed using HTTP JSON format only.</p>
- <p>This parameter or {@code notification_key} is used in HTTP in place of {@code to} in XMPP.</p></td>
- </tr>
- <tr>
- <td><code>notification_key</code></td>
- <td>HTTP</td>
- <td>Required if {@code registration_ids} not present, string</td>
- <td><p>This parameter specifies the mapping of a single user to
-multiple registration IDs associated with that user.</p>
- <p>This allows a 3rd-party app server to send a single message to multiple app instances
-(typically on multiple devices) owned by a single user.</p>
- <p>A 3rd-party app server can use {@code notification_key} as the target for a
-message instead of an individual registration ID (or array of registration IDs).
-The maximum number of members allowed for a {@code notification_key} is 20.</p>
- <p>This parameter or {@code registration_ids} is used in HTTP in place of {@code to} in XMPP.</p>
- <p>See <a href="notifications.html">User Notifications</a> for details.</p></td>
- </tr>
-<tr>
- <td colspan="4"><strong>Options</strong></td>
- </tr>
- <tr>
- <td><code>message_id</code></td>
- <td>XMPP</td>
- <td>Required, string</td>
- <td><p>This parameter uniquely identifies a message in an XMPP connection.</p></td>
- </tr>
- <tr>
- <td><code>collapse_key</code></td>
- <td>HTTP, XMPP</td>
- <td>Optional, string</td>
- <td><p>This parameters identifies a group of messages (e.g., with
-{@code collapse_key: "Updates Available"}) that can be collapsed, so that only the
-last message gets sent when delivery can be resumed. This is intended to avoid sending too
-many of the same messages when the device comes back online or becomes active (see {@code delay_while_idle}).</p>
- <p>Note that there is no guarantee of the order in which messages get sent.</p>
- <p>Messages with collapse key are also called
-<a href="{@docRoot}google/gcm/server.html#s2s">send-to-sync messages</a> messages.
-</p>
- <p>Note: A maximum of 4 different collapse keys is allowed at any given time. This means a
-GCM connection server can simultaneously store 4 different send-to-sync messages per client app. If you
-exceed this number, there is no guarantee which 4 collapse keys the GCM connection server will keep. </p></td>
- </tr>
- <tr>
- <td><code>delay_while_idle</code></td>
- <td>HTTP, XMPP</td>
- <td>Optional, JSON boolean</td>
- <td>When this parameter is set to {@code true}, it indicates that the message should not be
-sent until the device becomes active.</p>
- <p>The default value is {@code false}.</p></td>
- </tr>
- <tr>
- <td><code>time_to_live</code></td>
- <td>HTTP, XMPP</td>
- <td>Optional, JSON number</td>
- <td><p>This parameter specifies how long (in seconds) the message should be kept in GCM storage
-if the device is offline. The maximum time to live supported is 4 weeks.</p>
- <p>The default value is 4 weeks. </p></td>
- </tr>
- <tr>
- <td><code>delivery_receipt_
-<br>requested</code></td>
- <td>XMPP</td>
- <td>Optional, JSON boolean</td>
- <td><p>This parameter lets 3rd-party app server request confirmation of message delivery.</p>
- <p>When this parameter is set to {@code true}, CCS sends a delivery receipt
-when the device confirms that it received the message.</p>
- <p>The default value is {@code false}.</p></td>
- </tr>
- <tr>
- <td><code>restricted_package_
-<br>name</code></td>
- <td>HTTP</td>
- <td>Optional, string</td>
- <td>This parameter specifies the package name of the application where the
-registration IDs must match in order to receive the message.</td>
- </tr>
- <tr>
- <td><code>dry_run</code></td>
- <td>HTTP</td>
- <td>Optional, JSON boolean</td>
- <td><p>This parameter, when set to {@code true}, allows developers to test a
-request without actually sending a message.</p>
- <p>The default value is {@code false}.</p></td>
- </tr>
-<tr>
- <td colspan="4"><strong>Payload</strong></td>
- </tr>
- <tr>
- <td><code>data</code></td>
- <td>HTTP, XMPP</td>
- <td>Optional, JSON object</td>
- <td><p>This parameter specifies the key-value pairs of the message's payload. There is
-no limit on the number of key-value pairs, but there is a total message size limit of 4kb.</p>
- <p>For instance, in Android, <code>data:{"score":"3x1"}</code> would result in an intent extra
-named {@code score} with the string value {@code 3x1}.</p>
- <p>The key should not be a reserved word ({@code from} or any word starting with
-{@code google}). It is also not recommended to use words defined in this table
-(such as {@code collapse_key}) because that could yield unpredictable outcomes. </p>
- <p>Values in string types are recommended. You have to convert values in objects
-or other non-string data types (e.g., integers or booleans) to string.</p></td>
- </tr>
-</table>
-
-<h3>Downstream HTTP messages (Plain Text)</h3>
-
-<p>The following table lists the syntax for targets, options, and payload in plain
-text downstream HTTP messages.</p>
-
-<p class="table-caption" id="table2">
- <strong>Table 2.</strong> Targets, options, and payload for downstream plain text HTTP messages.</p>
-
-<table border="1">
- <tr>
- <th>Parameter</th>
- <th>Usage</th>
- <th>Description</th>
- </tr>
-<tr>
- <td colspan="3"><strong>Targets</strong></td>
- </tr>
- <tr>
- <td><code>registration _id</code></td>
- <td>Required, string</td>
- <td><p>This parameter specifies the client apps (registration ID) receiving the message.</p>
- <p>Multicast messaging (sending to more than one registration ID) is allowed using HTTP JSON format only.</p></td>
- </tr>
-<tr>
- <td colspan="3"><strong>Options</strong></td>
- </tr>
- <tr>
- <td><code>collapse_key</code></td>
- <td>Optional, string</td>
- <td>See <a href="#table1">table 1</a> for details.</td>
- </tr>
- <tr>
- <td><code>delay_while_idle</code></td>
- <td>Optional, boolean or number</td>
- <td>See <a href="#table1">table 1</a> for details.</td>
- </tr>
- <tr>
- <td><code>time_to_live</code></td>
- <td>Optional, number</td>
- <td>See <a href="#table1">table 1</a> for details.</td>
- </tr>
- <tr>
- <td><code>restricted_package_name</code></td>
- <td>Optional, string</td>
- <td>See <a href="#table1">table 1</a> for details.</td>
- </tr>
- <tr>
- <td><code>dry_run </code></td>
- <td>Optional, boolean</td>
- <td>See <a href="#table1">table 1</a> for details.</td>
- </tr>
-<tr>
- <td colspan="3"><strong>Payload</strong></td>
- </tr>
- <tr>
- <td><code>data.&lt;key&gt;</code></td>
- <td>Optional, string</td>
- <td><p>This parameter specifies the key-value pairs of the message's payload.
-There is no limit on the number of key-value parameters,
-but there is a total message size limit of 4kb.</p>
- <p>For instance, in Android, <code>data:{"score":"3x1"}</code> would result in an intent extra
-named {@code score} with the string value {@code 3x1}.</p>
- <p>The key should not be a reserved word ({@code from} or any word starting with
-{@code google}). It is also not recommended to use words defined in this table
-(such as {@code collapse_key}) because that could yield unpredictable outcomes.</p></td>
- </tr>
-</table>
-
-<h3 id="interpret-downstream">Interpreting a Downstream Message Response</h3>
-
-<p>This section describes the syntax of a response to a downstream message. A client
-app or the GCM Connection Server sends the response to 3rd-party app server upon processing
-the message request. </p>
-
-<h4>Interpreting a downstream HTTP message response </h4>
-<p>The 3rd-party app server should look at both the message response header and the body
-to interpret the message response sent from the GCM Connection Server. The following table
-describes the possible responses.</p>
-<p>
-
-<p class="table-caption" id="table3">
- <strong>Table 3.</strong> Downstream HTTP message response header.</p>
-<table border=1>
- <tr>
- <th>Response</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>200</td>
- <td>Message was processed successfully. The response body will contain more
-details about the message status, but its format will depend whether the request
-was JSON or plain text. See <a href="#table4">table 4</a>
-for more details.</td>
- </tr>
- <tr>
- <td>400</td>
- <td>Only applies for JSON requests.
-Indicates that the request could not be parsed as JSON, or it contained invalid
-fields (for instance, passing a string where a number was expected). The exact
-failure reason is described in the response and the problem should be addressed
-before the request can be retried.</td>
- </tr>
- <tr>
- <td>401</td>
- <td>There was an error authenticating the sender account.
-<a href="server.html#auth_error">Troubleshoot</a></td>
- </tr>
- <tr>
- <td>5xx</td>
- <td>Errors in the 500-599 range (such as 500 or 503) indicate that there was
-an internal error in the GCM server while trying to process the request, or that
-the server is temporarily unavailable (for example, because of timeouts). Sender
-must retry later, honoring any <code>Retry-After</code> header included in the
-response. Application servers must implement exponential back-off.
-<a href="server.html#internal_error">Troubleshoot</a></td>
- </tr>
-</table>
-
-<p>The following table lists the fields in a downstream message response body
-(JSON).</p>
-
-
-<p class="table-caption" id="table4">
- <strong>Table 4.</strong> Downstream HTTP message response body (JSON).</p>
-<table>
- <tr>
- <th>Parameter</th>
- <th>Usage</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>multicast_id</code></td>
- <td>Required, number</td>
- <td>Unique ID (number) identifying the multicast message.</td>
- </tr>
- <tr>
- <td><code>success</code></td>
- <td>Required, number</td>
- <td>Number of messages that were processed without an error.</td>
- </tr>
- <tr>
- <td><code>failure</code></td>
- <td>Required, number</td>
- <td>Number of messages that could not be processed.</td>
- </tr>
- <tr>
- <td><code>canonical_ids</code></td>
- <td>Required, number</td>
- <td>Number of results that contain a canonical registration ID. See the
-<a href="{@docRoot}google/gcm/gcm.html#canonical">Overview</a> for more discussion of this topic.</td>
- </tr>
- <tr>
- <td><code>results</code></td>
- <td>Optional, array object</td>
- <td>Array of objects representing the status of the messages processed. The
-objects are listed in the same order as the request (i.e., for each registration
-ID in the request, its result is listed in the same index in the response).<br>
- <ul>
- <li><code>message_id</code>: String specifying a unique ID for each successfully processed
- message.</li>
- <li><code>registration_id</code>: Optional string specifying the canonical registration ID
- for the client app that the message was processed and sent to. Sender should use this
- value as the Registration ID for future requests. Otherwise, the messages might
- be rejected.
- </li>
- <li><code>error</code>: String specifying the error that occurred when processing the
- message for the recipient. The possible values can be found in <a href="#table11">table 11
- </a>.</li>
- </ul></td>
- </tr>
-</table>
-
-
-<p class="table-caption" id="table5">
- <strong>Table 5.</strong> Success response for downstream HTTP message response body (Plain Text).</p>
-<table border="1">
- <tr>
- <th>Parameter</th>
- <th>Usage</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>id</code></td>
- <td>Required, string</td>
- <td>This parameter specifies the unique message ID that GCM server processed successfully.</td>
- </tr>
- <tr>
- <td><code>registration_id</code></td>
- <td>Optional, string</td>
- <td>This parameter specifies the canonical registration ID for the client app that the message was
-processed and sent to. Sender should replace the registration ID with this value on future requests,
-otherwise, the messages might be rejected.</td>
- </tr>
-</table>
-
-<p class="table-caption" id="table6">
- <strong>Table 6.</strong> Error response for downstream HTTP message response body (Plain Text).</p>
-<table border="1">
- <tr>
- <th>Parameter</th>
- <th>Usage</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>{@code Error}</td>
- <td>Required, string</td>
- <td>This parameter specifies the error value while processing the message for the recipient.
-See <a href="#table11">table 11</a> for details. </td>
- </tr>
-</table>
-
-<h4>Interpreting a downstream XMPP message response</h4>
-
-<p>The following table lists the fields that appear in a downstream XMPP message response.</p>
-
-<p class="table-caption" id="table7">
- <strong>Table 7.</strong> Downstream message XMPP message response body.</p>
-<table border="1">
- <tr>
- <th>Parameter</th>
- <th>Usage</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>from</code></td>
- <td>Required, string</td>
- <td><p>This parameter specifies who sent this response.</p>
- <p>The value is the registration ID of the client app.</p></td>
- </tr>
- <tr>
- <td><code>message_id</code></td>
- <td>Required, string</td>
- <td>This parameter uniquely identifies a message in an XMPP connection.
-The value is a string that uniquely identifies the associated message.</td>
- </tr>
- <tr>
- <td><code>message_type</code></td>
- <td>Required, string</td>
- <td><p>This parameter specifies an 'ack' or 'nack' message from XMPP (CCS)
-to the 3rd-party app server.</p>
- <p>If the value is set to {@code nack}, the 3rd-party app server should look at
-{@code error} and {@code error_description} to get failure information. </p></td>
- </tr>
- <tr>
- <td><code>error</code></td>
- <td>Optional, string</td>
- <td>This parameter specifies an error related to the downstream message. It is set when the
-{@code message_type} is {@code nack}. See <a href="#table11">table 6</a> for details.</td>
- </tr>
- <tr>
- <td><code>error_description</code></td>
- <td>Optional, string</td>
- <td>This parameter provides descriptive information for the error. It is set
-when the {@code message_type} is {@code nack}.</td>
- </tr>
-</table>
-<h2 id="upstream">Upstream Messages (XMPP)</h2>
-
-<p>An upstream message is a message the client app sends to the 3rd-party app server.
-Currently only CCS (XMPP) supports upstream messaging.</p>
-
-<h3 id="interpret-upstream">Interpreting an upstream XMPP message </h3>
-<p>The following table describes the fields that appear in an upstream XMPP message.
-
-<p class="table-caption" id="table8">
- <strong>Table 8.</strong> Upstream XMPP messages.</p>
-<table border="1">
- <tr>
- <th>Parameter</th>
- <th>Usage</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>from</code></td>
- <td>Required, string</td>
- <td><p>This parameter specifies who sent the message.</p>
- <p>The value is the registration ID of the client app.</p></td>
- </tr>
- <tr>
- <td><code>category</code></td>
- <td>Required, string</td>
- <td>This parameter specifies the application package name of the client app that sent the message. </td>
- </tr>
- <tr>
- <td><code>message_id</code></td>
- <td>Required, string</td>
- <td>This parameter specifies the unique ID of the message. </td>
- </tr>
- <tr>
- <td><code>data</code></td>
- <td>Optional, string</td>
- <td>This parameter specifies the key-value pairs of the message's payload.</td>
- </tr>
-</table>
-
-<h3 id="upstream-response">Sending an upstream XMPP message response</h3>
-
-<p>The following table describes the response that 3rd-party app server is expected to send to
-<a href="{@docRoot}google/gcm/ccs.html">XMPP (CCS)</a> in response to an
-upstream message it (the app server) received.</p>
-
-<p class="table-caption" id="table9">
- <strong>Table 9.</strong> Upstream XMPP message response.</p>
-<table border="1">
- <tr>
- <th>Parameter</th>
- <th>Usage</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>to</code></td>
- <td>Required, string</td>
- <td><p>This parameter specifies the recipient of a response message. </p>
- <p>The value must be a registration ID of the client app that sent the upstream message.</p></td>
- </tr>
- <tr>
- <td><code>message_id</code></td>
- <td>Required, string</td>
- <td>This parameter specifies which message the response is intended for. The value must be
-the {@code message_id} value from the corresponding upstream message.</td>
- </tr>
- <tr>
- <td><code>message_type</code></td>
- <td>Required, string</td>
- <td>This parameter specifies an {@code ack} message from a 3rd-party app server to CCS.</td>
- </tr>
-</table>
-<h2 id="ccs">Cloud Connection Server Messages (XMPP) </h2>
-<p>This is a message sent from XMPP (CCS) to a 3rd-party app server. Here are the primary types
-of messages that XMPP (CCS) sends to the 3rd-party app server:</p>
-<ul>
- <li><strong>Delivery Receipt:</strong> If the 3rd-party app server included {@code delivery_receipt_requested}
-in the downstream message, XMPP (CCS) sends a delivery receipt when it receives confirmation
-that the device received the message.</li>
- <li><strong>Control:</strong> These CCS-generated messages indicate that
-action is required from the 3rd-party app server.</li>
-</ul>
-
-<p>The following table describes the fields included in the messages CCS
-sends to a 3rd-party app server.</p>
-
-<p class="table-caption" id="table10">
- <strong>Table 10.</strong> GCM Cloud Connection Server messages (XMPP).</p>
-<table border="1">
- <tr>
- <th>Parameter</th>
- <th>Usage</th>
- <th>Description</th>
- </tr>
- <tr>
- <td colspan="3"><strong>Common Field</strong></td>
- </tr>
- <tr>
- <td><code>message_type</code></td>
- <td>Required, string</td>
- <td><p>This parameter specifies the type of the CCS message: either delivery receipt or control.</p>
- <p>When it is set to {@code receipt}, the message includes {@code from}, {@code message_id},
- {@code category} and {@code data} fields to provide additional information.</p>
- <p>When it is set to {@code control}, the message includes {@code control_type} to indicate the
-type of control message.</p></td>
- </tr>
- <tr>
- <td colspan="3"><strong>Delivery receipt-specific</strong></td>
- </tr>
- <tr>
- <td><code>from</code></td>
- <td>Required, string</td>
- <td>This parameter is set to {@code gcm.googleapis.com}, indicating that the
-message is sent from CCS.</td>
- </tr>
- <tr>
- <td><code>message_id</code></td>
- <td>Required, string</td>
- <td>This parameter specifies the original message ID that the receipt is intended for,
-prefixed with {@code dr2:} to indicate that the message is a delivery receipt. A 3rd-party app
-server must send an {@code ack} message with this message ID to acknowledge that it
-received this delivery receipt. See <a href="#table9">table 9</a> for the 'ack' message format.</td>
- </tr>
- <tr>
- <td><code>category</code></td>
- <td>Optional, string</td>
- <td>This parameter specifies the application package name of the client app that
-receives the message that this delivery receipt is reporting. This is available when
-{@code message_type} is {@code receipt}.</td>
- </tr>
- <tr>
- <td><code>data</code></td>
- <td>Optional, string</td>
- <td>This parameter specifies the key-value pairs for the delivery receipt message. This is available
-when the {@code message_type} is {@code receipt}.
- <ul>
- <li>{@code message_status}: This parameter specifies the status of the receipt message.
-It is set to {@code MESSAGE_SENT_TO_DEVICE} to indicate the device has confirmed its receipt of
-the original message.</li>
- <li>{@code original_message_id}: This parameter specifies the ID of the original message
-that the 3rd-party app server sent to the client app.</li>
- <li>{@code device_registration_id}: This parameter specifies the registration ID of the
-client app to which the original message was sent.</li>
- </ul>
-</td>
- </tr>
- <tr>
- <td colspan="3"><strong>Control-specific</strong></td>
- </tr>
- <tr>
- <td><code>control_type</code></td>
- <td>Optional, string</td>
- <td><p>This parameter specifies the type of control message sent from CCS.</p>
- <p>Currently, only {@code CONNECTION_DRAINING} is supported. XMPP (CCS) sends this control message
-before it closes a connection to perform load balancing. As the connection drains, no more messages
-are allowed to be sent to the connection, but existing messages in the pipeline will
-continue to be processed.</p></td>
- </tr>
-</table>
-
-<h2 id="error-codes">Downstream message error response codes (HTTP and XMPP)</h2>
-
-<p>The following table lists the error response codes for downstream messages (HTTP and XMPP).</p>
-
-<p class="table-caption" id="table11">
- <strong>Table 11.</strong> Downstream message error response codes.</p>
-<table border="1">
- <tr>
- <th>Error</th>
- <th>HTTP Code</th>
- <th>XMPP Code</th>
- <th>Recommended Action</th>
- </tr>
- <tr>
- <td>Missing Registration ID</td>
- <td>200 + error:MissingRegistration</td>
- <td><code>INVALID_JSON</code></td>
- <td>Check that the request contains a registration ID (either in the
-{@code registration_id} in a plain text message, or in the {@code registration_ids} in JSON).</td>
- </tr>
- <tr>
- <td>Invalid Registration ID</td>
- <td>200 + error:InvalidRegistration</td>
- <td><code>BAD_REGISTRATION</code></td>
- <td>Check the format of the registration ID you pass to the server. Make sure it
-matches the registration ID the client app receives from registering with GCM. Do not
-truncate or add additional characters.</td>
- </tr>
- <tr>
- <td>Unregistered Device</td>
- <td>200 + error:NotRegistered</td>
- <td><code>DEVICE_UNREGISTERED</code></td>
- <td>An existing registration ID may cease to be valid in a number of scenarios, including:<br>
- <ul>
- <li>If the client app unregisters with GCM.</li>
- <li>If the client app is automatically unregistered, which can happen if the user uninstalls the application.</li>
- <li>If the registration ID expires (for example, Google might decide to refresh registration IDs).</li>
- <li>If the client app is updated but the new version is not configured to receive messages.</li>
-</ul>
- For all these cases, remove this registration ID from the 3rd-party app
-server and stop using it to send messages.</td>
- </tr>
- <tr>
- <td>Invalid Package Name</td>
- <td>200 + error:InvalidPackageName</td>
- <td></td>
- <td>Make sure the message was addressed to a registration ID whose package name
-matches the value passed in the request.</td>
- </tr>
- <tr>
- <td>Authentication Error</td>
- <td>401</td>
- <td>&nbsp;</td>
- <td>The sender account used to send a message couldn't be authenticated. Possible causes are:<br>
-<ul>
- <li>Authorization header missing or with invalid syntax in HTTP request.</li>
- <li>Invalid project number sent as key.</li>
- <li>Key valid but with GCM service disabled.</li>
- <li>Request originated from a server not whitelisted in the Server Key IPs.</li>
-</ul>
- Check that the token you're sending inside the Authentication header is
-the correct API key associated with your project. See
-<a href="{@docRoot}google/gcm/http.html#checkAPIkey">Checking the validity of an API Key
-</a> for details.</td>
- </tr>
- <tr>
- <td>Mismatched Sender</td>
- <td>200 + error:MismatchSenderId</td>
- <td><code>BAD_REGISTRATION</code></td>
- <td>A registration ID is tied to a certain group of senders. When a client app registers
-for GCM, it must specify which senders are allowed to send messages. You should use one
-of those sender IDs when sending messages to the client app. If you switch to a different
-sender, the existing registration IDs won't work.</td>
- </tr>
- <tr>
- <td>Invalid JSON</td>
- <td>400</td>
- <td><code>INVALID_JSON</code></td>
- <td>Check that the JSON message is properly formatted and contains valid fields
-(for instance, making sure the right data type is passed in).</td>
- </tr>
- <tr>
- <td>Message Too Big</td>
- <td>200 + error:MessageTooBig</td>
- <td><code>INVALID_JSON</code></td>
- <td>Check that the total size of the payload data included in a message does
-not exceed 4096 bytes. This includes both the the keys and the values.</td>
- </tr>
- <tr>
- <td>Invalid Data Key</td>
- <td>200 + error:
-<br />
-InvalidDataKey</td>
- <td><code>INVALID_JSON</code></td>
- <td>Check that the payload data does not contain a key (such as {@code from} or any value
-prefixed by {@code google}) that is used internally by GCM. Note that some words (such as {@code collapse_key})
-are also used by GCM but are allowed in the payload, in which case the payload value
-will be overridden by the GCM value.</td>
- </tr>
- <tr>
- <td>Invalid Time to Live</td>
- <td>200 + error:InvalidTtl</td>
- <td><code>INVALID_JSON</code></td>
- <td>Check that the value used in {@code time_to_live} is an integer representing a
-duration in seconds between 0 and 2,419,200 (4 weeks).</td>
- </tr>
- <tr>
- <td>Bad ACK message</td>
- <td>N/A</td>
- <td><code>BAD_ACK</code></td>
- <td>Check that the 'ack' message is properly formatted before retrying. See
-<a href="#table9">table 9</a> for details.</td>
- </tr>
- <tr>
- <td>Timeout</td>
- <td>5xx or 200 + error:Unavailable</td>
- <td><code>SERVICE_UNAVAILABLE</code></td>
- <td><p>The server couldn't process the request in time. Retry the same request, but you must:<br>
-<ul>
- <li>For HTTP: Honor the {@code Retry-After} header if it is included in the response from the
-GCM Connection Server.</li>
- <li>Implement exponential back-off in your retry mechanism. (e.g. if you waited one second
-before the first retry, wait at least two second before the next one, then 4 seconds and so on).
-If you're sending multiple messages, delay each one independently by an additional random amount
-to avoid issuing a new request for all messages at the same time.</li>
- <li>For CCS: The initial retry delay should be set to 1 second.</li>
-</ul>
- <p>Senders that cause problems risk being blacklisted.</p></td>
- </tr>
- <tr>
- <td>Internal Server Error</td>
- <td>500 or 200 + error:InternalServerError</td>
- <td><code>INTERNAL_SERVER_
-<br />
-ERROR</code></td>
- <td>The server encountered an error while trying to process the request. You could retry
-the same request following the requirements listed in "Timeout" (see row above). If the error persists, please
-report the problem in the {@code android-gcm group}.</td>
- </tr>
- <tr>
- <td>Device Message Rate Exceeded</td>
- <td>200 + error:
-<br />DeviceMessageRate
-<br />
-Exceeded</td>
- <td><code>DEVICE_MESSAGE_RATE<br />
-_EXCEEDED</code></td>
- <td>The rate of messages to a particular device is too high. Reduce the
-number of messages sent to this device and do not immediately retry sending to this device.</td>
- </tr>
- <tr>
- <td>Connection Draining</td>
- <td>N/A</td>
- <td><code>CONNECTION_DRAINING</code></td>
- <td>The message couldn't be processed because the connection is draining. This happens because
-periodically, XMPP (CCS) needs to close down a connection to perform load balancing. Retry the message over
-another XMPP connection.</td>
- </tr>
-</table>
diff --git a/docs/html/google/gcm/server.jd b/docs/html/google/gcm/server.jd
deleted file mode 100644
index 004fd0e..0000000
--- a/docs/html/google/gcm/server.jd
+++ /dev/null
@@ -1,440 +0,0 @@
-page.title=Implementing GCM Server
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>In this document</h2>
-
-<ol class="toc">
- <li><a href="#role">Role of the 3rd-party Application Server</a></li>
- <li><a href="#choose">Choosing a GCM Connection Server</a></li>
- <li><a href="#send-msg">Sending Messages</a>
- <ol class="toc">
-
- <li><a href="#target">Target</a></li>
- <li><a href="#payload">Payload</a></li>
- <li><a href="#params">Message parameters</a>
- </ol>
- </li>
- <li><a href="#adv">Messaging Concepts and Best Practices</a>
-
- <ol class="toc">
-
- <li><a href="#collapsible">Send-to-Sync vs. Messages with Payload</a></li>
- <li><a href="#ttl">Setting an Expiration Date for a Message</a></li>
- <li><a href="#multi-senders">Receiving Messages from Multiple Senders</a>
- <li><a href="#lifetime">Lifetime of a Message</a>
- <li><a href="#throttling">Throttling</a>
- </ol>
-
-</li>
- </li>
-
-</ol>
-
-<h2>See Also</h2>
-
-<ol class="toc">
-<li><a href="server-ref.html">Server Reference</a></li>
-<li><a href="gs.html">Getting Started</a></li>
-<li><a href="client.html">Implementing GCM Client</a></li>
-<li><a href="ccs.html">Cloud Connection Server (XMPP)</a></li>
-<li><a href="http.html">HTTP Connection Server</a></li>
-
-
-</ol>
-
-</div>
-</div>
-
-
-<p>The server side of Google Cloud Messaging (GCM) consists of two components:</p>
-<ul>
-<li>Google-provided <strong>GCM Connection Servers</strong>
-take messages from a <a href="{@docRoot}google/gcm/server.html#role">3rd-party app server</a>
-and send them to a GCM-enabled
-application (the &quot;client app&quot;) running on a device. For example,
-Google provides connection servers for <a href="{@docRoot}google/gcm/http.html">
-HTTP</a> and <a href="{@docRoot}google/gcm/ccs.html">XMPP (CCS)</a> (XMPP).</li>
-<li>A <strong>3rd-party application server</strong> that you must implement. This application
-server sends data to a GCM-enabled client app via the chosen GCM connection server.</li>
-</ul>
-</p>
-
-<p>A full GCM implementation requires both a client implementation and a server
-implementation. For more
-information about implementing the client side, see <a href="client.html">
-Implementing GCM Client</a>.</p>
-
-
-<h2 id="role">Role of the 3rd-party Application Server</h2>
-
-<p>Before you can write client apps that use the GCM feature, you must
-have an application server that meets the following criteria:</p>
-
-<ul>
- <li>Able to communicate with your client.</li>
- <li>Able to fire off properly formatted requests to the GCM server.</li>
- <li>Able to handle requests and resend them as needed, using
-<a href="http://en.wikipedia.org/wiki/Exponential_backoff">exponential back-off.</a></li>
- <li>Able to store the API key and client registration IDs. In HTTP, the API key is
-included in the header of POST requests that send messages. In XMPP, the API key is
-used in the SASL PLAIN authentication request as a password to authenticate the connection.</li>
- <li>Able to generate message IDs to uniquely identify each message it sends. Message IDs
-should be unique per sender ID.</li>
-</ul>
-
-<p>Here are the basic steps you follow to implement your 3rd-party app server:</p>
-
-<ul>
- <li>Decide which GCM connection server(s) you want to use. Note that if you want to use
- upstream messaging from your client applications, you must use XMPP (CCS). For a more detailed
- discussion of this, see <a href="#choose">
- Choosing a GCM Connection Server</a>.</li>
- <li>Decide how you want to implement your app server. We provide helper libraries and code
-samples to assist you with your 3rd-party app server implementation. For example:
- <ul>
- <li>If you decide to use the HTTP connection server, you can use the
-GCM server helper library and demo app to help in implementing your app server.</li>
- <li>If you decide to use the XMPP connection server, you can use
-the provided Python or Java <a href="http://www.igniterealtime.org/projects/smack/">
-Smack</a> demo apps as a starting point.</li>
- <li>Note that Google AppEngine does not support connections to XMPP (CCS).</li>
- </ul>
- </li>
- </ul>
- </li>
-</ul>
-
-
-<h2 id="choose">Choosing a GCM Connection Server</h2>
-
-<p>Currently GCM provides two connection servers: <a href="{@docRoot}google/gcm/http.html">
-HTTP</a> and <a href="{@docRoot}google/gcm/ccs.html">XMPP (CCS)</a>. You can use them
-separately or in tandem. XMPP (CCS) messaging differs from HTTP messaging in the following ways:</p>
-<ul>
- <li>Upstream/Downstream messages
- <ul>
- <li>HTTP: Downstream only, cloud-to-device up to 4KB of data. </li>
- <li>XMPP (CCS): Upstream and downstream (device-to-cloud, cloud-to-device),
- up to 4 KB of data. </li>
- </ul>
- </li>
- <li>Messaging (synchronous or asynchronous)
- <ul>
- <li>HTTP: Synchronous. 3rd-party app servers send messages as HTTP POST requests and
-wait for a response. This mechanism is synchronous and blocks the sender from sending
-another message until the response is received.</li>
- <li>XMPP (CCS): Asynchronous. 3rd-party app servers send/receive messages to/from all their
-devices at full line speed over persistent XMPP connections.
-XMPP (CCS) sends acknowledgment or failure notifications (in the
-form of special ACK and NACK JSON-encoded XMPP messages) asynchronously.</li>
- </ul>
- </li>
-
- <li>JSON
- <ul>
- <li>HTTP: JSON messages sent as HTTP POST.</li>
- <li>XMPP (CCS): JSON messages encapsulated in XMPP messages.</li>
- </ul>
- </li>
- <li>Plain Text
- <ul>
- <li>HTTP: Plain Text messages sent as HTTP POST.</li>
- <li>XMPP (CCS): Not supported.</li>
- </ul>
- </li>
- <li>Multicast downstream send to multiple registration IDs.
- <ul>
- <li>HTTP: Supported in JSON message format.</li>
- <li>XMPP (CCS): Not supported.</li>
- </ul>
- </li>
-</ul>
-
-
-<h2 id="send-msg">Sending Messages</h2>
-
-<p>This section gives an overview of sending messages. For details of message syntax,
-see <a href="{@docRoot}google/gcm/server-ref.html">Server Reference</a>.</p>
-
-<h3>Overview</h3>
-
-<p>Here is the general sequence of events that occurs when a 3rd-party application
-server sends a message (the details vary depending on the platform):</p>
-<ol>
- <li>The 3rd-party app server sends a message to GCM servers.</li>
- <li>The GCM connection server enqueues and stores the message if the device is offline.</li>
- <li>When the device is online, GCM connection server sends the message to the device.</li>
- <li>The client app processes the message. </li>
-</ol>
-
-<h3>Implement send request</h3>
-
-<p>The following sections describe the basic components involved in
-sending a request. See the <a href="{@docRoot}google/gcm/server-ref.html">Server Reference</a>
-for details.</p>
-
-<h4 id="target">Target</h4>
-<p>Required. When your app server sends a message in GCM, it must specify a target.</p>
-<p>For HTTP you must specify the target as one of the following:</p>
-<ul>
-<li><code>registration_ids</code>: For sending to 1 or more devices (up to 1000).
-When you send a message to multiple registration IDs, that is called a multicast message.</li>
-<li><code>notification_key</code>: For sending to multiple devices owned by a single user.</li>
-</ul>
-<p>For CCS (XMPP) you must specify the target as:</p>
-<ul>
-<li>{@code to}: This
-field may contain a single registration ID or a notification key.
-XMPP (CCS) does not support multicast messaging.</li>
-</ul>
-
-<h4 id="options">Options</h4>
-
-<p>There are various options the 3rd-party app server can set when sending a downstream
-message to a client app. See the <a href="{@docRoot}google/gcm/server-ref.html#table1">
-Server Reference</a> for details. Here are a few examples of possible options:</p>
-
-<ul>
- <li>{@code collapse_key}: whether a message should be "send-to-sync" or a "message with
-payload".</li>
- <li>{@code time_to_live}: setting an expiration date for a message.</li>
- <li>{@code dry_run}: Test your server.
-<p>If you want to test your request (either JSON or plain text) without delivering
-the message to the devices, you can set an optional HTTP parameter called
-<code>dry_run</code> with the value <code>true</code>. The result will be almost
-identical to running the request without this parameter, except that the message
-will not be delivered to the devices. Consequently, the response will contain fake
-IDs for the message and multicast parameters.</p>
-</li>
-</ul>
-
-<h4 id="payload">Payload</h4>
-<p>Optional. If you are including a payload in the message, you use the <code>data</code>
-parameter to include the payload. This applies for both HTTP and XMPP.</p>
-
-<p>See the <a href="{@docRoot}google/gcm/server-ref.html">Server Reference</a> for details on sending
-and receiving messages.</p>
-
-<h2 id="adv">Messaging Concepts and Best Practices</h2>
-
-<p>This section has a discussion of general messaging topics.</p>
-
-<h3 id="collapsible">Send-to-Sync vs. Messages with Payload</h3>
-
-<p>Every message sent in GCM has the following characteristics:</p>
-<ul>
- <li>It has a payload limit of 4096 bytes.</li>
- <li>By default, it is stored by GCM for 4 weeks.</li>
-</ul>
-
-<p>But despite these similarities, messages can behave very differently depending
-on their particular settings. One major distinction between messages is whether
-they are collapsed (where each new message replaces the preceding message) or not
-collapsed (where each individual message is delivered). Every message sent in GCM
-is either a &quot;send-to-sync&quot; (collapsible) message or a &quot;message with
-payload&quot; (non-collapsible message).</p>
-
-<h4 id="s2s">Send-to-sync messages</h4>
-
-<p>A send-to-sync (collapsible) message is often a &quot;tickle&quot; that tells
-a mobile application to sync data from the server. For example, suppose you have
-an email application. When a user receives new email on the server, the server
-pings the mobile application with a &quot;New mail&quot; message. This tells the
-application to sync to the server to pick up the new email. The server might send
-this message multiple times as new mail continues to accumulate, before the application
-has had a chance to sync. But if the user has received 25 new emails, there's no
-need to preserve every &quot;New mail&quot; message. One is sufficient. Another
-example would be a sports application that updates users with the latest score.
-Only the most recent message is relevant. </p>
-
-<p>GCM allows a maximum of 4 different collapse keys to be used by the GCM server
-at any given time. In other words, the GCM server can simultaneously store 4
-different send-to-sync messages per device, each with a different collapse key.
-For example, Device A can have A1, A2, A3, and A4. Device B can have B1, B2, B3,
-and B4, and so on. If you exceed this number GCM will only keep 4 collapse keys, with no
-guarantees about which ones they will be.</p>
-
-<h3 id="payload">Messages with payload</h3>
-
-<p>Unlike a send-to-sync message, every &quot;message with payload&quot;
-(non-collapsible message) is delivered. The payload the message contains can be
-up to 4kb. For example, here is a JSON-formatted message in an IM application in
-which spectators are discussing a sporting event:</p>
-
-<pre class="prettyprint pretty-json">{
- "registration_id" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
- "data" : {
- "Nick" : "Mario",
- "Text" : "great match!",
- "Room" : "PortugalVSDenmark",
- },
-}</pre>
-
-<p>A &quot;message with payload&quot; is not simply a &quot;ping&quot; to the
-mobile application to contact the server to fetch data. In the aforementioned IM
-application, for example, you would want to deliver every message, because every
-message has different content. To specify a non-collapsible message, you simply
-omit the <code>collapse_key</code> parameter. Thus GCM will send each message
-individually. Note that the order of delivery is not guaranteed.</p>
-
-<p>GCM will store up to 100 non-collapsible messages. After that, all messages
-are discarded from GCM, and a new message is created that tells the client how
-far behind it is.</p>
-
-<p>The application should respond by syncing with the server to recover the
-discarded messages. </p>
-
-<h4 id="which">Which should I use?</h4>
- <p>If your application does not need to use non-collapsible messages, collapsible
-messages are a better choice from a performance standpoint. However, if you use
-collapsible messages, remember that <strong>GCM only allows a maximum of 4 different collapse
-keys to be used by the GCM server per registration ID at any given time</strong>. You must
-not exceed this number, or it could cause unpredictable consequences.</p>
-
-<h3 id="ttl">Setting an Expiration Date for a Message</h3>
-<p>You can use the <code>time_to_live</code> parameter in the send request
-to specify the maximum lifespan of a message.
-The value of this parameter must be a duration from 0 to 2,419,200 seconds, and
-it corresponds to the maximum period of time for which GCM will store and try to
-deliver the message. Requests that don't contain this field default to the maximum
-period of 4 weeks.</p>
-<p>Here are some possible uses for this feature:</p>
-<ul>
- <li>Video chat incoming calls</li>
- <li>Expiring invitation events</li>
- <li>Calendar events</li>
-</ul>
-<h4 id="bg">Background </h4>
-<p>GCM usually delivers messages immediately after they are sent. However,
-this might not always be possible. For example, if the platform is Android,
-the device could be turned off, offline, or otherwise unavailable.
-Or the sender itself might request
-that messages not be delivered until the device becomes active by using the
-<code>delay_while_idle</code> flag. Finally, GCM might intentionally delay messages
-to prevent an application from consuming excessive resources and negatively
-impacting battery life.</p>
-
-<p>When this happens, GCM will store the message and deliver it as soon as it's
-feasible. While this is fine in most cases, there are some applications for which
-a late message might as well never be delivered. For example, if the message is
-an incoming call or video chat notification, it will only be meaningful for a
-small period of time before the call is terminated. Or if the message is an
-invitation to an event, it will be useless if received after the event has ended.</p>
-
-<p>Another advantage of specifying the expiration date for a message is that GCM
-will never throttle messages with a <code>time_to_live</code> value of 0 seconds.
-In other words, GCM will guarantee best effort for messages that must be delivered
-&quot;now or never.&quot; Keep in mind that a <code>time_to_live</code> value of
-0 means messages that can't be delivered immediately will be discarded. However,
-because such messages are never stored, this provides the best latency for
-sending notifications.</p>
-
-<p>Here is an example of a JSON-formatted request that includes TTL:</p>
-<pre class="prettyprint pretty-json">
-{
- "collapse_key" : "demo",
- "delay_while_idle" : true,
- "registration_ids" : ["xyz"],
- "data" : {
- "key1" : "value1",
- "key2" : "value2",
- },
- "time_to_live" : 3
-},
-</pre>
-
-
-<h3 id="multi-senders">Receiving Messages from Multiple Senders</h3>
-
-<p>GCM allows multiple parties to send messages to the same application. For
-example, suppose your application is an articles aggregator with multiple
-contributors, and you want each of them to be able to send a message when they
-publish a new article. This message might contain a URL so that the application
-can download the article. Instead of having to centralize all sending activity in
-one location, GCM gives you the ability to let each of these contributors send
-its own messages.</p>
-
-<p>To make this possible, all you need to do is have each sender generate its own
-project number. Then include those IDs in the sender field, separated by commas,
-when requesting a registration. Finally, share the registration ID with your
-partners, and they'll be able to send messages to your application using their
-own authentication keys.</p>
-
-<p>Note that there is limit of 100 multiple senders.</p>
-
-<h3 id="lifetime">Lifetime of a Message</h3>
-
-<p>When a 3rd-party server posts a message to GCM and receives a message ID back,
-it does not mean that the message was already delivered to the device. Rather, it
-means that it was accepted for delivery. What happens to the message after it is
-accepted depends on many factors.</p>
-
-<p>In the best-case scenario, if the device is connected to GCM, the screen is on,
-and there are no throttling restrictions (see <a href="#throttling">Throttling</a>),
-the message will be delivered right away.</p>
-
-<p>If the device is connected but idle, the message will still be
-delivered right away unless the <code>delay_while_idle</code> flag is set to true.
-Otherwise, it will be stored in the GCM servers until the device is awake. And
-that's where the <code>collapse_key</code> flag plays a role: if there is already
-a message with the same collapse key (and registration ID) stored and waiting for
-delivery, the old message will be discarded and the new message will take its place
-(that is, the old message will be collapsed by the new one). However, if the collapse
-key is not set, both the new and old messages are stored for future delivery.
-Collapsible messages are also called <a href="#s2s">send-to-sync messages</a>.</p>
-
-<p class="note"><strong>Note:</strong> There is a limit on how many messages can
-be stored without collapsing. That limit is currently 100. If the limit is reached,
-all stored messages are discarded. Then when the device is back online, it receives
-a special message indicating that the limit was reached. The application can then
-handle the situation properly, typically by requesting a full sync.
-<br><br>
-Likewise, there is a limit on how many <code>collapse_key</code>s you can have for
-a particular device. GCM allows a maximum of 4 different collapse keys to be used
-by the GCM server per device
-any given time. In other words, the GCM server can simultaneously store 4 different
-send-to-sync messages, each with a different collapse key. If you exceed this number
-GCM will only keep 4 collapse keys, with no guarantees about which ones they will be.
-See <a href="#s2s">Send-to-sync messages</a> for more information.
-</p>
-
-<p>If the device is not connected to GCM, the message will be stored until a
-connection is established (again respecting the collapse key rules). When a connection
-is established, GCM will deliver all pending messages to the device, regardless of
-the <code>delay_while_idle</code> flag. If the device never gets connected again
-(for instance, if it was factory reset), the message will eventually time out and
-be discarded from GCM storage. The default timeout is 4 weeks, unless the
-<code>time_to_live</code> flag is set.</p>
-
-<p>Finally, when GCM attempts to deliver a message to the device and the
-application was uninstalled, GCM will discard that message right away and
-invalidate the registration ID. Future attempts to send a message to that device
-will get a <code>NotRegistered</code> error. See <a href="#unreg">
-How Unregistration Works</a> for more information.</p>
-<p>Although is not possible to track the status of each individual message, the
-Google Cloud Console stats are broken down by messages sent to device, messages
-collapsed, and messages waiting for delivery.</p>
-
-<h3 id="throttling">Throttling</h3>
-<p>To prevent abuse (such as sending a flood of messages to a device) and
-to optimize for the overall network efficiency and battery life of
-devices, GCM implements throttling of messages using a token bucket
-scheme. Messages are throttled on a per application and per <a href="#collapsible">collapse
-key</a> basis (including non-collapsible messages). Each application
-collapse key is granted some initial tokens, and new tokens are granted
-periodically therefter. Each token is valid for a single message sent to
-the device. If an application collapse key exhausts its supply of
-available tokens, new messages are buffered in a pending queue until
-new tokens become available at the time of the periodic grant. Thus
-throttling in between periodic grant intervals may add to the latency
-of message delivery for an application collapse key that sends a large
-number of messages within a short period of time. Messages in the pending
-queue of an application collapse key may be delivered before the time
-of the next periodic grant, if they are piggybacked with messages
-belonging to a non-throttled category by GCM for network and battery
-efficiency reasons.</p>
-
-
diff --git a/docs/html/google/gcs/gcs-signup.jd b/docs/html/google/gcs/gcs-signup.jd
deleted file mode 100644
index 7334cec..0000000
--- a/docs/html/google/gcs/gcs-signup.jd
+++ /dev/null
@@ -1,10 +0,0 @@
-page.title=Sign Up for Google Cloud Save
-
-@jd:body
-
-<p>Sign up to be a trial partner for Google Cloud Save.</p>
-
-
-<iframe src="https://docs.google.com/a/google.com/forms/d/1_V67YIXzLDLb-UzxOOpSjUDuJFfeYg3hEUT0oliK2ck/viewform?embedded=true" width="100%" height="930" frameborder="0" marginheight="0" marginwidth="0" id="signupform">Loading...</iframe>
-</body>
-</html>
diff --git a/docs/html/google/gcs/index.jd b/docs/html/google/gcs/index.jd
deleted file mode 100644
index e5f4776..0000000
--- a/docs/html/google/gcs/index.jd
+++ /dev/null
@@ -1,30 +0,0 @@
-page.title=Google Cloud Save
-page.tags="gcs"
-header.hide=1
-@jd:body
-
-
-<div class="landing-banner">
-
-<div class="col-5" style="min-height:100px">
- <img src="{@docRoot}images/google/gcs.png" />
-</div>
-<div class="col-7">
-
- <h1 itemprop="name" style="margin-bottom:0;">Google Cloud Save</h1>
- <p itemprop="description">
- Google Cloud Save is a service that enables per-user data storage
-and sync in your apps with no backend programming required. Google Cloud Save
-stores its data
-in <a href="http://developers.google.com/datastore/">Google Cloud Datastore</a>,
- a fully managed, schemaless database for storing non-relational data. Cloud
-Datastore automatically scales with your users.
-Google Cloud Save works even when your device is offline, and it
-provides an easy transition to server-side coding because
-the same database is accessible via App Engine and Compute Engine.
-Finally, Google Cloud Save provides a generous initial per-user free quota that
-expands as your user base grows.
-</p>
-<a href="{@docRoot}google/gcs/gcs-signup.html" class="button">Sign Up</a>
-</div>
-</div>
diff --git a/docs/html/google/play-services/ads.jd b/docs/html/google/play-services/ads.jd
deleted file mode 100644
index 2f915f3..0000000
--- a/docs/html/google/play-services/ads.jd
+++ /dev/null
@@ -1,110 +0,0 @@
-page.title=Google Mobile Ads
-page.tags=Ads,monetization,AdMob,Google Play services
-header.hide=1
-
-@jd:body
-
-
-<div class="landing-banner">
-
-<div class="col-6">
- <img src="{@docRoot}images/google/gps-ads.png" alt="">
-</div>
-<div class="col-6">
-
-<h1 itemprop="name" style="margin-bottom:0;">Google Mobile Ads</h1>
-<p itemprop="description">
- Monetize your app with banner or interstitial ads from
- Google's vast pool of advertisers. Integrate with top ad networks through
- mediation to maximize your revenue from impressions. Take advantage of new
- ad features and capabilities through Google Play services, without having to
- add or update a library in your APK.
-</p>
-
-<p>
- Check out the <a href=
- "{@docRoot}reference/gms-packages.html">Google Mobile Ads API reference</a> and visit <a class=
- "external-link" href=
- "http://developers.google.com/mobile-ads-sdk">developers.google.com/mobile-ads-sdk</a>
- for more information about integrating Google Mobile Ads into your app.
-</p>
-</div>
-</div>
-
-<div style=
-"background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;" class=
-"caution">
- <p><strong>Upgrade to the new AdMob</strong></p>
- <p>Legacy AdMob will be shutting down on August 31, 2014. Beginning August 31,
- you will no longer be able to use legacy AdMob to promote and monetize your
- apps. Specifically, please be aware of the following:</p>
- <ol style="margin-bottom:0;">
- <li>Ads will stop serving to legacy ad units that are not updated with new
- ad unit IDs.</li>
- <li>Legacy house ad campaigns will stop serving.</li>
- <li>You will not be able to access the legacy AdMob UI after August 31,
- 2014.</li>
- </ol>
- <p>If you are still using legacy AdMob, please upgrade your account to the new
- AdMob as soon as possible. Upgrading takes only 5 minutes. <a href=
- "https://apps.admob.com/admob/signup?">Start here</a>.</p>
-</div>
-
-<div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">Key Developer Features</h3>
-
- <h4>Seamless auto-updates</h4>
- <p>The Google Mobile Ads SDK is part of Google Play services, so you can take advantage of features
- and capabilities in each new release of Google Play services, without needing to update your
- APK. </p>
-
- <h4>Monetize your apps</h4>
- <p>Connect with over a million Google advertisers and show relevant ads in your app. Users
- engage with the ads, you make money. The Google Mobile Ads SDK fully supports AdMob,
- DoubleClick for Publishers, DoubleClick Ad Exchange, and Search Ads for Mobile Apps.
- <br>
- <a href="http://www.google.com/ads/admob/monetize.html" class="external-link">Learn more
- and sign up</a>.</p>
-
- <h4>Location-based ads</h4>
- <p>You can use the publisher-provided location API to provide Google with the location when
- requesting ads. Location-based ads can improve your app monetization.</p>
-
- <h4>Innovative ads</h4>
- <p>Choose from a range of ads across mobile devices and tablets, including interactive
- ad units.</p>
-
- <h4>Flexible and powerful tools </h4>
- <p>Filters and controls help you manage your ads. If you want to use multiple ad
- networks, you can do that too, with free ad network mediation.</p>
-
- <h4>Ad Policy Compliant</h4>
- <p>The Google Mobile Ads SDK available in Google Play services is compliant with
- Google Play Ad Poilcy regarding the usage of
- <a href="{@docRoot}google/play-services/id.html">advertising ID</a>.</p>
- </div>
-
- <div class="col-6 normal-links">
- <h3 style="clear:left">Getting Started</h3>
- <h4>1. Get the Google Play services SDK</h4>
- <p>The Google Mobile Ads APIs are part of the Google Play services platform.</p>
- <p>To get started, <a href="{@docRoot}google/play-services/setup.html">set up
- the Google Play services SDK</a>.</p>
-
- <h4>2. Run the sample</h4>
- <p>Once you've installed the Google Play services package, the Google Mobile Ads sample is located
- in <code>&lt;android-sdk&gt;/extras/google-play-services/samples/ads</code> and shows you how to
- serve banner and interstitial ads using the Google Mobile Ads APIs.</p>
-
- <h4>3. Read the documentation</h4>
- <p>Your use of the Google Mobile Ads SDK is governed by the terms between you and Google that
- govern your use of the Google product (AdSense/AdMob, AdX or DFP) with which you use the SDK.</p>
- <p>For quick access while developing your Android apps, the <a
- href="{@docRoot}reference/gms-packages.html">Google Mobile Ads API reference</a> is available here on
- developer.android.com.</p>
- <p>Detailed documentation for Google Mobile Ads for Android is available with the rest of the Google
- Mobile Ads developer documents at <a href="https://developers.google.com/mobile-ads-sdk"
- class="external-link">developers.google.com/mobile-ads-sdk</a>. </p>
- </div>
-</div>
diff --git a/docs/html/google/play-services/cast.jd b/docs/html/google/play-services/cast.jd
deleted file mode 100644
index 656f634..0000000
--- a/docs/html/google/play-services/cast.jd
+++ /dev/null
@@ -1,92 +0,0 @@
-page.title=Google Cast Android API
-page.tags="chromecast","miracast"
-header.hide=1
-
-@jd:body
-
-
-<div class="landing-banner">
-
-<div class="col-6">
- <img src="{@docRoot}images/google/googlecast.png" alt="">
-</div>
-<div class="col-6">
-
- <h1 itemprop="name" style="margin-bottom:0;">Google Cast Android API</h1>
- <p itemprop="description">Google Cast is a technology that enables multi-screen experiences, which
- allows users to send content from mobile devices and personal computers to their TVs.
- You can use the Google Cast Android API
- to add casting functionality to your Android app so users can view your app content on their
- big screens.</p>
-
- <p>Explore the <a href="{@docRoot}reference/com/google/android/gms/cast/package-summary.html"
- >Google Cast Android API reference</a> or visit <a
- href="http://developers.google.com/cast/" class="external-link">developers.google.com/cast</a>
- for more information about how to design and build your app to support Google Cast.</p>
- <p></p>
-</div>
-</div>
-
-<div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">Key Developer Features</h3>
-
- <h4>Add your own style to a pre-built receiver app</h4>
- <p>Adding support for Google Cast requires that you provide a companion app on the
- Google Cast device, known as the receiver app. If your app streams audio or video content
- using one of several supported media types, then you can create a receiver app with your
- own style and branding by creating nothing more than a CSS file.
- <br/><a href="http://developers.google.com/cast/docs/styled_receiver" class="external-link"
- >Create a Styled Media Receiver</a></p>
-
- <h4>Build an entirely custom receiver app</h4>
- <p>If the Styled Media Receiver does not provide the UI components required for your
- receiver app or does not support the media types your app requires, you can build your
- own receiver app as a web page using the JavaScript Receiver API.
- <br/><a href="http://developers.google.com/cast/docs/styled_receiver" class="external-link"
- >Create a Custom Receiver</a></p>
-
- <h4>Add playback controls to your app</h4>
- <p>To allow users to control playback on the receiver app, you can add a
- controller interface to your app on Android, iOS, and Chrome. The client app on these devices
- is known as the sender app and can perform a variety of actions using the Google Cast APIs
- such as start and pause playback and control the volume on the Google Cast device.
- <br/><a href="http://developers.google.com/cast/docs/sender_apps" class="external-link"
- >Create a Sender App</a></p>
- </div>
-
-
- <div class="col-6 normal-links">
- <h3 style="clear:left">Getting Started</h3>
- <h4>1. Get the Google Play services SDK</h4>
-
- <p>The Google Cast Android APIs are part of the Google Play services platform.</p>
- <p>To get started, <a href="{@docRoot}google/play-services/setup.html">set up
- the Google Play services SDK</a> on your development machine and be sure your test device has
- Google Play services 4.2 (or higher) installed.</p>
-
- <h4>2. Register your app</h4>
- <p>Before you can develop and test apps on your own Google Cast device,
- you need to acquire an app ID for your API calls and register your Google Cast device
- (such as a Chromecast) as a development device. For details, read the
- <a href="http://developers.google.com/cast/docs/registration"
- class="external-link">Registration</a> guide.</p>
-
- <h4>3. Design the Android app UI</h4>
- <p>To provide the perfect user experience when casting your content to TVs, be sure your
- app follows all the recommendations in the <a class="external-link"
- href="https://developers.google.com/cast/docs/design_checklist"
- >Design Checklist</a>.</p>
-
- <h4>4. Start developing</h4>
- <p>Read the <a class="external-link"
- href="https://developers.google.com/cast/docs/developers">Developer's Guide</a>
- to learn how to implement the receiver app and how to send it commands from your Android app.
- </p>
-
- <p>For quick access while developing your Android app, the
- <a href="{@docRoot}reference/com/google/android/gms/cast/package-summary.html">Google Cast
- Android API reference</a> is available here on developer.android.com.</p>
-
- </div>
-</div> \ No newline at end of file
diff --git a/docs/html/google/play-services/drive.jd b/docs/html/google/play-services/drive.jd
deleted file mode 100644
index e9662e6..0000000
--- a/docs/html/google/play-services/drive.jd
+++ /dev/null
@@ -1,141 +0,0 @@
-page.title=Google Drive Android API
-page.tags="storage","files","cloud"
-header.hide=1
-
-@jd:body
-
- <div class="landing-banner">
- <div class="col-6">
- <img src="{@docRoot}images/google/gps-drive.png" alt="">
- </div>
-
- <div class="col-6">
- <h1 itemprop="name" style="margin-bottom:0;">
- Google Drive Android API
- </h1>
-
- <p itemprop="description">
- Give your users access to their files, wherever they are, on any device.
- The Google Drive Android API makes it easier than ever to use Drive to
- store and sync user’s files between their mobile devices and the cloud.
- Simply use Drive like local file storage and the API will handle the
- syncing for you.
- </p>
-
- <p>
- Explore the <a href=
- "{@docRoot}reference/com/google/android/gms/drive/package-summary.html">Google
- Drive Android API reference</a> or visit <a href=
- "http://developers.google.com/drive/android">developers.google.com/drive/android</a>
- for more information about integrating Google Drive into your app.
- </p>
- </div>
- </div>
-
- <div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">
- Key Developer Features
- </h3>
-
- <h4>
- Automatic syncing
- </h4>
-
- <p>
- The Google Drive Android API uses the local device storage to create,
- edit, and open files, then syncs them automatically when the device
- is connected to the Internet. If a user requests a file that isn’t
- already cached on the device, the Drive service downloads the file
- the next time the device connects.<br>
- <a href="http://developers.google.com/drive/android/files" class=
- "external-link">Open a file</a>
- </p>
-
- <h4>
- User interface components
- </h4>
-
- <p>
- Building your own user interface for selecting or creating files is a
- thing of the past. The Drive API includes activity builders for two
- of the most common user activities: opening files and creating
- files.<br>
- <a href="http://developers.google.com/drive/android/create-file"
- class="external-link">Create a file</a>
- </p>
-
- <h4>
- Easily search for files
- </h4>
-
- <p>
- The query builder allows you to easily construct a query by joining
- together multiple parameters and filtering based on metadata. This
- allows you to easily display only relevant files, such as files
- shared with the user or files with a specific MIME type.<br>
- <a class="external-link" href=
- "http://developers.google.com/drive/android/queries">Query for a
- file</a>
- </p>
- </div>
-
- <div class="col-6 normal-links">
- <h3 style="clear:left">
- Getting Started
- </h3>
-
- <h4>
- 1. Get the Google Play services SDK
- </h4>
-
- <p>
- The Google Drive Android API is part of the Google Play services
- platform.
- </p>
-
- <p>
- To get started, <a href=
- "{@docRoot}google/play-services/setup.html">set up the Google Play
- services SDK</a>.
- </p>
-
- <h4>
- 2. Run the sample
- </h4>
-
- <p>
- Once you’ve set up the Google Play services SDK, you can run the
- Google Drive sample located in
- <code>&lt;android-sdk&gt;/extras/google-play-services/samples/drive</code>.
- However, before you can run the sample, you need to register your app
- in the Google Developers Console.
- </p>
-
- <p>
- See <a class="external-link" href=
- "http://developers.google.com/drive/android/get-started">Getting
- Started guide</a> to learn how to get up and running with the Google
- Drive Android API.
- </p>
-
- <h4>
- 3. Read the documentation
- </h4>
-
- <p>
- For quick access while developing your Android apps, the <a href=
- "{@docRoot}reference/com/google/android/gms/drive/package-summary.html">
- Google Drive API reference</a> is available here on
- developer.android.com.
- </p>
-
- <p>
- Detailed documentation for the Google Drive Android API is available
- with the rest of the Google Drive Platform documentation at <a class=
- "external-link" href=
- "https://developers.google.com/drive/android">developers.google.com/drive</a>.
- </p>
- </div>
- </div>
- \ No newline at end of file
diff --git a/docs/html/google/play-services/games.jd b/docs/html/google/play-services/games.jd
deleted file mode 100644
index f68751d..0000000
--- a/docs/html/google/play-services/games.jd
+++ /dev/null
@@ -1,94 +0,0 @@
-page.title=Google Play Game Services
-page.tags="games"
-header.hide=1
-
-@jd:body
-
-<div class="landing-banner">
-
-<div class="col-6">
- <img src="{@docRoot}images/google/gps-play_games_logo.png" alt="">
-</div>
-<div class="col-6">
-
-<h1 itemprop="name" style="margin-bottom:0;">Google Play Game Services</h1>
- <p itemprop="description">
-Make your games social with Google Play game services. Add achievements,
-leaderboards, real-time multiplayer, and other popular features using the
-Google Play game services SDK. Let players sign in using their Google+
-identities and share their gaming experience with friends.
- </p>
-<p>Explore the
-<a href="{@docRoot}reference/com/google/android/gms/games/package-summary.html">Google
-Play Games Android API reference</a> or visit
-<a class="external-link" href=
-"https://developers.google.com/games/services/">developers.google.com/games/services</a>
-for more information about integrating game services into your app.
-</p>
-</div>
-</div>
-
-<div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">Key Developer Features</h3>
-
- <h4>Reward players with achievements</h4>
- <p>Add hidden and incremental achievements to encourage users to explore your game in new
- and interesting ways. A built-in achievement UI is available to display progress. <br />
- <a class="external-link" href="https://developers.google.com/games/services/android/achievements">Add
- achievements to your game</a>.</p>
- </a>
-
- <h4>Drive engagement with leaderboards</h4>
- <p>Let players compare scores with friends using leaderboards and see how they rank
- against other players worldwide. Google Play game services automatically maintains daily,
- weekly, and all-time high scores. <br /><a class="external-link"
- href="https://developers.google.com/games/services/android/leaderboards">Build leaderboards</a></p>
-
- <h4>Save game data to the cloud</h4>
- <p>Offer seamless game progress across all of the user's devices. Use the Saved Games API
- to quickly store and synchronize game data on Google's cloud
- infrastructure. <br />
- <a
- class="external-link" href="https://developers.google.com/games/services/android/savedgames">Save
- game data to the cloud</a></p>
-
- <h4>Create real-time and turn-based multiplayer games</h4>
- <p>Make your game more dynamic with simultaneous or asynchronous gameplay.
- Use the multiplayer APIs to send match invitations, auto-match players
- anonymously, and exchange data between game clients. <br />Develop <a class="external-link"
- href="https://developers.google.com/games/services/android/multiplayer">real-time
- multiplayer</a> and <a class="external-link"
- href="https://developers.google.com/games/services/android/turnbasedMultiplayer">turn-based multiplayer</a> games</p>
- </div>
-
-
- <div class="col-6 normal-links">
- <h3 style="clear:left">Getting Started</h3>
- <h4>1. Get the Google Play services SDK</h4>
- <p>Google Play game services is part of the Google Play services platform.</p>
- <p>To use game services, <a href="{@docRoot}google/play-services/setup.html">set up
- the Google Play services SDK</a>. Then, see the <a class="external-link"
- href="https://developers.google.com/games/services/android/quickstart">
- Getting Started guide</a> to set up your app.
- </p>
-
- <h4>2. Run the sample</h4>
-
- <p>Once you've installed the Google Play services package, <a class="external-link"
- href="https://developers.google.com/games/services/downloads/">download the game services
- samples</a> to learn how to use the major components of the Google Play game services SDK.
- </p>
-
- <h4>3. Read the documentation</h4>
-
- <p>Read the <a class="external-link" href="https://developers.google.com/games/services/terms">
- API Terms of Service</a>.</p>
- <p>Detailed documentation for the Google Play game services SDK is available at <a class="external-link"
- href="https://developers.google.com/games/services/">developers.google.com/games/services</a>.
- </p>
- <p>For quick access while developing your Android apps, the
- <a href="{@docRoot}reference/com/google/android/gms/games/package-summary.html">API reference</a> is available here on developer.android.com.</p>
- </div>
-
-</div>
diff --git a/docs/html/google/play-services/id.jd b/docs/html/google/play-services/id.jd
deleted file mode 100644
index 43d1809..0000000
--- a/docs/html/google/play-services/id.jd
+++ /dev/null
@@ -1,211 +0,0 @@
-page.title=Advertising ID
-page.tags=Ads,Advertising ID,ID
-header.hide=1
-
-@jd:body
-
-<div class="landing-banner">
-
-<div class="col-8">
-
- <h1 itemprop="name" style="margin-bottom:0;">Advertising ID</h1>
- <p itemprop="description">The advertising ID is a user-specific, unique,
- resettable ID for advertising, provided by Google Play services. It gives
- users better controls and provides developers with a simple, standard system
- to continue to monetize your apps. It is an anonymous identifier for advertising
- purposes and enables users to reset their identifier or opt out of interest-based
- ads within Google Play apps. </p>
-
-<p>The advertising ID is accessible through a straightforward API that you can implement in your apps. For details,
-take a look at the
-<a href="#get_started">overview</a> and the <a
-href="{@docRoot}reference/com/google/android/gms/ads/identifier/package-summary.html">advertising ID API reference</a>.
-
-</div>
-</div>
-
-<div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">Key Developer Features</h3>
-
- <h4>Standard, simple ID</h4>
- <p>The advertising ID is a part of a standard, simple system for serving ads and performing analytics.</p>
-
- <h4>Giving users control</h4>
- <p>Users can reset their advertising ID or opt out of interest-based ads at any time, right from the Google Settings app.
- Their preferences apply across all ad companies that use the advertising ID.</p>
-
- </div>
-
- <div class="col-6 normal-links">
- <h3 style="clear:left">Getting Started</h3>
- <h4>1. Get the Google Play services SDK</h4>
- <p>The advertising ID APIs are part of the Google Play services platform.</p>
- <p>To get started, <a href="{@docRoot}google/play-services/setup.html">set up
- the Google Play services SDK</a>. </p>
-
- <h4>2. Read the docs and example code</h4>
- <p>Once you've installed the Google Play services package, review the <a href="#get_started">overview</a>
- below, as well as the <a href="#example">example</a>.</p>
- <p>
- For detailed documentation, take a look at the <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/package-summary.html">
- advertising ID API reference documentation</a>.
- </p>
- </div>
-</div>
-
-<p class="caution" style=
-"background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">
- As a reminder, please note that starting <strong>1 August 2014</strong>, new
- apps and app updates distributed through Google Play must use the advertising
- ID in lieu of any other persistent identifiers for any advertising purposes,
- on devices that support the advertising ID.<br>
- <br>
- To learn how to check your app's compliance through the Developer Console, or
- for details on the associated developer policy changes, please see the
- <a href=
- "https://support.google.com/googleplay/android-developer/answer/6048248">Advertising
- ID topic</a> in the Google Play developer help center.
-</p>
-
-<h2 id="get_started">Using the Advertising ID</h2>
-
-<p>
- The <strong>advertising ID</strong> is a unique but
- user-resettable string identifier that lets ad networks and other apps anonymously
- identify a user. The user's advertising ID is made available to apps through APIs
- provided in Google Play services.
-</p>
-<p>
- Users can reset their advertising ID at any time, right from the Ads section of the
- Google Settings app on their devices. From the same app, users can also
- opt-out of targeted advertising based on the advertising ID by setting the appropriate
- <strong style="white-space:nowrap">ad tracking preference</strong>. When the
- user opts-out of targeted ads, this ad tracking preference is made available
- to apps through a Google Play services API.
-</p>
-<p>
- Apps making use of the advertising ID <strong>must check for and respect</strong> the
- user's ad tracking preference. Also please note that any use of the advertising ID
- must abide by the terms of the <a class="external-link"
- href="http://play.google.com/about/developer-content-policy.html#ADID">Google Play
- Developer Content Policies</a>.
-</p>
-
-<h3 id="format">Format of the Advertising ID</h3>
-
-<p>
- Google Play services APIs expose the user's advertising ID as a string format of UUID,
- with values similar to this:
-</p>
-<p style="margin-left:1.5em;"><code>“38400000-8cf0-11bd-b23e-10b96e40000d”</code></p>
-
-<h3 id="requirements">Requirements</h3>
-
-<ul>
- <li>The advertising ID APIs are supported in Google Play services 4.0+</li>
- <li>Support for the advertising ID on specific devices is based on their installed versions
- of Google Play services</li>
-</ul>
-
-<h3 id="obtaining">Obtaining the user's advertising ID and ad tracking preference</h3>
-
-<p>
- If you want to use the advertising ID in your app, you must first install the Google
- Play services SDK. As noted in the requirements above, you should install the
- SDK for Google Play services 4.0 or higher if you will develop using the advertising ID
- APIs. For information about how to get started, see <a href=
- "{@docRoot}google/play-services/setup.html">Set Up Google Play services</a>.
-</p>
-<p>
- The advertising ID APIs are available in the <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/package-summary.html">
- <code>com.google.android.gms.ads.identifier</code></a> package in the Google
- Play Services library. To obtain the user's advertising ID and tracking preference,
- call the method
- <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html#getAdvertisingIdInfo(android.content.Context)">
- <code>getAdvertisingIdInfo()</code></a>, which returns an <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html">
- <code>AdvertisingIdClient.Info</code></a> encapsulating the user's current Advertising ID
- and tracking preference.
-</p>
-
-<p class="note">
- <strong>Note:</strong> The <code>getAdvertisingIdInfo()</code> method is a
- blocking call, so you must not call it on the main (UI) thread. If called on
- the main thread, the method throws <code>IllegalStateException</code>.
-</p>
-
-<p>
- Once you've retrieved the <code>AdvertisingIdClient.Info</code> object, you
- can use it's <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#getId()">
- <code>getId()</code></a> and <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#isLimitAdTrackingEnabled()">
- <code>isLimitAdTrackingEnabled()</code></a> methods to access the advertising ID and
- ad tracking preference.
-</p>
-
-<table>
-<tr>
-<th>Method</th>
-<th>Description</th>
-</tr>
-<tr>
-<td><code>public String getId()</code></td>
-<td style="white-space:nowrap;">Retrieves the advertising ID.</td>
-</tr>
-<tr>
-<td style="white-space:nowrap;"><code>public boolean isLimitAdTrackingEnabled()</code></td>
-<td>Retrieves whether the user has limit ad tracking enabled or not.</td>
-</tr>
-</table>
-
-<p>
- The advertising ID APIs do not include a "reset" method. Only users can initiate a
- reset of their own advertising IDs, through the Google Settings application.
-</p>
-<p>
- For more information about the advertising ID APIs, see the <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/package-summary.html">
- reference documentation</a>.
-</p>
-
-<h3 id="example">Example implementation</h3>
-
-<p>
- Here's a basic illustration of how you can retrieve the user's advertising ID and ad
- tracking preference in your app:
-</p>
-
-<pre>
-import com.google.android.gms.ads.identifier.AdvertisingIdClient;
-import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
-import com.google.android.gms.common.GooglePlayServicesAvailabilityException;
-import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
-import java.io.IOException;
-...
-
-// Do not call this function from the main thread. Otherwise,
-// an IllegalStateException will be thrown.
-public void getIdThread() {
-
- Info adInfo = null;
- try {
- adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
-
- } catch (IOException e) {
- // Unrecoverable error connecting to Google Play services (e.g.,
- // the old version of the service doesn't support getting AdvertisingId).
-
- } catch (GooglePlayServicesAvailabilityException e) {
- // Encountered a recoverable error connecting to Google Play services.
-
- } catch (GooglePlayServicesNotAvailableException e) {
- // Google Play services is not available entirely.
- }
- final String id = adInfo.getId();
- final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
-}</pre>
diff --git a/docs/html/google/play-services/location.jd b/docs/html/google/play-services/location.jd
deleted file mode 100644
index 98b0544..0000000
--- a/docs/html/google/play-services/location.jd
+++ /dev/null
@@ -1,125 +0,0 @@
-page.title=Location APIs
-page.tags=location,geofence,geofencing,gps
-header.hide=1
-@jd:body
-
-
- <div class="landing-banner">
-
-<div class="col-6">
- <img src="{@docRoot}images/google/gps-location.png" alt="Location APIs Logo">
-</div>
-
-<div class="col-6">
-
-<h1 itemprop="name" style="margin-bottom:0;">Location &amp; Places</h1>
-<p itemprop="description">
- The location APIs make it easy for you to build location-aware applications, without needing to
- focus on the details of the underlying location technology. The related Places APIs also help
- your app identify real-world points of interest near the user.
-</p>
-<p>
- To get started, first <a href="{@docRoot}google/play-services/setup.html">set up</a>
- the Google Play services SDK. To learn how to identify the user's location, see
- <a href="{@docRoot}training/location/index.html">Making Your App Location Aware</a>, or to
- identify nearby places, see the
-<a href="https://developers.google.com/places/android">Google Places API for Android</a>
-developer guide.
-</p>
-</div>
-</div>
-<div class="landing-docs">
- <h3 style="clear:left">Key Developer Features</h3>
- <div class="cols normal-links">
- <div class="col-6">
-
-
-
-<h4 style="font-weight:bold">Fused location provider</h4>
-
-<p>The Fused Location Provider intelligently manages the underlying location technology and gives you the best location according to your needs. </p>
-
-<ul>
- <li>
- <em>Simple APIs</em>: Lets you specify high-level needs like "high accuracy" or "low power", instead of
- having to worry about location providers.
- </li>
- <li>
- <em>Immediately available</em>: Gives your apps immediate access to the best, most recent location.
- </li>
- <li>
- <em>Power-efficiency</em>: Minimizes your app's use of power. Based on all incoming location requests and available sensors, fused location provider chooses the most efficient way to meet those needs.
- </li>
- <li>
- <em>Versatility</em>: Meets a wide range of needs, from foreground uses that need highly accurate
- location to background uses that need periodic location updates with negligible power impact.
- </li>
-
-</ul>
-
-<h4 style="font-weight:bold">Geofencing APIs</h4>
-
-<p>Lets your app setup geographic boundaries around specific locations and then receive notifications when the user enters or leaves those areas. </p>
-
-<ul>
- <li>
- <em>Simple but powerful APIs</em>: Allows batch addition and removal of geofences. Ability to manage
- multiple geofences at the same time. Ability to filter alerts for both entry and exit or
- entry only or exit only.
- </li>
- <li>
- <em>Optimized for battery</em>: Adjusts location updates based on user’s proximity to the geofence
- and user’s modality (still, walking, driving, and so on).
- </li>
-</ul>
-</div>
-
-<div class="col-6">
-
-<h4 style="font-weight:bold">Places API</h4>
-
-<p>The <a href="https://developers.google.com/places/android/">Google
-Places API for Android</a> helps you build location-aware apps
-that respond contextually to the local businesses and other places near the
-device:</p>
-
-<ul>
-<li>Use the built-in
- <a href="https://developers.google.com/places/android/placepicker">place
- picker</a> UI widget, allowing users to select a place on an interactive
- map.</li>
-<li>Identify the user's
- <a href="https://developers.google.com/places/android/current-place">current
- place</a>, such as a local business, point of interest, or other geographic location.</li>
-<li>Retrieve and display rich
- <a href="https://developers.google.com/places/android/place-details">information
- about a place</a>.</li>
-<li>Make it easy to enter place names and addresses, by
- <a href="https://developers.google.com/places/android/autocomplete">autocompleting</a>
- your users' queries as they type.</li>
-<li>Differentiate your app by supplying up-to-date local information, and
- <a href="https://developers.google.com/places/android/add-place">adding
- places</a> to Google's Places database.</li>
-</ul>
-
-
-<h4 style="font-weight:bold">Activity recognition</h4>
-
-<p>The Activity recognition API makes it easy to check the user’s current activity&mdash;still, walking, cycling, and in-vehicle&mdash;with very efficient use of the battery:</p>
-<ul>
- <li>
- <em>Optimized for battery</em>: Uses low-power sensors to recognize the user's current physical activity.
- </li>
- <li>
- <em>Enhances other services with context</em>: Great for adding movement awareness to location awareness. Apps can adjust the amount of
- location awareness they provide, based on the current user movement. For example, a
- navigation app can request more frequent updates when the user is driving.
- </li>
- <li>
- <em>Advanced activity detection</em>: For apps that want to do their own
- post-processing, the activity APIs provide confidence values for each of the activities.
- It also includes two activities that indicate unreliable measurements: unknown and tilt.
- </li>
-</ul>
-</div>
-</div>
diff --git a/docs/html/google/play-services/maps.jd b/docs/html/google/play-services/maps.jd
deleted file mode 100644
index 9bf5f80..0000000
--- a/docs/html/google/play-services/maps.jd
+++ /dev/null
@@ -1,97 +0,0 @@
-page.title=Google Maps Android API v2
-page.tags=mapview,location
-header.hide=1
-
-@jd:body
-
-
-<div class="landing-banner">
-
-<div class="col-6">
- <img src="{@docRoot}images/google/gps-maps.png" alt="">
-</div>
-<div class="col-6">
-
- <h1 itemprop="name" style="margin-bottom:0;">Google Maps Android API v2</h1>
- <p itemprop="description">Allow your users to explore the world with rich maps provided by
- Google. Identify locations with <b>custom markers</b>, augment the map data
- with <b>image overlays</b>, embed <b>one or more maps</b> as fragments,
- and much more.</p>
- <p>Explore the <a
-href="{@docRoot}reference/com/google/android/gms/maps/package-summary.html"
->Google Maps Android API v2 reference</a> or visit <a class="external-link"
-href="https://developers.google.com/maps/documentation/android/">developers.google.com/maps</a>
-for more information about adding maps to your app.</p>
-</div>
-</div>
-
-
-
-<div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">Key Developer Features</h3>
- <h4>Add maps to your app</h4>
- <p>With Google Maps Android API v2, you can embed maps into an activity
- as a fragment with a simple XML snippet. The new Maps offer exciting features such as 3D maps;
- indoor, satellite, terrain, and hybrid maps;
- vector-based tiles for efficient caching and drawing; animated transitions; and much more.
- <a class="external-link" href="https://developers.google.com/maps/documentation/android/map">Add
- a map object</a>.</p>
-
- <h4>Customize the map</h4>
- <p>Add markers onto the map to indicate special points of interest for your users.
- You can define custom colors or icons for your map markers to
- match your app's look and feel. To further enhance the app, draw polylines
- and polygons to indicate paths or regions, or provide complete image overlays.
- <a class="external-link" href="https://developers.google.com/maps/documentation/android/marker">Draw
- markers</a>.</p>
- </a>
-
- <h4>Control the user's view</h4>
- <p>Give your users a different view of the world with the ability to control the rotation, tilt,
- zoom, and pan properties of the "camera" perspective of the map.
- <a class="external-link" href="https://developers.google.com/maps/documentation/android/views">Change
- the view</a>.</p>
-
- <h4>Add Street View to your app</h4>
- <p>Embed Street View into an activity and let your users explore the world
- through panoramic 360-degree views. Programmatically control the zoom and
- orientation (tilt and bearing) of the Street View camera, and animate the
- camera movements over a given duration.
- <a class="external-link" href="https://developers.google.com/maps/documentation/android/streetview">Add Street View</a>.</p>
- </div>
-
-
- <div class="col-6 normal-links">
- <h3 style="clear:left">Getting Started</h3>
- <h4>1. Get the Google Play services SDK</h4>
- <p>Google Maps Android API v2 is part of the Google Play services platform.</p>
- <p>To use Google Maps, <a href="{@docRoot}google/play-services/setup.html">set up
- the Google Play services SDK</a>. Then see the <a class="external-link"
- href="https://developers.google.com/maps/documentation/android/start#installing_the_google_maps_android_v2_api">
- Getting Started guide</a> to get your API key for Maps and set up your app.
- </p>
-
- <h4>2. Run the sample</h4>
-
- <p>Once you've installed the Google Play services package, the Google Maps sample is located in
- <code>&lt;android-sdk&gt;/extras/google-play-services/samples/maps</code> and shows you
- how to use the major components of Google Maps Android API v2.
- </p>
-
- <h4>3. Read the documentation</h4>
-
- <p>Read the <a href="https://developers.google.com/maps/terms">Google Maps
- API Terms of Service</a>.</p>
-
- <p>For quick access while developing your Android apps, the
- <a href="{@docRoot}reference/com/google/android/gms/maps/package-summary.html">Google Maps
- Android API v2 reference</a> is available here on developer.android.com.</p>
-
- <p>Detailed documentation for Google Maps Android API v2 is available with the rest of the
- Google Maps developer documents at <a class="external-link"
- href="https://developers.google.com/maps/documentation/android/">developers.google.com/maps</a>.
- </p>
- </div>
-
-</div>
diff --git a/docs/html/google/play-services/plus.jd b/docs/html/google/play-services/plus.jd
deleted file mode 100644
index 84224e7..0000000
--- a/docs/html/google/play-services/plus.jd
+++ /dev/null
@@ -1,90 +0,0 @@
-page.title=Google+ Platform for Android
-page.tags=authentication,signin,social
-header.hide=1
-
-@jd:body
-
-
-<div class="landing-banner">
-
-<div class="col-6">
- <img src="{@docRoot}images/google/gps-googleplus.png" alt="">
-</div>
-<div class="col-6">
-
- <h1 itemprop="name" style="margin-bottom:0;">Google+ Platform for Android</h1>
- <p itemprop="description">The Google+ platform for Android lets you authenticate a user
- with the same credentials they use on Google every day. Once a user signs in with Google,
- you can create more engaging experiences and drive usage of your app.</p>
-
- <p>Explore the <a href="{@docRoot}reference/com/google/android/gms/plus/package-summary.html"
->Google+ Android API reference</a> or visit <a class="external-link"
-href="https://developers.google.com/+/mobile/android/">developers.google.com/+</a> for more
-information about integrating Google+ into your app.</p>
-</div>
-</div>
-
-<div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">Key Developer Features</h3>
-
- <h4>Trusted authentication</h4>
- <p>Google+ Sign-In is a simple, trusted, and secure way to let people sign in
- to your app with their Google credentials and bring along their Google+ info.
- <br />
- <a href="https://developers.google.com/+/mobile/android/sign-in"
- class="external-link">Add sign-in</a>.</p>
-
- <h4>Access the profile and social graph</h4>
- <p>Once users have signed in with Google, your app can welcome them by name,
- display their picture, connect them with friends, and lots more.
- <br />
- <a href="https://developers.google.com/+/mobile/android/people"
- class="external-link">Access the social graph</a>.</p>
-
- <h4>Stand out in the stream</h4>
- <p>Interactive posts is a rich way of sharing to Google+. It lets users prompt friends
- to take specific actions in your app from a Google+ post, like "listen," "RSVP," "check-in,"
- and over 100 more actions. <br />
- <a class="external-link"
- href="https://developers.google.com/+/mobile/android/share">Post interactive content</a>.</p>
-
- <h4>Recommend content</h4>
- <p>Add a native +1 button so users can recommend content from your app. These endorsements
- can give your app more credibility and help it grow faster. <br />
- <a class="external-link"
- href="https://developers.google.com/+/mobile/android/recommend">Add the +1 button</a>.</p>
- </div>
-
-
- <div class="col-6 normal-links">
- <h3 style="clear:left">Getting Started</h3>
- <h4>1. Get the Google Play services SDK</h4>
- <p>The Google+ Android APIs are part of the Google Play services platform.</p>
- <p>To get started, <a href="{@docRoot}google/play-services/setup.html">set up
- the Google Play services SDK</a>.
- </p>
-
- <h4>2. Run the sample</h4>
- <p>Once you've installed the Google Play services package, you can run the Google+ sample located in
- <code>&lt;android-sdk&gt;/extras/google-play-services/samples/plus</code>. However, before
- you can run the sample, you need to register your app in the Google APIs Console.</p>
- <p>See <a class="external-link"
- href="https://developers.google.com/+/mobile/android/getting-started">Getting Started with
- the Google+ Platform for Android</a> for more information about how to get the sample up and
- running.
- </p>
-
- <h4>3. Read the documentation</h4>
- <p>Read the <a href="https://developers.google.com/+/terms">Google+ Platform
- Terms of Service</a>.</p>
-
- <p>For quick access while developing your Android apps, the
- <a href="{@docRoot}reference/com/google/android/gms/plus/package-summary.html">Google+
- API reference</a> is available here on developer.android.com.</p>
-
- <p>Detailed documentation for the Google+ Android APIs is available with the rest of the
- Google+ developer documents at <a class="external-link"
- href="https://developers.google.com/+/mobile/android/">developers.google.com/+</a>.</p>
- </div>
-</div>
diff --git a/docs/html/google/play-services/wallet.jd b/docs/html/google/play-services/wallet.jd
deleted file mode 100644
index 744c8d3..0000000
--- a/docs/html/google/play-services/wallet.jd
+++ /dev/null
@@ -1,87 +0,0 @@
-page.title=Google Wallet Instant Buy for Android
-page.tags=Wallet,payments,Instant Buy
-header.hide=1
-
-@jd:body
-
-<div class="landing-banner">
-<div class="col-8">
- <h1 itemprop="name" style="margin-bottom:0;">Google Wallet Instant Buy</h1>
- <p itemprop="description">Add fast, secure checkout for users buying physical goods and
- services from your app. Transactions are monitored for fraud 24/7. Keep your existing
- payments infrastructure and integrate Google Wallet quickly, easily and free of charge.</p>
-
- <p>To ensure that your app content is consistent with the requirements for
- Instant Buy access, <a class="external-link" href="https://support.google.com/wallet/business/contact/interest">apply for content review</a> before
- starting development. Note that Instant Buy is currently only
- available to US-based merchants. Once you've completed integration, you can
- apply for production access by <a class="external-link" href="https://support.google.com/wallet/business/contact/ui_review">submitting your sandbox integration for review</a>.</p>
-
- <p>Check out the <a
- href="{@docRoot}reference/com/google/android/gms/wallet/package-summary.html">Instant
- Buy API reference</a> and visit
- <a href="https://developers.google.com/wallet/instant-buy/">developers.google.com/wallet/instant-buy/</a>
- for complete information about integrating Google Wallet Instant Buy into your app.</p>
-</div>
-
-<div class="col-4">
- <img src="{@docRoot}images/google/gps-wallet-instant.png" alt="" style="padding-bottom:14px;width:210px">
-</div>
-</div>
-
-<div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">Key Developer Features</h3>
-
- <h4>Add the "Buy with Google" button</h4>
- <p>Easily embed a “Buy with Google” button in your flow to let customers purchase instantly
- from your app. Customers can grant you access to their payment information with just
- a few clicks.
- <br />
- <a href="https://developers.google.com/commerce/wallet/instant-buy/android/tutorial#add_google_wallet_buttons_to_your_ui"
- class="external-link">Add a "Buy with Google" button</a>.</p>
-
- <h4>Streamline Purchases with Google+ Sign-On</h4>
- <p>For users ready to purchase, you can simplify the login and account creation steps
- by adding Google+ sign in. Users can sign in with a single click and share their
- profile information during the purchase.
- <br />
- <a href="https://developers.google.com/commerce/wallet/instant-buy/wallet-sso#android"
- class="external-link">Add Google+ Sign-In for Wallet</a>.</p>
-
- <h4>Minimize User Data Entry</h4>
- <p>Google Wallet provides auto-completion of addresses, minimizing user data entry. You can also
- retrieve billing and shipping addresses directly from the user’s Wallet to-do form pre-fills.<br />
- <a class="external-link"
- href="{@docRoot}reference/com/google/android/gms/wallet/MaskedWallet.html#getBillingAddress()">Get
- billing addresses</a>.</p>
- </div>
-
-
- <div class="col-6 normal-links">
- <h3 style="clear:left">Getting Started</h3>
- <h4>1. Get the Google Play services SDK</h4>
- <p>The Google Wallet Android APIs are part of the Google Play services platform.</p>
- <p>To get started, <a href="{@docRoot}google/play-services/setup.html">set up
- the Google Play services SDK</a>. Then see the <a class="external-link"
- href="https://developers.google.com/commerce/wallet/instant-buy/android/tutorial">tutorial</a>
- to learn how to set up your app.
- </p>
- <h4>2. Run the sample</h4>
- <p>Once you've installed the Google Play services package, try the Google Wallet
- sample located in <code>&lt;android-sdk&gt;/extras/google-play-services/samples/wallet</code>.
- The sample shows you how to use the major components of the Instant Buy API.</p>
- <p>The <a
- class="external-link" href="https://developers.google.com/wallet/instant-buy/android/tutorial">Instant Buy Android API tutorial</a>
- provides directions on how to get the Wallet sample up and running.</p>
- <h4>3. Read the documentation</h4>
- <p>For quick access while developing your Android apps, the <a
- href="{@docRoot}reference/com/google/android/gms/wallet/package-summary.html">Google Wallet
- API reference</a> is available here on developer.android.com.</p>
-
- <p>Detailed documentation for the Instant Buy API is available at <a class="external-link"
- href="https://developers.google.com/wallet/instant-buy/">developers.google.com/wallet/instant-buy/</a></p>
-
-
- </div>
-</div>
diff --git a/docs/html/google/play/safetynet/index.jd b/docs/html/google/play/safetynet/index.jd
deleted file mode 100644
index b728ca1..0000000
--- a/docs/html/google/play/safetynet/index.jd
+++ /dev/null
@@ -1,82 +0,0 @@
-page.title=SafetyNet for Android
-page.tags=compatibility, CTS
-header.hide=1
-
-@jd:body
-
-<div>
-
-<div>
-
-<h1 itemprop="name" style="margin-bottom:0;">
- Android SafetyNet API
-</h1>
-
-<p itemprop="description">
- SafetyNet provides access to Google services that help you assess the health and safety of an
- Android device. The wide variety of Android devices and configurations can make it difficult to
- know if your app will behave as you expect on all available devices. The SafetyNet API helps you
- determine if your app will function properly on a device by analyzing its compatibility with the
- Android platform specifications.
-</p>
-
-</div>
-</div>
-
-<div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">Key Developer Features</h3>
-
-<h4>
- Device Profile Compatibility Check
-</h4>
-
-<p>
- Check if your app is running on a device that matches a device model that has passed Android
- compatibility testing. This analysis can help you determine if your app will work as expected on
- the device where it is installed. The service evaluates both software and hardware
- characteristics of the device, and may use hardware roots of trust, when available.
-</p>
-
-</div>
-
-<div class="col-6 normal-links">
-<h3 style="clear:left">
- Getting Started
-</h3>
-
- <h4>
- 1. Review the Terms of Service
- </h4>
-
- <p>
- Use of SafetyNet is governed by specific terms of service, in addition to the <a href=
- "https://developers.google.com/terms/" class="external-link">Google APIs Terms of Service</a>.
- Before using this API, review the <a href="{@docRoot}google/play/safetynet/start.html#tos">
- Additional Terms of Service</a>.
- </p>
-
- <h4>
- 2. Get the Google Play services SDK
- </h4>
-
- <p>
- SafetyNet is part of the Google Play services platform. To get started, follow the instructions
- for <a href="{@docRoot}google/play-services/setup.html">Setting
- up Google Play services</a>.
- </p>
-
- <h4>
- 3. Read the documentation
- </h4>
-
- <p>
- Learn how to use SafetyNet in your app by reading the <a href=
- "{@docRoot}google/play/safetynet/start.html">Getting Started</a> instructions. For more
- details on the API, see the <a href=
- "{@docRoot}reference/com/google/android/gms/safetynet/package-summary.html">
- SafetyNet</a> reference documentation.
- </p>
-
-</div>
-</div>
diff --git a/docs/html/training/building-location.jd b/docs/html/training/building-location.jd
new file mode 100644
index 0000000..9ab0908
--- /dev/null
+++ b/docs/html/training/building-location.jd
@@ -0,0 +1,11 @@
+page.title=Building Apps with Location &amp; Maps
+page.trainingcourse=true
+
+@jd:body
+
+
+<p>
+ These classes teach you how to add user location and mapping information to your app.
+ Make your app more helpful and relevant to users by providing information about where
+ they are and the world around them.
+</p> \ No newline at end of file
diff --git a/docs/html/training/maps/index.jd b/docs/html/training/maps/index.jd
new file mode 100644
index 0000000..3efa493
--- /dev/null
+++ b/docs/html/training/maps/index.jd
@@ -0,0 +1,70 @@
+page.title=Adding Maps
+page.tags=mapview,location
+page.article=true
+page.trainingcourse=true
+@jd:body
+
+
+<img src="{@docRoot}images/google/gps-maps.png"
+ width="300"
+ style="float:right;margin:0 0 20px 20px"
+ alt="Google maps sample image">
+
+<p>
+ Allow your users to explore the world with rich maps provided by Google. Identify
+ locations with custom markers, augment the map data with image overlays, embed one
+ or more maps as fragments, and much more.
+</p>
+
+<p>
+ The <a href="https://developers.google.com/maps/documentation/android/">Google
+ Maps Android API</a> allows you to include maps and customized mapping information
+ in your app.
+</p>
+
+
+<h2 id="features">Key Developer Features</h2>
+
+<h4>Add maps to your app</h4>
+<p>
+ With Google Maps Android API v2, you can embed maps into an activity as a fragment with a simple
+ XML snippet. The new Maps offer exciting features such as 3D maps; indoor, satellite, terrain,
+ and hybrid maps; vector-based tiles for efficient caching and drawing; animated transitions; and
+ much more. <a class="external-link" href=
+ "https://developers.google.com/maps/documentation/android/map">Add a map object</a>.
+</p>
+
+<h4>Customize the map</h4>
+<p>
+ Add markers onto the map to indicate special points of interest for your users. You can define
+ custom colors or icons for your map markers to match your app's look and feel. To further enhance
+ the app, draw polylines and polygons to indicate paths or regions, or provide complete image
+ overlays. <a class="external-link" href=
+ "https://developers.google.com/maps/documentation/android/marker">Draw markers</a>.
+</p>
+
+<h4>Control the user's view</h4>
+<p>
+ Give your users a different view of the world with the ability to control the rotation, tilt,
+ zoom, and pan properties of the "camera" perspective of the map. <a class="external-link" href=
+ "https://developers.google.com/maps/documentation/android/views">Change the view</a>.
+</p>
+
+<h4>Add Street View to your app</h4>
+<p>
+ Embed Street View into an activity and let your users explore the world through panoramic
+ 360-degree views. Programmatically control the zoom and orientation (tilt and bearing) of the
+ Street View camera, and animate the camera movements over a given duration. <a class=
+ "external-link" href="https://developers.google.com/maps/documentation/android/streetview">Add
+ Street View</a>.
+</p>
+
+
+<h2 id="start">Get Started</h2>
+<p>
+ Google Maps Android API is part of the Google Play services platform. To use Google Maps,
+ set up the Google Play services SDK in your app development project. For more information,
+ see the <a class="external-link"
+ href="https://developers.google.com/maps/documentation/android/start">Getting Started</a> guide
+ for the Google Maps Android API.
+</p>
diff --git a/docs/html/training/monetization/ads-and-ux.jd b/docs/html/training/monetization/ads-and-ux.jd
deleted file mode 100644
index d3ab676..0000000
--- a/docs/html/training/monetization/ads-and-ux.jd
+++ /dev/null
@@ -1,250 +0,0 @@
-page.title=Advertising without Compromising User Experience
-parent.title=Monetizing Your App
-parent.link=index.html
-@jd:body
-
-
-<!-- This is the training bar -->
-<div id="tb-wrapper">
-<div id="tb">
-
-<h2>This lesson teaches you to</h2>
-<ol>
- <li><a href="#ObtainPubAccountAndSDK">Obtain a Publisher Account and Ad SDK</a></li>
- <li><a href="#DeclarePermissions">Declare Proper Permissions</a></li>
- <li><a href="#SetupAdPlacement">Set Up Ad Placement</a></li>
- <li><a href="#InitializeAd">Initialize the Ad</a></li>
- <li><a href="#EnableTestMode">Enable Test Mode</a></li>
- <li><a href="#ImplementListeners">Implement Ad Event Listeners</a></li>
-</ol>
-
-<h2>You should also read</h2>
-<ul>
- <li><a href="http://code.google.com/mobile/ads/">AdMob SDK</a></li>
-</ul>
-
-
-<h2>Try it out</h2>
-
-<div class="download-box">
- <a href="http://developer.android.com/shareables/training/MobileAds.zip" class="button">Download
-the sample app</a>
- <p class="filename">MobileAds.zip</p>
-</div>
-
-
-</div>
-</div>
-
-<p>Advertising is one of the means to monetize (make money with) mobile applications. In this
-lesson, you are going to learn how to incorporate banner ads in your Android application.</p>
-
-<p>While this lesson and the sample application use <a
-href="http://code.google.com/mobile/ads/">AdMob</a> to serve ads, the Android platform doesn’t
-impose any restrictions on the choice of mobile advertising network. To the extent possible, this
-lesson generically highlights concepts that are similar across advertising networks.</p>
-
-<p>For example, each advertising network may have some network-specific configuration settings such
-as geo-targeting and ad-text font size, which may be configurable on some networks but not on
-others. This lesson does not touch not these topics in depth and you should consult documentation
-provided by the network you choose.</p>
-
-
-<h2 id="ObtainPubAccountAndSDK">Obtain a Publisher Account and Ad SDK</h2>
-
-<p>In order to integrate advertisements in your application, you first must become a publisher by
-registering a publishing account with the mobile advertising network. Typically, an identifier is
-provisioned for each application serving advertisements. This is how the advertising network
-correlates advertisements served in applications. In the case of AdMob, the identifier is known as
-the Publisher ID. You should consult your advertising networks for details.</p>
-
-<p>Mobile advertising networks typically distribute a specific Android SDK, which consists of code
-that takes care of communication, ad refresh, look-and-feel customization, and so on.</p>
-
-<p>Most advertising networks distribute their SDK as a JAR file. Setting up ad network JAR file in
-your Android project is no different from integrating any third-party JAR files. First, copy the
-JAR files to the <code>libs/</code> directory of your project. If you’re using Eclipse as IDE, be
-sure to add the JAR file to the Build Path. It can be done through <b>Properties &gt;
-Java Build Path &gt; Libraries &gt; Add JARs</b>.</p>
-
-<img src="/images/training/ads-eclipse-build-path.png" id="figure1" />
-<p class="img-caption">
- <strong>Figure 1.</strong> Eclipse build path settings.
-</p>
-
-
-<h2 id="DeclarePermissions">Declare Proper Permissions</h2>
-
-<p>Because the mobile ads are fetched over the network, mobile advertising SDKs usually
-require the declaration of related permissions in the Android manifest. Other kinds of permissions
-may also be required.</p>
-
-<p>For example, here's how you can request the {@link android.Manifest.permission#INTERNET}
-permission:</p>
-
-<pre>
-&lt;/manifest&gt;
- &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
- ...
- &lt;application&gt;...&lt;/application&gt;
-&lt;/manifest&gt;
-</pre>
-
-
-<h2 id="SetupAdPlacement">Set Up Ad Placement</h2>
-
-<div class="figure" style="width:262px">
-<img src="/images/training/ads-top-banner.png" id="figure2" />
-<p class="img-caption">
- <strong>Figure 2.</strong> Screenshot of the ad layout in the Mobile Ads sample.
-</p>
-</div>
-
-<p>Banner ads typically are implemented as a custom {@link android.webkit.WebView} (a view for
-viewing web pages). Ads also come in different dimensions and shapes. Once you’ve decided to put an
-ad on a particular screen, you can add it in your activity's XML layout. The XML snippet below
-illustrates a banner ad displayed on top of a screen.</p>
-
-<pre>
-&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
- android:id=&quot;&#064;+id/ad_catalog_layout&quot;
- android:orientation=&quot;vertical&quot;
- android:layout_width=&quot;match_parent&quot;
- android:layout_height=&quot;match_parent&quot; &gt;
- &lt;com.google.ads.AdView
- xmlns:googleads=&quot;http://schemas.android.com/apk/lib/com.google.ads&quot;
- android:id=&quot;&#064;+id/ad&quot;
- android:layout_width=&quot;fill_parent&quot;
- android:layout_height=&quot;wrap_content&quot;
- googleads:adSize=&quot;BANNER&quot;
- googleads:adUnitId=&quot;&#064;string/admob_id&quot; /&gt;
- &lt;TextView android:id=&quot;&#064;+id/title&quot;
- android:layout_width=&quot;match_parent&quot;
- android:layout_height=&quot;wrap_content&quot;
- android:text=&quot;&#064;string/banner_top&quot; /&gt;
- &lt;TextView android:id=&quot;&#064;+id/status&quot;
- android:layout_width=&quot;match_parent&quot;
- android:layout_height=&quot;wrap_content&quot; /&gt;
-&lt;/LinearLayout&gt;
-</pre>
-
-<p>You should consider using alternative ad sizes based on various configurations such as screen
-size or screen orientation. This can easily be addressed by <a
-href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">providing
-alternative resources</a>. For instance, the above sample layout might placed under the
-<code>res/layout/</code> directory as the default layout. If larger ad
-sizes are available, you can consider using them for "large" (and above) screens. For example, the
-following snippet comes from a layout file in the <code>res/layout-large/</code> directory, which
-renders a larger ad for "large" screen sizes.</p>
-
-<pre>
-...
-&lt;com.google.ads.AdView
- xmlns:googleads=&quot;http://schemas.android.com/apk/lib/com.google.ads&quot;
- android:id=&quot;&#064;+id/ad&quot;
- android:layout_width=&quot;fill_parent&quot;
- android:layout_height=&quot;wrap_content&quot;
- <strong>googleads:adSize=&quot;IAB_LEADERBOARD&quot;</strong>
- googleads:adUnitId=&quot;&#064;string/admob_id&quot; /&gt;
-...
-</pre>
-
-<p>Notice that the custom view name and it’s configuration attributes are network-specific. Ad
-networks might support configurations with XML layout attributes (as shown above), runtime APIs, or
-both. In the sample application, Mobile Ads, the {@code AdView} ad size
-(<code>googleads:adSize</code>) and publisher ID (<code>googleads:adUnitId</code>) are set up in the
-XML layout.</p>
-
-<p>When deciding where to place ads within your application, you should carefully
-consider user-experience. For example, you don’t want to fill the screen with
-multiple ads that will quite likely annoy your users. In fact, this practice is banned by some ad
-networks. Also, avoid placing ads too closely to UI controls to avoid inadvertent clicks.</p>
-
-<p>Figures 3 and 4 illustrate what <strong>not</strong> to do.</p>
-
-<div style="float:left;width:275px">
-<img src="/images/training/ads-close-to-button.png" />
-<p class="img-caption">
- <strong>Figure 3.</strong> Avoid putting UI
-inputs too closely to an ad banner to prevent inadvertent ad clicks.
-</p>
-</div>
-
-<div style="float:left;width:275px;height:530px;margin-left:2em">
-<img src="/images/training/ads-cover-content.png" />
-<p class="img-caption">
- <strong>Figure 4.</strong> Don't overlay ad banner on useful content.
-</p>
-</div>
-
-
-<h2 id="InitializeAd" style="clear:left">Initialize the Ad</h2>
-
-<p>After setting up the ad in the XML layout, you can further customize the ad in {@link
-android.app.Activity#onCreate Activity.onCreate()} or {@link
-android.app.Fragment#onCreateView Fragment.onCreateView()} based on how your application is
-architected. Depending on the ad network, possible configuration parameters are: ad size, font
-color, keyword, demographics, location targeting, and so on.</p>
-
-<p>It is important to respect user privacy if certain parameters, such as demographics or location,
-are passed to ad networks for targeting purposes. Let your users know and give them a chance to opt
-out of these features.</p>
-
-<p>In the below code snippet, keyword targeting is used. After the keywords are set, the
-application calls <code>loadAd()</code> to begin serving ads.</p>
-
-<pre>
-public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- ...
- View v = inflater.inflate(R.layout.main, container, false);
- mAdStatus = (TextView) v.findViewById(R.id.status);
- mAdView = (AdView) v.findViewById(R.id.ad);
- mAdView.setAdListener(new MyAdListener());
-
- AdRequest adRequest = new AdRequest();
- adRequest.addKeyword("sporting goods");
- mAdView.loadAd(adRequest);
- return v;
-}
-</pre>
-
-
-
-<h2 id="EnableTestMode">Enable Test Mode</h2>
-
-<p>Some ad networks provide a test mode. This is useful during development and testing in which ad
-impressions and clicks are not counted.</p>
-
-<p class="caution"><strong>Important:</strong> Be sure to turn off test mode before publishing your
-application.</p>
-
-
-<h2 id="ImplementListeners">Implement Ad Event Listeners</h2>
-
-<p>Where available, you should consider implementing ad event listeners, which provide callbacks on
-various ad-serving events associated with the ad view. Depending on the ad network, the listener
-might provide notifications on events such as before the ad is loaded, after the ad is loaded,
-whether the ad fails to load, or other events. You can choose to react to these events based on
-your specific situation. For example, if the ad fails to load, you can display a custom banner
-within the application or create a layout such that the rest of content fills up the screen.</p>
-
-<p>For example, here are some event callbacks available from AdMob's {@code AdListener}
-interface:</p>
-
-<pre>
-private class MyAdListener implements AdListener {
- ...
-
- &#064;Override
- public void onFailedToReceiveAd(Ad ad, ErrorCode errorCode) {
- mAdStatus.setText(R.string.error_receive_ad);
- }
-
- &#064;Override
- public void onReceiveAd(Ad ad) {
- mAdStatus.setText("");
- }
-}
-</pre>
-
diff --git a/docs/html/training/monetization/index.jd b/docs/html/training/monetization/index.jd
deleted file mode 100644
index f90bfc7..0000000
--- a/docs/html/training/monetization/index.jd
+++ /dev/null
@@ -1,44 +0,0 @@
-page.title=Monetizing Your App
-
-trainingnavtop=true
-startpage=true
-next.title=Advertising without Compromising User Experience
-next.link=ads-and-ux.html
-
-@jd:body
-
-<div id="tb-wrapper">
-<div id="tb">
-
-<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
-<h2>Dependencies and prerequisites</h2>
-<ul>
- <li>Android 1.0 or higher</li>
- <li>Experience with <a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML layouts</a></li>
-</ul>
-
-
-<h2>Try it out</h2>
-
-<div class="download-box">
- <a href="http://developer.android.com/shareables/training/MobileAds.zip" class="button">Download
-the sample app</a>
- <p class="filename">MobileAds.zip</p>
-</div>
-
-</div>
-</div>
-
-<p>Apart from offering paid apps, there are a number of other ways to monetize your mobile applications. In this class, we are going to examine a number of typical methods (more lessons are to come) and their associated technical best practices. Obviously, each application is different and you should experiment with different combinations of these and other monetization methods to determine what works best for you.</p>
-
-<h2>Lessons</h2>
-
-<!-- Create a list of the lessons in this class along with a short description of each lesson.
-These should be short and to the point. It should be clear from reading the summary whether someone
-will want to jump to a lesson or not.-->
-
-<dl>
- <dt><b><a href="ads-and-ux.html">Advertising without Compromising User Experience</a></b></dt>
- <dd>In this lesson, you will learn how to monetize your application with mobile
-advertisements.</dd>
-</dl>
diff --git a/docs/html/google/play/safetynet/start.jd b/docs/html/training/safetynet/index.jd
index 8307928..6090f41 100644
--- a/docs/html/google/play/safetynet/start.jd
+++ b/docs/html/training/safetynet/index.jd
@@ -1,11 +1,10 @@
-page.title=Getting Started with SafetyNet
-parent.title=SafetyNet for Android
-parent.link=index.html
+page.title=Checking Device Compatibility with SafetyNet
+
@jd:body
-<div id="qv-wrapper">
-<div id="qv">
+<div id="tb-wrapper">
+<div id="tb">
<h2>In this document</h2>
<ol>
@@ -68,7 +67,9 @@ party rights. You will not violate any other terms of service with Google (or it
You acknowledge and understand that the SafetyNet API works by collecting hardware and software
information, such as device and application data and the results of integrity checks, and sending
that data to Google for analysis. Pursuant to Section 3(d) of the
-<a href= "https://developers.google.com/terms/">Google APIs Terms of Service</a>, you agree that if you use the APIs that it is your responsibility to provide any necessary notices or consents for the collection and sharing of this data with Google.
+<a href= "https://developers.google.com/terms/">Google APIs Terms of Service</a>, you agree that if
+you use the APIs that it is your responsibility to provide any necessary notices or consents for the
+collection and sharing of this data with Google.
</div>
<h2 id="connect-play">
@@ -256,9 +257,9 @@ certificate used to sign requesting app"],
<a href=
"{@docRoot}reference/com/google/android/gms/safetynet/SafetyNetApi.AttestationResult.html#getJwsResult()">
{@code getJwsResult()}</a> method is null or contains an {@code error:} field, then communication
- with the service failed and should be retried. You should use an <a href=
- "{@docRoot}google/gcm/gcm.html#retry">exponential backoff</a> technique for
- retries, to avoid flooding the service with additional requests.
+ with the service failed and should be retried. You should use an <a class="external-link" href=
+ "https://developers.google.com/api-client-library/java/google-http-java-client/backoff">
+ exponential backoff</a> technique for retries, to avoid flooding the service with additional requests.
</p>
<h3 id="verify-compat-check">
@@ -362,7 +363,7 @@ https&#58;&#47;&#47;www.googleapis.com/androidcheck/v1/attestations/verify?key=&
</li>
</ol>
-<p>
+<p class="note">
<strong>Important:</strong> This use of the Android Device Verification API only validates that the
provided JWS message was received from the SafetyNet service. It <em>does not</em> verify that the
payload data matches your original compatibility check request.
diff --git a/docs/html/training/sign-in/index.jd b/docs/html/training/sign-in/index.jd
new file mode 100644
index 0000000..9d49fd9
--- /dev/null
+++ b/docs/html/training/sign-in/index.jd
@@ -0,0 +1,68 @@
+page.title=Adding Sign-In
+page.tags=authentication,signin,social,google+
+page.article=true
+page.trainingcourse=true
+@jd:body
+
+
+<img src="{@docRoot}images/google/gps-googleplus.png"
+ width="300"
+ style="float:right;margin:0 0 20px 20px"
+ alt="Google maps sample image">
+
+<p>
+ The Google+ platform for Android lets you authenticate a user with the same credentials they use
+ on Google every day. Once a user signs in with Google, you can create more engaging experiences
+ and drive usage of your app.
+</p>
+
+<p>
+ The <a href="https://developers.google.com/+/mobile/android/">Google+ Android API</a> allows
+ you to integrate sign-in and social features into your app.
+</p>
+
+
+<h2 id="features">Key Developer Features</h2>
+
+<h4>Trusted authentication</h4>
+<p>
+ Google+ Sign-In is a simple, trusted, and secure way to let people sign in to your app with their
+ Google credentials and bring along their Google+ info.<br>
+ <a href="https://developers.google.com/+/mobile/android/sign-in" class="external-link">Add
+ sign-in</a>.
+</p>
+
+<h4>Access the profile and social graph</h4>
+<p>
+ Once users have signed in with Google, your app can welcome them by name, display their picture,
+ connect them with friends, and lots more.<br>
+ <a href="https://developers.google.com/+/mobile/android/people" class="external-link">Access the
+ social graph</a>.
+</p>
+
+<h4>Stand out in the stream</h4>
+<p>
+ Interactive posts is a rich way of sharing to Google+. It lets users prompt friends to take
+ specific actions in your app from a Google+ post, like "listen," "RSVP," "check-in," and over 100
+ more actions.<br>
+ <a class="external-link" href="https://developers.google.com/+/mobile/android/share">Post
+ interactive content</a>.
+</p>
+
+<h4>Recommend content</h4>
+<p>
+ Add a native +1 button so users can recommend content from your app. These endorsements can give
+ your app more credibility and help it grow faster.<br>
+ <a class="external-link" href="https://developers.google.com/+/mobile/android/recommend">Add the
+ +1 button</a>.
+</p>
+
+
+<h2 id="start">Get Started</h2>
+<p>
+ The Google+ Android APIs are part of the Google Play services platform. To use Google+ features,
+ set up the Google Play services SDK in your app development project. For more information, see
+ the <a class="external-link" href=
+ "https://developers.google.com/+/mobile/android/getting-started">Getting Started</a> guide for
+ the Google+ Platform for Android
+</p> \ No newline at end of file
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 089739b..7adc45a 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -672,12 +672,59 @@ include the action bar on devices running Android 2.1 or higher."
<!-- End connectivity and cloud -->
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/building-location.html">
+ <span class="small">Building Apps with</span><br/>
+ Location &amp; Maps
+ </a>
+ </div>
+ <ul>
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/location/index.html"
+ description="How to add location-aware features to your app by getting the user's current location.">
+ Making Your App Location-Aware
+ </a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/location/retrieve-current.html">
+ Getting the Last Known Location
+ </a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/location/receive-location-updates.html">
+ Receiving Location Updates
+ </a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/location/display-address.html">
+ Displaying a Location Address
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/location/geofencing.html">
+ Creating and Monitoring Geofences
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="nav-section">
+ <a href="<?cs var:toroot ?>training/maps/index.html"
+ description="How to add maps and mapping information to your app.">
+ Adding Maps
+ </a>
+ </li>
+ </ul>
+ </li>
+ <!-- End location and maps -->
+
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/building-userinfo.html">
<span class="small">Building Apps with</span><br/>
- User Info &amp; Location
+ User Info &amp; Sign-In
</a>
</div>
<ul>
@@ -712,39 +759,15 @@ include the action bar on devices running Android 2.1 or higher."
</li>
</ul>
</li>
-
<li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>training/location/index.html"
- description="How to add location-aware features to your app by getting the user's current location.">
- Making Your App Location-Aware
- </a>
- </div>
- <ul>
- <li>
- <a href="<?cs var:toroot ?>training/location/retrieve-current.html">
- Getting the Last Known Location
- </a>
- </li>
- <li>
- <a href="<?cs var:toroot ?>training/location/receive-location-updates.html">
- Receiving Location Updates
- </a>
- </li>
- <li>
- <a href="<?cs var:toroot ?>training/location/display-address.html">
- Displaying a Location Address
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/location/geofencing.html">
- Creating and Monitoring Geofences
- </a>
- </li>
- </ul>
+ <a href="<?cs var:toroot ?>training/sign-in/index.html"
+ description="How to add user sign-in functionality to your app.">
+ Adding Sign-In
+ </a>
</li>
</ul>
</li>
- <!-- End privacy and location -->
+ <!-- End user info and sign-in -->
<li class="nav-section">
@@ -1802,19 +1825,18 @@ results."
>Updating Your Security Provider to Protect Against SSL Exploits</a>
</li>
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>training/enterprise/index.html"
- description=
- "How to implement device management policies for enterprise-oriented apps."
- >Developing for Enterprise</a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot ?>training/enterprise/device-management-policy.html">
- Enhancing Security with Device Management Policies
- </a>
- </li>
- </ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/safetynet/index.html"
+ description=
+ "How to use the SafetyNet service to analyze a device where your app is running
+ and get information about its compatibility with your app."
+ >Checking Device Compatibility with SafetyNet</a>
+ </li>
+
+ <li>
+ <a href="<?cs var:toroot ?>training/enterprise/device-management-policy.html"
+ description="How to create an application that enforces security policies on devices."
+ >Enhancing Security with Device Management Policies</a>
</li>
</ul>
</li>
@@ -1956,21 +1978,6 @@ results."
</li>
</ul>
</li>
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>training/monetization/index.html"
- description=
- "How to implement monetization strategies for your app without compromising
- the user experience."
- >Monetizing Your App</a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot ?>training/monetization/ads-and-ux.html">
- Advertising without Compromising User Experience
- </a>
- </li>
- </ul>
- </li>
</ul>
</li>
<!-- End best Publishing -->