summaryrefslogtreecommitdiffstats
path: root/docs/html/google
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/google')
-rw-r--r--docs/html/google/auth/api-client.jd28
-rw-r--r--docs/html/google/gcm/c2dm.jd5
-rw-r--r--docs/html/google/gcm/ccs.jd136
-rw-r--r--docs/html/google/gcm/gcm.jd2
-rw-r--r--docs/html/google/gcm/http.jd223
-rw-r--r--docs/html/google/gcm/server-ref.jd3
-rw-r--r--docs/html/google/google_toc.cs13
-rw-r--r--docs/html/google/play-services/index.jd124
-rw-r--r--docs/html/google/play-services/location.jd51
-rw-r--r--docs/html/google/play-services/setup.jd134
-rw-r--r--docs/html/google/play-services/wallet.jd12
-rw-r--r--docs/html/google/play/billing/billing_integrate.jd152
-rw-r--r--docs/html/google/play/safetynet/index.jd82
-rw-r--r--docs/html/google/play/safetynet/start.jd369
14 files changed, 908 insertions, 426 deletions
diff --git a/docs/html/google/auth/api-client.jd b/docs/html/google/auth/api-client.jd
index a0836d1..e33721d 100644
--- a/docs/html/google/auth/api-client.jd
+++ b/docs/html/google/auth/api-client.jd
@@ -52,8 +52,7 @@ for REST APIs</a>.</p>
<p class="note">
<strong>Note:</strong> If you have an existing app that connects to Google Play services with a
-subclass of <a
-href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.html">{@code GooglePlayServicesClient}</a>, you should migrate to <a
+subclass of {@code GooglePlayServicesClient}, you should migrate to <a
href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code
GoogleApiClient}</a> as soon as possible.</p>
@@ -133,7 +132,9 @@ succeeds, fails, or becomes suspended.</p>
API Client:</p>
<pre>
-import gms.common.api.*;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import gms.drive.*;
import android.support.v4.app.FragmentActivity;
@@ -206,20 +207,18 @@ href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html
<p>However, if you run this code, there's a good chance it will fail and your app will receive a call
to <a
-href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)"
+href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)"
>{@code onConnectionFailed()}</a> with the <a
href="{@docRoot}reference/com/google/android/gms/common/ConnectionResult.html#SIGN_IN_REQUIRED"
>{@code SIGN_IN_REQUIRED}</a> error because the user account
has not been specified. The next section shows how to handle this error and others.</p>
-
-
<h3 id="HandlingFailures">Handle connection failures</h3>
-<p>When you receive a call to the <a
-href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)"
->{@code onConnectionFailed()}</a> callback, you should call <a
+<p>When you receive a call to the
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">
+{@code onConnectionFailed()}</a> callback, you should call <a
href="{@docRoot}reference/com/google/android/gms/common/ConnectionResult.html#hasResolution()"
>{@code hasResolution()}</a> on the provided <a
href="{@docRoot}reference/com/google/android/gms/common/ConnectionResult.html"
@@ -244,8 +243,9 @@ dialog may simply provide a message explaining the error, but it may also provid
launch an activity that can resolve the error (such as when the user needs to install a newer
version of Google Play services).</p>
-<p>For example, your <a
-href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)"
+<p>For example, your
+<a
+href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)"
>{@code onConnectionFailed()}</a> callback method should now look like this:</p>
<pre>
@@ -365,9 +365,9 @@ if retained across activity instances, though. The next section explains further
<h3 id="MaintainingState">Maintain state while resolving an error</h3>
-<p>To avoid executing the code in <a
-href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)"
->{@code onConnectionFailed()}</a> while a previous attempt to resolve an
+<p>To avoid executing the code in
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">
+{@code onConnectionFailed()}</a> while a previous attempt to resolve an
error is ongoing, you need to retain a boolean that tracks whether your app is already attempting
to resolve an error.</p>
diff --git a/docs/html/google/gcm/c2dm.jd b/docs/html/google/gcm/c2dm.jd
index 6ae7c1a..bc58e66 100644
--- a/docs/html/google/gcm/c2dm.jd
+++ b/docs/html/google/gcm/c2dm.jd
@@ -33,7 +33,10 @@ page.title=Migration
</div>
</div>
-<p>Android Cloud to Device Messaging (C2DM) is deprecated. The C2DM service will continue to be maintained in the short term, but C2DM will accept no new users, and it will grant no new quotas. <strong>C2DM developers are strongly encouraged to move to Google Cloud Messaging (GCM)</strong>. GCM is the next generation of C2DM.</p>
+<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>
diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd
index 143b057..c4d1b1d 100644
--- a/docs/html/google/gcm/ccs.jd
+++ b/docs/html/google/gcm/ccs.jd
@@ -13,16 +13,14 @@ page.title=GCM Cloud Connection Server (XMPP)
<li><a href="#auth">Authentication</a></li>
</ol>
</li>
- <li><a href="#format">Message Format</a>
+ <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>
- <ol>
- <li><a href="#receipts">Receive delivery receipts</a></li>
- </ol>
</li>
<li><a href="#flow">Flow Control</a> </li>
<li><a href="#implement">Implementing an XMPP-based App Server</a>
@@ -138,7 +136,7 @@ mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==&lt;/auth&gt;
<h4>Server</h4>
<pre>&lt;success xmlns=&quot;urn:ietf:params:xml:ns:xmpp-sasl&quot;/&gt;</pre>
-<h2 id="format">Message Format</h2>
+<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>
@@ -169,7 +167,8 @@ 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 will just resend it.
+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
@@ -316,7 +315,7 @@ connection, but allowing whatever is already in the pipeline to continue. When y
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 will handle initiating a connection close when it is ready.</p>
+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;
@@ -330,66 +329,11 @@ ACKing them)&mdash;CCS will handle initiating a connection close when it is read
<p>{@code CONNECTION_DRAINING} is currently the only {@code control_type} supported.</p>
-<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>
+<!--Delivery receipts section-->
<h3 id="receipts">Receive delivery receipts</h3>
-<p>You can use upstream messaging to get delivery receipts (sent from CCS to
+<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>
@@ -452,8 +396,68 @@ app server that a device received a message that CCS sent it:</p>
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
@@ -468,7 +472,7 @@ figure 1:</p>
<strong>Figure 1.</strong> Message/ack flow.
</p>
-<p>Conversely, to avoid overloading the 3rd-party app server, CCS will stop sending
+<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
@@ -663,7 +667,7 @@ public class SmackCcsClient {
* Creates a JSON encoded GCM message.
*
* &#64;param to RegistrationId of the target device (Required).
- * &#64;param messageId Unique messageId for which CCS will send an
+ * &#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).
diff --git a/docs/html/google/gcm/gcm.jd b/docs/html/google/gcm/gcm.jd
index 4e345b3..d4bb45e 100644
--- a/docs/html/google/gcm/gcm.jd
+++ b/docs/html/google/gcm/gcm.jd
@@ -279,7 +279,7 @@ receives match the logged in user.</li>
<h4 id="unreg-how">How unregistration works</h4>
-<p>An app can be automatically unregistered after it is uninstalled.
+<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>
diff --git a/docs/html/google/gcm/http.jd b/docs/html/google/gcm/http.jd
index 5022e09..e36440a 100644
--- a/docs/html/google/gcm/http.jd
+++ b/docs/html/google/gcm/http.jd
@@ -83,6 +83,32 @@ 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>
@@ -157,53 +183,10 @@ the body contains more information about the status of the message (including po
non-200 status code (such as 400, 401 or 5xx).</li>
</ul>
-<h3 id="success">Interpreting a success response</h3>
-<p>When a JSON request is successful (HTTP status code 200), the response body
-contains a JSON object with the following fields:</p>
-<table>
- <tr>
- <th>Field</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>multicast_id</code></td>
- <td>Unique ID (number) identifying the multicast message.</td>
- </tr>
- <tr>
- <td><code>success</code></td>
- <td>Number of messages that were processed without an error.</td>
- </tr>
- <tr>
- <td><code>failure</code></td>
- <td>Number of messages that could not be processed.</td>
- </tr>
- <tr>
- <td><code>canonical_ids</code></td>
- <td>Number of results that contain a canonical registration ID. See
-<a href="adv.html#canonical">Advanced Topics</a> for more discussion of this topic.</td>
- </tr>
- <tr>
- <td><code>results</code></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) and
-they can have these fields:<br>
- <ul>
- <li><code>message_id</code>: String representing the message when it was
-successfully processed.</li>
- <li><code>registration_id</code>: If set, means that GCM processed the
-message but it has another canonical registration ID for that device, so sender
-should replace the IDs on future requests (otherwise they might be rejected).
-This field is never set if there is an error in the request.
- </li>
- <li><code>error</code>: String describing an error that occurred while
-processing the message for that recipient. The possible values are the same as
-documented in the above table, plus &quot;Unavailable&quot; (meaning GCM servers
-were busy and could not process the message for that particular recipient, so
-it could be retried).</li>
- </ul></td>
- </tr>
-</table>
+<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
@@ -227,8 +210,9 @@ 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="#error_codes">Interpreting
-an error response</a> for all possible error values.</li>
+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>
@@ -260,147 +244,6 @@ error code, they would have returned a 500 HTTP status instead).</li>
</li>
</ul>
-<h3 id="error_codes">Interpreting an error response</h3>
-<p>Here are the recommendations for handling the different types of error that
-might occur when trying to send a message to a device:</p>
-
-<dl>
-<dt id="missing_reg"><strong>Missing Registration ID</strong></dt>
-<dd>Check that the request contains a registration ID (either in the
-<code>registration_id</code> parameter in a plain text message, or in the
-<code>registration_ids</code> field in JSON).
-<br/>Happens when error code is <code>MissingRegistration</code>.</dd>
-
-<dt id="invalid_reg"><strong>Invalid Registration ID</strong></dt>
-<dd>Check the formatting of the registration ID that you pass to the server. Make
-sure it matches the registration ID the client app receives and that you're
-not truncating it or adding additional characters.
-<br/>Happens when error code is <code>InvalidRegistration</code>.</dd>
-
-<dt id="mismatched_sender"><strong>Mismatched Sender</strong></dt>
-<dd>A registration ID is tied to a certain group of senders. When an application
-registers for GCM usage, it must specify which senders are allowed to send messages.
-Make sure you're using one of those when trying to send messages to the device.
-If you switch to a different sender, the existing registration IDs won't work.
-Happens when error code is <code>MismatchSenderId</code>.</dd>
-
-<dt id="unreg_device"><strong>Unregistered Device</strong></dt>
-<dd>An existing registration ID may cease to be valid in a number of scenarios, including:
-<ul>
- <li>If the application manually unregisters.</li>
- <li>If the application is automatically unregistered, which can happen
-(but is not guaranteed) if the user uninstalls the application.</li>
- <li>If the registration ID expires. Google might decide to refresh registration
-IDs. </li>
- <li>If the application is updated but the new version is not configured to receive
-messages.</li>
-</ul>
-For all these cases, you should remove this registration ID from the 3rd-party
-server and stop using it to send
-messages.
-<br/>Happens when error code is <code>NotRegistered</code>.</dd>
-
-<dt id="big_msg"><strong>Message Too Big</strong></dt>
- <dd>The total size of the payload data that is included in a message can't
-exceed 4096 bytes. Note that this includes both the size of the keys as well
-as the values.
-<br/>Happens when error code is <code>MessageTooBig</code>.</dd>
-
-<dt id="invalid_datakey"><strong>Invalid Data Key</strong></dt>
-<dd>The payload data contains a key (such as <code>from</code> or any value
-prefixed by <code>google.</code>) that is used internally by GCM and therefore cannot be used.
-Note that some words (such as <code>collapse_key</code>) are also used by GCM
-but are allowed in the payload, in which case the payload value will be
-overridden by the GCM value.
-<br />
-Happens when the error code is <code>InvalidDataKey</code>.</dd>
-
-<dt id="ttl_error"><strong>Invalid Time To Live</strong></dt>
- <dd>The value for the Time to Live field must be an integer representing
-a duration in seconds between 0 and 2,419,200 (4 weeks). Happens when error code
-is <code>InvalidTtl</code>.
-</dd>
-
- <dt id="auth_error"><strong>Authentication Error</strong></dt>
- <dd>The sender account that you're trying to use to send a message couldn't be
-authenticated. Possible causes are: <ul>
-<li>Authorization header missing or with invalid syntax.</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>
-When there is an Authentication Error, you can check the validity of your API key by running You can check the validity
-of your API key by running the following command (this example shows what you
-would do on Android; see the documentation for your platform):<br/>
-
-<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>
-
-
-
-If you receive a 401 HTTP status code, your API key is not valid. Otherwise you
-should see something like this:<br/>
-
-<pre>
-{"multicast_id":6782339717028231855,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
-</pre>
-If you want to confirm the validity of a registration ID, you can do so by
-replacing "ABC" with the registration ID.
-<br/>
-Happens when the HTTP status code is 401.
-
- <dt id="timeout"><strong>Timeout</strong></dt>
-
-<dd>The server couldn't process the request in time. You should retry the
-same request, but you MUST obey the following requirements:
-
-<ul>
-
-<li>Honor the <code>Retry-After</code> header if it's included in the response
-from the GCM server.</li>
-
-
-<li>Implement exponential back-off in your retry mechanism. This means an
-exponentially increasing delay after each failed retry (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>
-
-
-Senders that cause problems risk being blacklisted.
-<br />
-Happens when the HTTP status code is between 501 and 599, or when the
-<code>error</code> field of a JSON object in the results array is <code>Unavailable</code>.
-</dd>
-
-<dt id="internal_error"><strong>Internal Server Error</strong></dt>
-
-<dd>
-The server encountered an error while trying to process the request. You
-could retry the same request (obeying the requirements listed in the <a href="#timeout">Timeout</a>
-section), but if the error persists, please report the problem to Google.
-<br />
-Happens when the HTTP status code is 500, or when the <code>error</code> field of a JSON
-object in the results array is <code>InternalServerError</code>.
-</dd>
-
-<dt id="restricted_package_name"><strong>Invalid Package Name</strong></dt>
-
-<dd>
-A message was addressed to a registration ID whose package name did not match
-the value passed in the request. Happens when error code is
-<code>InvalidPackageName</code>.
-</dd>
-
-<dt id="big_msg"><strong>Device Message Rate Exceeded</strong></dt>
- <dd>The rate of messages to a particular device is too high. You should reduce the number
-of messages sent to this device and should not retry sending to this device immediately.
-<br/>Happens when error code is <code>DeviceMessageRateExceeded</code>.</dd>
-
-</dl>
<h3 id="example-responses">Example responses</h3>
<p>This section shows a few examples of responses indicating messages that were
diff --git a/docs/html/google/gcm/server-ref.jd b/docs/html/google/gcm/server-ref.jd
index a94e727..2a41e58 100644
--- a/docs/html/google/gcm/server-ref.jd
+++ b/docs/html/google/gcm/server-ref.jd
@@ -665,7 +665,8 @@ matches the value passed in the request.</td>
</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">GCM HTTP Connection Server</a> for details.</td>
+<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>
diff --git a/docs/html/google/google_toc.cs b/docs/html/google/google_toc.cs
index 4e8e638..510a755 100644
--- a/docs/html/google/google_toc.cs
+++ b/docs/html/google/google_toc.cs
@@ -65,7 +65,18 @@
<span class="en">Wallet</span>
</a></div>
</li>
-
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot?>google/play/safetynet/index.html">
+ <span class="en">SafetyNet</span>
+ </a></div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>google/play/safetynet/start.html">
+ <span class="en">Getting Started</span>
+ </a>
+ </li>
+ </ul>
+ </li>
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>google/play-services/index.html">
diff --git a/docs/html/google/play-services/index.jd b/docs/html/google/play-services/index.jd
index 0b1bdd9..3d0f7f6 100644
--- a/docs/html/google/play-services/index.jd
+++ b/docs/html/google/play-services/index.jd
@@ -52,11 +52,8 @@ your app with the most recent version of Google Play services without worrying
about your users' Android version.</p>
</div>
-
-
<p>To start integrating Google Play services into your app,
follow the <a href="/google/play-services/setup.html">Setup</a> guide.</p>
-
</div>
<h2 style="margin-top:0" id="newfeatures">New Features</h2>
@@ -65,6 +62,125 @@ about your users' Android version.</p>
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png"
class="toggle-content-img"
+ alt=""/>Google Play services, Version 7.0</a> <em>(March 2015)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+<dl>
+<dt>Highlights in Version 7.0</dt>
+<dd>
+<p>For a summary of the feature highlights in Google Play services 7.0, see the
+announcement
+<a href="http://android-developers.blogspot.com/2015/03/google-play-services-70-places-everyone.html"
+class="external-link">blog post</a>.</p>
+<ul>
+ <li><strong>Places</strong> - Using the Google Places API for Android, you can build
+ location-aware apps that respond contextually to the local businesses and other places near
+ the device. Use the built-in place picker UI widget and API methods to find the device’s
+ current place, autocomplete users’ queries, and more.
+ <ul>
+ <li><a href="https://developers.google.com/places/documentation/android/"
+ class="external-link">Places API developer guide</a></li>
+ <li><a href="{@docRoot}reference/com/google/android/gms/location/places/package-summary.html">
+ Places API reference</a></li>
+ </ul>
+ </li>
+ <li><strong>Location settings</strong> - While the
+ <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html">
+ {@code FusedLocationProviderApi}</a>
+ combines multiple sensors to give you the optimal location, the accuracy of the location your
+ app receives still depends greatly on the settings enabled on the device (GPS, wifi, airplane
+ mode, and others). Using the new
+ <a href="{@docRoot}reference/com/google/android/gms/location/SettingsApi.html">
+ {@code SettingsApi}</a>
+ class, you can bring up a Location Settings dialog which displays a one-touch control for users
+ to change their settings without leaving your app.
+ </li>
+ <li><strong>Fit</strong> - The Google Fit API is now more efficient with modular calls to specific
+ functionality within the API. You can now also access distance and granular sleep data.
+ <ul>
+ <li><a href="https://developers.google.com/fit/android/get-started.html#step_5_connect_to_the_fitness_service"
+ class="external-link">Fit API developer guide</a></li>
+ <li><a href="{@docRoot}reference/com/google/android/gms/fitness/package-summary.html">
+ Fit API reference</a></li>
+ </ul>
+ </li>
+ <li><strong>Google Mobile Ads</strong> - This release introduces the
+ <a href="{@docRoot}reference/com/google/android/gms/ads/doubleclick/PublisherAdRequest.Builder.html#addCustomTargeting(java.lang.String,%20java.lang.String)">
+ {@code addCustomTargeting()}</a>
+ and <a href="{@docRoot}reference/com/google/android/gms/ads/doubleclick/PublisherAdRequest.Builder.html#addCategoryExclusion(java.lang.String)">
+ {@code addCategoryExclusion()}</a>
+ methods to the <a href="{@docRoot}reference/com/google/android/gms/ads/doubleclick/PublisherAdRequest.Builder.html">
+ {@code PublisherAdRequest.Builder} </a>
+ class, enabling DoubleClick for Publishers (DFP) developers to
+ <a href="https://support.google.com/dfp_sb/answer/112648" class="external-link">target custom
+ criteria</a>
+ and <a href="https://support.google.com/dfp_premium/answer/2627086" class="external-link">use
+ ad exclusions to block ads</a>.
+ <ul>
+ <li><a href="https://developers.google.com/mobile-ads-sdk/docs/dfp/android/banner"
+ class="external-link">DFP targeting developer guide</a></li>
+ </ul>
+ </li>
+ <li><strong>Play Game services</strong> - The Nearby Connections API allows users to connect to
+ each other and exchange messages over a local network. This API supports local multiplayer
+ and second screen gaming.
+ <ul>
+ <li><a href="https://developers.google.com/games/services/android/nearby.html"
+ class="external-link">Nearby Connections developer guide</a></li>
+ <li><a href="{@docRoot}reference/com/google/android/gms/nearby/connection/package-summary.html">
+ Nearby Connection API reference</a></li>
+ </ul>
+ </li>
+ <li><strong>Google API client</strong> - This release introduces the
+ <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html#requestServerAuthCode(java.lang.String,%20com.google.android.gms.common.api.GoogleApiClient.ServerAuthCodeCallbacks)">{@code GoogleApiClient.Builder.requestServerAuthCode()}</a> method. This API makes it significantly easier
+ to enable servers to be able to make Google API calls on behalf of users. This method reduces
+ the lines of boilerplate code that you previously had to implement.
+ <ul>
+ <li><a href="https://developers.google.com/identity/sign-in/android/sign-in.html#enable_server-side_api_access_for_your_app"
+ class="external-link">Server-side API access developer guide</a></li>
+ </ul>
+ </li>
+ <li>
+ <strong>Drive</strong> - This release adds
+ <a href="{@docRoot}reference/com/google/android/gms/drive/DriveResource.html#trash(com.google.android.gms.common.api.GoogleApiClient))">
+ {@code trash()}</a> and
+ <a href="{@docRoot}reference/com/google/android/gms/drive/DriveResource.html#untrash(com.google.android.gms.common.api.GoogleApiClient)">
+ {@code untrash()}</a> methods to the
+ <a href="{@docRoot}reference/com/google/android/gms/drive/DriveResource.html">
+ {@code DriveResource}</a>
+ class. These methods enable you to move user-visible files and folders to the trash or
+ restore them from the trash. Trashing a folder recursively trashes its children. The
+ <a href="{@docRoot}reference/com/google/android/gms/drive/Metadata.html#isExplicitlyTrashed()">
+ {@code isExplicitlyTrashed()}</a> method indicates whether a resource was trashed directly,
+ or as the result of a trashed parent.
+ <ul>
+ <li><a href="https://developers.google.com/drive/android/trash.html"
+ class="external-link">Trashing and untrashing developer guide</a></li>
+ </ul>
+ </li>
+ <li><strong>SafetyNet API</strong> - The API lets you check if your app is running on a device
+ that matches a device model that has passed Android compatibility testing. The API evaluates
+ both software and hardware characteristics of a device to determine whether it matches a
+ known-good configuration that has been previously determined to be compatible. You can use the
+ SafetyNet API in conjunction with other tools to determine whether the device appears capable
+ of handling specific features in your app.
+ <ul>
+ <li><a href="{@docRoot}reference/com/google/android/gms/safetynet/package-summary.html">
+ SafetyNet API reference</a></li>
+ <li><a href="{@docRoot}google/play/safetynet/index.html">
+ SafetyNet developer guide</a></li>
+ </ul>
+ </li>
+</ul>
+</dd>
+</dl>
+ </div>
+</div>
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>Google Play services, Version 6.5</a> <em>(December 2014)</em>
</p>
@@ -154,6 +270,8 @@ enables you to get a ready-to-use Street View panorama.
</ul>
</dd>
</dl>
+ </div>
+</div>
<div class="toggle-content closed">
<p><a href="#" onclick="return toggleContent(this)">
diff --git a/docs/html/google/play-services/location.jd b/docs/html/google/play-services/location.jd
index 3fbf00e..b28302c 100644
--- a/docs/html/google/play-services/location.jd
+++ b/docs/html/google/play-services/location.jd
@@ -12,24 +12,25 @@ header.hide=1
<div class="col-6">
-<h1 itemprop="name" style="margin-bottom:0;">Location APIs</h1>
+<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. They also let you minimize
- power consumption by using all of the capabilities of the device hardware.
+ 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. You can learn how to use the APIs in the training
- class <a href="{@docRoot}training/location/index.html">Making Your App Location Aware</a>,
- and details are available in the <a href="{@docRoot}reference/com/google/android/gms/location/package-summary.html">Location API reference</a>. <!-- To look at a code example, <a href="">download the sample app</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="layout-content-row">
+ <div class="layout-content-row normal-links">
<div class="layout-content-col span-6">
@@ -74,9 +75,37 @@ header.hide=1
</div>
<div class="layout-content-col span-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>With apps becoming increasingly contextual, understanding what the user is doing is critical to surfacing the right content. 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>
+<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.
@@ -87,8 +116,8 @@ header.hide=1
navigation app can request more frequent updates when the user is driving.
</li>
<li>
- <em>Features for advanced applications</em>: For advanced applications that want to do their own
- post-processing, this API also makes available confidence values for each of the activities.
+ <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>
diff --git a/docs/html/google/play-services/setup.jd b/docs/html/google/play-services/setup.jd
index ad19cb3..70e7107 100644
--- a/docs/html/google/play-services/setup.jd
+++ b/docs/html/google/play-services/setup.jd
@@ -67,7 +67,7 @@ apply plugin: 'com.android.application'
dependencies {
compile 'com.android.support:appcompat-v7:21.0.3'
- <strong>compile 'com.google.android.gms:play-services:6.5.87'</strong>
+ <strong>compile 'com.google.android.gms:play-services:7.0.0'</strong>
}
</pre>
<p>Be sure you update this version number each time Google Play services is updated.</p>
@@ -82,14 +82,6 @@ see <a href="#split">Selectively compiling APIs into your executable</a>.
<img src="{@docRoot}images/tools/sync-project.png" style="vertical-align:bottom;margin:0;height:19px" />
in the toolbar.
</li>
- <li>Open your app's manifest file and add the following tag as a child of the <a
-href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application>}</a>
-element:
-<pre>
-&lt;meta-data android:name="com.google.android.gms.version"
- android:value="&#64;integer/google_play_services_version" />
-</pre>
- </li>
</ol>
<p>You can now begin developing features with the
@@ -106,14 +98,14 @@ example, to include only the Google Fit and Android Wear APIs, replace the follo
<code>build.gradle</code> file:</p>
<pre class="no-pretty-print">
-compile 'com.google.android.gms:play-services:6.5.87'
+compile 'com.google.android.gms:play-services:7.0.0'
</pre>
<p>with these lines:</p>
<pre class="no-pretty-print">
-compile 'com.google.android.gms:play-services-fitness:6.5.87'
-compile 'com.google.android.gms:play-services-wearable:6.5.87'
+compile 'com.google.android.gms:play-services-fitness:7.0.0'
+compile 'com.google.android.gms:play-services-wearable:7.0.0'
</pre>
<p>Table 1 shows a list of the separate APIs that you can include when compiling your app, and
@@ -129,67 +121,78 @@ you include an API that does have a separate library.)</p>
<th scope="col">Google Play services API</th>
<th scope="col">Description in <code>build.gradle</code></th>
</tr>
- <tr>
+ <tr>
<td>Google+</td>
- <td>com.google.android.gms:play-services-plus:6.5.87</td>
+ <td>com.google.android.gms:play-services-plus:7.0.0</td>
</tr>
<tr>
<td>Google Account Login</td>
- <td>com.google.android.gms:play-services-identity:6.5.87</td>
+ <td>com.google.android.gms:play-services-identity:7.0.0</td>
</tr>
<tr>
- <td>Google Activity Recognition</td>
- <td>com.google.android.gms:play-services-location:6.5.87</td>
+ <td>Google Actions, Base Client Library</td>
+ <td>com.google.android.gms:play-services-base:7.0.0</td>
</tr>
<tr>
<td>Google App Indexing</td>
- <td>com.google.android.gms:play-services-appindexing:6.5.87</td>
+ <td>com.google.android.gms:play-services-appindexing:7.0.0</td>
+ </tr>
+ <tr>
+ <td>Google Analytics</td>
+ <td>com.google.android.gms:play-services-analytics:7.0.0</td>
</tr>
<tr>
<td>Google Cast</td>
- <td>com.google.android.gms:play-services-cast:6.5.87</td>
+ <td>com.google.android.gms:play-services-cast:7.0.0</td>
+ </tr>
+ <tr>
+ <td>Google Cloud Messaging</td>
+ <td>com.google.android.gms:play-services-gcm:7.0.0</td>
</tr>
<tr>
<td>Google Drive</td>
- <td>com.google.android.gms:play-services-drive:6.5.87</td>
+ <td>com.google.android.gms:play-services-drive:7.0.0</td>
</tr>
<tr>
<td>Google Fit</td>
- <td>com.google.android.gms:play-services-fitness:6.5.87</td>
+ <td>com.google.android.gms:play-services-fitness:7.0.0</td>
+ </tr>
+ <tr>
+ <td>Google Location, Activity Recognition, and Places</td>
+ <td>com.google.android.gms:play-services-location:7.0.0</td>
</tr>
<tr>
<td>Google Maps</td>
- <td>com.google.android.gms:play-services-maps:6.5.87</td>
+ <td>com.google.android.gms:play-services-maps:7.0.0</td>
</tr>
<tr>
<td>Google Mobile Ads</td>
- <td>com.google.android.gms:play-services-ads:6.5.87</td>
+ <td>com.google.android.gms:play-services-ads:7.0.0</td>
+ </tr>
+ <tr>
+ <td>Google Nearby</td>
+ <td>com.google.android.gms:play-services-nearby:7.0.0</td>
</tr>
<tr>
<td>Google Panorama Viewer</td>
- <td>com.google.android.gms:play-services-panorama:6.5.87</td>
+ <td>com.google.android.gms:play-services-panorama:7.0.0</td>
</tr>
<tr>
<td>Google Play Game services</td>
- <td>com.google.android.gms:play-services-games:6.5.87</td>
+ <td>com.google.android.gms:play-services-games:7.0.0</td>
+ </tr>
+ <tr>
+ <td>SafetyNet</td>
+ <td>com.google.android.gms:play-services-safetynet:7.0.0</td>
</tr>
<tr>
<td>Google Wallet</td>
- <td>com.google.android.gms:play-services-wallet:6.5.87</td>
+ <td>com.google.android.gms:play-services-wallet:7.0.0</td>
</tr>
<tr>
<td>Android Wear</td>
- <td>com.google.android.gms:play-services-wearable:6.5.87</td>
- </tr>
- <tr>
- <td>
- Google Actions<br>
- Google Analytics<br>
- Google Cloud Messaging<br>
- </td>
- <td>com.google.android.gms:play-services-base:6.5.87</td>
+ <td>com.google.android.gms:play-services-wearable:7.0.0</td>
</tr>
-
</table>
<p class="note"><strong>Note:</strong> ProGuard directives are included in the Play services
@@ -210,13 +213,14 @@ To use ProGuard with Android Studio, you must enable the ProGuard setting in you
<p>To make the Google Play services APIs available to your app:</p>
<ol>
<li>Copy the library project at
- <code>&lt;android-sdk&gt;/extras/google/google_play_services/libproject/google-play-services_lib/</code>
+{@code &lt;android-sdk&gt;/extras/google/google_play_services/libproject/google-play-services_lib/}
to the location where you maintain your Android app projects.</li>
<li>Import the library project into your Eclipse workspace. Click
<b>File > Import</b>, select <b>Android > Existing Android Code into
Workspace</b>, and browse to the copy of the library project to import it.</li>
<li>In your app project, reference Google Play services library project. See
- <a href="{@docRoot}tools/projects/projects-eclipse.html#ReferencingLibraryProject">Referencing a Library Project for Eclipse</a> for more information on how to
+ <a href="{@docRoot}tools/projects/projects-eclipse.html#ReferencingLibraryProject">
+ Referencing a Library Project for Eclipse</a> for more information on how to
do this.
<p class="note"><strong>Note:</strong> You should be referencing a copy of the
library that you copied to your development workspace&mdash;you should not
@@ -270,7 +274,9 @@ required classes, add the following lines in the
<p>To make the Google Play services APIs available to your app:</p>
<ol>
- <li>Copy the library project at <code>&lt;android-sdk&gt;/extras/google/google_play_services/libproject/google-play-services_lib/</code> to the location where you maintain your Android app projects.</li>
+ <li>Copy the library project at
+{@code &lt;android-sdk&gt;/extras/google/google_play_services/libproject/google-play-services_lib/}
+to the location where you maintain your Android app projects.</li>
<li>In your app project, reference the Google Play services library project. See
<a href="{@docRoot}tools/projects/projects-cmdline.html#ReferencingLibraryProject">Referencing
@@ -282,7 +288,8 @@ workspace&mdash;you should not reference the library directly from the Android S
<li>After you've added the Google Play services library as a dependency for
your app project, open your app's manifest file and add the following tag as
a child of the
- <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application>}</a> element:
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application>}</a>
+ element:
<pre>
&lt;meta-data android:name="com.google.android.gms.version"
android:value="&#64;integer/google_play_services_version" />
@@ -336,23 +343,39 @@ perform API transactions.</p>
<strong>Important:</strong>
Because it is hard to anticipate the state of each device, you must <em>always</em> check for a
compatible Google Play services APK before you access Google Play services
- features. For many apps, the best time to check is during the
- {@link android.app.Activity#onResume onResume()} method of the main activity.
+ features.
</p>
-<p>The Google Play services library includes utility methods that help you determine whether or not
-the Google Play services version on the device supports the version of the client library you are
-using. If the version on the device is too old, the system will take the user to Google Play Store
-in order to install the recent version of the Google Play services.</p>
-
<p>Because each app uses Google Play services differently, it's up to you decide the appropriate
-place in your app to check verify the Google Play services version. For example, if Google Play
+place in your app to verify the Google Play services version. For example, if Google Play
services is required for your app at all times, you might want to do it when your app first
launches. On the other hand, if Google Play services is an optional part of your app, you can check
the version only once the user navigates to that portion of your app.</p>
-<p>To verify the Google Play services version, call <a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesUtil.html#isGooglePlayServicesAvailable(android.content.Context)"
->{@code isGooglePlayServicesAvailable()}</a>. If the result code is
+<p>You are strongly encouraged to use the
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">
+{@code GoogleApiClient}</a> class to access Google Play services features. This approach allows
+you to attach an
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.OnConnectionFailedListener.html">
+{@code OnConnectionFailedListener}</a> object to your client.
+To detect if the device has the appropriate version of the Google Play services APK, implement the
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">
+{@code onConnectionFailed()}</a>
+callback method. If the connection fails due to a missing or out-of-date version of
+the Google Play APK, the callback receives an error code such as
+<a href="{@docRoot}reference/com/google/android/gms/common/ConnectionResult.html#SERVICE_MISSING">
+{@code SERVICE_MISSING}</a>,
+<a href="{@docRoot}reference/com/google/android/gms/common/ConnectionResult.html#SERVICE_VERSION_UPDATE_REQUIRED">
+{@code SERVICE_VERSION_UPDATE_REQUIRED}</a>, or
+<a href="{@docRoot}reference/com/google/android/gms/common/ConnectionResult.html#SERVICE_DISABLED">
+{@code SERVICE_DISABLED}</a>. To learn more about how to build your client and handle such
+connection errors, see <a href="{@docRoot}google/auth/api-client.html">Accessing Google APIs</a>.
+</p>
+
+<p>Another approach is to use the
+<a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesUtil.html#isGooglePlayServicesAvailable(android.content.Context)"
+>{@code isGooglePlayServicesAvailable()}</a> method. You might call this method in the
+{@link android.app.Activity#onResume onResume()} method of the main activity. If the result code is
<a href="{@docRoot}reference/com/google/android/gms/common/ConnectionResult.html#SUCCESS"
>{@code SUCCESS}</a>,
then the Google Play services APK is up-to-date and you can continue to make a connection.
@@ -363,12 +386,11 @@ If, however, the result code is
>{@code SERVICE_VERSION_UPDATE_REQUIRED}</a>,
or
<a href="{@docRoot}reference/com/google/android/gms/common/ConnectionResult.html#SERVICE_DISABLED"
->{@code SERVICE_DISABLED}</a>, then the user needs to install an update. So,
- call <a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesUtil.html#getErrorDialog(int, android.app.Activity, int)"
- >{@code GooglePlayServicesUtil.getErrorDialog()}</a> and pass it the result error code.
-This returns a {@link android.app.Dialog} you should show, which provides an appropriate message
-about the error and provides an action
-that takes the user to Google Play Store to install the update.</p>
+>{@code SERVICE_DISABLED}</a>, then the user needs to install an update. In this case, call the
+<a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesUtil.html#getErrorDialog(int, android.app.Activity, int)">
+{@code getErrorDialog()}</a> method and pass it the result error code. The method returns a
+{@link android.app.Dialog} you should show, which provides an appropriate message about the error
+and provides an action that takes the user to Google Play Store to install the update.</p>
<p>To then begin a connection to Google Play services (required by most Google APIs such
diff --git a/docs/html/google/play-services/wallet.jd b/docs/html/google/play-services/wallet.jd
index 3d0c64a..744c8d3 100644
--- a/docs/html/google/play-services/wallet.jd
+++ b/docs/html/google/play-services/wallet.jd
@@ -17,14 +17,14 @@ header.hide=1
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
+ <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">
+<div class="col-4">
<img src="{@docRoot}images/google/gps-wallet-instant.png" alt="" style="padding-bottom:14px;width:210px">
</div>
</div>
@@ -44,16 +44,16 @@ header.hide=1
<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.
+ 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#getBillingAddress()">Get
+ href="{@docRoot}reference/com/google/android/gms/wallet/MaskedWallet.html#getBillingAddress()">Get
billing addresses</a>.</p>
</div>
@@ -75,7 +75,7 @@ header.hide=1
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
+ <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>
diff --git a/docs/html/google/play/billing/billing_integrate.jd b/docs/html/google/play/billing/billing_integrate.jd
index e3cacf9..eb58af4 100644
--- a/docs/html/google/play/billing/billing_integrate.jd
+++ b/docs/html/google/play/billing/billing_integrate.jd
@@ -34,7 +34,7 @@ page.tags="inapp, billing, iap"
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}training/in-app-billing/index.html">Selling In-app Products</a></li>
- </ol>
+ </ol>
</div>
</div>
@@ -42,26 +42,26 @@ page.tags="inapp, billing, iap"
<p class="note"><strong>Note:</strong> To see a complete implementation and learn how to test your application, see the <a href="{@docRoot}training/in-app-billing/index.html">Selling In-app Products</a> training class. The training class provides a complete sample In-app Billing application, including convenience classes to handle key tasks related to setting up your connection, sending billing requests and processing responses from Google Play, and managing background threading so that you can make In-app Billing calls from your main activity.</p>
-<p>Before you start, be sure that you read the <a href="{@docRoot}google/play/billing/billing_overview.html">In-app Billing Overview</a> to familiarize yourself with
+<p>Before you start, be sure that you read the <a href="{@docRoot}google/play/billing/billing_overview.html">In-app Billing Overview</a> to familiarize yourself with
concepts that will make it easier for you to implement In-app Billing.</p>
-<p>To implement In-app Billing in your application, you need to do the
+<p>To implement In-app Billing in your application, you need to do the
following:</p>
<ol>
<li>Add the In-app Billing library to your project.</li>
<li>Update your {@code AndroidManifest.xml} file.</li>
- <li>Create a {@code ServiceConnection} and bind it to
+ <li>Create a {@code ServiceConnection} and bind it to
{@code IInAppBillingService}.</li>
- <li>Send In-app Billing requests from your application to
+ <li>Send In-app Billing requests from your application to
{@code IInAppBillingService}.</li>
<li>Handle In-app Billing responses from Google Play.</li>
</ol>
<h2 id="billing-add-aidl">Adding the AIDL file to your project</h2>
-<p>{@code IInAppBillingService.aidl} is an Android Interface Definition
-Language (AIDL) file that defines the interface to the In-app Billing Version
-3 service. You will use this interface to make billing requests by invoking IPC
+<p>{@code IInAppBillingService.aidl} is an Android Interface Definition
+Language (AIDL) file that defines the interface to the In-app Billing Version
+3 service. You will use this interface to make billing requests by invoking IPC
method calls.</p>
<p>To get the AIDL file:</p>
<ol>
@@ -76,28 +76,28 @@ method calls.</p>
<ol>
<li>Copy the {@code IInAppBillingService.aidl} file to your Android project.
<ul>
- <li>If you are using Eclipse:
+ <li>If you are using Eclipse:
<ol type="a">
- <li>If you are starting from an existing Android project, open the project
-in Eclipse. If you are creating a new Android project from scratch, click
-<strong>File</strong> &gt; <strong>New</strong> &gt; <strong>Android Application
-Project</strong>, then follow the instructions in the <strong>New Android
+ <li>If you are starting from an existing Android project, open the project
+in Eclipse. If you are creating a new Android project from scratch, click
+<strong>File</strong> &gt; <strong>New</strong> &gt; <strong>Android Application
+Project</strong>, then follow the instructions in the <strong>New Android
Application</strong> wizard to create a new project in your workspace.</li>
- <li>In the {@code /src} directory, click <strong>File</strong> &gt;
+ <li>In the {@code /src} directory, click <strong>File</strong> &gt;
<strong>New</strong> &gt; <strong>Package</strong>, then create a package named {@code com.android.vending.billing}.</li>
- <li>Copy the {@code IInAppBillingService.aidl} file from {@code &lt;sdk&gt;/extras/google/play_billing/} and paste it into the {@code src/com.android.vending.billing/}
+ <li>Copy the {@code IInAppBillingService.aidl} file from {@code &lt;sdk&gt;/extras/google/play_billing/} and paste it into the {@code src/com.android.vending.billing/}
folder in your workspace.</li>
</ol>
</li>
- <li>If you are developing in a non-Eclipse environment: Create the following
-directory {@code /src/com/android/vending/billing} and copy the
-{@code IInAppBillingService.aidl} file into this directory. Put the AIDL file
+ <li>If you are developing in a non-Eclipse environment: Create the following
+directory {@code /src/com/android/vending/billing} and copy the
+{@code IInAppBillingService.aidl} file into this directory. Put the AIDL file
into your project and use the Ant tool to build your project so that the
<code>IInAppBillingService.java</code> file gets generated.</li>
</ul>
</li>
-<li>Build your application. You should see a generated file named
-{@code IInAppBillingService.java} in the {@code /gen} directory of your
+<li>Build your application. You should see a generated file named
+{@code IInAppBillingService.java} in the {@code /gen} directory of your
project.</li>
</ol>
@@ -135,7 +135,7 @@ ServiceConnection mServiceConn = new ServiceConnection() {
}
&#64;Override
- public void onServiceConnected(ComponentName name,
+ public void onServiceConnected(ComponentName name,
IBinder service) {
mService = IInAppBillingService.Stub.asInterface(service);
}
@@ -162,7 +162,7 @@ public void onDestroy() {
super.onDestroy();
if (mService != null) {
unbindService(mServiceConn);
- }
+ }
}
</pre>
@@ -185,13 +185,13 @@ querySkus.putStringArrayList(“ITEM_ID_LIST”, skuList);
</pre>
<p>To retrieve this information from Google Play, call the {@code getSkuDetails} method on the In-app Billing Version 3 API, and pass the method the In-app Billing API version (“3”), the package name of your calling app, the purchase type (“inapp”), and the {@link android.os.Bundle} that you created.</p>
<pre>
-Bundle skuDetails = mService.getSkuDetails(3,
+Bundle skuDetails = mService.getSkuDetails(3,
getPackageName(), "inapp", querySkus);
</pre>
<p>If the request is successful, the returned {@link android.os.Bundle}has a response code of {@code BILLING_RESPONSE_RESULT_OK} (0).</p>
<p class="note"><strong>Warning:</strong> Do not call the {@code getSkuDetails} method on the main thread. Calling this method triggers a network request which could block your main thread. Instead, create a separate thread and call the {@code getSkuDetails} method from inside that thread.</p>
-<p>To see all the possible response codes from Google Play, see <a href="{@docRoot}google/play/billing/billing_reference.html#billing-codes">In-app Billing Reference</a>.</p>
+<p>To see all the possible response codes from Google Play, see <a href="{@docRoot}google/play/billing/billing_reference.html#billing-codes">In-app Billing Reference</a>.</p>
<p>The query results are stored in a String ArrayList with key {@code DETAILS_LIST}. The purchase information is stored in the String in JSON format. To see the types of product detail information that are returned, see <a href="{@docRoot}google/play/billing/billing_reference.html#getSkuDetails">In-app Billing Reference</a>.</p>
@@ -201,7 +201,7 @@ int response = skuDetails.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList&lt;String&gt; responseList
= skuDetails.getStringArrayList("DETAILS_LIST");
-
+
for (String thisResponse : responseList) {
JSONObject object = new JSONObject(thisResponse);
String sku = object.getString("productId");
@@ -232,12 +232,12 @@ startIntentSenderForResult(pendingIntent.getIntentSender(),
1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
Integer.valueOf(0));
</pre>
-<p>Google Play sends a response to your {@link android.app.PendingIntent} to the {@link android.app.Activity#onActivityResult onActivityResult} method of your application. The {@link android.app.Activity#onActivityResult onActivityResult} method will have a result code of {@code Activity.RESULT_OK} (1) or {@code Activity.RESULT_CANCELED} (0). To see the types of order information that is returned in the response {@link android.content.Intent}, see <a href="{@docRoot}google/play/billing/billing_reference.html#getBuyIntent">In-app Billing Reference</a>.</p>
+<p>Google Play sends a response to your {@link android.app.PendingIntent} to the {@link android.app.Activity#onActivityResult onActivityResult} method of your application. The {@link android.app.Activity#onActivityResult onActivityResult} method will have a result code of {@code Activity.RESULT_OK} (1) or {@code Activity.RESULT_CANCELED} (0). To see the types of order information that is returned in the response {@link android.content.Intent}, see <a href="{@docRoot}google/play/billing/billing_reference.html#getBuyIntent">In-app Billing Reference</a>.</p>
<p>The purchase data for the order is a String in JSON format that is mapped to the {@code INAPP_PURCHASE_DATA} key in the response {@link android.content.Intent}, for example:
<pre>
-'{
- "orderId":"12999763169054705758.1371079406387615",
+'{
+ "orderId":"12999763169054705758.1371079406387615",
"packageName":"com.example.app",
"productId":"exampleSku",
"purchaseTime":1345678900000,
@@ -259,17 +259,17 @@ return the entire token.</p>
<p>Continuing from the previous example, you get the response code, purchase data, and signature from the response {@link android.content.Intent}.</p>
<pre>
&#64;Override
-protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == 1001) {
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == 1001) {
int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
-
+
if (resultCode == RESULT_OK) {
try {
JSONObject jo = new JSONObject(purchaseData);
String sku = jo.getString("productId");
- alert("You have bought the " + sku + ". Excellent choice,
+ alert("You have bought the " + sku + ". Excellent choice,
adventurer!");
}
catch (JSONException e) {
@@ -298,45 +298,45 @@ if (response == 0) {
ArrayList&lt;String&gt; purchaseDataList =
ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
ArrayList&lt;String&gt; signatureList =
- ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE");
- String continuationToken =
+ ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
+ String continuationToken =
ownedItems.getString("INAPP_CONTINUATION_TOKEN");
-
+
for (int i = 0; i < purchaseDataList.size(); ++i) {
String purchaseData = purchaseDataList.get(i);
String signature = signatureList.get(i);
String sku = ownedSkus.get(i);
-
+
// do something with this purchase information
// e.g. display the updated list of products owned by user
- }
+ }
- // if continuationToken != null, call getPurchases again
+ // if continuationToken != null, call getPurchases again
// and pass in the token to retrieve more items
}
</pre>
<h3 id="Consume">Consuming a Purchase</h3>
-<p>You can use the In-app Billing Version 3 API to track the ownership of
-purchased in-app products in Google Play. Once an in-app product is purchased,
-it is considered to be "owned" and cannot be purchased from Google Play. You
-must send a consumption request for the in-app product before Google Play makes
+<p>You can use the In-app Billing Version 3 API to track the ownership of
+purchased in-app products in Google Play. Once an in-app product is purchased,
+it is considered to be "owned" and cannot be purchased from Google Play. You
+must send a consumption request for the in-app product before Google Play makes
it available for purchase again.</p>
-<p class="caution"><strong>Important</strong>: Managed in-app products are
+<p class="caution"><strong>Important</strong>: Managed in-app products are
consumable, but subscriptions are not.</p>
-<p>How you use the consumption mechanism in your app is up to you. Typically,
-you would implement consumption for in-app products with temporary benefits that
-users may want to purchase multiple times (for example, in-game currency or
-equipment). You would typically not want to implement consumption for in-app
-products that are purchased once and provide a permanent effect (for example,
+<p>How you use the consumption mechanism in your app is up to you. Typically,
+you would implement consumption for in-app products with temporary benefits that
+users may want to purchase multiple times (for example, in-game currency or
+equipment). You would typically not want to implement consumption for in-app
+products that are purchased once and provide a permanent effect (for example,
a premium upgrade).</p>
-<p>To record a purchase consumption, send the {@code consumePurchase} method to
-the In-app Billing service and pass in the {@code purchaseToken} String value
-that identifies the purchase to be removed. The {@code purchaseToken} is part
-of the data returned in the {@code INAPP_PURCHASE_DATA} String by the Google
-Play service following a successful purchase request. In this example, you are
-recording the consumption of a product that is identified with the
+<p>To record a purchase consumption, send the {@code consumePurchase} method to
+the In-app Billing service and pass in the {@code purchaseToken} String value
+that identifies the purchase to be removed. The {@code purchaseToken} is part
+of the data returned in the {@code INAPP_PURCHASE_DATA} String by the Google
+Play service following a successful purchase request. In this example, you are
+recording the consumption of a product that is identified with the
{@code purchaseToken} in the {@code token} variable.</p>
<pre>
int response = mService.consumePurchase(3, getPackageName(), token);
@@ -346,10 +346,10 @@ int response = mService.consumePurchase(3, getPackageName(), token);
<p class="note"><strong>Security Recommendation:</strong> You must send a consumption request before provisioning the benefit of the consumable in-app purchase to the user. Make sure that you have received a successful consumption response from Google Play before you provision the item.</p>
<h3 id="Subs">Implementing Subscriptions</h3>
-<p>Launching a purchase flow for a subscription is similar to launching the
-purchase flow for a product, with the exception that the product type must be set
-to "subs". The purchase result is delivered to your Activity's
-{@link android.app.Activity#onActivityResult onActivityResult} method, exactly
+<p>Launching a purchase flow for a subscription is similar to launching the
+purchase flow for a product, with the exception that the product type must be set
+to "subs". The purchase result is delivered to your Activity's
+{@link android.app.Activity#onActivityResult onActivityResult} method, exactly
as in the case of in-app products.</p>
<pre>
Bundle bundle = mService.getBuyIntent(3, "com.example.myapp",
@@ -363,39 +363,39 @@ if (bundle.getInt(RESPONSE_CODE) == BILLING_RESPONSE_RESULT_OK) {
Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));
}
</pre>
-<p>To query for active subscriptions, use the {@code getPurchases} method, again
+<p>To query for active subscriptions, use the {@code getPurchases} method, again
with the product type parameter set to "subs".</p>
<pre>
Bundle activeSubs = mService.getPurchases(3, "com.example.myapp",
"subs", continueToken);
</pre>
-<p>The call returns a {@code Bundle} with all the active subscriptions owned by
-the user. Once a subscription expires without renewal, it will no longer appear
+<p>The call returns a {@code Bundle} with all the active subscriptions owned by
+the user. Once a subscription expires without renewal, it will no longer appear
in the returned {@code Bundle}.</p>
<h2 id="billing-security">Securing Your Application</h2>
-<p>To help ensure the integrity of the transaction information that is sent to
-your application, Google Play signs the JSON string that contains the response
-data for a purchase order. Google Play uses the private key that is associated
-with your application in the Developer Console to create this signature. The
+<p>To help ensure the integrity of the transaction information that is sent to
+your application, Google Play signs the JSON string that contains the response
+data for a purchase order. Google Play uses the private key that is associated
+with your application in the Developer Console to create this signature. The
Developer Console generates an RSA key pair for each application.<p>
-<p class="note"><strong>Note:</strong>To find the public key portion of this key
-pair, open your application's details in the Developer Console, then click on
-<strong>Services & APIs</strong>, and look at the field titled
+<p class="note"><strong>Note:</strong>To find the public key portion of this key
+pair, open your application's details in the Developer Console, then click on
+<strong>Services & APIs</strong>, and look at the field titled
<strong>Your License Key for This Application</strong>.</p>
-<p>The Base64-encoded RSA public key generated by Google Play is in binary
-encoded, X.509 subjectPublicKeyInfo DER SEQUENCE format. It is the same public
+<p>The Base64-encoded RSA public key generated by Google Play is in binary
+encoded, X.509 subjectPublicKeyInfo DER SEQUENCE format. It is the same public
key that is used with Google Play licensing.</p>
-<p>When your application receives this signed response you can
-use the public key portion of your RSA key pair to verify the signature.
-By performing signature verification you can detect responses that have
-been tampered with or that have been spoofed. You can perform this signature
-verification step in your application; however, if your application connects
-to a secure remote server then we recommend that you perform the signature
+<p>When your application receives this signed response you can
+use the public key portion of your RSA key pair to verify the signature.
+By performing signature verification you can detect responses that have
+been tampered with or that have been spoofed. You can perform this signature
+verification step in your application; however, if your application connects
+to a secure remote server then we recommend that you perform the signature
verification on that server.</p>
<p>For more information about best practices for security and design, see <a
diff --git a/docs/html/google/play/safetynet/index.jd b/docs/html/google/play/safetynet/index.jd
new file mode 100644
index 0000000..b728ca1
--- /dev/null
+++ b/docs/html/google/play/safetynet/index.jd
@@ -0,0 +1,82 @@
+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/google/play/safetynet/start.jd b/docs/html/google/play/safetynet/start.jd
new file mode 100644
index 0000000..8307928
--- /dev/null
+++ b/docs/html/google/play/safetynet/start.jd
@@ -0,0 +1,369 @@
+page.title=Getting Started with SafetyNet
+parent.title=SafetyNet for Android
+parent.link=index.html
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#tos">Additional Terms of Service</a></li>
+ <li><a href="#connect-play">Connect to Play Services</a></li>
+ <li><a href="#cts-check">Requesting a Compatibility Check</a>
+ <ol>
+ <li><a href="#single-use-token">Obtain Single Use Token</a></li>
+ <li><a href="#compat-check-request">Send Compatibility Check Request</a></li>
+ <li><a href="#compat-check-response">Read Compatibility Check Response</a></li>
+ <li><a href="#verify-compat-check">Verify Compatibility Check Response</a></li>
+ </ol>
+ </li>
+ </ol>
+
+</div>
+</div>
+
+<p>
+ SafetyNet provides services for analyzing the configuration of a particular device, to make sure
+ that apps function properly on a particular device and that users have a great experience.
+</p>
+
+<p>
+ The service provides an API your app can use to analyze the device where it is installed. The API
+ uses software and hardware information on the device where your app is installed to create a
+ profile of that device. The service then attempts to match it to a list of device models that
+ have passed Android compatibility testing. This check can help you decide if the device is
+ configured in a way that is consistent with the Android platform specifications and has the
+ capabilities to run your app.
+</p>
+
+<p>
+ This document shows you how to use SafetyNet for analyzing a device and help you determine if
+ your app will function as expected on that device.
+</p>
+
+<h2 id="tos">
+ Additional Terms of Service
+</h2>
+
+<p>
+ By accessing or using the SafetyNet APIs, you agree to the <a href=
+ "https://developers.google.com/terms/">Google APIs Terms of Service</a>, and to these Additional
+ Terms. Please read and understand all applicable terms and policies before accessing the APIs.
+</p>
+
+<div class="sdk-terms" onfocus="this.blur()" style="width:678px">
+<h3 class="norule">SafetyNet Terms of Service</h3>
+As with any data collected in large volume from in-the-field observation, there is a chance of
+both false positives and false negatives. We are presenting the data to the best of our
+understanding. We extensively test our detection mechanisms to ensure accuracy, and we are
+committed to improving those methods over time to ensure they continue to remain accurate.
+
+You agree to comply with all applicable law, regulation, and third party rights (including
+without limitation laws regarding the import or export of data or software, privacy, and local
+laws). You will not use the APIs to encourage or promote illegal activity or violation of third
+party rights. You will not violate any other terms of service with Google (or its affiliates).
+
+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.
+</div>
+
+<h2 id="connect-play">
+ Connect to Google Play Services
+</h2>
+
+<p>
+ The SafetyNet API is part of Google Play services. To connect to the API, you need to create an
+ instance of the Google Play services API client. For details about using the client in your app,
+ see <a href="{@docRoot}google/auth/api-client.html#Starting">Accessing Google
+ APIs</a>. Once you have established a connection to Google Play services, you can use the Google
+ API client classes to connect to the SafetyNet API.
+</p>
+
+<p>
+ To connect to the API, in your activity's <a href=
+ "{@docRoot}reference/android/app/Activity.html#onCreate(android.os.Bundle)">onCreate()</a>
+ method, create an instance of Google API Client using <a href=
+ "{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html">
+ {@code GoogleApiClient.Builder}</a>. Use the builder to add the SafetyNet API, as shown in the
+ following code example:
+</p>
+
+<pre>
+protected synchronized void buildGoogleApiClient() {
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .addApi(SafetyNet.API)
+ .addConnectionCallbacks(myMainActivity.this)
+ .build();
+}
+</pre>
+
+<p class="note">
+ <strong>Note:</strong> You can only call these methods after your app has established a connection to
+ Google Play services by receiving the <a href=
+ "{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">
+ {@code onConnected()}</a> callback. For details about listening for a completed client connection,
+ see <a href="{@docRoot}google/auth/api-client.html#Starting">Accessing Google APIs</a>.
+</p>
+
+<h2 id="cts-check">
+ Requesting a Compatibility Check
+</h2>
+
+<p>
+ A SafetyNet compatibility check allows your app to check if the device where it is running
+ matches the profile of a device that has passed Android compatibility testing. The compatibility
+ check creates a device profile by gathering information about the device hardware and software
+ characteristics, including the platform build.
+</p>
+
+<p>
+ Using the API to perform a check requires a few implementation steps in your app. Once you have
+ established a connection to Google Play services and requested the SafetyNet API from the Google
+ API client, your app can then perform the following steps to use the service:
+</p>
+
+<ul>
+ <li>Obtain a single use token
+ </li>
+
+ <li>Send the compatibility check request
+ </li>
+
+ <li>Read the response
+ </li>
+
+ <li>Validate the response
+ </li>
+</ul>
+
+<p>
+ For more information about Android compatibility testing, see <a href=
+ "https://source.android.com/compatibility/index.html" class="external-link">
+ Android Compatibility</a> and the <a href=
+ "https://source.android.com/compatibility/cts-intro.html" class="external-link">
+ Compatibility Testing Suite</a> (CTS).
+</p>
+
+<p>
+ SafetyNet checks use network resources, and so the speed of responses to requests can vary,
+ depending on a device's network connection status. The code described in this section should be
+ executed outside of your app's main execution thread, to avoid pauses and unresponsiveness in
+ your app user interface. For more information about using separate execution threads, see
+ <a href="{@docRoot}training/multiple-threads/index.html">Sending Operations
+ to Multiple Threads</a>.
+</p>
+
+<h3 id="single-use-token">
+ Obtain a single use token
+</h3>
+
+<p>
+ The SafetyNet API uses security techniques to help you verify the integrity of the communications
+ between your app and the service. When you request a compatibility check, you must provide a
+ single use token in the form of a number used once, or <em>nonce</em>, as part of your request. A
+ nonce is a random token generated in a cryptographically secure manner.
+</p>
+
+<p>
+ You can obtain a nonce by generating one within your app each time you make a compatibility check
+ request. As a more secure option, you can obtain a nonce from your own server, using a secure
+ connection.
+</p>
+
+<p>
+ A nonce used with a SafetyNet request should be at least 16 bytes in length. After you make a
+ check request, the response from the SafetyNet service includes your nonce, so you can verify it
+ against the one you sent. As the name indicates, you should only use a nonce value once, for a
+ single check request. Use a different nonce for any subsequent check requests. For tips on using
+ cryptography functions, see <a href=
+ "{@docRoot}training/articles/security-tips.html#Crypto">Security Tips</a>.
+</p>
+
+<h3 id="compat-check-request">
+ Send the compatibility check request
+</h3>
+
+<p>
+ After you have established a connection to Google Play services and created a nonce, you are
+ ready to make a compatibility check request. Since the response to your request may not be
+ immediate, you set up a callback listener to catch the response from the service, as shown in the
+ following code example:
+</p>
+
+<pre>
+byte[] nonce = getRequestNonce(); // Should be at least 16 bytes in length.
+SafetyNet.SafetyNetApi.attest(mGoogleApiClient, nonce)
+ .setResultCallback(new ResultCallback&lt;SafetyNetApi.AttestationResult&gt;() {
+
+ &#64;Override
+ public void onResult(SafetyNetApi.AttestationResult result) {
+ Status status = result.getStatus();
+ if (status.isSuccess()) {
+ // Indicates communication with the service was successful.
+ // result.getJwsResult() contains the result data
+ } else {
+ // An error occurred while communicating with the service
+ }
+ }
+});
+</pre>
+
+<p>
+ The <a href=
+ "{@docRoot}reference/com/google/android/gms/common/api/Status.html#isSuccess()">
+ {@code isSuccess()}</a>
+ method indicates whether or not communication with the service was successful, but does not
+ indicate if the device has passed the compatibility check. The next section discusses how to read
+ the check result and verify its integrity.
+</p>
+
+<h3 id="compat-check-response">
+ Read the compatibility check response
+</h3>
+
+<p>
+ When your app communicates with SafetyNet, the service provides a response containing the result
+ and additional information to help you verify the integrity of the message. The result is
+ provided as a <a href=
+ "{@docRoot}reference/com/google/android/gms/safetynet/SafetyNetApi.html">
+ {@code AttestationResult}</a>
+ object. Use the <a href=
+ "{@docRoot}reference/com/google/android/gms/safetynet/SafetyNetApi.AttestationResult.html#getJwsResult()">
+{@code getJwsResult()}</a> method of this object to obtain the data of the request. The response is
+ formatted as a <a href="https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-36" class="external-link">
+ JSON Web Signature</a> (JWS), the following JWS excerpt shows the format of the payload data:
+</p>
+
+<pre>
+{
+"nonce": "R2Rra24fVm5xa2Mg",
+"timestampMs": 9860437986543,
+"apkPackageName": "com.package.name.of.requesting.app",
+"apkCertificateDigestSha256": ["base64 encoded, SHA-256 hash of the
+certificate used to sign requesting app"],
+"apkDigestSha256": "base64 encoded, SHA-256 hash of the app's APK",
+"ctsProfileMatch": true,
+}
+</pre>
+
+<p>
+ If the value of {@code ctsProfileMatch} is {@code true}, this indicates that the device
+ profile matches a device that has passed Android compatibility testing. If the output of the
+ <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.
+</p>
+
+<h3 id="verify-compat-check">
+ Verify the compatibility check response
+</h3>
+
+<p>
+ You should take steps to make sure the response received by your app actually came from the
+ SafetyNet service and matches the request data you provided. Follow these steps to verify the
+ origin of the JWS message:
+</p>
+
+<ul>
+ <li>Extract the SSL certificate chain from the JWS message.
+ </li>
+
+ <li>Validate the SSL certificate chain and use SSL hostname matching to verify that the leaf
+ certificate was issued to the hostname {@code attest.android.com}.
+ </li>
+
+ <li>Use the certificate to verify the signature of the JWS message.
+ </li>
+</ul>
+
+<p>
+ After completing this validation, you should also check the data of the JWS message to make sure
+ it matches your original request, including the nonce, timestamp, package name, and the SHA-256
+ hashes. You can perform these validation steps within your app, or as a more secure option, send
+ the entire JWS response to your own server for verification, via a secure connection.
+</p>
+
+<h4>
+ Validating the response with Google APIs
+</h4>
+
+<p>
+ Google provides an Android Device Verification API for validating the output of the SafetyNet
+ compatibility check. This API performs a validation check on the JWS message returned from the
+ SafetyNet service.
+</p>
+
+<p>
+ To enable access to the Android Device Verification API:
+</p>
+
+<ol>
+ <li>Go to the <a href="https://console.developers.google.com/" class="external-link">
+ Google Developers Console</a>.
+ </li>
+
+ <li>Select a project, or create a new one.
+ </li>
+
+ <li>In the sidebar on the left, expand <strong>APIs &amp; auth</strong>.
+ Next, click <strong>APIs</strong>. In the
+ list of APIs, make sure all of the APIs you are using show a status of <strong>ON</strong>.
+ </li>
+
+ <li>In the <strong>Browse APIs</strong> list, find the
+ <strong>Android Device Verification API</strong> and turn it
+ on.
+ </li>
+
+ <li>Obtain your API key by expanding <strong>APIs &amp; auth</strong> and
+ clicking <strong>Credentials</strong>.
+ Record the <strong>API KEY</strong> value on this page for later use.
+ </li>
+</ol>
+
+<p>
+ After enabling this API for your project, you can call the verification service from your app or
+ server. You need the contents of the JWS message from the SafetyNet API and your API key to call
+ the verification API and get a result.
+</p>
+
+<p>
+ To use the Android Device Verification API:
+</p>
+
+<ol>
+ <li>Create a JSON message containing the entire contents of the JWS message in the following
+ format:
+<pre>
+{ "signedAttestation": "&lt;output of getJwsResult()&gt;" }
+</pre>
+ </li>
+
+ <li>Use an HTTP POST request to send the message with a Content-Type of {@code "application/json"}
+ to the following URL:
+<pre>
+https&#58;&#47;&#47;www.googleapis.com/androidcheck/v1/attestations/verify?key=&lt;your API key&gt;
+</pre>
+ </li>
+
+ <li>The service validates the integrity of the message, and if the message is valid, it returns a
+ JSON message with the following contents:
+
+<pre>
+{ “isValidSignature”: true }
+</pre>
+ </li>
+</ol>
+
+<p>
+ <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.
+</p> \ No newline at end of file