diff options
Diffstat (limited to 'docs/html/google')
-rw-r--r-- | docs/html/google/auth/api-client.jd | 2 | ||||
-rw-r--r-- | docs/html/google/gcm/ccs.jd | 149 | ||||
-rw-r--r-- | docs/html/google/gcm/client.jd | 3 | ||||
-rw-r--r-- | docs/html/google/gcm/gcm.jd | 2 | ||||
-rw-r--r-- | docs/html/google/gcm/index.jd | 39 | ||||
-rw-r--r-- | docs/html/google/gcm/notifications.jd | 129 | ||||
-rw-r--r-- | docs/html/google/gcm/server.jd | 3 | ||||
-rw-r--r-- | docs/html/google/gcs/gcs-signup.jd | 10 | ||||
-rw-r--r-- | docs/html/google/gcs/index.jd | 30 | ||||
-rw-r--r-- | docs/html/google/google_toc.cs | 8 | ||||
-rw-r--r-- | docs/html/google/index.jd | 10 | ||||
-rw-r--r-- | docs/html/google/play-services/games.jd | 1 | ||||
-rw-r--r-- | docs/html/google/play-services/index.jd | 6 | ||||
-rw-r--r-- | docs/html/google/play-services/setup.jd | 102 | ||||
-rw-r--r-- | docs/html/google/play/billing/billing_admin.jd | 10 | ||||
-rw-r--r-- | docs/html/google/play/billing/billing_testing.jd | 131 | ||||
-rw-r--r-- | docs/html/google/play/billing/v2/billing_integrate.jd | 19 | ||||
-rw-r--r-- | docs/html/google/play/expansion-files.jd | 78 | ||||
-rw-r--r-- | docs/html/google/play/licensing/licensing-reference.jd | 23 | ||||
-rw-r--r-- | docs/html/google/play/licensing/overview.jd | 17 |
20 files changed, 487 insertions, 285 deletions
diff --git a/docs/html/google/auth/api-client.jd b/docs/html/google/auth/api-client.jd index 402a95f..5331d1e 100644 --- a/docs/html/google/auth/api-client.jd +++ b/docs/html/google/auth/api-client.jd @@ -1,4 +1,4 @@ -page.title=Accessing Google Play Services APIs +page.title=Accessing Google APIs page.tags="oauth 2.0","GoogleAuthUtil" trainingnavtop=true diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd index 03addfd..4389e3d 100644 --- a/docs/html/google/gcm/ccs.jd +++ b/docs/html/google/gcm/ccs.jd @@ -19,7 +19,11 @@ page.title=GCM Cloud Connection Server (XMPP) <li><a href="#response">Response format</a></li> </ol> </li> - <li><a href="#upstream">Upstream Messages</a> </li> + <li><a href="#upstream">Upstream Messages</a> + <ol> + <li><a href="#receipts">Receive return receipts</a></li> + </ol> + </li> <li><a href="#flow">Flow Control</a> </li> <li><a href="#implement">Implementing an XMPP-based App Server</a> <ol class="toc"> @@ -43,9 +47,6 @@ target="_android">CCS and User Notifications Signup Form</a></li> </div> </div> -<p class="note"><strong>Note:</strong> To try out this feature, sign up using -<a href="https://services.google.com/fb/forms/gcm/">this form</a>.</p> - <p>The 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 @@ -149,8 +150,8 @@ exceptions:</p> <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, but -always present.</li> +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 @@ -188,7 +189,8 @@ parameters and which connection server(s) supports them.</p> "hello":"world", } "time_to_live":"600", - "delay_while_idle": true/false + "delay_while_idle": true/false, + "delivery_receipt_requested": true/false } </gcm> </message> @@ -227,42 +229,48 @@ message is "nack". A NACK message contains:</p> <p>Below are some examples.</p> <p>Bad registration:</p> + <pre><message> - <data:gcm xmlns:data="google:mobile:data"> + <gcm xmlns="google:mobile:data"> { - "error":"BAD_REGISTRATION", // error code + "message_type":"nack", "message_id":"msgId1", - "from":"PA91bHFOtaQGSwupt5l1og", - "message_type":"nack" + "from":"SomeInvalidRegistrationId", + "error":"BAD_REGISTRATION", + "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId" } - </data:gcm> + </gcm> </message></pre> -<p>Invalid "time to live":</p> +<p>Invalid JSON:</p> <pre><message> - <data:gcm xmlns:data="google:mobile:data"> - { - "error":"InvalidJson : INVALID_TTL : Invalid value (-1) for \"time_to_live\": must be between 0 and \"2419200\"\n", - "message_id":"msgId1", - "from":"APA91bHFOtaQGSwupt5l1og", - "message_type":"nack" - } - </data:gcm> -</message></pre> + <gcm xmlns="google:mobile:data"> + { + "message_type":"nack", + "message_id":"msgId1", + "from":"APA91bHFOtaQGSwupt5l1og", + "error":"INVALID_JSON", + "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc" + } + </gcm> +</message> +</pre> -<p>JSON type error:</p> +<p>Quota exceeded:</p> <pre><message> - <data:gcm xmlns:data="google:mobile:data"> - { - "error":"InvalidJson : JSON_TYPE_ERROR : Field \"delay_while_idle\" must be a JSON java.lang.Boolean: not-boolean-user-supplied-value\n", - "message_id":"msgId1", - "from":"APA91bHFOtaQGSwupt5l1og", - "message_type":"nack" - } - </data:gcm> -</message></pre> + <gcm xmlns="google:mobile:data"> + { + "message_type":"nack", + "message_id":"msgId1", + "from":"APA91bHFOtaQGSwupt5l1og", + "error":"QUOTA_EXCEEDED", + "error_description":"Short-term downstream quota exceeded for this registration id" + } + </gcm> +</message> +</pre> <p>The following table lists NACK error codes. Unless otherwise @@ -300,7 +308,7 @@ message should be immediately retried over another connection.</td> </tr> <tr> <td>{@code INVALID_JSON}</td> -<td>The JSON message payload was not valid.</td> +<td>The JSON message payload is not valid.</td> </tr> <tr> <td>{@code QUOTA_EXCEEDED}</td> @@ -309,10 +317,10 @@ sender/device pair) is too high. If you want to retry the message, try using a s rate.</td> </tr> <tr> -<td>{@code SERVICE_UNAVAILABLE}</td> -<td>CCS is not currently able to process the message. The -message should be retried over the same connection using exponential backoff -with an initial delay of 1 second.</td> + <td>{@code SERVICE_UNAVAILABLE}</td> + <td>CCS is not currently able to process the message. The + message should be retried over the same connection using exponential backoff + with an initial delay of 1 second.</td> </tr> </table> @@ -382,8 +390,8 @@ 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 4 weeks. -int ttl = [0 seconds, 4 weeks] +// This is optional. It specifies a value in seconds up to 24 hours. +int ttl = [0 seconds, 24 hours] gcm.send(GCM_SENDER_ID + "@gcm.googleapis.com", id, ttl, data); </pre> @@ -419,6 +427,69 @@ response to the above message:</p> </gcm> </message></pre> +<h3 id="receipts">Receive return receipts</h3> + +<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.</p> + +<p>To enable this feature, the message your 3rd-party app server sends to CCS must include +a field called <code>"delivery_receipt_requested"</code>. When this field is set to +<code>true</code>, CCS sends a return receipt. Here is an XMPP stanza containing a JSON +message with <code>"delivery_receipt_requested"</code> set to <code>true</code>:</p> + +<pre><message id=""> + <gcm xmlns="google:mobile:data"> + { + "to":"REGISTRATION_ID", + "message_id":"m-1366082849205" + "data": + { + "hello":"world", + } + "time_to_live":"600", + "delay_while_idle": true, + <strong>"delivery_receipt_requested": true</strong> + } + </gcm> +</message> +</pre> + +<p>Here is an example of a receipt notification message that CCS sends back to your 3rd-party +app server:</p> + +</p> +<pre><message id=""> + <gcm xmlns="google:mobile:data"> + { + "category":"com.example.yourapp", // to know which app sent it + "data": + { + “message_status":"MESSAGE_SENT_TO_DEVICE", + “original_message_id”:”m-1366082849205” + “device_registration_id”: “REGISTRATION_ID” + }, + "message_id":"dr2:m-1366082849205", + "message_type":"receipt", + "from":"gcm.googleapis.com" + } + </gcm> +</message></pre> + +<p>Note the following:</p> + +<ul> + <li>The {@code "message_type"} is set to {@code "receipt"}. + <li>The {@code "message_status"} is set to {@code "MESSAGE_SENT_TO_DEVICE"}, + indicating that the message was delivered. Notice that in this case, +{@code "message_status"} 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>dr:</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 and status are inside the +{@code "data"} field.</li> +</ul> + <h2 id="flow">Flow Control</h2> <p>Every message sent to CCS receives either an ACK or a NACK response. Messages diff --git a/docs/html/google/gcm/client.jd b/docs/html/google/gcm/client.jd index ac446dc..20bff10 100644 --- a/docs/html/google/gcm/client.jd +++ b/docs/html/google/gcm/client.jd @@ -246,7 +246,8 @@ private boolean checkPlayServices() { <h3 id="sample-register">Register for GCM</h3> <p>An Android application needs to register with GCM servers before it can receive messages. When an app registers, it receives a registration ID, which it can then -store for future use. In the following snippet the {@code onCreate()} method in the sample app's +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> diff --git a/docs/html/google/gcm/gcm.jd b/docs/html/google/gcm/gcm.jd index 88bf659..19151b9 100644 --- a/docs/html/google/gcm/gcm.jd +++ b/docs/html/google/gcm/gcm.jd @@ -123,7 +123,7 @@ it to receive messages. Once the Android application has the registration ID, it it to the 3rd-party application server, which uses it to identify each device that has registered to receive messages for a given Android application. In other words, a registration ID is tied to a particular Android application running on a particular -device. +device. Note that registration IDs must be kept secret. <br/> <br/> <strong>Note:</strong> If you use diff --git a/docs/html/google/gcm/index.jd b/docs/html/google/gcm/index.jd index 70f7a9c..56e0865 100644 --- a/docs/html/google/gcm/index.jd +++ b/docs/html/google/gcm/index.jd @@ -14,7 +14,10 @@ header.hide=1 <h1 itemprop="name" style="margin-bottom:0;">Google Cloud Messaging for Android</h1> <p itemprop="description"> Google Cloud Messaging for Android (GCM) 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. GCM is completely free no matter how big your messaging needs are, and there are no quotas. +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. GCM is +completely free no matter how big your messaging needs are, and there are no quotas. </p> </div> @@ -27,31 +30,39 @@ from your server to your users' Android-powered device, and also to receive mess <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> +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">Send-to-sync messages</a>.</p> - </a> + <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 »</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">Messages with payload</a>.</p> + <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 »</a></p> </div> <div class="col-6 normal-links"> <h3 style="clear:left">New Features</h3> - <h4>Faster, easier GCM setup</h4> - <p>Streamlined registration makes it simple and fast to add GCM support to your Android app. <a href="{@docRoot}google/gcm/gs.html">Learn more »</a></p> - <h4>Upstream messaging over XMPP</h4> - <p>GCM's Cloud Connection Service (CCS) lets you communicate with Android devices over a persistent XMPP connection. The primary advantages of CCS are speed, and the ability to receive upstream messages (that is, messages from a device to the cloud). You can use the service in tandem with existing GCM APIs. Use <a href="https://services.google.com/fb/forms/gcm/">this form</a> to sign up for CCS. <a href="{@docRoot}google/gcm/ccs.html">Learn more »</a></p> - <h4>Seamless multi-device messaging</h4> - <p>Maps a single user to a notification key, which you can then use to send a single message to multiple devices owned by the user. Use <a href="https://services.google.com/fb/forms/gcm/">this form</a> to sign up for User Notifications. <a href="{@docRoot}google/gcm/notifications.html">Learn more »</a></p> + + + <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 »</a></p> + <h4>Get Started</h4> - <p>Get started using the new features with a tutorial that walks you through creating a GCM app. <a href="{@docRoot}google/gcm/gs.html">Learn more »</a></p> + <p>Get started with a tutorial that walks you through creating a GCM app. + <a href="{@docRoot}google/gcm/gs.html">Learn more »</a></p> </div> </div> diff --git a/docs/html/google/gcm/notifications.jd b/docs/html/google/gcm/notifications.jd index 43a7368..2815f3d 100644 --- a/docs/html/google/gcm/notifications.jd +++ b/docs/html/google/gcm/notifications.jd @@ -14,8 +14,8 @@ page.title=User Notifications <h2>In this document</h2> <ol class="toc"> - <li><a href="#request">Request Format</a></li> - <li><a href="#create">Generate a Notification Key</a></li> + <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> @@ -31,15 +31,11 @@ page.title=User Notifications <ol class="toc"> <li><a href="{@docRoot}google/gcm/gs.html">Getting Started</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 class="note"><strong>Note:</strong> To try out this feature, sign up using <a href="https://services.google.com/fb/forms/gcm/">this form</a>.</p> - - <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 @@ -76,27 +72,23 @@ and then reconciling it with the corresponding notification. <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="request">Request Format</h2> -<p>To send a message, the application server issues a POST request to -<code>https://android.googleapis.com/gcm/notification</code>.</p> +<h2 id="gen-server">Generate a Notification Key on the Server</h2> -<p>Here is the HTTP request header you should use for all create/add/remove operations:</p> - -<pre>content-type: "application/json" -Header : "project_id": <projectID> -Header: "Authorization", "key=API_KEY" -</pre> - -<h2 id="create">Generate a Notification Key</h2> +<p>To generate a notification key on the server, you create a new +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 (can be a username for +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 @@ -116,10 +108,109 @@ to use in subsequent operations:</p> "registration_ids": ["4", "8", "15", "16", "23", "42"] }</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": <projectID> +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 & AUTH > 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 > 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("com.google"); + 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 = "audience:server:client_id:" + + "1262xxx48712-9qs6n32447mcj9dirtnkyrejt82saa52.apps.googleusercontent.com"; +String id_token = null; +try { + id_token = GoogleAuthUtil.getToken(context, accountName, scope); +} catch (Exception e) { + log("exception while getting id_token: " + 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: +{ + "operation": "add", + "notification_key_name": "appUser-Chris", + "registration_ids": ["4"] + "id_token": "id_token" +}</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": <projectID> +</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 10.</p> +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 diff --git a/docs/html/google/gcm/server.jd b/docs/html/google/gcm/server.jd index ccd1267..e3a6b25 100644 --- a/docs/html/google/gcm/server.jd +++ b/docs/html/google/gcm/server.jd @@ -120,7 +120,8 @@ have an application server that meets the following criteria:</p> <li>Able to store the API key and client registration IDs. The API key is included in the header of POST requests that send messages.</li> - <li>Able to generate message IDs to uniquely identify each message it sends.</li> + <li>Able to generate message IDs to uniquely identify each message it sends. Message IDs +should be unique per sender ID.</li> </ul> <h2 id="send-msg">Sending Messages</h2> diff --git a/docs/html/google/gcs/gcs-signup.jd b/docs/html/google/gcs/gcs-signup.jd new file mode 100644 index 0000000..7334cec --- /dev/null +++ b/docs/html/google/gcs/gcs-signup.jd @@ -0,0 +1,10 @@ +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 new file mode 100644 index 0000000..e5f4776 --- /dev/null +++ b/docs/html/google/gcs/index.jd @@ -0,0 +1,30 @@ +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/google_toc.cs b/docs/html/google/google_toc.cs index 6ff00c0..b4028bd 100644 --- a/docs/html/google/google_toc.cs +++ b/docs/html/google/google_toc.cs @@ -3,11 +3,11 @@ ######## ATTENTION ############### ######## ############### ######################################################### - + IF YOU MAKE CHANGES TO THIS FILE, YOU MUST GENERATE THE GMS REFERENCE DOCS, BECAUSE THEY ARE NOT INCLUDED IN THE DOCS BUILD RULE. - + ######################################################### ######################################################### ?> @@ -73,11 +73,11 @@ </div> <ul> <li><a href="<?cs var:toroot?>google/play-services/setup.html"> - <span class="en">Setup</span></a> + <span class="en">Setting Up Google Play Services</span></a> </li> <li class="nav-section"> <div class="nav-section-header"><a href="<?cs var:toroot?>google/auth/api-client.html"> - <span class="en">Accessing Google Play Services APIs</span></a> + <span class="en">Accessing Google APIs</span></a> </div> <ul> <li> diff --git a/docs/html/google/index.jd b/docs/html/google/index.jd index 2e97d62..4778a85 100644 --- a/docs/html/google/index.jd +++ b/docs/html/google/index.jd @@ -89,6 +89,16 @@ cloud messaging.</p> to use Google Cloud Messaging.</p> </div> +<div class="landing-cell"> + <div class="cell-icon"> + <img src="{@docRoot}images/google/gcs-small.png" width="40" > + </div> + <h4><a href="{@docRoot}google/gcs/index.html" + >Google Cloud Save</a></h4> + <p>Enable per-user data storage and sync in your apps with no backend programming + required.</p> +</div> + </div><!-- col-6 --> diff --git a/docs/html/google/play-services/games.jd b/docs/html/google/play-services/games.jd index 94f6715..a73f688 100644 --- a/docs/html/google/play-services/games.jd +++ b/docs/html/google/play-services/games.jd @@ -1,4 +1,5 @@ page.title=Google Play Game Services +page.tags="games" header.hide=1 @jd:body diff --git a/docs/html/google/play-services/index.jd b/docs/html/google/play-services/index.jd index f5d4574..eec4f5a 100644 --- a/docs/html/google/play-services/index.jd +++ b/docs/html/google/play-services/index.jd @@ -11,10 +11,8 @@ header.hide=1 <div class="col-6"> <h1 itemprop="name" style="margin-bottom:0;">Google Play Services</h1> - <p itemprop="description"> - </p> - - <p>Give your apps more features to attract users on a wider range of devices. + <p itemprop="description">Give your apps more features to attract users + on a wider range of devices. With Google Play services, your app can take advantage of the latest, Google-powered features such as Maps, Google+, and more, with automatic platform updates distributed as an APK through diff --git a/docs/html/google/play-services/setup.jd b/docs/html/google/play-services/setup.jd index d502e8d..4332953 100644 --- a/docs/html/google/play-services/setup.jd +++ b/docs/html/google/play-services/setup.jd @@ -1,4 +1,4 @@ -page.title=Set Up Google Play Services SDK +page.title=Setting Up Google Play Services @jd:body @@ -8,8 +8,7 @@ page.title=Set Up Google Play Services SDK <h2>In this document</h2> <ol> - <li><a href="#Install">Install the Google Play Services SDK</a></li> - <li><a href="#Setup">Set Up a Project that Uses Google Play Services</a></li> + <li><a href="#Setup">Add Google Play Services to Your Project</a></li> <li><a href="#Proguard">Create a Proguard Exception</a></li> <li><a href="#ensure">Ensure Devices Have the Google Play services APK</a></li> </ol> @@ -18,12 +17,17 @@ page.title=Set Up Google Play Services SDK </div> </div> +<script> +$(document).ready(function() { + setupIdeDocToggle(); +}); +</script> + - <p>To develop an app using the <a href="{@docRoot}reference/gms-packages.html">Google -Play services APIs</a>, you must download the Google Play services SDK -from the <a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a>. -The download includes the client library and code samples.</p> +Play services APIs</a>, you need to set up your project with the Google Play services SDK. +<p>If you haven't installed the Google Play services SDK yet, go get it now by following the guide +to <a href="{@docRoot}sdk/installing/adding-packages.html">Adding SDK Packages</a>.</p> <p>To test your app when using the Google Play services SDK, you must use either:</p> <ul> @@ -33,69 +37,28 @@ The download includes the client library and code samples.</p> that runs the Google APIs platform based on Android 4.2.2 or higher.</li> </ul> -<p>Ideally, you should develop and test your app on a variety of devices, including -both phones and tablets.</p> - - -<h2 id="Install">Install the Google Play Services SDK</h2> - -<p>To install the Google Play services SDK for development:</p> -<ol> - <li>Launch the SDK Manager in one of the following ways: - <ul> - <li>In Android Studio, click <strong>SDK Manager</strong> -<img src="{@docRoot}images/tools/sdk-manager-studio.png" style="vertical-align:bottom;margin:0;height:19px" /> -in the toolbar.</li> - <li>In Eclipse (with <a href="{@docRoot}tools/help/adt.html">ADT</a>), - select <strong>Window</strong> > <strong>Android SDK Manager</strong>.</li> - <li>On Windows, double-click the <code>SDK Manager.exe</code> file at the root of the Android - SDK directory.</li> - <li>On Mac or Linux, open a terminal and navigate to the <code>tools/</code> directory in the - Android SDK, then execute <code>android sdk</code>.</li> - </ul> - </li> - <li>Install the Google Play services SDK. - <p>Scroll to the bottom of the package list, expand <b>Extras</b>, select - <b>Google Play services</b>, and install it. If you're using Android Studio, also install - <b>Google Repository</b> (it provides the Maven repository used for Gradle builds).</p> - <p>The Google Play services SDK is saved in your Android SDK environment at - <code><android-sdk>/extras/google/google_play_services/</code>.</p> - -<p class="note"><strong>Note:</strong> Google Play services 4.0.30 (released -November 2013) and newer versions require Android 2.3 or higher. If your app supports Android 2.2, -you can continue development with the Google Play services SDK, but must instead install -<b>Google Play services for Froyo</b> from the SDK Manager.</p> - - </li> - <li>Install a compatible version of the Google APIs platform. - <p>If you want to test your app on the emulator, expand the directory for <b>Android 4.2.2 - (API 17)</b> or a higher version, select <b>Google APIs</b>, and install it. Then create a - new <a href="{@docRoot}tools/devices/index.html">AVD</a> with Google APIs as - the platform target.</p> - </li> - <li>Make a copy of the Google Play services library project. - <p class="note"><strong>Note:</strong> If you are using Android Studio, skip this step.</p> - <p>Copy the library project at - <code><android-sdk>/extras/google/google_play_services/libproject/google-play-services_lib/</code> - to the location where you maintain your Android app projects. - <p>If you are using Eclipse, import the library project into your 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.</p> - </li> -</ol> +<h2 id="Setup">Add Google Play Services to Your Project</h2> +<p> +<select class="ide"> + <option value="eclipse">Using Eclipse with ADT</option> + <option value="studio">Using Android Studio</option> + <option value="other">Using something else</option> +</select> +</p> -<h2 id="Setup">Set Up a Project that Uses Google Play Services</h2> -<p><b>Using Android Studio:</b></p> +<div class="select-ide studio"> <ol> - <li>Open the <code>build.gradle</code> file inside your application module directory. - <p class="note"><strong>Note:</strong> Android Studio projects contain a top-level - <code>build.gradle</code> file and a <code>build.gradle</code> file for each module. - Be sure to edit the file for your application module.</p></li> + <li>Open the <code>build.gradle</code> file inside your application module directory. + <p class="note"><strong>Note:</strong> Android Studio projects contain a top-level + <code>build.gradle</code> file and a <code>build.gradle</code> file for each module. + Be sure to edit the file for your application module. See + <a href="{@docRoot}sdk/installing/studio-build.html">Building Your Project with + Gradle</a> for more information about Gradle.</p></li> <li>Add a new build rule under <code>dependencies</code> for the latest version of <code>play-services</code>. For example: <pre class="no-pretty-print"> @@ -126,8 +89,11 @@ element: <p>You can now begin developing features with the <a href="{@docRoot}reference/gms-packages.html">Google Play services APIs</a>.</p> +</div><!-- end studio --> -<p><b>Using Eclipse or another IDE:</b></p> + + +<div class="select-ide eclipse other"> <p>To make the Google Play services APIs available to your app, you must reference the library project you created in step 4 of the <a href="#Install">installation instructions</a>.</p> @@ -154,6 +120,9 @@ element: you can begin developing features with the <a href="{@docRoot}reference/gms-packages.html">Google Play services APIs</a>.</p> +</div><!-- end eclipse and other --> + + <h2 id="Proguard">Create a Proguard Exception</h2> @@ -234,5 +203,6 @@ 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, read <a -href="{@docRoot}google/auth/api-client.html">Accessing Google Play Services APIs</a>.</p> +<p>To then begin a connection to Google Play services (required by most Google APIs such +as Google Drive, Google+, and Games), read <a +href="{@docRoot}google/auth/api-client.html">Accessing Google APIs</a>.</p> diff --git a/docs/html/google/play/billing/billing_admin.jd b/docs/html/google/play/billing/billing_admin.jd index 46ad905..5904b03 100644 --- a/docs/html/google/play/billing/billing_admin.jd +++ b/docs/html/google/play/billing/billing_admin.jd @@ -66,7 +66,8 @@ storing and delivering the digital content that you sell in your applications.</ </p> </div> -<p>You can create a product list for any published application or any draft application that's been +<p>You can create a product list for any published application, or any +application in the alpha or beta channels, that's been uploaded and saved to the Developer Console. However, you must have a Google Wallet merchant account and the application's manifest must include the <code>com.android.vending.BILLING</code> permission. If an application's manifest does not include this permission, you will be able to edit @@ -75,6 +76,13 @@ information about this permission, see <a href="{@docRoot}google/play/billing/billing_integrate.html#billing-permission">Updating Your Application's Manifest</a>.</p> +<p class="note"><strong>Note:</strong> Previously you could test an app by +uploading an unpublished "draft" version. This functionality is no longer +supported; instead, you must publish it to the alpha or beta distribution +channel. For more information, see <a +href="{@docRoot}google/play/billing/billing_testing.html#draft_apps">Draft Apps +are No Longer Supported</a>. + <p>In addition, an application package can have only one product list. If you create a product list for an application, and you use the <a href="{@docRoot}google/play/publishing/multiple-apks.html">multiple APK feature</a> to distribute diff --git a/docs/html/google/play/billing/billing_testing.jd b/docs/html/google/play/billing/billing_testing.jd index df6c657..8a49433 100644 --- a/docs/html/google/play/billing/billing_testing.jd +++ b/docs/html/google/play/billing/billing_testing.jd @@ -8,8 +8,9 @@ parent.link=index.html <h2>In this document</h2> <ol> <li><a href="#testing-purchases">Testing In-app Purchases</a></li> - <li><a href="#billing-testing-static">Testing with static responses</a></li> + <li><a href="#billing-testing-static">Testing with Static Responses</a></li> <li><a href="#billing-testing-real">Setting Up for Test Purchases</a></li> + <li><a href="#draft_apps">Draft Apps are No Longer Supported</a></li> </ol> <h2>See also</h2> <ol> @@ -79,8 +80,7 @@ method).</p> <p>First, upload and publish in-app products that you want testers to be able to purchase. You can upload and publish in-app products in the Developer Console. Note that you can upload and publish your in-app items before you publish the -APK itself. For example, you can publish your in-app items while your APK is -still a draft. </p> +APK itself.</p> <p>Next, create license test accounts for authorized users. In the Developer Console, go to <strong>Settings</strong> > <strong>Account details</strong>, @@ -149,11 +149,12 @@ license accounts in your alpha and beta distribution groups, those users will only be able to make test purchases. </p> -<h2 id="billing-testing-static">Testing with static responses</h2> +<h2 id="billing-testing-static">Testing with Static Responses</h2> <p>We recommend that you first test your In-app Billing implementation using static responses from Google Play. This enables you to verify that your application is handling the primary Google -Play responses correctly and that your application is able to verify signatures correctly.</p> +Play responses correctly and that your application is able to verify signatures correctly. You can do this +even if the app hasn't been published yet.</p> <p>To test your implementation with static responses, you make an In-app Billing request using a special item that has a reserved product ID. Each reserved product ID returns a specific static @@ -173,6 +174,12 @@ the Developer Console to perform static response tests with the reserved product install your application on a device, log into the device, and make billing requests using the reserved product IDs.</p> +<p class="note"><strong>Note:</strong> Previously you could test an app by +uploading an unpublished "draft" version. This functionality is no longer +supported. However, you can test your app with static responses even before you +upload it to the Google Play store. For more information, see <a +href="#draft_apps">Draft Apps are No Longer Supported</a>. + <p>There are four reserved product IDs for testing static In-app Billing responses:</p> <ul> @@ -205,67 +212,12 @@ Pricing</a>.</p> </li> </ul> -<p>In some cases, the reserved items may return signed static responses, which lets you test -signature verification in your application. To test signature verification with the special reserved -product IDs, you may need to set up <a -href="{@docRoot}google/play/billing/billing_admin.html#billing-testing-setup">test accounts</a> or -upload your application as a unpublished draft application. Table 1 shows you the conditions under -which static responses are signed.</p> - -<p class="table-caption" id="static-responses-table"><strong>Table 1.</strong> -Conditions under which static responses are signed.</p> - -<table> -<tr> -<th>Application ever been published?</th> -<th>Draft application uploaded and unpublished?</th> -<th>User who is running the application</th> -<th>Static response signature</th> -</tr> - -<tr> -<td>No</td> -<td>No</td> -<td>Any</td> -<td>Unsigned</td> -</tr> - -<tr> -<td>No</td> -<td>No</td> -<td>Developer</td> -<td>Signed</td> -</tr> - -<tr> -<td>Yes</td> -<td>No</td> -<td>Any</td> -<td>Unsigned</td> -</tr> - -<tr> -<td>Yes</td> -<td>No</td> -<td>Developer</td> -<td>Signed</td> -</tr> - -<tr> -<td>Yes</td> -<td>No</td> -<td>Test account</td> -<td>Signed</td> -</tr> - -<tr> -<td>Yes</td> -<td>Yes</td> -<td>Any</td> -<td>Signed</td> -</tr> - -</table> +<p>In some cases, the reserved items may return signed static responses, which +lets you test signature verification in your application. The reserved items +only return signed responses if the user running the application has a <a +href="{@docRoot}distribute/googleplay/start.html">developer</a> or <a +href="{@docRoot}google/play/billing/billing_admin.html#billing-testing-setup">test +account.</a> <p>To make an In-app Billing request with a reserved product ID, you simply construct a normal <code>REQUEST_PURCHASE</code> request, but instead of using a real product ID from your @@ -310,9 +262,11 @@ purchases. Testing real in-app purchases enables you to test the end-to-end In-a experience, including the actual purchases from Google Play and the actual checkout flow that users will experience in your application.</p> -<p class="note"><strong>Note</strong>: You do not need to publish your application to do end-to-end -testing. You only need to upload your application as a draft application to perform end-to-end -testing.</p> +<p class="note"><strong>Note:</strong> You can do end-to-end testing of your app + by publishing it to an <a + href="{@docRoot}distribute/googleplay/developer-console.html#alpha-beta">alpha + distribution channel</a>. This allows you to publish the app to the Google + Play store, but limit its availability to just the testers you designate. </p> <p>To test your In-app Billing implementation with actual in-app purchases, you will need to register at least one test account on the Google Play Developer Console. You cannot use your @@ -327,14 +281,16 @@ application does not need to be published, but the item does need to be publishe <p>To test your In-app Billing implementation with actual purchases, follow these steps:</p> <ol> - <li><strong>Upload your application as a draft application to the Developer Console.</strong> - <p>You do not need to publish your application to perform end-to-end testing with real product - IDs; you only need to upload your application as a draft application. However, you must sign - your application with your release key before you upload it as a draft application. Also, the - version number of the uploaded application must match the version number of the application you - load to your device for testing. To learn how to upload an application to Google Play, see - <a href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=113469">Uploading - applications</a>.</p> + <li><strong>Upload your application to the <a + href="{@docRoot}distribute/googleplay/developer-console.html#alpha-beta">alpha + distribution channel</a> with the Developer Console.</strong> + + <p class="note"><strong>Note:</strong> Previously you could test an app by + uploading an unpublished "draft" version. This functionality is no longer + supported; instead, you must publish it to the alpha or beta distribution + channel. For more information, see <a href="#draft_apps">Draft Apps are No + Longer Supported</a>. + </li> <li><strong>Add items to the application's product list.</strong> <p>Make sure that you publish the items (the application can remain unpublished). See <a @@ -370,3 +326,24 @@ href="{@docRoot}tools/publishing/app-signing.html">signing</a>, and <a href="{@docRoot}distribute/tools/launch-checklist.html">publishing on Google Play</a>. </p> +<h2 id="draft_apps">Draft Apps are No Longer Supported</h2> + +<p>Previously, you could publish a "draft" version of your app for testing. This +functionality is no longer supported. Instead, there are two ways you can test +how a pre-release app functions on the Google Play store:</p> + +<ul> + + <li>You can publish an app to the <a + href="{@docRoot}distribute/googleplay/developer-console.html#alpha-beta">alpha + or beta distribution channels</a>. This makes the app available on the Google + Play store, but only to the testers you put on a "whitelist".</li> + + <li>In a few cases, you can test Google Play functionality with an unpublished + app. For example, you can test an unpublished app's in-app billing support by + using <a + href="{@docRoot}google/play/billing/billing_testing.html#billing-testing-static">static + responses</a>, special reserved product IDs that always return a specific + result (like "purchased" or "refunded").</li> + +</ul> diff --git a/docs/html/google/play/billing/v2/billing_integrate.jd b/docs/html/google/play/billing/v2/billing_integrate.jd index ca41e0b..5eb17d5 100644 --- a/docs/html/google/play/billing/v2/billing_integrate.jd +++ b/docs/html/google/play/billing/v2/billing_integrate.jd @@ -208,6 +208,14 @@ following:</p> a draft to the Google Play Developer Console. You also need to create a product list for the in-app items that are available for purchase in the sample application. The following instructions show you how to do this.</p> + +<p class="caution"><strong>Caution:</strong> Draft applications are no longer +supported. To test an application, publish it in the <a +href="{@docRoot}distribute/googleplay/developer-console.html#alpha-beta">alpha +or beta channels</a>. For more information, see <a +href="{@docRoot}google/play/billing/billing_testing.html#draft_apps">Draft Apps +are No Longer Supported</a>.</p> + <ol> <li><strong>Upload the release version of the sample application to Google Play.</strong> <p>Do not publish the sample application; leave it as an unpublished draft application. The @@ -928,10 +936,12 @@ public class BillingReceiver extends BroadcastReceiver { // Intent actions that we receive in the BillingReceiver from Google Play. // These are defined by Google Play and cannot be changed. // The sample application defines these in the Consts.java file. - public static final String ACTION_NOTIFY = "com.android.vending.billing.IN_APP_NOTIFY"; - public static final String ACTION_RESPONSE_CODE = "com.android.vending.billing.RESPONSE_CODE"; + public static final String ACTION_NOTIFY = + "com.android.vending.billing.IN_APP_NOTIFY"; + public static final String ACTION_RESPONSE_CODE = + "com.android.vending.billing.RESPONSE_CODE"; public static final String ACTION_PURCHASE_STATE_CHANGED = - "com.android.vending.billing.PURCHASE_STATE_CHANGED"; + "com.android.vending.billing.PURCHASE_STATE_CHANGED"; // The intent extras that are passed in an intent from Google Play. // These are defined by Google Play and cannot be changed. @@ -962,7 +972,8 @@ public class BillingReceiver extends BroadcastReceiver { Log.w(TAG, "unexpected action: " + action); } } - // Perform other processing here, such as forwarding intent messages to your local service. + // Perform other processing here, such as forwarding intent messages + // to your local service. } </pre> diff --git a/docs/html/google/play/expansion-files.jd b/docs/html/google/play/expansion-files.jd index e90f8fa..601ea48 100644 --- a/docs/html/google/play/expansion-files.jd +++ b/docs/html/google/play/expansion-files.jd @@ -527,17 +527,21 @@ are:</p> <!-- Required to download files from Google Play --> <uses-permission android:name="android.permission.INTERNET" /> - <!-- Required to keep CPU alive while downloading files (NOT to keep screen awake) --> + <!-- Required to keep CPU alive while downloading files + (NOT to keep screen awake) --> <uses-permission android:name="android.permission.WAKE_LOCK" /> - <!-- Required to poll the state of the network connection and respond to changes --> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <!-- Required to poll the state of the network connection + and respond to changes --> + <uses-permission + android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- Required to check whether Wi-Fi is enabled --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <!-- Required to read and write the expansion files on shared storage --> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission + android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ... </manifest> </pre> @@ -650,8 +654,8 @@ public class SampleAlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { try { - DownloaderClientMarshaller.startDownloadServiceIfRequired(context, intent, - SampleDownloaderService.class); + DownloaderClientMarshaller.startDownloadServiceIfRequired(context, + intent, SampleDownloaderService.class); } catch (NameNotFoundException e) { e.printStackTrace(); } @@ -693,16 +697,19 @@ versionCode)}</li> <p>For example, the sample app provided in the Apk Expansion package calls the following method in the activity's {@link android.app.Activity#onCreate onCreate()} method to check whether the expansion files already exist on the device:</p> + <pre> boolean expansionFilesDelivered() { for (XAPKFile xf : xAPKS) { - String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsBase, xf.mFileVersion); + String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsBase, + xf.mFileVersion); if (!Helpers.doesFileExist(this, fileName, xf.mFileSize, false)) return false; } return true; } </pre> + <p>In this case, each {@code XAPKFile} object holds the version number and file size of a known expansion file and a boolean as to whether it's the main expansion file. (See the sample application's {@code SampleDownloaderActivity} class for details.)</p> @@ -740,6 +747,7 @@ the Downloader Library begins the download and you should update your activity U display the download progress (see the next step). If the response <em>is</em> {@code NO_DOWNLOAD_REQUIRED}, then the files are available and your application can start.</p> <p>For example:</p> + <pre> @Override public void onCreate(Bundle savedInstanceState) { @@ -754,11 +762,14 @@ public void onCreate(Bundle savedInstanceState) { notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT); // Start the download service (if required) - int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this, + int startResult = + DownloaderClientMarshaller.startDownloadServiceIfRequired(this, pendingIntent, SampleDownloaderService.class); - // If download has started, initialize this activity to show download progress + // If download has started, initialize this activity to show + // download progress if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { - // This is where you do set up to display the download progress (next step) + // This is where you do set up to display the download + // progress (next step) ... return; } // If the download wasn't necessary, fall through to start the app @@ -766,6 +777,7 @@ public void onCreate(Bundle savedInstanceState) { startApp(); // Expansion files are available, start the app } </pre> + </li> <li>When the {@code startDownloadServiceIfRequired()} method returns anything <em>other than</em> {@code NO_DOWNLOAD_REQUIRED}, create an instance of {@code IStub} by @@ -783,9 +795,11 @@ android.app.Activity#onCreate onCreate()} method, after {@code startDownloadServ starts the download. </p> <p>For example, in the previous code sample for {@link android.app.Activity#onCreate onCreate()}, you can respond to the {@code startDownloadServiceIfRequired()} result like this:</p> + <pre> // Start the download service (if required) - int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this, + int startResult = + DownloaderClientMarshaller.startDownloadServiceIfRequired(this, pendingIntent, SampleDownloaderService.class); // If download has started, initialize activity to show progress if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { @@ -892,7 +906,8 @@ others. By default, this flag is <em>not</em> enabled, so the user must be on Wi expansion files. You might want to provide a user preference to enable downloads over the cellular network. In which case, you can call: <pre> -mRemoteService.setDownloadFlags(IDownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR); +mRemoteService + .setDownloadFlags(IDownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR); </pre> </dd> </dl> @@ -975,10 +990,12 @@ to both your expansion files:</p> // The shared path to all app expansion files private final static String EXP_PATH = "/Android/obb/"; -static String[] getAPKExpansionFiles(Context ctx, int mainVersion, int patchVersion) { +static String[] getAPKExpansionFiles(Context ctx, int mainVersion, + int patchVersion) { String packageName = ctx.getPackageName(); Vector<String> ret = new Vector<String>(); - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + if (Environment.getExternalStorageState() + .equals(Environment.MEDIA_MOUNTED)) { // Build the full path to the app's expansion files File root = Environment.getExternalStorageDirectory(); File expPath = new File(root.toString() + EXP_PATH + packageName); @@ -1102,7 +1119,8 @@ following:</p> <pre> // Get a ZipResourceFile representing a merger of both the main and patch files -ZipResourceFile expansionFile = APKExpansionSupport.getAPKExpansionZipFile(appContext, +ZipResourceFile expansionFile = + APKExpansionSupport.getAPKExpansionZipFile(appContext, mainVersion, patchVersion); // Get an input stream for a known file inside the expansion file ZIPs @@ -1190,28 +1208,18 @@ android.content.Context#getExternalFilesDir getExternalFilesDir()}.</li> opens, it's important that you test this process to be sure your application can successfully query for the URLs, download the files, and save them to the device.</p> -<p>To test your application's implementation of the manual download procedure, you must upload -your application to Google Play as a "draft" to make your expansion files available for -download:</p> - -<ol> - <li>Upload your APK and corresponding expansion files using the Google Play Developer -Console.</li> - <li>Fill in the necessary application details (title, screenshots, etc.). You can come back and -finalize these details before publishing your application. - <p>Click the <strong>Save</strong> button. <em>Do not click Publish.</em> This saves -the application as a draft, such that your application is not published for Google Play users, -but the expansion files are available for you to test the download process.</p></li> - <li>Install the application on your test device using the Eclipse tools or <a -href="{@docRoot}tools/help/adb.html">{@code adb}</a>.</li> - <li>Launch the app.</li> -</ol> - -<p>If everything works as expected, your application should begin downloading the expansion +<p>To test your application's implementation of the manual download procedure, +you can publish it to the alpha or beta channel, so it will only be available to +authorized testers. +If everything works as expected, your application should begin downloading the expansion files as soon as the main activity starts.</p> - - +<p class="note"><strong>Note:</strong> Previously you could test an app by +uploading an unpublished "draft" version. This functionality is no longer +supported; instead, you must publish it to the alpha or beta distribution +channel. For more information, see <a +href="{@docRoot}google/play/billing/billing_testing.html#draft_apps">Draft Apps +are No Longer Supported</a>. <h2 id="Updating">Updating Your Application</h2> diff --git a/docs/html/google/play/licensing/licensing-reference.jd b/docs/html/google/play/licensing/licensing-reference.jd index 7bfa61a..d4ca79a 100644 --- a/docs/html/google/play/licensing/licensing-reference.jd +++ b/docs/html/google/play/licensing/licensing-reference.jd @@ -151,7 +151,8 @@ returned by the Google Play server in a license response.</p> <tr> <td>{@code LICENSED}</td> <td>The application is licensed to the user. The user has purchased the -application or the application only exists as a draft.</td> +application, or is authorized to download and install the alpha or beta version +of the application.</td> <td>Yes</td> <td><code>VT</code>, <code>GT</code>, <code>GR</code></td> <td><em>Allow access according to {@code Policy} constraints.</em></td> @@ -233,16 +234,14 @@ implementation.</p> href="{@docRoot}google/play/licensing/setting-up.html#test-env"> Setting Up The Testing Environment</a>, the response code can be manually overridden for the application developer and any registered test users via the -Google Play Developer Console. -<br/><br/> -Additionally, as noted above, applications that are in draft mode (in other -words, applications that have been uploaded but have <em>never</em> been -published) will return {@code LICENSED} for all users, even if not listed as a test -user. Since the application has never been offered for download, it is assumed -that any users running it must have obtained it from an authorized channel for -testing purposes.</p> - +Google Play Developer Console.</p> +<p class="note"><strong>Note:</strong> Previously you could test an app by +uploading an unpublished "draft" version. This functionality is no longer +supported; instead, you must publish it to the alpha or beta distribution +channel. For more information, see <a +href="{@docRoot}google/play/billing/billing_testing.html#draft_apps">Draft Apps +are No Longer Supported</a>. <h2 id="extras">Server Response Extras</h2> @@ -430,8 +429,8 @@ public boolean allowAccess() { } } else if (mLastResponse == LicenseResponse.RETRY && ts < mLastResponseTime + MILLIS_PER_MINUTE) { - // Only allow access if we are within the retry period or we haven't used up our - // max retries. + // Only allow access if we are within the retry period + // or we haven't used up our max retries. return (ts <= mRetryUntil || mRetryCount <= mMaxRetries); } return false; diff --git a/docs/html/google/play/licensing/overview.jd b/docs/html/google/play/licensing/overview.jd index 4e1a9c9..a2d5379 100644 --- a/docs/html/google/play/licensing/overview.jd +++ b/docs/html/google/play/licensing/overview.jd @@ -38,12 +38,11 @@ the licensing server and receives the result. The Google Play application sends the result to your application, which can allow or disallow further use of the application as needed.</p> -<p class="note"><strong>Note:</strong> If a paid application has been uploaded -to Google Play, but saved only as a draft application (the app is -unpublished), the licensing server considers all users to be licensed users of -the application (because it's not even possible to purchase the app). This -exception is necessary in order for you to perform testing of your licensing -implementation.</p> +<p class="note"><strong>Note:</strong> If a version of an app is in the alpha or +beta channel, all users who are authorized to download and install that app are +considered to be licensed users of the app. For more information, see <a +href="{@docRoot}distribute/googleplay/developer-console.html#alpha-beta">Alpha +and Beta Testing</a>.</p> <div class="figure" style="width:469px"> <img src="{@docRoot}images/licensing_arch.png" alt=""/> @@ -52,6 +51,12 @@ license check through the License Verification Library and the Google Play client, which handles communication with the Google Play server.</p> </div> +<p class="note"><strong>Note:</strong> Previously you could test an app by +uploading an unpublished "draft" version. This functionality is no longer +supported; instead, you must publish it to the alpha or beta distribution +channel. For more information, see <a +href="{@docRoot}google/play/billing/billing_testing.html#draft_apps">Draft Apps +are No Longer Supported</a>. <p>To properly identify the user and determine the license status, the licensing server requires information about the application and user—your application and the Google Play client work |