diff options
21 files changed, 1267 insertions, 137 deletions
diff --git a/docs/html-intl/intl/ja/distribute/index.jd b/docs/html-intl/intl/ja/distribute/index.jd new file mode 100644 index 0000000..27f1cb4 --- /dev/null +++ b/docs/html-intl/intl/ja/distribute/index.jd @@ -0,0 +1,16 @@ +page.title=Google Play でアプリを配信する +page.viewport_width=970 +section.landing=true +header.hide=1 +nonavpage=true +page.metaDescription=Google Play は最もよく利用されている Android アプリストアです。クラウドと同期された強力な基盤により、ユーザーは簡単に あなたのアプリを見つけてダウンロードできます。 + +@jd:body + + <div class="resource-widget resource-flow-layout col-16" + style="margin-top:20px" + data-query="collection:launch/static/ja" + data-sortOrder="" + data-cardSizes="6x6,6x6,6x2x3,12x6,6x6,6x2x3,6x6,6x6,12x6,6x6" + data-maxResults="24"></div> + diff --git a/docs/html-intl/intl/ja/training/tv/start/index.jd b/docs/html-intl/intl/ja/training/tv/start/index.jd index 8f946a1..e8db099 100755 --- a/docs/html-intl/intl/ja/training/tv/start/index.jd +++ b/docs/html-intl/intl/ja/training/tv/start/index.jd @@ -1,5 +1,7 @@ -page.title=TV アプリのビルド +page.title=Android TV アプリ開発 page.tags=tv, leanback +page.metaDescription=Android TV 対応アプリ開発の手順が日本語化。 +page.image=design/tv/images/atv-home.jpg startpage=true @jd:body diff --git a/docs/html/google/play/billing/billing_reference.jd b/docs/html/google/play/billing/billing_reference.jd index da9178d..01e680f 100644 --- a/docs/html/google/play/billing/billing_reference.jd +++ b/docs/html/google/play/billing/billing_reference.jd @@ -12,6 +12,7 @@ parent.link=index.html <ol> <li><a href="#getSkuDetails">getSkuDetails()</a></li> <li><a href="#getBuyIntent">getBuyIntent()</a></li> + <li><a href="#upgrade-getBuyIntentToReplaceSkus">getBuyIntentToReplaceSkus()</a></li> <li><a href="#getPurchases">getPurchases()</a></li> </ol> </li> @@ -107,8 +108,8 @@ parent.link=index.html </tr> <tr> <td>{@code type}</td> - <td>Value must be “inapp” for an in-app product or "subs" for -subscriptions.</td> + <td>Value must be <code>“inapp”</code> for an in-app product or + <code>"subs"</code> for subscriptions.</td> </tr> <tr> <td>{@code price}</td> @@ -140,7 +141,17 @@ does not include tax.</td> </p> <h3 id="getBuyIntent">The getBuyIntent() method</h3> -<p>This method returns a response code integer mapped to the {@code RESPONSE_CODE} key, and a {@code PendingIntent} to launch the puchase flow for the in-app item mapped to the {@code BUY_INTENT} key. When it receives the {@code PendingIntent}, Google Play sends a response {@code Intent} with the data for that purchase order. The data that is returned in the response {@code Intent} is summarized in table 3.</p> +<p> + This method returns a response code integer mapped to the {@code + RESPONSE_CODE} key, and a {@link android.app.PendingIntent} to launch the + purchase flow for the in-app item mapped to the {@code BUY_INTENT} key, as + described in <a href= + "{@docRoot}google/play/billing/billing_integrate.html#purchase">Purchasing an + Item</a>. When it receives the {@link android.app.PendingIntent}, Google Play + sends a response {@code Intent} with the data for that purchase order. The + data that is returned in the response {@code Intent} is summarized in table + 3. +</p> <p class="table-caption" id="purchase-pendingintent-response-table"> <strong>Table 3.</strong> Response data from an In-app Billing Version 3 purchase request.</p> @@ -151,7 +162,7 @@ does not include tax.</td> </tr> <tr> <td>{@code RESPONSE_CODE}</td> - <td>0 if the purchase was success, error otherwise.</td> + <td>Value is <code>0</code> if the purchase was success, error otherwise.</td> </tr> <tr> <td>{@code INAPP_PURCHASE_DATA}</td> @@ -176,9 +187,22 @@ RSASSA-PKCS1-v1_5 scheme.</td> <th scope="col">Field</th> <th scope="col">Description</th> </tr> + <tr> + <td>{@code autoRenewing}</td> + <td>Indicates whether the subscription renews automatically. If + <code>true</code>, the subscription is active, and will + automatically renew on the next billing date. If <code>false</code>, + indicates that the user has canceled the subscription. The user has + access to subscription content until the next billing date and will + lose access at that time unless they re-enable automatic renewal + (or manually renew, as described in + <a href="{@docRoot}google/play/billing/billing_subscriptions.html#manual-renewal">Manual + Renewal</a>).</td> + </tr> <tr> <td>{@code orderId}</td> - <td>A unique order identifier for the transaction. This corresponds to the Google Wallet Order ID.</td> + <td>A unique order identifier for the transaction. This identifier + corresponds to the Google Wallet Order ID.</td> </tr> <tr> <td>{@code packageName}</td> @@ -194,7 +218,8 @@ RSASSA-PKCS1-v1_5 scheme.</td> </tr> <tr> <td>{@code purchaseState}</td> - <td>The purchase state of the order. Possible values are 0 (purchased), 1 (canceled), or 2 (refunded).</td> + <td>The purchase state of the order. Possible values are <code>0</code> + (purchased), <code>1</code> (canceled), or <code>2</code> (refunded).</td> </tr> <tr> <td>{@code developerPayload}</td> @@ -202,20 +227,80 @@ RSASSA-PKCS1-v1_5 scheme.</td> </tr> <tr> <td>{@code purchaseToken}</td> - <td>A token that uniquely identifies a purchase for a given item and user - pair. This token may be up to 1,000 characters long. - Pass this entire token to other methods, such as when you consume the - purchase (as described in -<a href="{@docRoot}training/in-app-billing/purchase-iab-products.html#Consume">Consume - a Purchase</a>). Do not abbreviate or truncate this token.</td> + <td>A token that uniquely identifies a purchase for a given item and user pair. </td> </tr> </table> </p> +<h3 id="upgrade-getBuyIntentToReplaceSkus">The getBuyIntentToReplaceSkus() + method</h3> + +<p>This method is used to upgrade or downgrade a subscription purchase. The method +is similar to <a href="#getBuyIntent"><code>getBuyIntent()</code></a>, except +that it takes a list of already-purchased SKUs that are to be +replaced with the SKU being purchased. When the user completes the purchase, +Google Play cancels the old SKUs and credits the user with the unused value of +their subscription time on a pro-rated basis. Google Play applies this credit +to the new subscription, and does not begin billing the user for the new +subscription until after the credit is used up.</p> + +<p>This method was added with version 5 of the in-app billing API. To verify +that the method is reported, send an <code>isBillingSupported</code> AIDL +request.</p> + +<p class="note"><strong>Note:</strong> You can only use this method for +subscription purchases. If the passed <code>type</code> parameter is anything +other than <code>"subs"</code>, the method returns +<a href="#billing-codes"><code>BILLING_RESPONSE_RESULT_DEVELOPER_ERROR</code></a>. +Furthermore, the passed SKUs may not include SKUs for seasonal +subscriptions.</p> + +<p> + This method returns a response code integer mapped to the {@code + RESPONSE_CODE} key, and a {@link android.app.PendingIntent} to launch the + purchase flow for the in-app subscription mapped to the {@code BUY_INTENT} + key, as described in <a href= + "{@docRoot}google/play/billing/billing_integrate.html#purchase">Purchasing an + Item</a>. When it receives the {@link android.app.PendingIntent}, Google Play + sends a response {@code Intent} with the data for that purchase order. The + data that is returned in the response {@code Intent} is summarized in table + 5. +</p> + +<p class="table-caption" id="upgrade-purchase-pendingintent-response-table"> +<strong>Table 5.</strong> Response data from an In-app Billing Version 5 purchase request.</p> +<table> + <tr> + <th scope="col">Key</th> + <th scope="col">Description</th> + </tr> + <tr> + <td>{@code RESPONSE_CODE}</td> + <td>Value is <code>0</code> if the purchase succeeds. If the purchase fails, contains an error + code.</td> + </tr> + <tr> + <td>{@code INAPP_PURCHASE_DATA}</td> + <td> + A String in JSON format that contains details about the purchase order. + See <a href="#purchase-data-table">table 4</a> for a description of the JSON fields. + </td> + </tr> + <tr> + <td>{@code INAPP_DATA_SIGNATURE}</td> + <td>String containing the signature of the purchase data that the developer + signed with their private key. The data signature uses the + RSASSA-PKCS1-v1_5 scheme.</td> + </tr> +</table> +</p> + +</p> + <h3 id="getPurchases">The getPurchases() method</h3> <p>This method returns the current un-consumed products owned by the user. Table 5 lists the response data that is returned in the {@code Bundle}.</p> <p class="table-caption" id="getpurchases-response-table"> -<strong>Table 5.</strong> Response data from a {@code getPurchases} request.</p> +<strong>Table 6.</strong> Response data from a {@code getPurchases} request.</p> <table> <tr> <th scope="col">Key</th> @@ -223,7 +308,7 @@ RSASSA-PKCS1-v1_5 scheme.</td> </tr> <tr> <td>{@code RESPONSE_CODE}</td> - <td>0 if the request was successful, error otherwise.</td> + <td>Value is <code>0</code> if the request was successful, error otherwise.</td> </tr> <tr> <td>{@code INAPP_PURCHASE_ITEM_LIST}</td> diff --git a/docs/html/google/play/billing/billing_subscriptions.jd b/docs/html/google/play/billing/billing_subscriptions.jd index b9b77df..8f55354 100644 --- a/docs/html/google/play/billing/billing_subscriptions.jd +++ b/docs/html/google/play/billing/billing_subscriptions.jd @@ -1,4 +1,4 @@ -page.title=In-App Subscriptions +page.title=In-app Subscriptions parent.title=In-app Billing parent.link=index.html page.metaDescription=Subscriptions let you sell content or features in your app with automated, recurring billing. @@ -21,6 +21,11 @@ meta.tags="monetization, inappbilling, subscriptions" Developer API</a>.</li> <li>Users purchase your subscriptions from inside your apps, rather than directly from Google Play.</li> + <li>Users can renew their subscriptions while a current subscription is + active.</li> + <li>Users can upgrade or downgrade a subscription in the middle of a + subscription period. The old subscription's cost is pro-rated, and the + unused portion is applied to the replacement subscription.</li> <li>You can defer billing for a particular user's subscription, to manage accounts or offer rewards.</li> </ul> @@ -206,6 +211,65 @@ app to notify your backend servers of subscription purchases, tokens, and any billing errors that may occur. Your backend servers can use the server-side API to query and update your records and follow up with customers directly, if needed.</p> +<h3 id="manual-renewal">Manual Renewal</h3> + +<p>With version 5 of the In-app Billing API, users can renew a subscription +during its active period even if the subscription is not set to +automatically renew. If the user purchases a subscription while the subscription +is active, it is extended by the appropriate period at the current rate.</p> + +<p>For example, Achilles has a subscription to the <em>Modern Hoplite</em> app. +His subscription is currently due to expire on August 1. On July 10, he +purchases a 3-month subscription at the current rate. Those three months are +added to his existing subscription, so the subscription now expires on November +1.</p> + +<p>It is up to the app to convey this with an appropriate UI. For example, if a +user does not have an active subscription, the app might have a +<strong>buy</strong> button, but if the user has a subscription the button might +say <strong>renew</strong>.</p> + +<h3 id="upgrade">Subscription Upgrade/Downgrade</h3> + +<p> + With version 5 of the In-app Billing API, users can upgrade or downgrade a + subscription during its active period. When the user does this, the active + subscription is canceled and a new subscription is created. The unused + balance of the old subscription is applied on a pro-rated basis to the new + subscription. The first billing period for the new subscription begins after + that balance is used up. (The new subscription does not need to have a period + of the same length as the old one.) +</p> + +<p>For example, Samwise has a subscription to online content from the +<em>Country Gardener</em> app. He currently has a monthly subscription to the +Tier 1 +version of the content (which has text-only content). This subscription costs +him £2/month, and renews on the first of the month. On April +15, he chooses to upgrade to the Tier 2 subscription (which includes video +updates), costing £3/month. His Tier 1 subscription is immediately ended. +Since he paid for a full month (April 1-30), but only used half of it, half of a +month's subscription (£1) is applied to his new subscription. However, since +that new subscription costs £3/month, the £1 credit balance only pays for ten +days. So Samwise's credit pays for his subscription from April 15-25. On April +26, he is charged £3 for his new subscription, and another £3 on the 26th of +each month following.</p> + +<p class="note"> + <strong>Note:</strong> The new subscription's billing date depends on when + the subscriber's pro-rated credit runs out, so the subscriber cannot upgrade + or downgrade to a seasonal subscription, which has fixed and predetermined + beginning and end dates. +</p> + +<p>When a user upgrades or downgrades a subscription, your app calls +<a href="{@docRoot}google/play/billing/billing_reference.html#upgrade-getBuyIntentToReplaceSkus"> +<code>getBuyIntentToReplaceSkus()</code></a>. +This method is passed the new SKU the user wants to buy, and all +the old SKUs that are superseded by it. The remaining portions of the old SKUs +are used to pay for the new subscription, and billing begins when this credit +is used up.</p> + <h3 id="deferred-billing">Deferred Billing</h3> <p>Using the @@ -316,7 +380,7 @@ canceling subscriptions from inside the purchasing app.</p> <p>When the user cancels a subscription, Google Play does not offer a refund for the current billing cycle. Instead, it allows the user to have access to the -cancelled subscription until the end of the current billing cycle, at which time +canceled subscription until the end of the current billing cycle, at which time it terminates the subscription. For example, if a user purchases a monthly subscription and cancels it on the 15th day of the cycle, Google Play will consider the subscription valid until the end of the 30th day (or other day, @@ -357,12 +421,12 @@ Orders</strong> page in the Play Store, or by contacting you directly.</p> <p>If you receive requests for refunds, you can use the <a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play Developer API</a> or the Merchant Center to cancel the subscription, verify that it -is already cancelled, or refund the user's payment without cancelling it. You +is already canceled, or refund the user's payment without canceling it. You can also use the <a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play Developer API</a> to <em>refund and revoke</em> a user's subscription. If you refund and revoke a subscription, the user's -subscription is immediately cancelled, and the user's most recent subscription +subscription is immediately canceled, and the user's most recent subscription payment is refunded. (If you want to refund more than the most recent payment, you can process additional refunds through the Merchant Center.)</p> @@ -423,7 +487,7 @@ approach to purchase verification accounts for the offline use-case.</p> <li>Remotely query the validity of a specific subscription at any time</li> <li>Cancel a subscription</li> <li>Defer a subscription's next billing date</li> - <li>Refund a subscription payment without cancelling the subscription</li> + <li>Refund a subscription payment without canceling the subscription</li> <li>Refund and revoke a subscription</li> </ul> diff --git a/docs/html/google/play/billing/billing_testing.jd b/docs/html/google/play/billing/billing_testing.jd index 36456cc..44b3286 100644 --- a/docs/html/google/play/billing/billing_testing.jd +++ b/docs/html/google/play/billing/billing_testing.jd @@ -25,8 +25,8 @@ page.tags="inapp, billing, iap" implementation:</p> <ul> -<li>Test purchases, which let test account users make real purchase your published in-app items, -but without any actual charges to the user accounts.</li> +<li>Test purchases, which let license-test users purchase your published in-app + items, but without any actual charges to their accounts.</li> <li>Static billing responses from Google Play, for testing in early development</p> </ul> @@ -43,14 +43,13 @@ Devices</a>.</p> <p>When your In-app Billing implementation is ready, you can test purchasing of your in-app SKUs in two ways:</p> -<ul> -<li><strong>Test purchases</strong>, which let your selected license test users -purchase your in-app products before the app is published, but without any -resulting charges to the user, and </li> +<ul> <li><strong>Test purchases</strong>, which let your selected license-test +users purchase your in-app products without any resulting charges to the user. +Test purchases can be used in alpha/beta releases or in published apps. </li> <li><strong>Real purchases</strong>, which let regular users make real purchases of your in-app products with actual charges to the user’s payment instruments. -In this case, you can use Google Play’s alpha and beta release groups to manage -the users who can make “live” purchases using your implementation. </li> +You can use Google Play’s alpha and beta release groups to manage +the users who can make live purchases using your implementation. </li> </ul> <p>The sections below provide more detail about how to use these approaches for @@ -61,16 +60,21 @@ testing and validation. </p> <p>Test purchases offer a secure, convenient way to enable larger-scale testing of your In-app Billing implementation during development or in preparation for launch. They let authorized user accounts make purchases of your in-app products -through Google Play while the app is still unpublished, without incurring any -actual charges to the user accounts.</p> +through Google Play without incurring any actual charges to the user +accounts.</p> -<p>Once authorized with testing access, those users can side-load your app and -test the full merchandising, purchase, and fulfillment flow for your products. +<p>Once authorized for testing access, those users can make purchases without +being charged. Test purchases are real orders and Google Play processes them in the same way as other orders. When purchases are complete, Google Play prevents the orders from going to financial processing, ensuring that there are no actual charges to user accounts, and automatically canceling the completed orders after 14 days. </p> +<p class="note"> + <strong>Note:</strong> Test subscription purchases recur daily, regardless of + the product's subscription period. +</p> + <h4 id="setup">Setting up test purchases</h4> <p>It’s easy to set up test purchases—any user account can be chosen to be @@ -91,14 +95,13 @@ href="#billing-testing-test">Setting Up for Test Purchases</a>.</p> <p>Once you’ve added the users as license tester accounts and saved the change, within 15 minutes those users can begin making test purchases of your in-app -products. You can then distribute your app to your testers and provide a means -of getting feedback. </p> +products.</p> <p class="note"><strong>Note</strong>: To make test purchases, the license test account must be on the user’s Android device. If the device has more than one account, the purchase will be made with the account that downloaded the app. If none of the accounts has downloaded the app, the purchase is made with the first -account.Users can confirm the account that is making a purchase by expanding the +account. Users can confirm the account that is making a purchase by expanding the purchase dialog.</p> <h4 id="tp-account">Test purchases and developer account</h4> @@ -114,13 +117,13 @@ as a normal item with an actual price. However, Google Play marks test purchases with a notice across the center of the purchase dialog, for easy identification. </p> -<h4 id="cancelling">Cancelling completed test purchases</h4> +<h4 id="cancelling">Canceling completed test purchases</h4> <p>Google Play accumulates completed test purchases for each user but does not pass them on to financial processing. Over time, it automatically clears out -the purchases by cancelling them. </p> +the purchases by canceling them. </p> <p>In some cases, you might want to manually cancel a test purchase to continue -testing. For cancelling purchases, you have these options:</p> +testing. For canceling purchases, you have these options:</p> <ul> <li>Wait for the transactions to expire—Google Play clears completed test @@ -130,13 +133,6 @@ Center, look up the transaction, and then cancel it. You can find transactions by looking up their order numbers.</li> </ul> -<h4 id="requirements">Requirements for using test purchases</h4> -<p>If you plan to use test purchases, please note the requirements and limitations below: </p> -<ul> -<li>Test purchases is only supported for license test accounts when the app is using the In-app Billing v3 API.</li> -<li>Test purchases are only supported for in-app products, not for in-app subscriptions.</li> -</ul> - <h3 id="transations">Testing with real transactions</h3> <p>As you prepare to launch an app that uses In-app Billing, you can make use of Google Play alpha/beta release options to do validation and load testing on your @@ -276,8 +272,8 @@ you buy items from yourself. If you have not set up test accounts before, see <a href="{@docRoot}google/play/billing/billing_admin.html#billing-testing-setup">Setting up test accounts</a>.</p> -<p>Also, a test account can purchase an item in your product list only if the item is published. The -application does not need to be published, but the item does need to be published.</p> +<p>A test account can purchase an item in your product list only if the +item is published.</p> <p>To test your In-app Billing implementation with actual purchases, follow these steps:</p> diff --git a/docs/html/google/play/billing/index.jd b/docs/html/google/play/billing/index.jd index bdbf5c7..47620c8 100644 --- a/docs/html/google/play/billing/index.jd +++ b/docs/html/google/play/billing/index.jd @@ -14,6 +14,16 @@ and features, and more. You can use In-app Billing to sell products as</p> <div class="sidebox"> <h2><strong>New in In-App Billing</strong></h2> <ul> + <li><strong>Subscription Upgrade/Downgrade</strong>—A user can + subscribe to a higher or lower tier of subscription while their current + subscription is active. The old subscription is canceled, and the unused + portion is applied on a pro-rated basis to the new subscription.</li> + <li><strong>Manual Subscription Renewal</strong>—A user can purchase + a subscription at the current rate while their existing subscription is + still active. The existing subscription is extended by the appropriate + period.</li> + <li><strong>IAB Sandbox</strong>—The In-app Billing Sandbox now supports + testing subscription purchases.</li> <li><strong>IAB v2 shutdown</strong>—In-app Billing v2 API is deprecated and will be shut down in January 2015. If your app is still using In-app Billing v2, please migrate to the v3 API as soon as possible.</li> <li><strong>Seasonal subscriptions</strong>—You can now set up a recurring <a href="billing_subscriptions.html#user-billing">seasonal @@ -35,7 +45,6 @@ and features, and more. You can use In-app Billing to sell products as</p> subscription ends immediately, and his or her most recent subscription payment is refunded.</li> - <li><strong>In-app Billing Version 3</strong>—The <a href="{@docRoot}google/play/billing/api.html">latest version</a> of In-app Billing features a synchronous API that is easier to implement and lets you manage in-app products and subscriptions more effectively.</li> </ul> </div> </div> diff --git a/docs/html/google/play/billing/versions.jd b/docs/html/google/play/billing/versions.jd index dbe3ea3..aa35501 100644 --- a/docs/html/google/play/billing/versions.jd +++ b/docs/html/google/play/billing/versions.jd @@ -11,10 +11,30 @@ page.title=In-app Billing Version Notes <p>At run time, your app can query the Google Play Store app to determine what version of the API it supports and what features are available. </p> <ul> -<li>If you are using in-app billing version 3, the version information is not directly returned the Google Play. Instead, you can check if Google Play supports the version of the In-app Billing API that you are using by sending a {@code isBillingSupported} request.</li> + +<li>If you are using in-app billing version 3 or later, the version information +is not directly returned by Google Play. Instead, you can check if Google Play +supports the version of the In-app Billing API that you are using by sending an +{@code isBillingSupported} request.</li> + <li>If the In-app Billing API version that you are using is earlier than version 3, the version information is returned in the <code>API_VERSION</code> key of the Bundle object passed in the {@code sendBillingRequest} method. For more information, see <a href="{@docRoot}google/play/billing/v2/billing_reference.html#billing-interface-v2">In-app Billing Service Interface</a>.</li> </ul> +<h3 id="version_5">In-app Billing version 5</h3> +<p><em>February 2015</em></p> +<ul> +<li>A user can manually extend an existing subscription. The subscription +is extended by the appropriate amount of time.</li> +<li>A user can upgrade or downgrade a subscription while it is active. The +old subscription is canceled, and the unused portion is applied on a pro-rata +basis to the new subscription.</li> +</ul> + +<h3 id="version_4">In-app Billing version 4</h3> + +<p>Version 4 of the In-app Billing API did not introduce any public +functionality.</p> + <h3 id="version_3">In-app Billing version 3</h3> <p><em>February 2013</em></p> <ul> diff --git a/docs/html/guide/topics/admin/device-admin.jd b/docs/html/guide/topics/admin/device-admin.jd index bed4b4d..45bd76a 100644 --- a/docs/html/guide/topics/admin/device-admin.jd +++ b/docs/html/guide/topics/admin/device-admin.jd @@ -48,6 +48,11 @@ solutions for Android-powered devices. It discusses the various features provided by the Device Administration API to provide stronger security for employee devices that are powered by Android.</p> +<p class="note"><strong>Note</strong> For information on building a Work Policy +Controller for Android for Work deployments, see <a +href="{@docRoot}training/enterprise/work-policy-ctrl.html">Building a Work +Policy Controller</a>.</p> + <h2 id="overview">Device Administration API Overview</h2> @@ -712,4 +717,4 @@ mDPM.setStorageEncryption(mDeviceAdminSample, true); </pre> <p> See the Device Administration API sample for a complete example of how to enable storage encryption. -</p>
\ No newline at end of file +</p> diff --git a/docs/html/images/enterprise/work-launcher.png b/docs/html/images/enterprise/work-launcher.png Binary files differnew file mode 100644 index 0000000..3bbd835 --- /dev/null +++ b/docs/html/images/enterprise/work-launcher.png diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js index 6fb906e..127134f 100644 --- a/docs/html/jd_collections.js +++ b/docs/html/jd_collections.js @@ -56,6 +56,25 @@ var RESOURCE_COLLECTIONS = { "distribute/googleplay/developer-console.html" ] }, + "launch/static/ja": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=xelYnWcYkuE", + "https://www.youtube.com/playlist?list=PLCOC_kP3nqGIHEgwm9mybvA04Vn4Cg9nn", + "http://googledevjp.blogspot.jp/2014/12/android-wear.html", + "http://googledevjp.blogspot.jp/2014/12/android-studio-10.html", + "http://googledevjp.blogspot.jp/2014/12/google-play-65.html", + "intl/ja/distribute/googleplay/developer-console.html#alpha-beta", + "intl/ja/distribute/googleplay/guide.html", + "intl/ja/distribute/essentials/quality/core.html", + "http://support.google.com/googleplay/android-developer/answer/4430948?hl=ja", + "intl/ja/support.html", + "intl/ja/distribute/essentials/quality/wear.html", + "intl/ja/training/tv/start/index.html", + "http://googleforwork-japan.blogspot.jp/2014/12/gcp-google-cloud-platform-rpg-gcp.html", + "intl/ja/distribute/monetize/ads.html" + ] + }, "distribute/gp/gplanding": { "resources": [ "distribute/googleplay/about.html", @@ -1186,5 +1205,21 @@ var RESOURCE_COLLECTIONS = { "training/multiscreen/index.html", "training/monitoring-device-state/index.html" ] + }, + "training/work/apps": { + "title": "", + "resources": [ + "training/enterprise/app-compatibility.html", + "training/enterprise/app-restrictions.html", + "samples/AppRestrictionSchema/index.html", + "samples/AppRestrictionEnforcer/index.html" + ] + }, + "training/work/admin": { + "title": "", + "resources": [ + "training/enterprise/work-policy-ctrl.html", + "samples/BasicManagedProfile/index.html" + ] } -}
\ No newline at end of file +} diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js index e2a0539..288b614 100644 --- a/docs/html/jd_extras.js +++ b/docs/html/jd_extras.js @@ -1988,5 +1988,161 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": ["analytics"], "type": "Guide", "titleFriendly": "" + }, + { + "lang": "ja", + "title": "Gaming Everywhere", + "titleFriendly": "", + "summary": "東京ゲームショウ 2014 の基調講演より。", + "url": "https://www.youtube.com/watch?v=xelYnWcYkuE", + "group": "", + "keywords": [], + "tags": [], + "image": "http://img.youtube.com/vi/xelYnWcYkuE/hqdefault.jpg", + "type": "youtube" + }, + { + "lang": "ja", + "title": "Playtime Tokyo", + "titleFriendly": "", + "summary": "アプリビジネスのノウハウを各担当者が講演しました。", + "url": "https://www.youtube.com/playlist?list=PLCOC_kP3nqGIHEgwm9mybvA04Vn4Cg9nn", + "group": "", + "keywords": [], + "tags": [], + "image": "http://img.youtube.com/vi/lJdjY3z6-LY/hqdefault.jpg", + "type": "youtube" + }, + { + "lang": "ja", + "title": "Android Wear 関連の動画に日本語字幕が付きました", + "titleFriendly": "", + "summary": "", + "url": "http://googledevjp.blogspot.jp/2014/12/android-wear.html", + "group": "", + "keywords": [], + "tags": [], + "image": "http://i1.ytimg.com/vi/4JcDYkgqksY/maxresdefault.jpg", + "type": "blog" + }, + { + "lang": "ja", + "title": "Android Studio 1.0 をリリースしました", + "titleFriendly": "", + "summary": "", + "url": "http://googledevjp.blogspot.jp/2014/12/android-studio-10.html", + "group": "", + "keywords": [], + "tags": [], + "image": "http://3.bp.blogspot.com/-1hV3sD1At74/VIaQSWBasUI/AAAAAAAABAU/9vYLJMsmMuQ/s1600/studio-logo.png", + "type": "blog" + }, + { + "lang": "ja", + "title": "Google Play 開発者サービス 6.5 のご紹介", + "titleFriendly": "", + "summary": "", + "url": "http://googledevjp.blogspot.jp/2014/12/google-play-65.html", + "group": "", + "keywords": [], + "tags": [], + "image": "http://1.bp.blogspot.com/-4BNREC0Jojo/VGo7ahW35wI/AAAAAAAABAc/9thZl94F6fY/s1600/GMS%2B-%2BRelease%2BBlog%2BNacho%2B-%2BMap%2BToolbar.png", + "type": "blog" + }, + { + "lang": "ja", + "title": "Alpha and Beta Testing", + "titleFriendly": "", + "summary": "アプリのローンチにまつわるリスクを最小限にするために必須のツールです。[英語コンテンツ]", + "url": "intl/ja/distribute/googleplay/developer-console.html#alpha-beta", + "group": "", + "keywords": [], + "tags": [], + "image": "images/gp-dc-ab.png", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Finding Success on Google Play", + "titleFriendly": "", + "summary": "Google Play での成功の秘訣がこの一冊に。[英語コンテンツ]", + "url": "intl/ja/distribute/googleplay/guide.html", + "group": "", + "keywords": [], + "tags": [], + "image": "distribute/images/play_dev_guide_b.jpg", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Core App Quality", + "titleFriendly": "", + "summary": "", + "url": "intl/ja/distribute/essentials/quality/core.html", + "group": "", + "keywords": [], + "tags": [], + "image": "images/gp-core-quality.png", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Google Play アプリ ポリシー センター", + "titleFriendly": "", + "summary": "", + "url": "http://support.google.com/googleplay/android-developer/answer/4430948?hl=ja", + "group": "", + "keywords": [], + "tags": [], + "image": "https://storage.googleapis.com/support-kms-prod/SNP_712EA2784949DDF085C46E3BE7B1DC618A09_4389356_en_v0", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Developer Support", + "titleFriendly": "", + "summary": "", + "url": "intl/ja/support.html", + "group": "", + "keywords": [], + "tags": [], + "image": "", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Wear App Quality", + "titleFriendly": "", + "summary": "いよいよウェアラブルの時代が到来。[英語コンテンツ]", + "url": "intl/ja/distribute/essentials/quality/wear.html", + "group": "", + "keywords": [], + "tags": [], + "image": "distribute/images/gp-wear-quality.png", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Google Cloud Platform が支える、新感覚リアルタイム RPG ユニゾンリーグ - 株式会社エイチームの GCP 導入事例", + "titleFriendly": "", + "summary": "スケーラブルなバックエンドを実現する Google Cloud Platform の最新導入事例。", + "url": "http://googleforwork-japan.blogspot.jp/2014/12/gcp-google-cloud-platform-rpg-gcp.html", + "group": "", + "keywords": [], + "tags": [], + "image": "http://3.bp.blogspot.com/-xp7KoPkbne4/VI_PfoFil3I/AAAAAAAAA3U/-k1UZ0zjCBc/s1600/unison-league.jpeg", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Monetize with Ads", + "titleFriendly": "", + "summary": "アプリ内広告成功のコツがここに。[英語コンテンツ]", + "url": "intl/ja/distribute/monetize/ads.html", + "group": "", + "keywords": [], + "tags": [], + "image": "distribute/images/advertising.jpg", + "type": "distribute" } ]);
\ No newline at end of file diff --git a/docs/html/sdk/installing/index.jd b/docs/html/sdk/installing/index.jd index 40f5e4a..dc258db 100644 --- a/docs/html/sdk/installing/index.jd +++ b/docs/html/sdk/installing/index.jd @@ -122,7 +122,7 @@ you can access them at:</p> <li>If the SDK is not already installed, follow the setup wizard to install the SDK and any necessary SDK tools. <p class="note"><strong>Note:</strong> You may also need to install the ia32-libs, - lib32ncurses5-dev, and lib32stc++6 packages. These packages are required to support 32-bit apps + lib32ncurses5-dev, and lib32stdc++6 packages. These packages are required to support 32-bit apps on a 64-bit machine. </p> </li> </ol> diff --git a/docs/html/tools/help/android.jd b/docs/html/tools/help/android.jd index 19891e8..0d7d2aa 100644 --- a/docs/html/tools/help/android.jd +++ b/docs/html/tools/help/android.jd @@ -6,25 +6,26 @@ parent.link=index.html <p>{@code android} is an important development tool that lets you:</p> <ul> - <li>Create, delete, and view Android Virtual Devices (AVDs). See <a href= - "{@docRoot}tools/devices/managing-avds-cmdline.html">Managing AVDs from the Command -Line</a>.</li> + <li>Create, delete, and view Android Virtual Devices (AVDs). See <a href= + "{@docRoot}tools/devices/managing-avds-cmdline.html">Managing AVDs from the Command Line</a>.</li> - <li>Create and update Android projects. See <a href= + <li>Create and update Android projects. See <a href= "{@docRoot}tools/projects/projects-cmdline.html">Managing Projects from the Command Line</a>.</li> - <li>Update your Android SDK with new platforms, add-ons, and documentation. See <a href= - "{@docRoot}sdk/exploring.html">Exploring the SDK</a>.</li> - </ul>If you are using Eclipse, the <code>android</code> tool's features are integrated - into ADT, so you should not need to use this tool directly. - + <li>Update your Android SDK with new platforms, add-ons, and documentation. See <a href= + "{@docRoot}tools/help/sdk-manager.html">SDK Manager</a>.</li> + </ul> + +<p>If you are using Android Studio or Eclipse, the <code>android</code> tool's features are +integrated into the IDE, so you should not need to use this tool directly. </p> + <p class="note"><strong>Note:</strong> The documentation of options below is not exhaustive and may be out of date. For the most current list of options, execute <code>android --help</code>.</p> - - - + + + <h2>Syntax</h2> <pre>android [global options] action [action options]</pre> diff --git a/docs/html/tools/help/draw9patch.jd b/docs/html/tools/help/draw9patch.jd index 859b1cf..7c26441 100644 --- a/docs/html/tools/help/draw9patch.jd +++ b/docs/html/tools/help/draw9patch.jd @@ -2,42 +2,50 @@ page.title=Draw 9-patch page.tags=NinePatch @jd:body -<p>The Draw 9-patch tool allows you to easily create a - {@link android.graphics.NinePatch} graphic using a WYSIWYG editor.</p> -<p>For an introduction to Nine-patch graphics and how they work, please read -the section about Nine-patch in the -<a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D Graphics</a> +<p>The Draw 9-patch tool is a WYSIWYG editor that allows you to create bitmap images that +automatically resize to accommodate the contents of the view and the size of the screen. Selected +parts of the image are scaled horizontally or vertically based indicators drawn within the image. </p> +<p>For an introduction to NinePatch graphics and how they work, please read +the section about NinePatch Drawables in the +<a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">Canvas and Drawables</a> document.</p> <img src="{@docRoot}images/draw9patch-norm.png" style="float:right" alt="" height="300" width="341" /> -<p>Here's a quick guide to create a Nine-patch graphic using the Draw 9-patch tool. -You'll need the PNG image with which you'd like to create a NinePatch.</p> +<p>Here's a quick guide to create a NinePatch graphic using the Draw 9-patch tool. +You'll need the PNG image with which you'd like to create a NinePatch image.</p> <ol> - <li>From a terminal, launch the <code>draw9patch</code> application from your SDK - <code>/tools</code> directory. + <li>From a terminal, run the <code>draw9patch</code> command from your SDK + <code>sdk/tools</code> directory to launch the Draw 9-patch tool. </li> - <li>Drag your PNG image into the Draw 9-patch window + <li>Drag your PNG image into the Draw 9-patch window (or <strong>File</strong> > <strong>Open 9-patch...</strong> to locate the file). Your workspace will now open. <p>The left pane is your drawing area, in which you can edit the lines for the - stretchable patches and content area. The right + stretchable patches and content area. The right pane is the preview area, where you can preview your graphic when stretched.</p> </li> - <li>Click within the 1-pixel perimeter to draw the lines that define the stretchable - patches and (optional) content area. Right-click (or hold Shift and click, on Mac) to erase + <li>Click within the 1-pixel perimeter to draw the lines that define the stretchable + patches and (optional) content area. Right-click (or hold Shift and click, on Mac) to erase previously drawn lines. </li> <li>When done, select <strong>File</strong> > <strong>Save 9-patch...</strong> <p>Your image will be saved with the <code>.9.png</code> file name.</p> </li> </ol> - <p class="note"><strong>Note:</strong> A normal PNG file (<code>*.png</code>) will be - loaded with an empty one-pixel border added around the image, in which you can draw + + <p>To make sure that your NinePatch graphics scale down properly, verify that any + stretchable regions are at least 2x2 pixels in size. + Otherwise, they may disappear when scaled down. Also, provide one pixel of extra safe space in + the graphics before and after stretchable regions to avoid interpolation during scaling that may + cause the color at the boundaries to change. </p> + + <p class="note"><strong>Note:</strong> A normal PNG file (<code>*.png</code>) will be + loaded with an empty one-pixel border added around the image, in which you can draw the stretchable patches and content area. - A previously saved 9-patch file (<code>*.9.png</code>) will be loaded as-is, + A previously saved NinePatch file (<code>*.9.png</code>) will be loaded as-is, with no drawing area added, because it already exists.</p> <img src="{@docRoot}images/draw9patch-bad.png" style="float:right;clear:both" alt="" height="300" width="341" diff --git a/docs/html/training/enterprise/app-compatibility.jd b/docs/html/training/enterprise/app-compatibility.jd index 1ae1ee3..216a799 100644 --- a/docs/html/training/enterprise/app-compatibility.jd +++ b/docs/html/training/enterprise/app-compatibility.jd @@ -1,4 +1,6 @@ page.title=Ensuring Compatibility with Managed Profiles +page.metaDescription=Learn how to make sure your apps operate smoothly in a corporate environment by following some best practices. + @jd:body <div id="tb-wrapper"> diff --git a/docs/html/training/enterprise/app-restrictions.jd b/docs/html/training/enterprise/app-restrictions.jd new file mode 100644 index 0000000..fc5dfcc --- /dev/null +++ b/docs/html/training/enterprise/app-restrictions.jd @@ -0,0 +1,351 @@ +page.title=Implementing App Restrictions +page.metaDescription=Learn how to implement app restrictions and configuration settings that can be changed by other apps on the same device. +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#define_restrictions">Define App Restrictions</a></li> + <li><a href="#check_restrictions">Check App Restrictions</a></li> + <li><a href="#listen">Listen for App Restriction Changes</a></li> +</ol> + +<!-- related docs (NOT javadocs) --> +<h2>Resources</h2> +<ul> + <li><a href="{@docRoot}samples/AppRestrictionSchema/index.html">AppRestrictionSchema</a> + sample app</li> + <li><a href="{@docRoot}samples/AppRestrictionEnforcer/index.html">AppRestrictionEnforcer</a> + sample app</li> +</ul> + +</div> +</div> + +<p>If you are developing apps for the enterprise market, you may need to satisfy +particular requirements set by a company's policies. Application restrictions +allow the enterprise administrator to remotely specify settings for apps. +This capability is particularly useful for enterprise-approved apps deployed to +a managed profile.</p> + +<p>For example, an enterprise might require that approved apps allow the +enterprise administrator to:</p> + +<ul> + <li>Whitelist or blacklist URLs for a web browser</li> + <li>Configure whether an app is allowed to sync content via cellular, or just + by Wi-Fi</li> + <li>Configure the app's email settings</li> +</ul> + +<p> + This guide shows how to implement these configuration settings in your app. +</p> + +<p class="note"> + <strong>Note:</strong> For historical reasons, these configuration settings are known as + <em>restrictions,</em> and are implemented with files and classes that use this + term (such as {@link android.content.RestrictionsManager}). However, these + restrictions can actually implement a wide range of configuration options, + not just restrictions on app functionality. +</p> + +<h2 id="overview"> + Remote Configuration Overview +</h2> + +<p> + Apps define the restrictions and configuration options that can be remotely + set by an administrator. These restrictions are + arbitrary configuration settings that can be changed by a restrictions + provider. If your app is running on an enterprise device's managed + profile, the enterprise administrator can change your app's restrictions. +</p> + +<p> + The restrictions provider is another app running on the same device. + This app is typically controlled by the enterprise administrator. The + enterprise administrator communicates restriction changes to the restrictions + provider app. That app, in turn, changes the restrictions on your app. +</p> + +<p> + To provide externally configurable restrictions: +</p> + +<ul> + <li>Declare the restrictions in your app manifest. Doing so allows the + enterprise administrator to read the app's restrictions through Google + Play APIs. + </li> + + <li>Whenever the app resumes, use the {@link + android.content.RestrictionsManager} object to check the current + restrictions, and change your app's UI and behavior to conform with those + restrictions. + </li> + + <li>Listen for the + {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED + ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. When you receive this + broadcast, check the {@link android.content.RestrictionsManager} to see what + the current restrictions are, and make any necessary changes to your app's + behavior. + </li> +</ul> + +<h2 id="define_restrictions"> + Define App Restrictions +</h2> + +<p> + Your app can support any restrictions you want to define. You declare the + app's restrictions in a <em>restrictions file</em>, and declare the + restrictions file in the manifest. Creating a restrictions file allows other + apps to examine the restrictions your app provides. Enterprise Mobility + Management (EMM) partners can read your app's restrictions by using Google + Play APIs. +</p> + +<p> + To define your app's remote configuration options, put the following element + in your manifest's + <a href="{@docRoot}guide/topics/manifest/application-element.html"> + <code><application></code></a> element: +</p> + +<pre><meta-data android:name="android.content.APP_RESTRICTIONS" + android:resource="@xml/app_restrictions" /> +</pre> + +<p> + Create a file named <code>app_restrictions.xml</code> in your app's + <code>res/xml</code> directory. The structure of that file is described in + the reference for {@link android.content.RestrictionsManager}. The file has a + single top-level <code><restrictions></code> element, which contains + one <code><restriction></code> child element for every configuration + option the app has. +</p> + +<p class="note"> + <strong>Note:</strong> Do not create localized versions of the restrictions + file. Your app is only allowed to have a single restrictions file, + so restrictions will be consistent for your app in all locales. +</p> + +<p> + In an enterprise environment, an EMM will typically use the restrictions + schema to generate a remote console for IT administrators, so the + administrators can remotely configure your application. +</p> + +<p> + For example, suppose your app can be remotely configured to allow or forbid + it to download data over a cellular connection. Your app could have a + <code><restriction></code> element like this: +</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<restrictions xmlns:android="http://schemas.android.com/apk/res/android" > + + <restriction + android:key="downloadOnCellular" + android:title="App is allowed to download data via cellular" + android:restrictionType="bool" + android:description="If 'false', app can only download data via Wi-Fi" + android:defaultValue="true" /> + +</restrictions> +</pre> + +<p> + The supported types for the <code>android:restrictionType</code> element are + documented in the reference for {@link android.content.RestrictionsManager}. +</p> + +<p> + You use each restriction's <code>android:key</code> attribute to read its + value from a restrictions bundle. For this reason, each restriction must have + a unique key string, and the string <em>cannot</em> be localized. It must be + specified with a string literal. +</p> + +<p class="note"> + <strong>Note:</strong> In a production app, <code>android:title</code> and + <code>android:description</code> should be drawn from a localized resource + file, as described in <a href= + "{@docRoot}guide/topics/resources/localization.html">Localizing with + Resources</a>. +</p> + +<p> + The restrictions provider can query the app to find details on the app's + available restrictions, including their description text. Restrictions + providers and enterprise administrators can change your app's restrictions at + any time, even when the app is not running. +</p> + +<h2 id="check_restrictions"> + Check App Restrictions +</h2> + +<p> + Your app is not automatically notified when other apps change its restriction + settings. Instead, you need to check what the restrictions are when your app + starts or resumes, and listen for a system intent to find out if the + restrictions change while your app is running. +</p> + +<p> + To find out the current restriction settings, your app uses a {@link + android.content.RestrictionsManager} object. Your app should check for the + current restrictions at the following times: +</p> + +<ul> + <li>When the app starts or resumes, in its + {@link android.app.Activity#onResume onResume()} method + </li> + + <li>When the app is notified of a restriction change, as described in + <a href="#listen">Listen for Device Configuration + Changes</a> + </li> +</ul> + +<p> + To get a {@link android.content.RestrictionsManager} object, get the current + activity with {@link android.app.Fragment#getActivity getActivity()}, then + call that activity's {@link android.app.Activity#getSystemService + Activity.getSystemService()} method: +</p> + +<pre>RestrictionsManager myRestrictionsMgr = + (RestrictionsManager) getActivity() + .getSystemService(Context.RESTRICTIONS_SERVICE);</pre> + +<p> + Once you have a {@link android.content.RestrictionsManager}, you can get the current restrictions + settings by calling its + {@link android.content.RestrictionsManager#getApplicationRestrictions + getApplicationRestrictions()} method: +</p> + +<pre>Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();</pre> + +<p class="note"> + <strong>Note:</strong> For convenience, you can also fetch the current + restrictions with a {@link android.os.UserManager}, by calling {@link + android.os.UserManager#getApplicationRestrictions + UserManager.getApplicationRestrictions()}. This method behaves exactly the + same as {@link android.content.RestrictionsManager#getApplicationRestrictions + RestrictionsManager.getApplicationRestrictions()}. +</p> + +<p> + The {@link android.content.RestrictionsManager#getApplicationRestrictions + getApplicationRestrictions()} method requires reading from data storage, so + it should be done sparingly. Do not call this method every time you need to + know the current restrictions. Instead, you should call it once when your app + starts or resumes, and cache the fetched restrictions bundle. Then listen for + the {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED + ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent to find out if restrictions + change while your app is active, as described in <a href="#listen">Listen for + Device Configuration Changes</a>. +</p> + +<h3 id="read_restrictions"> + Reading and applying restrictions +</h3> + +<p> + The {@link android.content.RestrictionsManager#getApplicationRestrictions + getApplicationRestrictions()} method returns a {@link android.os.Bundle} + containing a key-value pair for each restriction that has been set. The + values are all of type <code>Boolean</code>, <code>int</code>, + <code>String</code>, and <code>String[]</code>. Once you have the + restrictions {@link android.os.Bundle}, you can check the current + restrictions settings with the standard {@link android.os.Bundle} methods for + those data types, such as {@link android.os.Bundle#getBoolean getBoolean()} + or + {@link android.os.Bundle#getString getString()}. +</p> + +<p class="note"> + <strong>Note:</strong> The restrictions {@link android.os.Bundle} contains + one item for every restriction that has been explicitly set by a restrictions + provider. However, you <em>cannot</em> assume that a restriction will be + present in the bundle just because you defined a default value in the + restrictions XML file. +</p> + +<p> + It is up to your app to take appropriate action based on the current + restrictions settings. For example, if your app has a restriction specifying + whether it can download data over a cellular connection, and you find that + the restriction is set to <code>false</code>, you would have to disable data + download except when the device has a Wi-Fi connection, as shown in the + following example code: +</p> + +<pre> +boolean appCanUseCellular; + +if appRestrictions.containsKey("downloadOnCellular") { + appCanUseCellular = appRestrictions.getBoolean("downloadOnCellular"); +} else { + // here, cellularDefault is a boolean set with the restriction's + // default value + appCanUseCellular = cellularDefault; +} + +if (!appCanUseCellular) { + // ...turn off app's cellular-download functionality + // ...show appropriate notices to user +}</pre> + +<h2 id="listen"> + Listen for App Restriction Changes +</h2> + +<p> + Whenever an app's restrictions are changed, the system fires the + {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED + ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. Your app has to listen for + this intent so you can change the app's behavior when the restriction settings + change. The following code shows how to dynamically register a broadcast + receiver for this intent: +</p> + +<pre>IntentFilter restrictionsFilter = + new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); + +BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { + + // Get the current restrictions bundle + Bundle <code>appRestrictions</code> = + + myRestrictionsMgr.getApplicationRestrictions(); + + // Check current restrictions settings, change your app's UI and + // functionality as necessary. + + } + +}; + +registerReceiver(restrictionsReceiver, restrictionsFilter); +</pre> +<p class="note"> + <strong>Note:</strong> Ordinarily, your app does not need to be notified + about restriction changes when it is paused. Instead, you should unregister + your broadcast receiver when the app is paused. When the app resumes, you + first check for the current restrictions (as discussed in <a href= + "#check_restrictions">Check Device Restrictions</a>), then register your + broadcast receiver to make sure you're notified about restriction changes + that happen while the app is active. +</p> diff --git a/docs/html/training/enterprise/index.jd b/docs/html/training/enterprise/index.jd index 0ac68cc..10be14e 100644 --- a/docs/html/training/enterprise/index.jd +++ b/docs/html/training/enterprise/index.jd @@ -1,58 +1,67 @@ -page.title=Developing for Enterprise -page.tags=policy,privacy - -trainingnavtop=true -startpage=true -next.title=Enhancing Security with Device Management Policies -next.link=device-management-policy.html +page.title=Building Apps for Work +meta.tags="work, enterprise, corporate" +page.tags="work", "enterprise", "corporate" +page.metaDescription=Learn how to build Android apps for the enterprise and take advantage of Google's Android for Work program. +page.tags="education" +page.article=true @jd:body -<div id="tb-wrapper"> -<div id="tb"> - -<!-- Required platform, tools, add-ons, devices, knowledge, etc. --> -<h2>Dependencies and prerequisites</h2> -<ul> - <li>Android 2.2 (API Level 8) or higher</li> -</ul> - -<!-- related docs (NOT javadocs) --> -<h2>You should also read</h2> -<ul> - <li><a href="{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a></li> -</ul> - -<h2>Try it out</h2> - -<div class="download-box"> - <a href="http://developer.android.com/shareables/training/DeviceManagement.zip" -class="button">Download the sample</a> - <p class="filename">DeviceManagement.zip</p> -</div> - +<img src="{@docRoot}images/enterprise/work-launcher.png" + width="300" + style="float:right;margin:0 0 20px 20px" + alt="Android for Work apps in a managed profile"> + +<p> + The Android framework provides features to support the security, data separation, and + administration needs of a enterprise environment. As an app developer, you can make your app more + appealing to corporate customers by gracefully handling enterprise security and feature + restrictions. You can also modify your app so that technology administrators can remotely + configure it for use with enterprise resources. +</p> + +<p> + To help businesses incorporate Android devices and apps into the workplace, Google provides the + <a href="http://www.google.com/work/android">Android for Work</a> program, which offers a suite + of APIs and services for device distribution and administration. Through this program companies + can connect with Enterprise Mobility Management (EMM) providers to help integrate Android with + their businesses. +</p> + +<p> + For more information, follow the links below to learn how to update your Android app to support + the enterprise environment or build enterprise-specific solutions. +</p> + + +<h2 id="apps">App Development for Enterprises</h2> + +<p> + Learn how to make your app function smoothly in corporate environments that restrict device + features and data access. Go further to support enterprise use of your app by enabling + restrictions that corporate technology administrators can use to remotely configure your app: +</p> + +<div class="dynamic-grid"> + <div class="resource-widget resource-flow-layout landing col-12" + data-query="collection:training/work/apps" + data-cardSizes="9x3" + data-maxResults="6"> + </div> </div> -</div> - - -<p>In this class, you'll learn APIs and techniques you can use when developing applications -for the enterprise.</p> - -<h2>Lessons</h2> +<h2 id="admin">Device and App Administration</h2> -<dl> - <dt><b><a href="device-management-policy.html">Enhancing Security with Device Management -Policies</a></b></dt> - <dd>In this lesson, you will learn how to create a security-aware application that manages -access to its content by enforcing device management policies</dd> +<p> + Learn how to build policy controller apps that enable enterprise technology administrators + to manage devices, manage corporate apps, and provide access to company resources: +</p> - <dt><b><a href="app-compatibility.html">Ensuring Compatibility with Managed Profiles</a></b></dt> - - <dd>In this lesson, you will learn the best practices to follow to ensure - that your app functions properly on devices that use <a - href="{@docRoot}about/versions/android-5.0.html#Enterprise">managed - profiles</a></dd> - -</dl> +<div class="dynamic-grid"> + <div class="resource-widget resource-flow-layout landing col-12" + data-query="collection:training/work/admin" + data-cardSizes="9x3" + data-maxResults="4"> + </div> +</div> diff --git a/docs/html/training/enterprise/work-policy-ctrl.jd b/docs/html/training/enterprise/work-policy-ctrl.jd new file mode 100644 index 0000000..5854e65 --- /dev/null +++ b/docs/html/training/enterprise/work-policy-ctrl.jd @@ -0,0 +1,339 @@ +page.title=Building a Work Policy Controller +page.metaDescription=Learn how to develop a Work Policy Controller to create and administer a managed profile on an employee's device. +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#after_creating_profile">Create a Managed Profile</a></li> + <li><a href="#set_up_policies">Set Up Device Policies</a></li> + <li><a href="#apply_restrictions">Apply App Restrictions</a></li> +</ol> + +<!-- related docs (NOT javadocs) --> + +<h2> + You should also read +</h2> + +<ul> + <li> + <a href="{@docRoot}guide/topics/admin/device-admin.html">Device + Administration</a> + </li> +</ul> + +<h2>Resources</h2> +<ul> + + <li> + <a href= + "{@docRoot}samples/BasicManagedProfile/index.html">BasicManagedProfile</a> + </li> + + <li> + <a href= + "{@docRoot}samples/AppRestrictionEnforcer/index.html">AppRestrictionEnforcer</a> + </li> +</ul> + +</div> +</div> + + +<p> + In an Android for Work deployment, an enterprise needs to maintain control + over certain aspects of the employees' devices. The enterprise needs to + ensure that work-related information is encrypted and is kept separate from + employees' personal data. The enterprise may also need to limit device + capabilities, such as whether the device is allowed to use its camera. And + the enterprise may require that approved apps provide app restrictions, so + the enterprise can turn app capability on or off as needed. +</p> + +<p> + To handle these tasks, an enterprise develops and deploys a Work Policy + Controller app. This app is installed on each employee's device. The + controller app installed on each employee's device and creates a work user + profile, which accesses enterprise apps and data separately from the user's + personal account. The controller app also acts as the + bridge between the enterprise's management software and the device; the + enterprise tells the controller app when it needs to make configuration + changes, and the controller app makes the appropriate settings changes for the + device and for other apps. +</p> + +<p> + This lesson describes how to develop a Work Policy Controller app for devices + in an Android for Work deployment. The lesson describes how to create a work + user profile, how to set device policies, and how to apply + restrictions to other apps running on the managed profile. +</p> + +<p class="note"> + <strong>Note:</strong> This lesson does not cover the situation where the + only profile on the device is the managed profile, under the enterprise's + control. +</p> + +<h2 id="overview">Device Administration Overview</h2> + +<p> + In an Android for Work deployment, the enterprise administrator can set + policies to control the behavior of employees' devices and apps. The + enterprise administrator sets these policies with software provided by their + Enterprise Mobility Management (EMM) provider. The EMM software communicates + with a Work Policy Controller on each device. The Work Policy Controller, in + turn, manages the settings and behavior of the work user profile on each + individual’s device. +</p> + +<p class="note"> + <strong>Note:</strong> A Work Policy Controller is built on the existing + model used for device administration applications, as described in <a href= + "{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a>. + In particular, your app needs to create a subclass of {@link + android.app.admin.DeviceAdminReceiver}, as described in that document. +</p> + +<h3 id="managed_profiles">Managed profiles</h3> + +<p> + Users often want to use their personal devices in an enterprise setting. This + situation can present enterprises with a dilemma. If the user can use their + own device, the enterprise has to worry that confidential information (like + employee emails and contacts) are on a device the enterprise does not + control. +</p> + +<p> + To address this situation, Android 5.0 (API level 21) allows enterprises to + set up a special work user profile using the Managed Profile API. This + user profile is called a <em>managed profile</em>, or a <em>work profile</em> + in the Android for Work program. If a device has a + managed profile for work, the profile's settings are under the control of the + enterprise administrator. The administrator can choose which apps are allowed + for that profile, and can control just what device features are available to + the profile. +</p> + +<h2 id="create_profile">Create a Managed Profile</h2> + +<p>To create a managed profile on a device that already has a personal profile, +first check that the device can support a managed profile, by seeing if the +device supports the {@link +android.content.pm.PackageManager#FEATURE_MANAGED_USERS FEATURE_MANAGED_USERS} +system feature:</p> + +<pre>PackageManager pm = getPackageManager(); +if (!pm.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) { + + // This device does not support native managed profiles! + +}</pre> + +<p>If the device supports managed profiles, create one by sending an intent with +an {@link android.app.admin.DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE +ACTION_PROVISION_MANAGED_PROFILE} action. Include the device admin package +name as an extra.</p> + +<pre>Activity provisioningActivity = getActivity(); + +// You'll need the package name for the WPC app. +String myWPCPackageName = "com.example.myWPCApp"; + +// Set up the provisioning intent +Intent provisioningIntent = + new Intent("android.app.action.PROVISION_MANAGED_PROFILE"); +intent.putExtra(myWPCPackageName, + provisioningActivity.getApplicationContext().getPackageName()); + +if (provisioningIntent.resolveActivity(provisioningActivity.getPackageManager()) + == null) { + + // No handler for intent! Can't provision this device. + // Show an error message and cancel. +} else { + + // REQUEST_PROVISION_MANAGED_PROFILE is defined + // to be a suitable request code + startActivityForResult(provisioningIntent, + REQUEST_PROVISION_MANAGED_PROFILE); + provisioningActivity.finish(); +}</pre> + +<p>The system responds to this intent by doing the following:</p> + +<ul> + <li>Verifies that the device is encrypted. If it is not, the system prompts + the user to encrypt the device before proceeding. + </li> + + <li>Creates a managed profile. + </li> + + <li>Removes non-required applications from the managed profile. + </li> + + <li>Copies the Work Policy Controller application into the managed profile and + sets it as the profile owner. + </li> +</ul> + +<p>Override {@link android.app.Activity#onActivityResult onActivityResult()} to +see whether the provisioning was successful, as shown in the following +example code:</p> + +<pre>@Override +public void onActivityResult(int requestCode, int resultCode, Intent data) { + + // Check if this is the result of the provisioning activity + if (requestCode == REQUEST_PROVISION_MANAGED_PROFILE) { + + // If provisioning was successful, the result code is + // Activity.RESULT_OK + if (resultCode == Activity.RESULT_OK) { + // Hurray! Managed profile created and provisioned! + } else { + // Boo! Provisioning failed! + } + return; + + } else { + // This is the result of some other activity, call the superclass + super.onActivityResult(requestCode, resultCode, data); + } +}</pre> + +<h3 id="after_creating_profile">After Creating the Managed Profile</h3> + +<p>When the profile has been provisioned, the system calls the Work Policy +Controller app's {@link +android.app.admin.DeviceAdminReceiver#onProfileProvisioningComplete +DeviceAdminReceiver.onProfileProvisioningComplete()} method. Override this +callback method to finish enabling the managed profile.</p> + +<p>Typically, your {@link +android.app.admin.DeviceAdminReceiver#onProfileProvisioningComplete +DeviceAdminReceiver.onProfileProvisioningComplete()} callback implementation +would perform these tasks:</p> + +<ul> + <li>Verify that the device is complying with the EMM's device policies, as + described in <a href="#set_up_policies">Set Up Device Policies</a> + </li> + + <li>Enable any system applications that the administrator chooses to make + available within the managed profile, using {@link + android.app.admin.DevicePolicyManager#enableSystemApp + DevicePolicyManager.enableSystemApp()} </li> + + <li>If the device uses Google Play for Work, add the Google account + to the managed profile with {@link android.accounts.AccountManager#addAccount + AccountManager.addAccount()}, so administrators can install + applications to the device + </li> +</ul> + +<p>Once you have completed these tasks, call the device policy manager's +{@link android.app.admin.DevicePolicyManager#setProfileEnabled +setProfileEnabled()} method to activate the managed profile:</p> + + +<pre>// Get the device policy manager +DevicePolicyManager myDevicePolicyMgr = + (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); + +ComponentName componentName = myDeviceAdminReceiver.getComponentName(this); + +// Set the name for the newly created managed profile. +myDevicePolicyMgr.setProfileName(componentName, "My New Managed Profile"); + +// ...and enable the profile +manager.setProfileEnabled(componentName);</pre> + +<h2 id="set_up_policies">Set Up Device Policies</h2> + +<p> + The Work Policy Controller app is responsible for applying the enterprise's + device policies. For example, a particular enterprise might require that all + devices become locked after a certain number of failed attempts to enter the + device password. The controller app queries the EMM to find out what + the current policies are, then uses the <a href= + "{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a> + API to apply those policies. +</p> + +<p>For information on how to apply device policies, see the +<a href="{@docRoot}guide/topics/admin/device-admin.html#policies">Device +Administration</a> guide.</p> + + +<h2 id="apply_restrictions">Apply App Restrictions</h2> + +<p>Enterprise environments may require that approved apps implement apps +implement security or feature restrictions. App developers must implement these +restrictions and declare them for use by enterprise administrators, as described +in <a href="{@docRoot}training/enterprise/app-restrictions.html">Implementing +App Restrictions</a>. The Work Policy Controller receives restriction changes +from the enterprise administrator, and forwards those restriction changes to the +apps.</p> + +<p>For example, a particular news app might have a restriction setting that +controls whether the app is allowed to download videos over a cellular +network. When the EMM wants to disable cellular downloads, it sends a +notification to the controller app. The controller app, in turn, +notifies the news app that the restriction setting has changed.</p> + +<p class="note"><strong>Note:</strong> This document covers how the Work Policy +Controller app changes the restriction settings for the other apps on the +managed profile. Details on how the Work Policy Controller app communicates with +the EMM are out of scope for this document.</p> + +<p>To change an app's restrictions, call the {@link +android.app.admin.DevicePolicyManager#setApplicationRestrictions +DevicePolicyManager.setApplicationRestrictions()} method. This method is passed +three parameters: the controller app's {@link +android.app.admin.DeviceAdminReceiver}, the package name of the app whose +restrictions are being changed, and a {@link android.os.Bundle Bundle} that +contains the restrictions you want to set.</p> + +<p>For example, suppose there's an app on the managed profile with the package +name <code>"com.example.newsfetcher"</code>. This app has a single boolean +restriction that can be configured, with the key +<code>"downloadByCellular"</code>. If this restriction is set to +<code>false</code>, the newsfetcher app is not allowed to download data through +a cellular network; it must use a Wi-Fi network instead.</p> + +<p> + If your Work Policy Controller app needs to turn off cellular downloads, it + would first fetch the device policy service object, as described above. It + then assembles a restrictions bundle and passes this bundle to {@link + android.app.admin.DevicePolicyManager#setApplicationRestrictions + setApplicationRestrictions()}: +</p> + +<pre>// Fetch the DevicePolicyManager +DevicePolicyManager myDevicePolicyMgr = + (DevicePolicyManager) thisActivity + .getSystemService(Context.DEVICE_POLICY_SERVICE); + +// Set up the restrictions bundle +bundle restrictionsBundle = new Bundle(); +restrictionsBundle.putBoolean("downloadByCellular", false); + +// Pass the restrictions to the policy manager. Assume the WPC app +// already has a DeviceAdminReceiver defined (myDeviceAdminReceiver). +myDevicePolicyMgr.setApplicationRestrictions( + myDeviceAdminReceiver, "com.example.newsfetcher", restrictionsBundle);</pre> + + +<p class="note"><strong>Note:</strong> The device policy service conveys the restrictions +change to the app you name. However, it is up to that app to actually implement +the restriction. For example, in this case, the app would be responsible for +disabling its ability to use cellular networks for video downloads. Setting the +restriction does not cause the system to enforce this restriction on the app. +For more information, see <a href="{@docRoot}training/enterprise/app- +restrictions.html">Implementing App Restrictions</a>.</p> diff --git a/docs/html/training/material/animations.jd b/docs/html/training/material/animations.jd index efc0ee3..86e91a7 100644 --- a/docs/html/training/material/animations.jd +++ b/docs/html/training/material/animations.jd @@ -46,9 +46,10 @@ between different states with a ripple effect.</p> background as:</p> <ul> -<li><code>?android:attr/selectableItemBackground</code> for a bounded ripple</li> +<li><code>?android:attr/selectableItemBackground</code> for a bounded ripple.</li> <li><code>?android:attr/selectableItemBackgroundBorderless</code> for a ripple that extends beyond -the view</li> +the view. It will be drawn upon, and bounded by, the nearest parent of the view with a non-null +background.</li> </ul> <p class="note"><strong>Note:</strong> <code>selectableItemBackgroundBorderless</code> is a new diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index c59d8ff..89e72f1 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -1040,6 +1040,32 @@ include the action bar on devices running Android 2.1 or higher." <!-- End: Building for Auto --> + <!-- Start: Building for Work --> + <li class="nav-section"> + <div class="nav-section-header"> + <a href="<?cs var:toroot ?>training/enterprise/index.html"> + <span class="small">Building Apps for</span><br/> + Work + </a> + </div> + <ul> + <li><a href="<?cs var:toroot ?>training/enterprise/app-compatibility.html"> + Ensuring Compatibility with Managed Profiles + </a> + </li> + <li><a href="<?cs var:toroot ?>training/enterprise/app-restrictions.html"> + Implementing App Restrictions + </a> + </li> + <li><a href="<?cs var:toroot ?>training/enterprise/work-policy-ctrl.html"> + Building a Work Policy Controller + </a> + </li> + </ul> + </li> + <!-- End: Building for Work --> + + <li class="nav-section"> <div class="nav-section-header"> <a href="<?cs var:toroot ?>training/best-ux.html"> @@ -1752,10 +1778,6 @@ results." Enhancing Security with Device Management Policies </a> </li> - <li><a href="<?cs var:toroot ?>training/enterprise/app-compatibility.html"> - Ensuring Compatibility with Managed Profiles - </a> - </li> </ul> </li> </ul> @@ -1887,4 +1909,4 @@ results." buildToggleLists(); changeNavLang(getLangPref()); //--> -</script>
\ No newline at end of file +</script> diff --git a/docs/html/training/wearables/apps/creating.jd b/docs/html/training/wearables/apps/creating.jd index c12ffa7..487615b 100644 --- a/docs/html/training/wearables/apps/creating.jd +++ b/docs/html/training/wearables/apps/creating.jd @@ -106,6 +106,15 @@ types of screen shapes, which is useful for testing.</p> <li>Follow the app's instructions to pair your handheld with your wearable. This allows you to test out synced handheld notifications, if you're building them.</li> <li>Leave the Android Wear app open on your phone.</li> + <li>Enable adb debugging on the Android Wear device.</li> + <ol> + <li>Go to <strong>Settings > About</strong>.</li> + <li>Tap <strong>Build number</strong> seven times.</li> + <li>Swipe right to return to the Settings menu.</li> + <li>Go to <strong>Developer options</strong> at the bottom of the screen. + </li> + <li>Tap <strong>ADB Debugging</strong> to enable adb.</li> + </ol> <li>Connect the wearable to your machine through USB, so you can install apps directly to it as you develop. A message appears on both the wearable and the Android Wear app prompting you to allow debugging.</li> <p class="note"><strong>Note:</strong> If you can not connect your wearable to your machine via USB, |