summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/html/guide/appendix/install-location.jd6
-rw-r--r--docs/html/guide/appendix/market-filters.jd675
-rw-r--r--docs/html/guide/appendix/media-formats.jd6
-rw-r--r--docs/html/guide/developing/debug-tasks.jd76
-rw-r--r--docs/html/guide/developing/eclipse-adt.jd93
-rw-r--r--docs/html/guide/developing/other-ide.jd20
-rw-r--r--docs/html/guide/developing/testing/index.jd3
-rw-r--r--docs/html/guide/developing/testing/testing_eclipse.jd720
-rw-r--r--docs/html/guide/developing/testing/testing_otheride.jd631
-rw-r--r--docs/html/guide/developing/tools/MonkeyDevice.jd1353
-rw-r--r--docs/html/guide/developing/tools/MonkeyImage.jd435
-rw-r--r--docs/html/guide/developing/tools/MonkeyRunner.jd445
-rw-r--r--docs/html/guide/developing/tools/avd.jd269
-rw-r--r--docs/html/guide/developing/tools/index.jd75
-rw-r--r--docs/html/guide/developing/tools/monkeyrunner_concepts.jd308
-rw-r--r--docs/html/guide/developing/tools/proguard.jd187
-rw-r--r--docs/html/guide/guide_toc.cs137
-rw-r--r--docs/html/guide/practices/design/performance.jd265
-rw-r--r--docs/html/guide/practices/design/responsiveness.jd75
-rw-r--r--docs/html/guide/practices/design/seamlessness.jd35
-rw-r--r--docs/html/guide/practices/screens_support.jd804
-rw-r--r--docs/html/guide/practices/ui_guidelines/activity_task_design.jd6
-rw-r--r--docs/html/guide/practices/ui_guidelines/icon_design.jd25
-rw-r--r--docs/html/guide/practices/ui_guidelines/icon_design_1.jd11
-rw-r--r--docs/html/guide/practices/ui_guidelines/menu_design.jd2
-rw-r--r--docs/html/guide/practices/ui_guidelines/widget_design.jd4
-rw-r--r--docs/html/guide/publishing/app-signing.jd2
-rw-r--r--docs/html/guide/publishing/licensing.jd2376
-rw-r--r--docs/html/guide/publishing/preparing.jd56
-rw-r--r--docs/html/guide/publishing/publishing.jd27
-rw-r--r--docs/html/guide/publishing/versioning.jd2
-rw-r--r--docs/html/guide/samples/index.jd98
-rw-r--r--docs/html/guide/topics/admin/device-admin.jd532
-rw-r--r--docs/html/guide/topics/appwidgets/index.jd21
-rw-r--r--docs/html/guide/topics/data/backup.jd8
-rw-r--r--docs/html/guide/topics/data/data-storage.jd4
-rw-r--r--docs/html/guide/topics/fundamentals.jd24
-rw-r--r--docs/html/guide/topics/intents/intents-filters.jd18
-rw-r--r--docs/html/guide/topics/location/index.jd107
-rw-r--r--docs/html/guide/topics/location/obtaining-user-location.jd454
-rw-r--r--docs/html/guide/topics/manifest/activity-element.jd122
-rw-r--r--docs/html/guide/topics/manifest/application-element.jd9
-rw-r--r--docs/html/guide/topics/manifest/manifest-element.jd5
-rw-r--r--docs/html/guide/topics/manifest/uses-feature-element.jd966
-rw-r--r--docs/html/guide/topics/manifest/uses-permission-element.jd41
-rw-r--r--docs/html/guide/topics/media/index.jd18
-rw-r--r--docs/html/guide/topics/providers/content-providers.jd23
-rw-r--r--docs/html/guide/topics/resources/available-resources.jd17
-rw-r--r--docs/html/guide/topics/resources/color-list-resource.jd1
-rw-r--r--docs/html/guide/topics/resources/drawable-resource.jd1335
-rw-r--r--docs/html/guide/topics/resources/layout-resource.jd87
-rwxr-xr-xdocs/html/guide/topics/resources/localization.jd12
-rw-r--r--docs/html/guide/topics/resources/menu-resource.jd12
-rw-r--r--docs/html/guide/topics/resources/more-resources.jd139
-rw-r--r--docs/html/guide/topics/resources/providing-resources.jd28
-rw-r--r--docs/html/guide/topics/search/adding-custom-suggestions.jd589
-rw-r--r--docs/html/guide/topics/search/adding-recent-query-suggestions.jd214
-rw-r--r--docs/html/guide/topics/search/index.jd106
-rw-r--r--docs/html/guide/topics/search/search-dialog.jd460
-rw-r--r--docs/html/guide/topics/search/searchable-config.jd268
-rw-r--r--docs/html/guide/topics/security/security.jd76
-rw-r--r--docs/html/guide/topics/testing/activity_testing.jd392
-rw-r--r--docs/html/guide/topics/testing/contentprovider_testing.jd222
-rw-r--r--docs/html/guide/topics/testing/index.jd84
-rw-r--r--docs/html/guide/topics/testing/service_testing.jd178
-rwxr-xr-xdocs/html/guide/topics/testing/testing_android.jd918
-rw-r--r--docs/html/guide/topics/testing/what_to_test.jd84
-rw-r--r--docs/html/guide/topics/ui/binding.jd8
-rw-r--r--docs/html/guide/topics/ui/declaring-layout.jd12
-rw-r--r--docs/html/guide/topics/ui/dialogs.jd9
-rw-r--r--docs/html/guide/topics/ui/index.jd14
-rw-r--r--docs/html/guide/topics/ui/menus.jd892
-rw-r--r--docs/html/guide/topics/ui/notifiers/index.jd8
-rw-r--r--docs/html/guide/topics/ui/notifiers/notifications.jd20
-rw-r--r--docs/html/guide/topics/ui/notifiers/toasts.jd14
-rw-r--r--docs/html/guide/topics/ui/ui-events.jd4
-rw-r--r--docs/html/guide/topics/wireless/bluetooth.jd28
-rw-r--r--docs/html/guide/webapps/best-practices.jd90
-rw-r--r--docs/html/guide/webapps/debugging.jd158
-rw-r--r--docs/html/guide/webapps/index.jd71
-rw-r--r--docs/html/guide/webapps/targeting.jd439
-rw-r--r--docs/html/guide/webapps/webview.jd328
-rwxr-xr-xdocs/html/images/admin/device-admin-activate-prompt.pngbin0 -> 38584 bytes
-rwxr-xr-xdocs/html/images/admin/device-admin-app.pngbin0 -> 31310 bytes
-rw-r--r--docs/html/images/axis_device.pngbin0 -> 17625 bytes
-rw-r--r--docs/html/images/axis_globe.pngbin0 -> 8306 bytes
-rw-r--r--docs/html/images/axis_globe_inverted.pngbin0 -> 6296 bytes
-rwxr-xr-xdocs/html/images/developing/avd-dialog.pngbin0 -> 86111 bytes
-rw-r--r--docs/html/images/developing/lib-migration-0.pngbin0 -> 26786 bytes
-rw-r--r--docs/html/images/developing/lib-migration-1.pngbin0 -> 93526 bytes
-rw-r--r--docs/html/images/developing/lib-migration-2.pngbin0 -> 18598 bytes
-rw-r--r--docs/html/images/home/market-intl.pngbin0 -> 4953 bytes
-rw-r--r--docs/html/images/licensing_add_library.pngbin0 -> 70285 bytes
-rw-r--r--docs/html/images/licensing_arch.pngbin0 -> 41227 bytes
-rw-r--r--docs/html/images/licensing_device_signin.pngbin0 -> 75152 bytes
-rw-r--r--docs/html/images/licensing_flow.pngbin0 -> 47151 bytes
-rw-r--r--docs/html/images/licensing_gapis_8.pngbin0 -> 84597 bytes
-rw-r--r--docs/html/images/licensing_package.pngbin0 -> 78821 bytes
-rw-r--r--docs/html/images/licensing_public_key.pngbin0 -> 95876 bytes
-rw-r--r--docs/html/images/licensing_test_response.pngbin0 -> 120461 bytes
-rw-r--r--docs/html/images/location/content-tagging.pngbin0 -> 16634 bytes
-rw-r--r--docs/html/images/location/getting-location.pngbin0 -> 25174 bytes
-rw-r--r--docs/html/images/location/where-to-go.pngbin0 -> 19859 bytes
-rw-r--r--docs/html/images/resources/clip.pngbin0 -> 2464 bytes
-rw-r--r--docs/html/images/resources/layers.pngbin0 -> 8248 bytes
-rw-r--r--docs/html/images/screens_support/screens-ranges.pngbin0 -> 21221 bytes
-rwxr-xr-xdocs/html/images/sdk_manager_packages.pngbin79905 -> 88599 bytes
-rwxr-xr-xdocs/html/images/testing/android_test_framework.pngbin82419 -> 47368 bytes
-rw-r--r--docs/html/images/testing/eclipse_test_results.pngbin0 -> 24260 bytes
-rw-r--r--docs/html/images/testing/eclipse_test_run_failure.pngbin0 -> 49342 bytes
-rw-r--r--docs/html/images/testing/test_framework.pngbin0 -> 43397 bytes
-rw-r--r--docs/html/images/webapps/compare-default.pngbin0 -> 44013 bytes
-rw-r--r--docs/html/images/webapps/compare-initialscale-devicedpi.pngbin0 -> 48657 bytes
-rw-r--r--docs/html/images/webapps/compare-initialscale.pngbin0 -> 50448 bytes
-rw-r--r--docs/html/images/webapps/compare-width-devicedpi-css.pngbin0 -> 50771 bytes
-rw-r--r--docs/html/images/webapps/compare-width400.pngbin0 -> 48665 bytes
-rw-r--r--docs/html/images/webapps/webapps.pngbin0 -> 35420 bytes
-rw-r--r--docs/html/index.jd41
-rw-r--r--docs/html/resources/articles/layout-tricks-reuse.jd18
-rw-r--r--docs/html/resources/community-groups.jd10
-rw-r--r--docs/html/resources/dashboard/platform-versions.jd75
-rw-r--r--docs/html/resources/dashboard/screens.jd14
-rw-r--r--docs/html/resources/faq/commontasks.jd2
-rw-r--r--docs/html/resources/faq/framework.jd43
-rw-r--r--docs/html/resources/resources_toc.cs20
-rw-r--r--docs/html/resources/samples/images/NfcDemo.pngbin0 -> 12750 bytes
-rwxr-xr-xdocs/html/resources/samples/images/SipDemo.pngbin0 -> 72267 bytes
-rw-r--r--docs/html/resources/samples/index.jd7
-rw-r--r--docs/html/resources/tutorials/notepad/codelab/NotepadCodeLab.zipbin88600 -> 93415 bytes
-rw-r--r--docs/html/resources/tutorials/notepad/notepad-ex2.jd6
-rw-r--r--docs/html/resources/tutorials/views/hello-formstuff.jd26
-rw-r--r--docs/html/sdk/adding-components.jd137
-rw-r--r--docs/html/sdk/adt_download.jd27
-rw-r--r--docs/html/sdk/android-1.5.jd6
-rw-r--r--docs/html/sdk/android-1.6.jd6
-rw-r--r--docs/html/sdk/android-2.0.1.jd4
-rw-r--r--docs/html/sdk/android-2.0.jd4
-rw-r--r--docs/html/sdk/android-2.1.jd5
-rw-r--r--docs/html/sdk/android-2.2.jd41
-rw-r--r--docs/html/sdk/download.jd4
-rw-r--r--docs/html/sdk/eclipse-adt.jd342
-rw-r--r--docs/html/sdk/index.jd83
-rw-r--r--docs/html/sdk/installing.jd446
-rw-r--r--docs/html/sdk/ndk/index.jd1032
-rw-r--r--docs/html/sdk/ndk/overview.jd334
-rw-r--r--docs/html/sdk/older_releases.jd42
-rw-r--r--docs/html/sdk/requirements.jd22
-rw-r--r--docs/html/sdk/sdk_toc.cs21
-rw-r--r--docs/html/sdk/tools-notes.jd99
-rw-r--r--docs/html/sitemap.txt5
-rw-r--r--docs/html/videos/index.jd132
-rw-r--r--docs/knowntags.txt38
152 files changed, 16661 insertions, 5327 deletions
diff --git a/docs/html/guide/appendix/install-location.jd b/docs/html/guide/appendix/install-location.jd
index be89caf..914aa66 100644
--- a/docs/html/guide/appendix/install-location.jd
+++ b/docs/html/guide/appendix/install-location.jd
@@ -111,7 +111,7 @@ storage.</p>
<p class="caution"><strong>Caution:</strong> Although XML markup such as this will be ignored by
older platforms, you must be careful not to use programming APIs introduced in API Level 8
while your {@code minSdkVersion} is less than "8", unless you perform the work necessary to
-provide backward compatiblity in your code. For information about building
+provide backward compatibility in your code. For information about building
backward compatibility in your application code, see the <a
href="{@docRoot}resources/articles/backward-compatibility.html">Backward Compatibility</a>
article.</p>
@@ -167,6 +167,10 @@ not work until external storage is remounted.</dd>
<dd>Your {@link android.app.admin.DeviceAdminReceiver} and all its admin capabilities will
be disabled, which can have unforeseeable consequences for the device functionality, which may
persist after external storage is remounted.</dd>
+ <dt>Broadcast Receivers listening for "boot completed"</dt>
+ <dd>The system delivers the {@link android.content.Intent#ACTION_BOOT_COMPLETED} broadcast
+before the external storage is mounted to the device. If your application is installed on the
+external storage, it can never receive this broadcast.</dd>
</dl>
<p>If your application uses any of the features listed above, you <strong>should not</strong> allow
diff --git a/docs/html/guide/appendix/market-filters.jd b/docs/html/guide/appendix/market-filters.jd
index 0797892..6ca8acc 100644
--- a/docs/html/guide/appendix/market-filters.jd
+++ b/docs/html/guide/appendix/market-filters.jd
@@ -1,322 +1,353 @@
-page.title=Market Filters
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2 align="left">Market filters quickview</h2>
-<ul> <li>Android Market applies filters to that let you control whether your app is shown to a
-user who is browing or searching for apps.</li>
-<li>Filtering is determined by elements in an app's manifest file,
-aspects of the device being used, and other factors.</li> </ul>
-
-<h2>In this document</h2>
-
-<ol> <li><a href="#how-filters-work">How Filters Work in Android Market</a></li>
-<li><a href="#manifest-filters">Filtering based on Manifest File Elements</a></li>
-<li><a href="#other-filters">Other Filters</a></li>
-</ol>
-
-<h2>See also</h2>
- <ol>
-<li><a
-href="{@docRoot}guide/practices/compatibility.html">Compatibility</a></li>
-<li style="margin-top:2px;"><code><a
-href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></code></li>
-<li><code><a
-href="{@docRoot}guide/topics/manifest/uses-configuration-element.html">&lt;uses-configuration&gt;</a></code></li>
-<li><code><a
-href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature&gt;</a></code></li>
-<li><code><a
-href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code></li>
-<li><code><a
-href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code></li>
-<li><code><a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt;</code></a></li>
-</ol>
-
-<div id="qv-extra"> <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
-<div id="qv-sub-rule"> <img src="{@docRoot}assets/images/icon_market.jpg"
-style="float:left;margin:0;padding:0;"> <p style="color:#669999;">Interested in
-publishing your app on Android Market?</p> <a id="publish-link"
-href="http://market.android.com/publish">Go to Android Market &raquo;</a> </div>
-</div>
-
-</div> </div>
-
-<p>When a user searches or browses in Android Market, the results are filtered, and
-some applications might not be visible. For example, if an application requires a
-trackball (as specified in the manifest file), then Android Market will not show
-the app on any device that does not have a trackball.</p> <p>The manifest file and
-the device's hardware and features are only part of how applications are filtered
-&#8212; filtering also depends on the country and carrier, the presence or absence
-of a SIM card, and other factors. </p>
-
-<p>Changes to the Android Market filters are independent of changes
-to the Android platform itself. This document will be updated periodically to reflect
-any changes that occur. </p>
-
-<h2 id="how-filters-work">How Filters Work in Android Market</h2>
-
-<p>Android Market uses the filter restrictions described below to determine
-whether to show your application to a user who is browsing or searching for
-applications on a given device. When determining whether to display your app,
-Market checks the device's hardware and software capabilities, as well as it's
-carrier, location, and other characteristics. It then compares those against the
-restrictions and dependencies expressed by the application itself, in its
-manifest, <code>.apk</code>, and publishing details. If the application is
-compatible with the device according to the filter rules, Market displays the
-application to the user. Otherwise, Market hides your application from search
-results and category browsing. </p>
-
-<p> You can use the filters described below to control whether Market shows or
-hides your application to users. You can request any combination of the
-available filters for your app &#8212; for example, you could set a
-<code>minSdkVersion</code> requirement of <code>"4"</code> and set
-<code>smallScreens="false"</code> in the app, then when uploading the app to
-Market you could target European countries (carriers) only. Android Market's
-filters would prevent the application from being visible on any device that did
-not match all three of these requirements. </p>
-
- <p>A filtered app is not visible within Market, even if a user specifically requests
-the app by clicking a deep link that points directly to the app's ID within Market.
-All filtering restrictions are associated with an application's version and can
-change between versions. For example:</p>
-
-<ul>
-<li>If you publish a new version of your app with stricter restrictions, the app
-will not be visible to users for whom it is filtered, even if those users were
-able see the previous version.</li>
-<li>If a user has installed your application and you publish an upgrade that
-makes the app invisible to the user, the user will not see that an upgrade is
-available. </li>
-</ul>
-
-<h2 id="manifest-filters">Filtering based on Manifest Elements</h2>
-
-<p>Most Market filters are triggered by elements within an application's
-manifest file, <a
-href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a>,
-although not everything in the manifest file can trigger filtering. The
-table below lists the manifest elements that you can use to trigger Android
-Market filtering, and explains how the filtering works.</p>
-
-<p class="table-caption"><strong>Table 1.</strong> Manifest elements that
-trigger filtering on Market.</p>
-<table>
- <tr>
- <th>Manifest Element</th>
- <th>Filter Name</th>
- <th>How It Works</th>
- </tr>
- <tr>
- <td valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></code>
- <!-- ##api level 4## --></td>
- <td valign="top">Screen Size</td>
- <td valign="top">
-
-<p>An application indicates the screen sizes that it is capable of supporting by
-setting attributes of the <code>&lt;supports-screens&gt;</code> element. When
-the application is published, Market uses those attributes to determine whether
-to show the application to users, based on the screen sizes of their
-devices. </p>
-
-<p>As a general rule, Market assumes that the platform on the device can adapt
-smaller layouts to larger screens, but cannot adapt larger layouts to smaller
-screens. Thus, if an application declares support for "normal" screen size only,
-Market makes the application available to both normal- and large-screen devices,
-but filters the application so that it is not available to small-screen
-devices.</p>
-
-<p>If an application does not declare attributes for
-<code>&lt;supports-screens&gt;</code>, Market uses the default values for those
-attributes, which vary by API Level. Specifically: </p>
-
-<ul>
-<li><p>In API level 3, the <code>&lt;supports-screens&gt;</code> element itself
-is undefined and no attributes are available. In this case, Market assumes that
-the application is designed for normal-size screens and shows the application to
-devices that have normal or large screens. </p>
-
-<p>This behavior is especially significant for applications that set their
-<code><a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">android:
-minSdkVersion</a></code> to 3 or lower, since Market will filter them from
-small-screen devices by default. Such applications can enable support for
-small-screen devices by adding a <code>android:targetSdkVersion="4"</code>
-attribute to the <code>&lt;uses-sdk&gt;</code> element in their manifest
-files. For more information, see <a
-href="{@docRoot}guide/practices/screens_support.html#strategies">Strategies for
-Legacy Applications</a>.</p></li>
-
-<li>In API Level 4, the defaults for all of the attributes is
-<code>"true"</code>. If an application does not declare a
-<code>&lt;supports-screens&gt;</code> element, Market assumes that the
-application is designed for all screen sizes and does not filter it from any
-devices. If the application does not declare one of the attributes, Market uses
-the default value of <code>"true"</code> and does not filter the app for devices
-of corresponding screen size.</li>
-</ul>
-
- <p><strong>Example 1</strong><br />
- The manifest declares <code>&lt;uses-sdk android:minSdkVersion="3"&gt;</code>
- and does not does not include a <code>&lt;supports-screens&gt;</code> element.
- <strong>Result</strong>: Android Market will not show the app to a user of a
- small-screen device, but will show it to users of normal and large-screen
- devices, users, unless other filters apply. </p>
- <p><strong>Example 2<br />
- </strong>The manifest declares <code>&lt;uses-sdk android:minSdkVersion="3"
- android:targetSdkVersion="4"&gt;</code> and does not include a
- <code>&lt;supports-screens&gt;</code> element.
- <strong>Result</strong>: Android Market will show the app to users on all
- devices, unless other filters apply. </p>
- <p><strong>Example 3<br />
- </strong>The manifest declares <code>&lt;uses-sdk android:minSdkVersion="4"&gt;</code>
- and does not include a <code>&lt;supports-screens&gt;</code> element.
- <strong>Result</strong>: Android Market will show the app to all users,
- unless other filters apply. </p>
- <p>For more information on how to declare support for screen sizes in your
- application, see <code><a
- href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></code>
- and <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
- Screens</a>.</p>
-</td>
- </tr>
- <tr>
- <td valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html">&lt;uses-configuration&gt;</a></code>
- <!-- ##api level 3## --></td>
- <td valign="top">Device
- Configuration: <br />
- keyboard, navigation, touch screen</td>
- <td valign="top"><p>An application can
- request certain hardware features, and Android Market will show the app only on devices that have the required hardware.</p>
- <p><strong>Example 1<br />
- </strong>The manifest includes <code>&lt;uses-configuration android:reqFiveWayNav=&quot;true&quot; /&gt;</code>, and a user is searching for apps on a device that does not have a five-way navigational control. <strong>Result</strong>: Android Market will not show the app to the user. </p>
- <p><strong>Example 2<br />
- </strong>The manifest does not include a <code>&lt;uses-configuration&gt;</code> element. <strong>Result</strong>: Android Market will show the app to all users, unless other filters apply.</p>
-<p>For more details, see <a
-href="{@docRoot}guide/topics/manifest/uses-configuration-element.html"><code>&lt;uses-configuration&gt;</code></a>.</p></td>
- </tr>
- <tr>
- <td rowspan="2" valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature&gt;</a></code>
- <!-- ##api level 4## --></td>
- <td valign="top">Device Features<br />
- (<code>name</code>)</td>
- <td valign="top"><p>An
- application can require certain device features to be present on the device. This functionality
- was introduced in Android 2.0 (API Level 5).</p>
- <p><strong>Example 1<br />
- </strong>The manifest includes <code>&lt;uses-feature android:name=&quot;android.hardware.sensor.light&quot; /&gt;</code>, and a user is searching for apps on a device that does not have a light sensor. <strong>Result</strong>: Android Market will not show the app to the user. </p>
- <p><strong>Example 2<br />
- </strong>The manifest does not include a <code>&lt;uses-feature&gt;</code> element. <strong>Result</strong>: Android Market will show the app to all users, unless other filters apply.</p>
- <p>For more details, see <code><a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature&gt;</a></code>.</p>
-<p><em>A note about camera:</em> If an
- application requests the CAMERA permission using the <a
-href="{@docRoot}guide/topics/manifest/uses-permission-element.html"> <code>&lt;uses-permission&gt;</code></a> element, Market assumes that the
- application requires the camera and all camera features (such as autofocus). For applications that require the camera and are designed to run on Android 1.5 (API Level 3), declaring the CAMERA permission is an effective way of ensuring that Market filters your app properly, since <code>uses-feature</code> filtering is not available to applications compiled against the Android 1.5 platform. For more details about requiring or requesting a camera, see the <a href="{@docRoot}guide/topics/manifest/uses-library-element.html#required"> <code>required</code></a> attribute of <code>&lt;uses-feature&gt;</code>. </p></td>
- </tr>
- <tr>
- <td valign="top">OpenGL-ES
- Version<br />
-(<code>openGlEsVersion</code>)</td>
- <td valign="top"><p>An application can require that the device support a specific
- OpenGL-ES version using the <code>&lt;uses-feature
- android:openGlEsVersion=&quot;int&quot;&gt;</code> attribute.</p>
- <p><strong>Example 1<br />
- </strong>An app
- requests multiple OpenGL-ES versions by specifying <code>openGlEsVersion</code> multiple times in the
- manifest. <strong>Result</strong>: Market assumes that the app requires the highest of the indicated versions.</p>
-<p><strong>Example 2<br />
-</strong>An app
- requests OpenGL-ES version 1.1, and a user is searching for apps on a device that supports OpenGL-ES version 2.0. <strong>Result</strong>: Android Market will show the app to the user, unless other filters apply. If a
- device reports that it supports OpenGL-ES version <em>X</em>, Market assumes that it
- also supports any version earlier than <em>X</em>.
-</p>
-<p><strong>Example 3<br />
-</strong>A user is searching for apps on a device that does not
- report an OpenGL-ES version (for example, a device running Android 1.5 or earlier). <strong>Result</strong>: Android Market assumes that the device
- supports only OpenGL-ES 1.0. Market will only show the user apps that do not specify <code>openGlEsVersion</code>, or apps that do not specify an OpenGL-ES version higher than 1.0. </p>
- <p><strong>Example 4<br />
- </strong>The manifest does not specify <code>openGlEsVersion</code>. <strong>Result</strong>: Android Market will show the app to all users, unless other filters apply. </p>
-<p>For more details, see <a
-href="{@docRoot}guide/topics/manifest/uses-feature-element.html"><code>&lt;uses-feature&gt;</code></a>.</p></td>
- </tr>
- <tr>
- <td valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code></td>
- <td valign="top">Software Libraries</td>
- <td valign="top"><p>An application can require specific
- shared libraries to be present on the device. </p>
- <p><strong>Example 1<br />
- </strong>An app requires the <code>com.google.android.maps</code> library, and a user is searching for apps on a device that does not have the <code>com.google.android.maps</code> library. <strong>Result</strong>: Android Market will not show the app to the user. </p>
- <p><strong>Example 2</strong><br />
- The manifest does not include a <code>&lt;uses-library&gt;</code> element. <strong>Result</strong>: Android Market will show the app to all users, unless other filters apply.</p>
-<p>For more details, see <a
-href="{@docRoot}guide/topics/manifest/uses-library-element.html"><code>&lt;uses-library&gt;</code></a>.</p></td>
- </tr>
- <tr>
- <td valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code></td>
- <td valign="top">&nbsp;</td>
- <td valign="top"><em>(See the note in the description of <code>&lt;uses-feature&gt;</code>, above.)</em></td>
- </tr>
- <tr>
- <td rowspan="2" valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt;</a></code></td>
- <td valign="top">Minimum Framework Version (<code>minSdkVersion</code>)</td>
- <td valign="top"><p>An application can require a minimum API level. </p>
- <p><strong>Example 1</strong><br />
- The manifest includes <code>&lt;uses-sdk
- android:minSdkVersion=&quot;3&quot;&gt;</code>, and the app uses APIs that were introduced in API Level 3. A user is searching for apps on a device that has API Level 2. <strong>Result</strong>: Android Market will not show the app to the user. </p>
- <p><strong>Example 2</strong><br />
- The manifest does not include <code>minSdkVersion</code>, and the app uses APIs that were introduced in API Level 3. A user is searching for apps on a device that has API Level 2. <strong>Result</strong>: Android Market assumes that <code>minSdkVersion</code> is &quot;1&quot; and that the app is compatible with all versions of Android. Market shows the app to the user and allows the user to download the app. The app crashes at runtime. </p>
- <p>Because you want to avoid this second scenario, we recommend that you always declare a <code>minSdkVersion</code>. For details, see <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min"><code>android:minSdkVersion</code></a>.</p></td>
- </tr>
- <tr>
- <td valign="top">Maximum Framework Version (<code>maxSdkVersion</code>)</td>
- <td valign="top"><p><em>Deprecated.</em> Android
- 2.1 and later do not check or enforce the <code>maxSdkVersion</code> attribute, and
- the SDK will not compile if <code>maxSdkVersion</code> is set in an app's manifest. For devices already
- compiled with <code>maxSdkVersion</code>, Market will respect it and use it for
- filtering.</p>
-<p> Declaring <code>maxSdkVersion</code> is <em>not</em> recommended. For details, see <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#max"><code>android:maxSdkVersion</code></a>.</p></td>
- </tr>
-</table>
-
-<h2 id="other-filters">Other Filters</h2>
-<p>Android Market uses other application characteristics to determine whether to show or hide an application for a particular user on a given device, as described in the table below. </p>
-
-<p class="table-caption"><strong>Table 2.</strong> Application and publishing characteristics that affect filtering on Market.</p>
-<table> <tr>
- <th>Filter Name</th> <th>How It Works</th> </tr>
-
- <tr>
- <td valign="top">Publishing Status</td> <td valign="top"><p>Only published applications will appear in
- searches and browsing within Android Market.</p> <p>Even if an app is unpublished, it can
- be installed if users can see it in their Downloads area among their purchased,
- installed, or recently uninstalled apps.</p> <p>If an application has been
- suspended, users will not be able to reinstall or update it, even if it appears in their Downloads.</p> </td></tr>
- <tr>
- <td valign="top">Priced
- Status</td> <td valign="top"><p>Not all users can see paid apps. To show paid apps, a device
-must have a SIM card and be running Android 1.1 or later, and it must be in a
-country (as determined by SIM carrier) in which paid apps are available.</p></td>
-</tr> <tr>
- <td valign="top">Country / Carrier Targeting</td> <td valign="top"> <p>When you upload your app to
- the Android Market, you can select specific countries to target. The app will only
- be visible to the countries (carriers) that you select, as follows:</p>
- <ul><li><p>A device's country is determined based on the carrier, if a carrier is
- available. If no carrier can be determined, the Market application tries to
- determine the country based on IP.</p></li> <li><p>Carrier is determined based on
- the device's SIM (for GSM devices), not the current roaming carrier.</p></li></ul>
-</td> </tr> <tr>
- <td valign="top">Native Platform</td> <td valign="top"><p>An application that includes native
- libraries that target a specific platform (ARM EABI v7, for example) will only be
- visible on devices that support that platform. For details about the NDK and using
- native libraries, see <a href="{@docRoot}sdk/ndk/index.html#overview">What is the
- Android NDK?</a></p> </tr> <tr>
- <td valign="top">Forward-Locked Applications</td> <td valign="top"><p>To
- forward lock an application, set copy protection to "On" when you upload the
- application to Market. Market will not show copy-protected applications on
-developer devices or unreleased devices.</p></td> </tr> </table>
-
-
+page.title=Market Filters
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Quickview</h2>
+<ul> <li>Android Market applies filters to that let you control whether your app is shown to a
+user who is browing or searching for apps.</li>
+<li>Filtering is determined by elements in an app's manifest file,
+aspects of the device being used, and other factors.</li> </ul>
+
+<h2>In this document</h2>
+
+<ol> <li><a href="#how-filters-work">How Filters Work in Android Market</a></li>
+<li><a href="#manifest-filters">Filtering based on Manifest File Elements</a></li>
+<li><a href="#other-filters">Other Filters</a></li>
+</ol>
+
+<h2>See also</h2>
+ <ol>
+<li><a
+href="{@docRoot}guide/practices/compatibility.html">Compatibility</a></li>
+<li style="margin-top:2px;"><code><a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></code></li>
+<li><code><a
+href="{@docRoot}guide/topics/manifest/uses-configuration-element.html">&lt;uses-configuration&gt;</a></code></li>
+<li><code><a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature&gt;</a></code></li>
+<li><code><a
+href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code></li>
+<li><code><a
+href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code></li>
+<li><code><a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt;</code></a></li>
+</ol>
+
+<div id="qv-extra"> <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
+<div id="qv-sub-rule"> <img src="{@docRoot}assets/images/icon_market.jpg"
+style="float:left;margin:0;padding:0;"> <p style="color:#669999;">Interested in
+publishing your app on Android Market?</p> <a id="publish-link"
+href="http://market.android.com/publish">Go to Android Market &raquo;</a> </div>
+</div>
+
+</div> </div>
+
+<p>When a user searches or browses in Android Market, the results are filtered, and
+some applications might not be visible. For example, if an application requires a
+trackball (as specified in the manifest file), then Android Market will not show
+the app on any device that does not have a trackball.</p> <p>The manifest file and
+the device's hardware and features are only part of how applications are filtered
+&#8212; filtering also depends on the country and carrier, the presence or absence
+of a SIM card, and other factors. </p>
+
+<p>Changes to the Android Market filters are independent of changes
+to the Android platform itself. This document will be updated periodically to reflect
+any changes that occur. </p>
+
+<h2 id="how-filters-work">How Filters Work in Android Market</h2>
+
+<p>Android Market uses the filter restrictions described below to determine
+whether to show your application to a user who is browsing or searching for
+applications on a given device. When determining whether to display your app,
+Market checks the device's hardware and software capabilities, as well as it's
+carrier, location, and other characteristics. It then compares those against the
+restrictions and dependencies expressed by the application itself, in its
+manifest, <code>.apk</code>, and publishing details. If the application is
+compatible with the device according to the filter rules, Market displays the
+application to the user. Otherwise, Market hides your application from search
+results and category browsing. </p>
+
+<p> You can use the filters described below to control whether Market shows or
+hides your application to users. You can request any combination of the
+available filters for your app &#8212; for example, you could set a
+<code>minSdkVersion</code> requirement of <code>"4"</code> and set
+<code>smallScreens="false"</code> in the app, then when uploading the app to
+Market you could target European countries (carriers) only. Android Market's
+filters would prevent the application from being visible on any device that did
+not match all three of these requirements. </p>
+
+ <p>A filtered app is not visible within Market, even if a user specifically requests
+the app by clicking a deep link that points directly to the app's ID within Market.
+All filtering restrictions are associated with an application's version and can
+change between versions. For example:</p>
+
+<ul>
+<li>If you publish a new version of your app with stricter restrictions, the app
+will not be visible to users for whom it is filtered, even if those users were
+able see the previous version.</li>
+<li>If a user has installed your application and you publish an upgrade that
+makes the app invisible to the user, the user will not see that an upgrade is
+available. </li>
+</ul>
+
+<h2 id="manifest-filters">Filtering based on Manifest Elements</h2>
+
+<p>Most Market filters are triggered by elements within an application's
+manifest file, <a
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a>,
+although not everything in the manifest file can trigger filtering. The
+table below lists the manifest elements that you can use to trigger Android
+Market filtering, and explains how the filtering works.</p>
+
+<p class="table-caption"><strong>Table 1.</strong> Manifest elements that
+trigger filtering on Market.</p>
+<table>
+ <tr>
+ <th>Manifest Element</th>
+ <th>Filter Name</th>
+ <th>How It Works</th>
+ </tr>
+ <tr>
+ <td valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></code>
+ <!-- ##api level 4## --></td>
+ <td valign="top">Screen Size</td>
+ <td valign="top">
+
+<p>An application indicates the screen sizes that it is capable of supporting by
+setting attributes of the <code>&lt;supports-screens&gt;</code> element. When
+the application is published, Market uses those attributes to determine whether
+to show the application to users, based on the screen sizes of their
+devices. </p>
+
+<p>As a general rule, Market assumes that the platform on the device can adapt
+smaller layouts to larger screens, but cannot adapt larger layouts to smaller
+screens. Thus, if an application declares support for "normal" screen size only,
+Market makes the application available to both normal- and large-screen devices,
+but filters the application so that it is not available to small-screen
+devices.</p>
+
+<p>If an application does not declare attributes for
+<code>&lt;supports-screens&gt;</code>, Market uses the default values for those
+attributes, which vary by API Level. Specifically: </p>
+
+<ul>
+<li><p>In API level 3, the <code>&lt;supports-screens&gt;</code> element itself
+is undefined and no attributes are available. In this case, Market assumes that
+the application is designed for normal-size screens and shows the application to
+devices that have normal or large screens. </p>
+
+<p>This behavior is especially significant for applications that set their
+<code><a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">android:
+minSdkVersion</a></code> to 3 or lower, since Market will filter them from
+small-screen devices by default. Such applications can enable support for
+small-screen devices by adding a <code>android:targetSdkVersion="4"</code>
+attribute to the <code>&lt;uses-sdk&gt;</code> element in their manifest
+files. For more information, see <a
+href="{@docRoot}guide/practices/screens_support.html#strategies">Strategies for
+Legacy Applications</a>.</p></li>
+
+<li>In API Level 4, the defaults for all of the attributes is
+<code>"true"</code>. If an application does not declare a
+<code>&lt;supports-screens&gt;</code> element, Market assumes that the
+application is designed for all screen sizes and does not filter it from any
+devices. If the application does not declare one of the attributes, Market uses
+the default value of <code>"true"</code> and does not filter the app for devices
+of corresponding screen size.</li>
+</ul>
+
+ <p><strong>Example 1</strong><br />
+ The manifest declares <code>&lt;uses-sdk android:minSdkVersion="3"&gt;</code>
+ and does not does not include a <code>&lt;supports-screens&gt;</code> element.
+ <strong>Result</strong>: Android Market will not show the app to a user of a
+ small-screen device, but will show it to users of normal and large-screen
+ devices, users, unless other filters apply. </p>
+ <p><strong>Example 2<br />
+ </strong>The manifest declares <code>&lt;uses-sdk android:minSdkVersion="3"
+ android:targetSdkVersion="4"&gt;</code> and does not include a
+ <code>&lt;supports-screens&gt;</code> element.
+ <strong>Result</strong>: Android Market will show the app to users on all
+ devices, unless other filters apply. </p>
+ <p><strong>Example 3<br />
+ </strong>The manifest declares <code>&lt;uses-sdk android:minSdkVersion="4"&gt;</code>
+ and does not include a <code>&lt;supports-screens&gt;</code> element.
+ <strong>Result</strong>: Android Market will show the app to all users,
+ unless other filters apply. </p>
+ <p>For more information on how to declare support for screen sizes in your
+ application, see <code><a
+ href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></code>
+ and <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+ Screens</a>.</p>
+</td>
+ </tr>
+ <tr>
+ <td valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html">&lt;uses-configuration&gt;</a></code>
+ <!-- ##api level 3## --></td>
+ <td valign="top">Device
+ Configuration: <br />
+ keyboard, navigation, touch screen</td>
+ <td valign="top"><p>An application can
+ request certain hardware features, and Android Market will show the app only on devices that have the required hardware.</p>
+ <p><strong>Example 1<br />
+ </strong>The manifest includes <code>&lt;uses-configuration android:reqFiveWayNav=&quot;true&quot; /&gt;</code>, and a user is searching for apps on a device that does not have a five-way navigational control. <strong>Result</strong>: Android Market will not show the app to the user. </p>
+ <p><strong>Example 2<br />
+ </strong>The manifest does not include a <code>&lt;uses-configuration&gt;</code> element. <strong>Result</strong>: Android Market will show the app to all users, unless other filters apply.</p>
+<p>For more details, see <a
+href="{@docRoot}guide/topics/manifest/uses-configuration-element.html"><code>&lt;uses-configuration&gt;</code></a>.</p></td>
+ </tr>
+ <tr>
+ <td rowspan="2" valign="top" style="white-space:nowrap;"><code><a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature&gt;</a>
+</code>
+ <!-- ##api level 4## --></td>
+ <td valign="top">Device Features<br />
+ (<code>name</code>)</td>
+ <td valign="top"><p>An application can require certain device features to be
+present on the device. This functionality was introduced in Android 2.0 (API
+Level 5).</p>
+ <p><strong>Example 1<br />
+ </strong>The manifest includes <code>&lt;uses-feature
+android:name=&quot;android.hardware.sensor.light&quot; /&gt;</code>, and a user
+is searching for apps on a device that does not have a light sensor.
+<strong>Result</strong>: Android Market will not show the app to the user. </p>
+ <p><strong>Example 2<br />
+ </strong>The manifest does not include a <code>&lt;uses-feature&gt;</code>
+element. <strong>Result</strong>: Android Market will show the app to all users,
+unless other filters apply.</p>
+ <p>For complete information, see <code><a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature&gt;</a>
+</code>.</p>
+ <p><em>Filtering based on implied features:</em> In some cases, Android
+Market interprets permissions requested through
+<code>&lt;uses-permission&gt;</code> elements as feature requirements equivalent
+to those declared in <code>&lt;uses-feature&gt;</code> elements. See <a
+href="#uses-permission-filtering"><code>&lt;uses-permission&gt;</code></a>,
+below.</p>
+</td>
+ </tr>
+ <tr>
+ <td valign="top">OpenGL-ES
+ Version<br />
+(<code>openGlEsVersion</code>)</td>
+ <td valign="top"><p>An application can require that the device support a specific
+ OpenGL-ES version using the <code>&lt;uses-feature
+ android:openGlEsVersion=&quot;int&quot;&gt;</code> attribute.</p>
+ <p><strong>Example 1<br />
+ </strong>An app
+ requests multiple OpenGL-ES versions by specifying <code>openGlEsVersion</code> multiple times in the
+ manifest. <strong>Result</strong>: Market assumes that the app requires the highest of the indicated versions.</p>
+<p><strong>Example 2<br />
+</strong>An app
+ requests OpenGL-ES version 1.1, and a user is searching for apps on a device that supports OpenGL-ES version 2.0. <strong>Result</strong>: Android Market will show the app to the user, unless other filters apply. If a
+ device reports that it supports OpenGL-ES version <em>X</em>, Market assumes that it
+ also supports any version earlier than <em>X</em>.
+</p>
+<p><strong>Example 3<br />
+</strong>A user is searching for apps on a device that does not
+ report an OpenGL-ES version (for example, a device running Android 1.5 or earlier). <strong>Result</strong>: Android Market assumes that the device
+ supports only OpenGL-ES 1.0. Market will only show the user apps that do not specify <code>openGlEsVersion</code>, or apps that do not specify an OpenGL-ES version higher than 1.0. </p>
+ <p><strong>Example 4<br />
+ </strong>The manifest does not specify <code>openGlEsVersion</code>. <strong>Result</strong>: Android Market will show the app to all users, unless other filters apply. </p>
+<p>For more details, see <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html"><code>&lt;uses-feature&gt;</code></a>.</p></td>
+ </tr>
+ <tr>
+ <td valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code></td>
+ <td valign="top">Software Libraries</td>
+ <td valign="top"><p>An application can require specific
+ shared libraries to be present on the device. </p>
+ <p><strong>Example 1<br />
+ </strong>An app requires the <code>com.google.android.maps</code> library, and a user is searching for apps on a device that does not have the <code>com.google.android.maps</code> library. <strong>Result</strong>: Android Market will not show the app to the user. </p>
+ <p><strong>Example 2</strong><br />
+ The manifest does not include a <code>&lt;uses-library&gt;</code> element. <strong>Result</strong>: Android Market will show the app to all users, unless other filters apply.</p>
+<p>For more details, see <a
+href="{@docRoot}guide/topics/manifest/uses-library-element.html"><code>&lt;uses-library&gt;</code></a>.</p></td>
+ </tr>
+ <tr id="uses-permission-filtering">
+ <td valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code></td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">Strictly, Android Market does not filter based on
+<code>&lt;uses-permission&gt;</code> elements. However, it does read the
+elements to determine whether the application has hardware feature requirements
+that may not have been properly declared in <code>&lt;uses-feature&gt;</code>
+elements. For example, if an application requests the <code>CAMERA</code>
+permission but does not declare a <code>&lt;uses-feature&gt;</code> element for
+<code>android.hardware.camera</code>, Android Market considers that the
+application requires a camera and should not be shown to users whose devices do
+not offer a camera.</p>
+ <p>In general, if an application requests hardware-related permissions,
+Android Market assumes that the application requires the underlying hardware
+features, even though there might be no corresponding to
+<code>&lt;uses-feature&gt;</code> declarations. Android Market then sets up
+filtering based on the features implied by the <code>&lt;uses-feature&gt;</code>
+declarations.</p>
+ <p>For a list of permissions that imply hardware features, see
+the documentation for the <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html#permissions-features"><code>&lt;uses-feature&gt;</code></a>
+element.</p>
+</td>
+ </tr>
+ <tr>
+ <td rowspan="2" valign="top" style="white-space:nowrap;"><code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt;</a></code></td>
+ <td valign="top">Minimum Framework Version (<code>minSdkVersion</code>)</td>
+ <td valign="top"><p>An application can require a minimum API level. </p>
+ <p><strong>Example 1</strong><br />
+ The manifest includes <code>&lt;uses-sdk
+ android:minSdkVersion=&quot;3&quot;&gt;</code>, and the app uses APIs that were introduced in API Level 3. A user is searching for apps on a device that has API Level 2. <strong>Result</strong>: Android Market will not show the app to the user. </p>
+ <p><strong>Example 2</strong><br />
+ The manifest does not include <code>minSdkVersion</code>, and the app uses APIs that were introduced in API Level 3. A user is searching for apps on a device that has API Level 2. <strong>Result</strong>: Android Market assumes that <code>minSdkVersion</code> is &quot;1&quot; and that the app is compatible with all versions of Android. Market shows the app to the user and allows the user to download the app. The app crashes at runtime. </p>
+ <p>Because you want to avoid this second scenario, we recommend that you always declare a <code>minSdkVersion</code>. For details, see <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min"><code>android:minSdkVersion</code></a>.</p></td>
+ </tr>
+ <tr>
+ <td valign="top">Maximum Framework Version (<code>maxSdkVersion</code>)</td>
+ <td valign="top"><p><em>Deprecated.</em> Android
+ 2.1 and later do not check or enforce the <code>maxSdkVersion</code> attribute, and
+ the SDK will not compile if <code>maxSdkVersion</code> is set in an app's manifest. For devices already
+ compiled with <code>maxSdkVersion</code>, Market will respect it and use it for
+ filtering.</p>
+<p> Declaring <code>maxSdkVersion</code> is <em>not</em> recommended. For details, see <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#max"><code>android:maxSdkVersion</code></a>.</p></td>
+ </tr>
+</table>
+
+<h2 id="other-filters">Other Filters</h2>
+<p>Android Market uses other application characteristics to determine whether to show or hide an application for a particular user on a given device, as described in the table below. </p>
+
+<p class="table-caption"><strong>Table 2.</strong> Application and publishing characteristics that affect filtering on Market.</p>
+<table> <tr>
+ <th>Filter Name</th> <th>How It Works</th> </tr>
+
+ <tr>
+ <td valign="top">Publishing Status</td> <td valign="top"><p>Only published applications will appear in
+ searches and browsing within Android Market.</p> <p>Even if an app is unpublished, it can
+ be installed if users can see it in their Downloads area among their purchased,
+ installed, or recently uninstalled apps.</p> <p>If an application has been
+ suspended, users will not be able to reinstall or update it, even if it appears in their Downloads.</p> </td></tr>
+ <tr>
+ <td valign="top">Priced
+ Status</td> <td valign="top"><p>Not all users can see paid apps. To show paid apps, a device
+must have a SIM card and be running Android 1.1 or later, and it must be in a
+country (as determined by SIM carrier) in which paid apps are available.</p></td>
+</tr> <tr>
+ <td valign="top">Country / Carrier Targeting</td> <td valign="top"> <p>When you upload your app to
+ the Android Market, you can select specific countries to target. The app will only
+ be visible to the countries (carriers) that you select, as follows:</p>
+ <ul><li><p>A device's country is determined based on the carrier, if a carrier is
+ available. If no carrier can be determined, the Market application tries to
+ determine the country based on IP.</p></li> <li><p>Carrier is determined based on
+ the device's SIM (for GSM devices), not the current roaming carrier.</p></li></ul>
+</td> </tr> <tr>
+ <td valign="top">Native Platform</td> <td valign="top"><p>An application that includes native
+ libraries that target a specific platform (ARM EABI v7, for example) will only be
+ visible on devices that support that platform. For details about the NDK and using
+ native libraries, see <a href="{@docRoot}sdk/ndk/index.html#overview">What is the
+ Android NDK?</a></p> </tr> <tr>
+ <td valign="top">Forward-Locked Applications</td> <td valign="top"><p>To
+ forward lock an application, set copy protection to "On" when you upload the
+ application to Market. Market will not show copy-protected applications on
+developer devices or unreleased devices.</p></td> </tr> </table>
+
+
diff --git a/docs/html/guide/appendix/media-formats.jd b/docs/html/guide/appendix/media-formats.jd
index 94a6471..8709994 100644
--- a/docs/html/guide/appendix/media-formats.jd
+++ b/docs/html/guide/appendix/media-formats.jd
@@ -22,7 +22,7 @@ page.title=Android Supported Media Formats
<tr>
<td rowspan="9">Audio</td>
<td>AAC LC/LTP</td>
-<td>&nbsp;</td>
+<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td rowspan="3">Mono/Stereo content in any combination of standard bit rates up to 160 kbps and sampling rates from 8 to 48kHz</td>
<td rowspan="3">3GPP (.3gp) and MPEG-4 (.mp4, .m4a). No support for raw AAC (.aac)</td>
@@ -51,7 +51,7 @@ page.title=Android Supported Media Formats
<tr>
<td>AMR-WB</td>
-<td>&nbsp;</td>
+<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td>9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16kHz</td>
<td>3GPP (.3gp)</td>
@@ -109,7 +109,7 @@ page.title=Android Supported Media Formats
<tr>
<td>PNG</td>
-<td>&nbsp;</td>
+<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td>&nbsp;</td>
<td>PNG (.png)</td>
diff --git a/docs/html/guide/developing/debug-tasks.jd b/docs/html/guide/developing/debug-tasks.jd
index 500ef58..f0bf84c 100644
--- a/docs/html/guide/developing/debug-tasks.jd
+++ b/docs/html/guide/developing/debug-tasks.jd
@@ -40,10 +40,13 @@ your applications. Here are some tools that you'll use most often:</p>
your application, which can help you profile the performance of your application.</dd>
<dt><strong><a href="{@docRoot}guide/developing/tools/ddms.html#logcat">logcat</a></strong></dt>
<dd>Dumps a log of system
- messages. The messages include a stack trace when the emulator throws an error,
+ messages. The messages include a stack trace when the device throws an error,
as well as {@link android.util.Log} messages you've written from your application. To run
- logcat, execute <code>adb logcat</code> or, from DDMS, select <strong>Device > Run
- logcat</strong>.
+ logcat, execute <code>adb logcat</code> from your Android SDK {@code tools/} directory or,
+from DDMS, select <strong>Device > Run
+ logcat</strong>. When using the <a href="{@docRoot}sdk/eclipse-adt.html">ADT plugin for
+Eclipse</a>, you can also view logcat messages by opening the Logcat view, available from
+<strong>Window > Show View > Other > Android > Logcat</strong>.
<p>{@link android.util.Log} is a logging
class you can use to print out messages to the logcat. You can read messages
in real time if you run logcat on DDMS (covered next). Common logging methods include:
@@ -148,72 +151,7 @@ following options (among others):</p>
<h2 id="DebuggingWebPages">Debugging Web Pages</h2>
-<p>If you're developing a web application for Android devices, you can debug your JavaScript in the
-Android Browser using the Console APIs, which will output messages to logcat. If you're familiar
-debugging web pages with Firefox's FireBug or WebKit's Web Inspector, then you're probably familiar
-with the Console APIs. The Android Browser (and the {@link android.webkit.WebChromeClient}) supports
-most of the same APIs.</p>
-
-<p>When you call a function from the Console APIs (in the DOM's {@code window.console} object),
-you will see the output in logcat as a warning. For example, if your web page
-executes the following JavaScript:</p>
-<pre class="no-pretty-print">
-console.log("Hello World");
-</pre>
-<p>Then the logcat output from the Android Browser will look like this:</p>
-<pre class="no-pretty-print">
-W/browser ( 202): Console: Hello World http://www.example.com/hello.html :82
-</pre>
-
-<p>All Console messages from the Android Browser are tagged with the name "browser" on Android
-platforms running API Level 7 or higher. On platforms running API Level 6 or lower, Browser
-messages are tagged with the name "WebCore". The Android Browser also formats console messages
-with the log message
-preceded by "Console:" and then followed by the address and line number where the
-message occurred. (The format for the address and line number will appear different from the example
-above on platforms running API Level 6 or lower.)</p>
-
-<p>The Android Browser (and {@link android.webkit.WebChromeClient}) does not implement all of the
-Console APIs provided by Firefox or other WebKit-based browsers. Primarily, you need to depend
-on the basic text logging functions:</p>
-<ul>
- <li>{@code console.log(String)}</li>
- <li>{@code console.info(String)}</li>
- <li>{@code console.warn(String)}</li>
- <li>{@code console.error(String)}</li>
-</ul>
-<p>Although the Android Browser may not fully implement other Console functions, they will not raise
-run-time errors, but may not behave the same as they do on other desktop browsers.</p>
-
-<p>If you've implemented a custom {@link android.webkit.WebView} in your application, then in order
-to receive messages that are sent through the Console APIs, you must provide a {@link
-android.webkit.WebChromeClient} that implements the {@link
-android.webkit.WebChromeClient#onConsoleMessage(String,int,String) onConsoleMessage()} callback
-method. For example, assuming that the {@code myWebView} field references the {@link
-android.webkit.WebView} in your application, you can log debug messages like this:</p>
-<pre>
-myWebView.setWebChromeClient(new WebChromeClient() {
- public void onConsoleMessage(String message, int lineNumber, String sourceID) {
- Log.d("MyApplication", message + " -- From line " + lineNumber + " of " + sourceID);
- }
-});
-</pre>
-<p>The {@link android.webkit.WebChromeClient#onConsoleMessage(String,int,String)
-onConsoleMessage()} method will be called each time one of the Console methods is called from
-within your {@link android.webkit.WebView}.</p>
-<p>When the "Hello World" log is executed through your {@link android.webkit.WebView}, it will
-now look like this:</p>
-<pre class="no-pretty-print">
-D/MyApplication ( 430): Hello World -- From line 82 of http://www.example.com/hello.html
-</pre>
-
-<p class="note"><strong>Note:</strong> The {@link
-android.webkit.WebChromeClient#onConsoleMessage(String,int,String) onConsoleMessage()} callback
-method was added with API Level 7. If you are using a custom {@link
-android.webkit.WebView} on a platform running API Level 6 or lower, then your Console messages will
-automatically be sent to logcat with the "WebCore" logging tag.</p>
-
-
+<p>See the <a href="{@docRoot}guide/webapps/debugging.html">Debugging Web Apps</a> document.</p>
<h2 id="toptips">Top Debugging Tips</h2>
diff --git a/docs/html/guide/developing/eclipse-adt.jd b/docs/html/guide/developing/eclipse-adt.jd
index cf2a457..1594159 100644
--- a/docs/html/guide/developing/eclipse-adt.jd
+++ b/docs/html/guide/developing/eclipse-adt.jd
@@ -21,6 +21,7 @@ page.title=Developing In Eclipse, with ADT
<li><a href="#librarySetup">Setting up a library project</a></li>
<li><a href="#libraryReference">Referencing a library project</a></li>
<li><a href="#considerations">Development considerations</a></li>
+ <li><a href="#libraryMigrating">Migrating library projects to ADT 0.9.8</a></li>
</ol>
</li>
<li><a href="#Tips">Eclipse Tips</a></li>
@@ -391,11 +392,11 @@ which you could make use of library projects: </p>
<ul>
<li>If you are developing multiple related applications that use some of the
-same components, you move the redundant components out of their respective
+same components, you could move the redundant components out of their respective
application projects and create a single, reuseable set of the same components
in a library project. </li>
<li>If you are creating an application that exists in both free and paid
-versions. You move the part of the application that is common to both versions
+versions, you could move the part of the application that is common to both versions
into a library project. The two dependent projects, with their different package
names, will reference the library project and provide only the difference
between the two application versions.</li>
@@ -527,7 +528,7 @@ Marking a project as an Android library project. </p>
<p>A library project's manifest file must declare all of the shared components
that it includes, just as would a standard Android application. For more
information, see the documentation for <a
-href="{@docRoot}guide/manifest/manifest-intro.html">AndroidManifest.xml</a>.</p>
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a>.</p>
<p>For example, the <a
href="{@docRoot}resources/samples/TicTacToeLib/AndroidManifest.html">TicTacToeLib</a>
@@ -613,7 +614,8 @@ like this: </p>
...
&lt;/manifest&gt;</pre>
-<p>For more information about the manifest file, see the documentation for <a href="{@docRoot}guide/manifest/manifest-intro.html">AndroidManifest.xml</a>.</p>
+<p>For more information about the manifest file, see the documentation for <a
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a>.</p>
<h3 id="considerations">Development considerations</h3>
@@ -643,10 +645,6 @@ across all projects). </p>
is because the library project is compiled by the main project to use the
correct resource IDs.</p>
-<p><strong>One library project cannot reference another</strong></p>
-
-<p>A library cannot depend on another library.</p>
-
<p><strong>A library project can include a JAR library</strong></p>
<p>You can develop a library project that itself includes a JAR library, however
@@ -663,13 +661,6 @@ application must declare the external library their manifest files, in a <a
href="{@docRoot}guide/topics/manifest/uses-library-element.html"><code>&lt;uses-library&gt;</code></a>
element. </p>
-<p><strong>Library project can not include AIDL files</strong></p>
-
-<p>The tools do not support the use of <a
-href="{@docRoot}guide/developing/tools/aidl.html">AIDL</a> files in a library project.
-Any AIDL files used by an application must be stored in the application project
-itself.</p>
-
<p><strong>Library project can not include raw assets</strong></p>
<p>The tools do not support the use of raw asset files in a library project.
@@ -729,8 +720,76 @@ project can reference the library project by a relative link. You can place the
library project What is important is that the main project can reference the
library project through a relative link.</p>
+<h3 id="libraryMigrating">Migrating library projects to ADT 0.9.8</h3>
+
+<p>This section provides information about how to migrate a library project
+created with ADT 0.9.7 to ADT 0.9.8 (or higher). The migration is needed only if
+you are developing in Eclipse with ADT and assumes that you have also upgraded
+to SDK Tools r7 (or higher). </p>
+
+<p>The way that ADT handles library projects has changed between
+ADT 0.9.7 and ADT 0.9.8. Specifically, in ADT 0.9.7, the <code>src/</code>
+source folder of the library was linked into the dependent application project
+as a folder that had the same name as the library project. This worked because
+of two restrictions on the library projects:</p>
+
+<ul>
+<li>The library was only able to contain a single source folder (excluding the
+special <code>gen/</code> source folder), and</li>
+<li>The source folder was required to have the name <code>src/</code> and be
+stored at the root of the project.</li>
+</ul>
+
+<p>In ADT 0.9.8, both of those restrictions were removed. A library project can
+have as many source folders as needed and each can have any name. Additionally,
+a library project can store source folders in any location of the project. For
+example, you could store sources in a <code>src/java/</code> directory. In order
+to support this, the name of the linked source folders in the main project are
+now called &lt;<em>library-name</em>&gt;_&lt;<em>folder-name</em>&gt; For
+example: <code>MyLibrary_src/</code> or <code>MyLibrary_src_java/</code>.</p>
+
+<p>Additionally, the linking process now flags those folders in order for ADT to
+recognize that it created them. This will allow ADT to automatically migrate the
+project to new versions of ADT, should they contain changes to the handling of
+library projects. ADT 0.9.7 did not flag the linked source folders, so ADT 0.9.8
+cannot be sure whether the old linked folders can be removed safely. After
+upgrading ADT to 0.9.8, you will need to remove the old linked folders manually
+in a simple two-step process, as described below.</p>
+
+<p>Before you begin, make sure to create a backup copy of your application or
+save the latest version to your code version control system. This ensures that
+you will be able to easily revert the migration changes in case there is a
+problem in your environment.</p>
+
+<p>When you first upgrade to ADT 0.9.8, your main project will look as shown
+below, with two linked folders (in this example, <code>MyLibrary</code> and
+<code>MyLibrary_src</code> &mdash; both of which link to
+<code>MyLibrary/src</code>. Eclipse shows an error on one of them because they
+are duplicate links to a single class.</p>
+
+<img src="{@docRoot}images/developing/lib-migration-0.png" alt="">
+
+<p>To fix the error, remove the linked folder that <em>does not</em> contain the
+<code>_src</code> suffix. </p>
+
+<ol>
+<li>Right click the folder that you want to remove (in this case, the
+<code>MyLibrary</code> folder) and choose <strong>Build Path</strong> &gt;
+<strong>Remove from Build Path</strong>, as shown below.</li>
+
+<img src="{@docRoot}images/developing/lib-migration-1.png" style="height:600px"
+alt="">
+
+<li>Next, When asked about unlinking the folder from the project, select
+<strong>Yes</strong>, as shown below.</li>
-<h2 id="Tips">Eclipse Tips </h2>
+<img src="{@docRoot}images/developing/lib-migration-2.png" alt="">
+</ol>
+
+<p>This should resolve the error and migrate your library project to the new
+ADT environment. </p>
+
+<h2 id="Tips">Eclipse Tips</h2>
<h3 id="arbitraryexpressions">Executing arbitrary Java expressions in Eclipse</h3>
@@ -784,6 +843,8 @@ DDMS and configure Eclipse to debug on port 8700. (<strong>Note: </strong>Be sur
have first started <a href="{@docRoot}guide/developing/tools/ddms.html">DDMS</a>). </p>
+
+
<!-- TODO: clean this up and expand it to cover more wizards and features
<h3>ADT Wizards</h3>
diff --git a/docs/html/guide/developing/other-ide.jd b/docs/html/guide/developing/other-ide.jd
index e8a6fb6..8c61771 100644
--- a/docs/html/guide/developing/other-ide.jd
+++ b/docs/html/guide/developing/other-ide.jd
@@ -555,11 +555,11 @@ which you could make use of library projects: </p>
<ul>
<li>If you are developing multiple related applications that use some of the
-same components, you move the redundant components out of their respective
+same components, you could move the redundant components out of their respective
application projects and create a single, reuseable set of the same components
in a library project. </li>
<li>If you are creating an application that exists in both free and paid
-versions. You move the part of the application that is common to both versions
+versions, you could move the part of the application that is common to both versions
into a library project. The two dependent projects, with their different package
names, will reference the library project and provide only the difference
between the two application versions.</li>
@@ -687,7 +687,7 @@ so that other applications can use it, you can do so by adding a the
<p>A library project's manifest file must declare all of the shared components
that it includes, just as would a standard Android application. For more
information, see the documentation for <a
-href="{@docRoot}guide/manifest/manifest-intro.html">AndroidManifest.xml</a>.</p>
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a>.</p>
<p>For example, the <a
href="{@docRoot}resources/samples/TicTacToeLib/AndroidManifest.html">TicTacToeLib</a>
@@ -799,7 +799,8 @@ like this: </p>
...
&lt;/manifest&gt;</pre>
-<p>For more information about the manifest file, see the documentation for <a href="{@docRoot}guide/manifest/manifest-intro.html">AndroidManifest.xml</a>.</p>
+<p>For more information about the manifest file, see the documentation for <a
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a>.</p>
<h3 id="depAppBuild">Building a dependent application</h3>
@@ -837,10 +838,6 @@ across all projects). </p>
is because the library project is compiled by the main project to use the
correct resource IDs.</p>
-<p><strong>One library project cannot reference another</strong></p>
-
-<p>A library cannot depend on another library.</p>
-
<p><strong>A library project can include a JAR library</strong></p>
<p>You can develop a library project that itself includes a JAR library. When
@@ -857,13 +854,6 @@ application must declare the external library their manifest files, in a <a
href="{@docRoot}guide/topics/manifest/uses-library-element.html"><code>&lt;uses-library&gt;</code></a>
element. </p>
-<p><strong>Library project cannot include AIDL files</strong></p>
-
-<p>The tools do not support the use of <a
-href="{@docRoot}guide/developing/tools/aidl.html">AIDL</a> files in a library project.
-Any AIDL files used by an application must be stored in the application project
-itself.</p>
-
<p><strong>Library project cannot include raw assets</strong></p>
<p>The tools do not support the use of raw asset files in a library project.
diff --git a/docs/html/guide/developing/testing/index.jd b/docs/html/guide/developing/testing/index.jd
index ea61cc3..2164705 100644
--- a/docs/html/guide/developing/testing/index.jd
+++ b/docs/html/guide/developing/testing/index.jd
@@ -1,6 +1,5 @@
page.title=Testing Overview
@jd:body
-
<p>
Android includes powerful tools for setting up and running test applications.
Whether you are working in Eclipse with ADT or working from the command line, these tools
@@ -9,7 +8,7 @@ page.title=Testing Overview
</p>
<p>
If you aren't yet familiar with the Android testing framework, please read the topic
- <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing and Instrumentation</a>
+ <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Fundamentals</a>
before you get started.
For a step-by-step introduction to Android testing, try the <a
href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello, Testing</a>
diff --git a/docs/html/guide/developing/testing/testing_eclipse.jd b/docs/html/guide/developing/testing/testing_eclipse.jd
index da1c0f0..ba7eaba 100644
--- a/docs/html/guide/developing/testing/testing_eclipse.jd
+++ b/docs/html/guide/developing/testing/testing_eclipse.jd
@@ -1,28 +1,23 @@
page.title=Testing In Eclipse, with ADT
@jd:body
-
<div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#CreateTestProjectEclipse">Creating a Test Project</a></li>
- <li><a href="#CreateTestAppEclipse">Creating a Test Application</a></li>
- <li><a href="#RunTestEclipse">Running Tests</a></li>
- </ol>
- </div>
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#CreateTestProjectEclipse">Creating a Test Project</a></li>
+ <li><a href="#CreateTestAppEclipse">Creating a Test Package</a></li>
+ <li><a href="#RunTestEclipse">Running Tests</a></li>
+ </ol>
+ </div>
</div>
<p>
- This topic explains how create and run tests of Android applications in Eclipse with ADT.
-
- with the basic processes for creating and running applications with ADT, as described in
- <a href="{@docRoot}guide/developing/eclipse-adt.html">Developing In Eclipse, with ADT</a>.
-
- Before you read this topic, you should read about how to create a Android application with the
- basic processes for creating and running applications with ADT, as described in
- <a href="{@docRoot}guide/developing/eclipse-adt.html">Developing In Eclipse, with ADT</a>.
- You may also want to read
- <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing and Instrumentation</a>,
- which provides an overview of the Android testing framework.
+ This topic explains how create and run tests of Android applications in Eclipse with ADT.
+ Before you read this topic, you should read about how to create a Android application with the
+ basic processes for creating and running applications with ADT, as described in
+ <a href="{@docRoot}guide/developing/eclipse-adt.html">Developing In Eclipse, with ADT</a>.
+ You may also want to read
+ <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Fundamentals</a>,
+ which provides an overview of the Android testing framework.
</p>
<p>
ADT provides several features that help you set up and manage your testing environment
@@ -32,20 +27,20 @@ page.title=Testing In Eclipse, with ADT
<li>
It lets you quickly create a test project and link it to the application under test.
When it creates the test project, it automatically inserts the necessary
- <code>&lt;instrumentation&gt;</code> element in the test application's manifest file.
+ <code>&lt;instrumentation&gt;</code> element in the test package's manifest file.
</li>
<li>
It lets you quickly import the classes of the application under test, so that your
tests can inspect them.
</li>
<li>
- It lets you create run configurations for your test application and include in
+ It lets you create run configurations for your test package and include in
them flags that are passed to the Android testing framework.
</li>
<li>
- It lets you run your test application without leaving Eclipse. ADT builds both the
- application under test and the test application automatically, installs them if
- necessary to your device or emulator, runs the test application, and displays the
+ It lets you run your test package without leaving Eclipse. ADT builds both the
+ application under test and the test package automatically, installs them if
+ necessary to your device or emulator, runs the test package, and displays the
results in a separate window in Eclipse.
</li>
</ul>
@@ -55,305 +50,452 @@ page.title=Testing In Eclipse, with ADT
<a href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other IDEs</a>.
</p>
<h2 id="CreateTestProjectEclipse">Creating a Test Project</h2>
- <p>
+<p>
To set up a test environment for your Android application, you must first create a separate
- application project that holds the test code. The new project follows the directory structure
+ project that holds the test code. The new project follows the directory structure
used for any Android application. It includes the same types of content and files, such as
- source code, resources, a manifest file, and so forth. The test application you
+ source code, resources, a manifest file, and so forth. The test package you
create is connected to the application under test by an
<a href="{@docRoot}guide/topics/manifest/instrumentation-element.html">
<code>&lt;instrumentation&gt;</code></a> element in its manifest file.
- </p>
- <p>
- The <strong>New Android Test Project</strong> dialog makes it easy for you to generate a
+</p>
+<p>
+ The <em>New Android Test Project</em> dialog makes it easy for you to generate a
new test project that has the proper structure, including the
- <code>&lt;instrumentation&gt;</code> element in the manifest file. You can use the New Android
- Test Project dialog to generate the test project at any time. The dialog appears just after you
- create a new Android main application project, but you can also run it to create a test project
- for a project that you created previously.
- </p>
+ <code>&lt;instrumentation&gt;</code> element in the manifest file. You can use the New
+ Android Test Project dialog to generate the test project at any time. The dialog appears
+ just after you create a new Android main application project, but you can also run it to
+ create a test project for a project that you created previously.
+</p>
<p>
- To create a test project in Eclipse with ADT:
+ To create a test project in Eclipse with ADT:
</p>
<ol>
- <li>
- In Eclipse, select <strong>File &gt; New &gt; Other</strong>. This
- opens the Select a Wizard dialog.
- </li>
- <li>
- In the dialog, in the Wizards drop-down list,
- find the entry for Android, then click the toggle to the left. Select
- Android Test Project, then at the bottom
- of the dialog click Next. The New Android Test Project wizard appears.
- </li>
- <li>
- Enter a project name. You may use any name, but you may want to
- associate the name with the project name for your Application. One
- way to do this is to take the Application's project name, append the
- string "Test" to it, and then use this as the test case project name.
- </li>
- <li>
- In the Test Target panel, set
- An Existing Android Project, click
- Browse, then select your Android application from
- the list. You now see that the wizard has completed the Test
- Target Package, Application Name, and
- Package Name fields for you (the latter two are in
- the Properties panel).
- </li>
- <li>
- In the Build Target panel, select the Android SDK
- platform that you will use to test your application. Make this the same as the
- build target of the application under test.
- </li>
- <li>
- Click Finish to complete the wizard. If
- Finish is disabled, look
- for error messages at the top of the wizard dialog, and then fix
- any problems.
- </li>
+ <li>
+ In Eclipse, select <strong>File &gt; New &gt; Other</strong>. This opens the <em>Select a
+ Wizard</em> dialog.
+ </li>
+ <li>
+ In the dialog, in the <em>Wizards</em> drop-down list, find the entry for Android, then
+ click the toggle to the left. Select <strong>Android Test Project</strong>, then at the
+ bottom of the dialog click <strong>Next</strong>. The <em>New Android Test Project</em>
+ wizard appears.
+ </li>
+ <li>
+ Next to <em>Test Project Name</em>, enter a name for the project. You may use any name,
+ but you may want to associate the name with the project name for the application under test.
+ One way to do this is to take the application's project name, append the string "Test" to
+ it, and then use this as the test package project name.
+ <p>
+ The name becomes part of the suggested project path, but you can change this in the
+ next step.
+ </p>
+ </li>
+ <li>
+ In the <em>Content</em> panel, examine the suggested path to the project.
+ If <em>Use default location</em> is set, then the wizard will suggest a path that is
+ a concatenation of the workspace path and the project name you entered. For example,
+ if your workspace path is <code>/usr/local/workspace</code> and your project name is
+ <code>MyTestApp</code>, then the wizard will suggest
+ <code>/usr/local/workspace/MyTestApp</code>. To enter your own
+ choice for a path, unselect <em>Use default location</em>, then enter or browse to the
+ path where you want your project.
+ <p>
+ To learn more about choosing the location of test projects, please read
+ <a href="{@docRoot}guide/topics/testing/testing_android.html#TestProjectPaths">
+ Testing Fundamentals</a>.
+ </p>
+ </li>
+ <li>
+ In the Test Target panel, set An Existing Android Project, click Browse, then select your
+ Android application from the list. You now see that the wizard has completed the Test
+ Target Package, Application Name, and Package Name fields for you (the latter two are in
+ the Properties panel).
+ </li>
+ <li>
+ In the Build Target panel, select the Android SDK platform that the application under test
+ uses.
+ </li>
+ <li>
+ Click Finish to complete the wizard. If Finish is disabled, look for error messages at the
+ top of the wizard dialog, and then fix any problems.
+ </li>
</ol>
+<h2 id="CreateTestAppEclipse">Creating a Test Package</h2>
+<p>
+ Once you have created a test project, you populate it with a test package. This package does not
+ require an Activity, although you can define one if you wish. Although your test package can
+ combine Activity classes, test case classes, or ordinary classes, your main test case
+ should extend one of the Android test case classes or JUnit classes, because these provide the
+ best testing features.
+</p>
<p>
+ Test packages do not need to have an Android GUI. When you run the package in
+ Eclipse with ADT, its results appear in the JUnit view. Running tests and seeing the results is
+ described in more detail in the section <a href="#RunTestEclipse">Running Tests</a>.
+</p>
+<p>
+ To create a test package, start with one of Android's test case classes defined in
+ {@link android.test android.test}. These extend the JUnit
+ {@link junit.framework.TestCase TestCase} class. The Android test classes for Activity objects
+ also provide instrumentation for testing an Activity. To learn more about test case
+ classes, please read the topic <a href="{@docRoot}guide/topics/testing/testing_android.html">
+ Testing Fundamentals</a>.
</p>
-<h2 id="CreateTestAppEclipse">Creating a Test Application</h2>
<p>
- Once you have created a test project, you populate it with a test
- Android application. This application does not require an {@link android.app.Activity Activity},
- although you can define one if you wish. Although your test application can
- combine Activities, Android test class extensions, JUnit extensions, or
- ordinary classes, you should extend one of the Android test classes or JUnit classes,
- because these provide the best testing features.
+ Before you create your test package, you choose the Java package identifier you want to use
+ for your test case classes and the Android package name you want to use. To learn more
+ about this, please read
+ <a href="{@docRoot}guide/topics/testing/testing_android.html#PackageNames">
+ Testing Fundamentals</a>.
</p>
<p>
- Test applications do not have an Android GUI. Instead, when you run the application in
- Eclipse with ADT, its results appear in the JUnit view. If you run
- your tests with {@link android.test.InstrumentationTestRunner InstrumentationTestRunner} (or a related test runner),
- then it will run all the methods in each class. You can modify this behavior
- by using the {@link junit.framework.TestSuite TestSuite} class.
+ To add a test case class to your project:
</p>
-
+<ol>
+ <li>
+ In the <em>Project Explorer</em> tab, open your test project, then open the <em>src</em>
+ folder.
+ </li>
+ <li>
+ Find the Java package identifier set by the projection creation wizard. If you haven't
+ added classes yet, this node won't have any children, and its icon will not be filled in.
+ If you want to change the identifier value, right-click the identifier and select
+ <strong>Refactor</strong> &gt; <strong>Rename</strong>, then enter the new name.
+ </li>
+ <li>
+ When you are ready, right-click the Java package identifier again and select
+ <strong>New</strong> &gt; <strong>Class</strong>. This displays the <em>New Java Class</em>
+ dialog, with the <em>Source folder</em> and <em>Package</em> values already set.
+ </li>
+ <li>
+ In the <em>Name</em> field, enter a name for the test case class. One way to choose a
+ class name is to append the string "Test" to the class of the component you are testing.
+ For example, if you are testing the class MyAppActivity, your test case class
+ name would be MyAppActivityTest. Leave the modifiers set to <em>public</em>.
+ </li>
+ <li>
+ In the <em>Superclass</em> field, enter the name of the Android test case class you
+ are extending. You can also browse the available classes.
+ </li>
+ <li>
+ In <em>Which method stubs would you like to create?</em>, unset all the options, then
+ click <strong>Finish</strong>. You will set up the constructor manually.
+ </li>
+ <li>
+ Your new class appears in a new Java editor pane.
+ </li>
+</ol>
<p>
- To create a test application, start with one of Android's test classes in the Java package {@link android.test android.test}.
- These extend the JUnit {@link junit.framework.TestCase TestCase} class. With a few exceptions, the Android test classes
- also provide instrumentation for testing.
+ You now have to ensure that the constructor is set up correctly. Create a constructor for your
+ class that has no arguments; this is required by JUnit. As the first statement in this
+ constructor, add a call to the base class' constructor. Each base test case class has its
+ own constructor signature. Refer to the class documentation in the documentation for
+ {@link android.test} for more information.
</p>
<p>
- For test classes that extend {@link junit.framework.TestCase TestCase}, you probably want to override
- the <code>setUp()</code> and <code>tearDown()</code> methods:
+ To control your test environment, you will want to override the <code>setUp()</code> and
+ <code>tearDown()</code> methods:
</p>
<ul>
- <li>
- <code>setUp()</code>: This method is invoked before any of the test methods in the class.
- Use it to set up the environment for the test. You can use <code>setUp()</code>
- to instantiate a new <code>Intent</code> object with the action <code>ACTION_MAIN</code>. You can
- then use this intent to start the Activity under test.
- <p class="note"><strong>Note:</strong> If you override this method, call
- <code>super.setUp()</code> as the first statement in your code.
- </p>
- </li>
- <li>
- <code>tearDown()</code>: This method is invoked after all the test methods in the class. Use
- it to do garbage collection and re-setting before moving on to the next set of tests.
- <p class="note"><strong>Note:</strong> If you override this method, you must call
- <code>super.tearDown()</code> as the <em>last</em> statement in your code.</p>
- </li>
+ <li>
+ <code>setUp()</code>: This method is invoked before any of the test methods in the class.
+ Use it to set up the environment for the test (the test fixture. You can use
+ <code>setUp()</code> to instantiate a new Intent with the action <code>ACTION_MAIN</code>.
+ You can then use this intent to start the Activity under test.
+ </li>
+ <li>
+ <code>tearDown()</code>: This method is invoked after all the test methods in the class. Use
+ it to do garbage collection and to reset the test fixture.
+ </li>
</ul>
<p>
- Another useful convention is to add the method <code>testPreConditions()</code> to your test
- class. Use this method to test that the application under test is initialized correctly. If this
- test fails, you know that that the initial conditions were in error. When this happens, further test
- results are suspect, regardless of whether or not the tests succeeded.
+ Another useful convention is to add the method <code>testPreconditions()</code> to your test
+ class. Use this method to test that the application under test is initialized correctly. If this
+ test fails, you know that that the initial conditions were in error. When this happens, further
+ test results are suspect, regardless of whether or not the tests succeeded.
</p>
<p>
- The Resources tab contains an <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
- tutorial with more information about creating test classes and methods.
+ The Resources tab contains an
+ <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
+ tutorial with more information about creating test classes and methods.
</p>
<h2 id="RunTestEclipse">Running Tests</h2>
-<div class="sidebox-wrapper">
- <div class="sidebox">
- <h2>Running tests from the command line</h2>
- <p>
- If you've created your tests in Eclipse, you can still run your tests and test
- suites by using command-line tools included with the Android SDK. You may want to
- do this, for example, if you have a large number of tests to run, if you have a
- large test case, or if you want a fine level of control over which tests are run at
- a particular time.
- </p>
- <p>
- To run tests created in Eclipse with ADT with command-line tools, you must first
- install additional files into the test project using the <code>android</code> tool's
- "create test-project" option. To see how to do this, read the section
- <a href="{@docRoot}guide/developing/testing/testing_otheride.html#CreateProject">
- Creating a test project</a> in the topic
- <a href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other
- IDEs</a>.
- </p>
+ <div class="sidebox-wrapper">
+ <div class="sidebox">
+ <h2>Running tests from the command line</h2>
+ <p>
+ If you've created your tests in Eclipse, you can still run your tests and test
+ suites by using command-line tools included with the Android SDK. You may want
+ to do this, for example, if you have a large number of tests to run, if you
+ have a large test case, or if you want a fine level of control over which
+ tests are run at a particular time.
+ </p>
+ <p>
+ To run tests created in Eclipse with ADT with command-line tools, you must first
+ install additional files into the test project using the <code>android</code>
+ tool's "create test-project" option. To see how to do this, read
+ <a href="{@docRoot}guide/developing/testing/testing_otheride.html#CreateProject">
+ Testing in Other IDEs</a>.
+ </p>
+ </div>
</div>
-</div>
<p>
- When you run a test application in Eclipse with ADT, the output appears in
- an Eclipse view panel. You can run the entire test application, one class, or one
- method of a class. To do this, Eclipse runs the <code>adb</code> command for running a test application, and
- displays the output, so there is no difference between running tests inside Eclipse and running them from the command line.
+ When you run a test package in Eclipse with ADT, the output appears in the Eclipse JUnit view.
+ You can run the entire test package or one test case class. To do run tests, Eclipse runs the
+ <code>adb</code> command for running a test package, and displays the output, so there is no
+ difference between running tests inside Eclipse and running them from the command line.
</p>
<p>
- As with any other application, to run a test application in Eclipse with ADT you must either attach a device to your
- computer or use the Android emulator. If you use the emulator, you must have an Android Virtual Device (AVD) that uses
- the same target
+ As with any other package, to run a test package in Eclipse with ADT you must either attach a
+ device to your computer or use the Android emulator. If you use the emulator, you must have an
+ Android Virtual Device (AVD) that uses the same target as the test package.
</p>
<p>
- To run a test in Eclipse, you have two choices:</p>
+ To run a test in Eclipse, you have two choices:</p>
+<ul>
+ <li>
+ Run a test just as you run an application, by selecting
+ <strong>Run As... &gt; Android JUnit Test</strong> from the project's context menu or
+ from the main menu's <strong>Run</strong> item.
+ </li>
+ <li>
+ Create an Eclipse run configuration for your test project. This is useful if you want
+ multiple test suites, each consisting of selected tests from the project. To run
+ a test suite, you run the test configuration.
+ <p>
+ Creating and running test configurations is described in the next section.
+ </p>
+ </li>
+</ul>
+<p>
+ To create and run a test suite using a run configuration:
+</p>
<ol>
- <li>
- Run a test just as you run an application, by selecting
- <strong>Run As... &gt; Android JUnit Test</strong> from the project's context menu or
- from the main menu's <strong>Run</strong> item.
- </li>
- <li>
- Create an Eclipse run configuration for your test project. This is useful if you want multiple test suites, each consisting of selected tests from the project. To run
- a test suite, you run the test configuration.
- <p>
- Creating and running test configurations is described in the next section.
- </p>
- </li>
+ <li>
+ In the Package Explorer, select the test project, then from the main menu, select
+ <strong>Run &gt; Run Configurations...</strong>. The Run Configurations dialog appears.
+ </li>
+ <li>
+ In the left-hand pane, find the Android JUnit Test entry. In the right-hand pane, click the
+ Test tab. The Name: text box shows the name of your project. The Test class: dropdown box
+ shows one of the test classes in your project.
+ </li>
+ <li>
+ To run one test class, click Run a single test, then enter your project name in the
+ Project: text box and the class name in the Test class: text box.
+ <p>
+ To run all the test classes, click Run all tests in the selected project or package,
+ then enter the project or package name in the text box.
+ </p>
+ </li>
+ <li>
+ Now click the Target tab.
+ <ul>
+ <li>
+ Optional: If you are using the emulator, click Automatic, then in the Android
+ Virtual Device (AVD) selection table, select an existing AVD.
+ </li>
+ <li>
+ In the Emulator Launch Parameters pane, set the Android emulator flags you want to
+ use. These are documented in the topic
+ <a href="{@docRoot}guide/developing/tools/emulator.html#startup-options">
+ Android Emulator</a>.
+ </li>
+ </ul>
+ </li>
+ <li>
+ Click the Common tab. In the Save As pane, click Local to save this run configuration
+ locally, or click Shared to save it to another project.
+ </li>
+ <li>
+ Optional: Add the configuration to the Run toolbar and the <strong>Favorites</strong>
+ menu: in the Display in Favorites pane click the checkbox next to Run.
+ </li>
+ <li>
+ Optional: To add this configuration to the <strong>Debug</strong> menu and toolbar, click
+ the checkbox next to Debug.
+ </li>
+ <li>
+ To save your settings, click Close.<br/>
+ <p class="note"><strong>Note:</strong>
+ Although you can run the test immediately by clicking Run, you should save the test
+ first and then run it by selecting it from the Eclipse standard toolbar.
+ </p>
+ </li>
+ <li>
+ On the Eclipse standard toolbar, click the down arrow next to the green Run arrow. This
+ displays a menu of saved Run and Debug configurations.
+ </li>
+ <li>
+ Select the test run configuration you just created. The test starts.
+ </li>
</ol>
-<p>To create and run a test suite using a run configuration:</p>
-<ol>
- <li>
- In the Package Explorer, select the test
- project, then from the main menu, select
- <strong>Run &gt; Run Configurations...</strong>. The
- Run Configurations dialog appears.
- </li>
- <li>
- In the left-hand pane, find the
- Android JUnit Test entry.
- In the right-hand pane, click the Test tab.
- The Name: text box
- shows the name of your project. The
- Test class: dropdown box shows one your project's classes
- test classes in your project.
- </li>
- <li>
- To run one test class, click Run a single test, then enter your project
- name in the Project: text box and the class name in the
- Test class: text box.
- <p>
- To run all the test classes,
- click Run all tests in the selected project or package,
- then enter the project or package name in the text box.
- </p>
- </li>
- <li>
- Now click the Target tab.
- <ul>
- <li>
- Optional: If you are using the emulator, click
- Automatic, then in the Android Virtual Device (AVD)
- selection table, select an existing AVD.
- </li>
- <li>
- In the Emulator Launch Parameters pane, set the
- Android emulator flags you want to use. These are documented in the topic
- <a href="{@docRoot}guide/developing/tools/emulator.html#startup-options">Emulator Startup Options</a>.
- </li>
- </ul>
- <li>
- Click the Common tab. In the
- Save As pane, click Local to save
- this run configuration locally, or click Shared to
- save it to another project.
- </li>
- <li>
- Optional: Add the configuration to the Run toolbar and the <strong>Favorites</strong>
- menu: in the Display in Favorites pane
- click the checkbox next to Run.
- </li>
- <li>
- Optional: To add this configuration to the <strong>Debug</strong> menu and toolbar, click
- the checkbox next to Debug.
- </li>
- <li>
- To save your settings, click Close.<br/>
- <p class="note"><strong>Note:</strong> Although you can run the test immediately by
- clicking Run, you should save the test first and then
- run it by selecting it from the Eclipse standard toolbar.</p>
- </li>
- <li>
- On the Eclipse standard toolbar, click the down arrow next to the
- green Run arrow. This displays a menu of saved Run and Debug
- configurations.
- </li>
- <li>
- Select the test run configuration you just created.
- </li>
- <li>
- The progress of your test appears in the Console view.
- You should see the following messages, among others:
- <ul>
- <li>
- <code>Performing Android.test.InstrumentationTestRunner JUnit launch</code><br>
- The class name that proceeds "JUnit" depends on the Android instrumentation
- class you have chosen.
- </li>
- <li>
- If you are using an emulator and you have not yet started it, then you will see
+<p>
+ The progress of your test appears in the Console view as a series of messages. Each message is
+ preceded by a timestamp and the <code>.apk</code> filename to which it applies. For example,
+ this message appears when you run a test to the emulator, and the emulator is not yet started:
+</p>
+<div class="sidebox-wrapper">
+ <div class="sidebox">
+ <h2>Message Examples</h2>
+ <p>
+ The examples shown in this section come from the
+ <a href="{@docRoot}resources/samples/SpinnerTest/index.html">SpinnerTest</a>
+ sample test package, which tests the
+ <a href="{@docRoot}resources/samples/Spinner/index.html">Spinner</a>
+ sample application. This test package is also featured in the
+ <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
+ tutorial.
+ </p>
+ </div>
+</div>
+<pre>
+ [<em>yyyy-mm-dd hh:mm:ss</em> - <em>testfile</em>] Waiting for HOME ('android.process.acore') to be launched...
+</pre>
+<p>
+ In the following description of these messages, <code><em>devicename</em></code> is the name of
+ the device or emulator you are using to run the test, and <code><em>port</em></code> is the
+ port number for the device. The name and port number are in the format used by the
+ <code><a href="{@docRoot}guide/developing/tools/adb.html#devicestatus">adb devices</a></code>
+ command. Also, <code><em>testfile</em></code> is the <code>.apk</code> filename of the test
+ package you are running, and <em>appfile</em> is the filename of the application under test.
+</p>
+<ul>
+ <li>
+ If you are using an emulator and you have not yet started it, then Eclipse
+ first starts the emulator. When this is complete, you see
the message:
<p>
- <code>Automatic Target Mode: launching new emulator with compatible
- AVD <em>avdname</em></code><br>(where <em>avdname</em> is the name of
- the AVD you are using.)
+ <code>HOME is up on device '<em>devicename</em>-<em>port</em>'</code>
</p>
- </li>
- <li>
- If you have not already installed your test application, then you will see
+ </li>
+ <li>
+ If you have not already installed your test package, then you see
the message:
<p>
- <code>Uploading <em>testclass</em>.apk onto device '<em>device-id</em>'</code><br>
- where <em>testclass</em> is the name of your unit test class and <em>device-id</em>
- is the name and port for your test device or emulator, followed by the message <code>Installing <em>testclass</em>.apk</code>
+ <code>Uploading <em>testfile</em> onto device '<em>devicename</em>-<em>port</em>'
+ </code>
</p>
- </li>
- <li>
- <code>Launching instrumentation Android.test.InstrumentationTestRunner on device <em>device-id</em></code>.<br>
- This indicates that Android's Instrumentation system is now testing your code. Again, the
- instrumentation class name depends on the Android instrumentation class you have chosen.
- </li>
- <li>
- <code>Test run complete</code>.<br> When you see this, your unit tests have finished.
- </li>
- </ul>
-</ol>
+ <p>
+ then the message <code>Installing <em>testfile</em></code>.
+ </p>
+ <p>
+ and finally the message <code>Success!</code>
+ </p>
+ </li>
+</ul>
<p>
- The test results appear in the JUnit view. This is divided into an upper summary pane,
- and a lower stack trace pane.
+ The following lines are an example of this message sequence:
</p>
+<code>
+[2010-07-01 12:44:40 - MyTest] HOME is up on device 'emulator-5554'<br>
+[2010-07-01 12:44:40 - MyTest] Uploading MyTest.apk onto device 'emulator-5554'<br>
+[2010-07-01 12:44:40 - MyTest] Installing MyTest.apk...<br>
+[2010-07-01 12:44:49 - MyTest] Success!<br>
+</code>
+<br>
+<ul>
+ <li>
+ Next, if you have not yet installed the application under test to the device or
+ emulator, you see the message
+ <p>
+ <code>Project dependency found, installing: <em>appfile</em></code>
+ </p>
+ <p>
+ then the message <code>Uploading <em>appfile</em></code> onto device
+ '<em>devicename</em>-<em>port</em>'
+ </p>
+ <p>
+ then the message <code>Installing <em>appfile</em></code>
+ </p>
+ <p>
+ and finally the message <code>Success!</code>
+ </p>
+ </li>
+</ul>
<p>
- The upper pane contains test information. In the pane's header, you see the following
- information:
+ The following lines are an example of this message sequence:
</p>
- <ul>
- <li>
- Total time elapsed for the test application (labeled Finished after <em>x</em> seconds).
- </li>
- <li>
- Number of runs (Runs:) - the number of tests in the entire test class.
- </li>
- <li>
- Number of errors (Errors:) - the number of program errors and exceptions encountered
- during the test run.
- </li>
- <li>
- Number of failures (Failures:) - the number of test failures encountered during the test
- run. This is the number of assertion failures. A test can fail even if the program does
- not encounter an error.
- </li>
- <li>
- A progress bar. The progress bar extends from left to right as the tests run. If all the
- tests succeed, the bar remains green. If a test fails, the bar turns from green to red.
- </li>
- </ul>
+<code>
+[2010-07-01 12:44:49 - MyTest] Project dependency found, installing: MyApp<br>
+[2010-07-01 12:44:49 - MyApp] Uploading MyApp.apk onto device 'emulator-5554'<br>
+[2010-07-01 12:44:49 - MyApp] Installing MyApp.apk...<br>
+[2010-07-01 12:44:54 - MyApp] Success!<br>
+</code>
+<br>
+<ul>
+ <li>
+ Next, you see the message
+ <code>Launching instrumentation <em>instrumentation_class</em> on device
+ <em>devicename</em>-<em>port</em></code>
+ <p>
+ <code>instrumentation_class</code> is the fully-qualified class name of the
+ instrumentation test runner you have specified (usually
+ {@link android.test.InstrumentationTestRunner}.
+ </p>
+ </li>
+ <li>
+ Next, as {@link android.test.InstrumentationTestRunner} builds a list of tests to run,
+ you see the message
+ <p>
+ <code>Collecting test information</code>
+ </p>
+ <p>
+ followed by
+ </p>
+ <p>
+ <code>Sending test information to Eclipse</code>
+ </p>
+ </li>
+ <li>
+ Finally, you see the message <code>Running tests</code>, which indicates that your tests
+ are running. At this point, you should start seeing the test results in the JUnit view.
+ When the tests are finished, you see the console message <code>Test run complete</code>.
+ This indicates that your tests are finished.
+ </li>
+</ul>
+<p>
+ The following lines are an example of this message sequence:
+</p>
+<code>
+[2010-01-01 12:45:02 - MyTest] Launching instrumentation android.test.InstrumentationTestRunner on device emulator-5554<br>
+[2010-01-01 12:45:02 - MyTest] Collecting test information<br>
+[2010-01-01 12:45:02 - MyTest] Sending test information to Eclipse<br>
+[2010-01-01 12:45:02 - MyTest] Running tests...<br>
+[2010-01-01 12:45:22 - MyTest] Test run complete<br>
+</code>
+<br>
+<p>
+ The test results appear in the JUnit view. This is divided into an upper summary pane,
+ and a lower stack trace pane.
+</p>
+<p>
+ The upper pane contains test information. In the pane's header, you see the following
+ information:
+</p>
+<ul>
+ <li>
+ Total time elapsed for the test package (labeled Finished after <em>x</em> seconds).
+ </li>
+ <li>
+ Number of runs (Runs:) - the number of tests in the entire test class.
+ </li>
+ <li>
+ Number of errors (Errors:) - the number of program errors and exceptions encountered
+ during the test run.
+ </li>
+ <li>
+ Number of failures (Failures:) - the number of test failures encountered during the test
+ run. This is the number of assertion failures. A test can fail even if the program does
+ not encounter an error.
+ </li>
+ <li>
+ A progress bar. The progress bar extends from left to right as the tests run. If all the
+ tests succeed, the bar remains green. If a test fails, the bar turns from green to red.
+ </li>
+</ul>
<p>
The body of the upper pane contains the details of the test run. For each test case class
that was run, you see a line with the class name. To look at the results for the individual
@@ -363,8 +505,30 @@ page.title=Testing In Eclipse, with ADT
pane and moves the focus to the first line of the test method.
</p>
<p>
+ The results of a successful test are shown in
+ <a href="#TestResults">Figure 1. Messages for a successful test</a>:
+</p>
+<a href="{@docRoot}images/testing/eclipse_test_results.png">
+ <img src="{@docRoot}images/testing/eclipse_test_results.png"
+ alt="Messages for a successful test" height="327px" id="TestResults"/>
+</a>
+<p class="img-caption">
+ <strong>Figure 1.</strong> Messages for a successful test
+</p>
+<p>
The lower pane is for stack traces. If you highlight a failed test in the upper pane, the
lower pane contains a stack trace for the test. If a line corresponds to a point in your
test code, you can double-click it to display the code in an editor view pane, with the
line highlighted. For a successful test, the lower pane is empty.
</p>
+<p>
+ The results of a failed test are shown in
+ <a href="#FailedTestResults">Figure 2. Messages for a test failure</a>
+</p>
+<a href="{@docRoot}images/testing/eclipse_test_run_failure.png">
+ <img src="{@docRoot}images/testing/eclipse_test_run_failure.png"
+ alt="Messages for a test failure" height="372px" id="TestRun"/>
+</a>
+<p class="img-caption">
+ <strong>Figure 2.</strong> Messages for a test failure
+</p>
diff --git a/docs/html/guide/developing/testing/testing_otheride.jd b/docs/html/guide/developing/testing/testing_otheride.jd
index 2bdf4d0..523a8e5 100644
--- a/docs/html/guide/developing/testing/testing_otheride.jd
+++ b/docs/html/guide/developing/testing/testing_otheride.jd
@@ -2,122 +2,128 @@ page.title=Testing In Other IDEs
@jd:body
<div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
- <ol>
- <li>
- <a href="#CreateTestProjectCommand">Working with Test Projects</a>
- <ol>
- <li>
- <a href="#CreateTestProject">Creating a test project</a>
- </li>
- <li>
- <a href="#UpdateTestProject">Updating a test project</a>
- </li>
- </ol>
- </li>
- <li>
- <a href="#CreateTestApp">Creating a Test Application</a>
- </li>
- <li>
- <a href="#RunTestsCommand">Running Tests</a>
- <ol>
- <li>
- <a href="#RunTestsAnt">Quick build and run with Ant</a>
- </li>
- <li>
- <a href="#RunTestsDevice">Running tests on a device or emulator</a>
- </li>
- </ol>
- </li>
- <li>
- <a href="#AMSyntax">Using the Instrument Command</a>
- <ol>
- <li>
- <a href="#AMOptionsSyntax">Instrument options</a>
- </li>
- <li>
- <a href="#RunTestExamples">Instrument examples</a>
- </li>
- </ol>
- </li>
-
- </ol>
- <h2>See Also</h2>
- <ol>
- <li>
- <a
- href="{@docRoot}guide/topics/testing/testing_android.html">Testing and Instrumentation</a>
- </li>
- <li>
- <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
- </li>
- <li>
- <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug Bridge</a>
- </li>
- </ol>
- </div>
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li>
+ <a href="#CreateTestProjectCommand">Working with Test Projects</a>
+ <ol>
+ <li>
+ <a href="#CreateTestProject">Creating a test project</a>
+ </li>
+ <li>
+ <a href="#UpdateTestProject">Updating a test project</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#CreateTestApp">Creating a Test Package</a>
+ </li>
+ <li>
+ <a href="#RunTestsCommand">Running Tests</a>
+ <ol>
+ <li>
+ <a href="#RunTestsAnt">Quick build and run with Ant</a>
+ </li>
+ <li>
+ <a href="#RunTestsDevice">Running tests on a device or emulator</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#AMSyntax">Using the Instrument Command</a>
+ <ol>
+ <li>
+ <a href="#AMOptionsSyntax">Instrument options</a>
+ </li>
+ <li>
+ <a href="#RunTestExamples">Instrument examples</a>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ <h2>See Also</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/topics/testing/testing_android.html">
+ Testing Fundamentals</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug Bridge</a>
+ </li>
+ </ol>
+ </div>
</div>
<p>
- This document describes how to create and run tests directly from the command line.
- You can use the techniques described here if you are developing in an IDE other than Eclipse
- or if you prefer to work from the command line. This document assumes that you already know how
- to create a Android application in your programming environment. Before you start this
- document, you should read the document <a
- href="{@docRoot}guide/topics/testing/testing_android.html">Testing and Instrumentation</a>,
- which provides an overview of Android testing.
+ This document describes how to create and run tests directly from the command line.
+ You can use the techniques described here if you are developing in an IDE other than Eclipse
+ or if you prefer to work from the command line. This document assumes that you already know how
+ to create a Android application in your programming environment. Before you start this
+ document, you should read the topic
+ <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Fundamentals</a>,
+ which provides an overview of Android testing.
</p>
<p>
- If you are developing in Eclipse with ADT, you can set up and run your tests
-directly in Eclipse. For more information, please read <a
- href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing&nbsp;in&nbsp;Eclipse,&nbsp;with&nbsp;ADT</a>.
+ If you are developing in Eclipse with ADT, you can set up and run your tests
+ directly in Eclipse. For more information, please read
+ <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">
+ Testing in Eclipse, with ADT</a>.
</p>
<h2 id="CreateTestProjectCommand">Working with Test Projects</h2>
<p>
- You use the <code>android</code> tool to create test projects.
- You also use <code>android</code> to convert existing test code into an Android test project,
- or to add the <code>run-tests</code> Ant target to an existing Android test project.
- These operations are described in more detail in the section <a
- href="#UpdateTestProject">Updating a test project</a>.
- The <code>run-tests</code> target is described in <a
- href="#RunTestsAnt">Quick build and run with Ant</a>.
+ You use the <code>android</code> tool to create test projects.
+ You also use <code>android</code> to convert existing test code into an Android test project,
+ or to add the <code>run-tests</code> Ant target to an existing Android test project.
+ These operations are described in more detail in the section <a href="#UpdateTestProject">
+ Updating a test project</a>. The <code>run-tests</code> target is described in
+ <a href="#RunTestsAnt">Quick build and run with Ant</a>.
</p>
<h3 id="CreateTestProject">Creating a test project</h3>
<p>
- To create a test project with the <code>android</code> tool, enter:
-<pre>android create test-project -m &lt;main_path&gt; -n &lt;project_name&gt; -p &lt;test_path&gt;</pre>
+ To create a test project with the <code>android</code> tool, enter:
+</p>
+<pre>
+android create test-project -m &lt;main_path&gt; -n &lt;project_name&gt; -p &lt;test_path&gt;
+</pre>
<p>
- You must supply all the flags. The following table explains them in detail:
+ You must supply all the flags. The following table explains them in detail:
</p>
<table>
- <tr>
- <th>Flag</th>
- <th>Value</th>
- <th>Description</th>
- <tr>
- <td><code>-m, --main</code></td>
- <td>
- Path to the project of the application under test, relative to the test application
- directory.
- </td>
- <td>
- For example, if the application under test is in <code>source/HelloAndroid</code>, and you
- want to create the test project in <code>source/HelloAndroidTest</code>, then the value of
- <code>--main</code> should be <code>../HelloAndroid</code>.
- </td>
- <tr>
- <td><code>-n, --name</code></td>
- <td>Name that you want to give the test project.</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td><code>-p, --path</code></td>
- <td>Directory in which you want to create the new test project.</td>
- <td>
- The <code>android</code> tool creates the test project files and directory structure in this
- directory. If the directory does not exist, <code>android</code> creates it.
- </td>
- </tr>
+ <tr>
+ <th>Flag</th>
+ <th>Value</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>-m, --main</code></td>
+ <td>
+ Path to the project of the application under test, relative to the test package
+ directory.
+ </td>
+ <td>
+ For example, if the application under test is in <code>source/HelloAndroid</code>, and
+ you want to create the test project in <code>source/HelloAndroidTest</code>, then the
+ value of <code>--main</code> should be <code>../HelloAndroid</code>.
+ <p>
+ To learn more about choosing the location of test projects, please read
+ <a href="{@docRoot}guide/topics/testing/testing_android.html#TestProjects">
+ Testing Fundamentals</a>.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>-n, --name</code></td>
+ <td>Name that you want to give the test project.</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td><code>-p, --path</code></td>
+ <td>Directory in which you want to create the new test project.</td>
+ <td>
+ The <code>android</code> tool creates the test project files and directory structure
+ in this directory. If the directory does not exist, <code>android</code> creates it.
+ </td>
+ </tr>
</table>
<p>
If the operation is successful, <code>android</code> lists to STDOUT the names of the files
@@ -135,11 +141,10 @@ directly in Eclipse. For more information, please read <a
are testing and control it with instrumentation.
</p>
<p>
- For example, suppose you create the <a
- href="{@docRoot}resources/tutorials/hello-world.html">Hello, World</a> tutorial application
- in the directory <code>~/source/HelloAndroid</code>. In the tutorial, this application uses the
- package name <code>com.example.helloandroid</code> and the activity name
- <code>HelloAndroid</code>. You can to create the test for this in
+ For example, suppose you create the <a href="{@docRoot}resources/tutorials/hello-world.html">
+ Hello, World</a> tutorial application in the directory <code>~/source/HelloAndroid</code>.
+ In the tutorial, this application uses the package name <code>com.example.helloandroid</code>
+ and the activity name <code>HelloAndroid</code>. You can to create the test for this in
<code>~/source/HelloAndroidTest</code>. To do so, you enter:
</p>
<pre>
@@ -196,7 +201,7 @@ $ android create test-project -m ../HelloAndroid -n HelloAndroidTest -p HelloAnd
<p class="note">
<strong>Note:</strong> If you change the Android package name of the application under test,
you must <em>manually</em> change the value of the <code>&lt;android:targetPackage&gt;</code>
- attribute within the <code>AndroidManifest.xml</code> file of the test application.
+ attribute within the <code>AndroidManifest.xml</code> file of the test package.
Running <code>android update test-project</code> does not do this.
</p>
<p>
@@ -205,38 +210,38 @@ $ android create test-project -m ../HelloAndroid -n HelloAndroidTest -p HelloAnd
<pre>android update-test-project -m &lt;main_path&gt; -p &lt;test_path&gt;</pre>
<table>
-<tr>
- <th>Flag</th>
- <th>Value</th>
- <th>Description</th>
-</tr>
-<tr>
- <td><code>-m, --main</code></td>
- <td>The path to the project of the application under test, relative to the test project</td>
- <td>
- For example, if the application under test is in <code>source/HelloAndroid</code>, and
- the test project is in <code>source/HelloAndroidTest</code>, then the value for
- <code>--main</code> is <code>../HelloAndroid</code>.
- </td>
-</tr>
-<tr>
- <td><code>-p, --path</code></td>
- <td>The of the test project.</td>
- <td>
- For example, if the test project is in <code>source/HelloAndroidTest</code>, then the
- value for <code>--path</code> is <code>HelloAndroidTest</code>.
- </td>
-</tr>
+ <tr>
+ <th>Flag</th>
+ <th>Value</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>-m, --main</code></td>
+ <td>The path to the project of the application under test, relative to the test project</td>
+ <td>
+ For example, if the application under test is in <code>source/HelloAndroid</code>, and
+ the test project is in <code>source/HelloAndroidTest</code>, then the value for
+ <code>--main</code> is <code>../HelloAndroid</code>.
+ </td>
+ </tr>
+ <tr>
+ <td><code>-p, --path</code></td>
+ <td>The of the test project.</td>
+ <td>
+ For example, if the test project is in <code>source/HelloAndroidTest</code>, then the
+ value for <code>--path</code> is <code>HelloAndroidTest</code>.
+ </td>
+ </tr>
</table>
<p>
If the operation is successful, <code>android</code> lists to STDOUT the names of the files
and directories it has created.
</p>
-<h2 id="CreateTestApp">Creating a Test Application</h2>
+<h2 id="CreateTestApp">Creating a Test Package</h2>
<p>
- Once you have created a test project, you populate it with a test application.
+ Once you have created a test project, you populate it with a test package.
The application does not require an {@link android.app.Activity Activity},
- although you can define one if you wish. Although your test application can
+ although you can define one if you wish. Although your test package can
combine Activities, Android test class extensions, JUnit extensions, or
ordinary classes, you should extend one of the Android test classes or JUnit classes,
because these provide the best testing features.
@@ -248,7 +253,7 @@ $ android create test-project -m ../HelloAndroid -n HelloAndroidTest -p HelloAnd
</p>
<p>
- To create a test application, start with one of Android's test classes in the Java package
+ To create a test package, start with one of Android's test classes in the Java package
{@link android.test android.test}. These extend the JUnit
{@link junit.framework.TestCase TestCase} class. With a few exceptions, the Android test
classes also provide instrumentation for testing.
@@ -282,24 +287,17 @@ $ android create test-project -m ../HelloAndroid -n HelloAndroidTest -p HelloAnd
test results are suspect, regardless of whether or not the tests succeeded.
</p>
<p>
- To learn more about creating test applications, see the topic <a
- href="{@docRoot}guide/topics/testing/testing_android.html">Testing and Instrumentation</a>,
+ To learn more about creating test packages, see the topic <a
+ href="{@docRoot}guide/topics/testing/testing_android.html">Testing Fundamentals</a>,
which provides an overview of Android testing. If you prefer to follow a tutorial,
try the <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
tutorial, which leads you through the creation of tests for an actual Android application.
</p>
<h2 id="RunTestsCommand">Running Tests</h2>
<p>
- If you are not developing in Eclipse with ADT, you need to run tests from the command line.
- You can do this either with Ant or with the {@link android.app.ActivityManager ActivityManager}
- command line interface.
-</p>
-<p>
- You can also run tests from the command line even if you are using Eclipse with ADT to develop
- them. To do this, you need to create the proper files and directory structure in the test
- project, using the <code>android</code> tool with the option <code>create test-project</code>.
- This is described in the section <a
- href="#CreateTestProjectCommand">Working with Test Projects</a>.
+ You run tests from the command line, either with Ant or with an
+ <a href="{@docRoot}http://developer.android.com/guide/developing/tools/adb.html">
+ Android Debug Bridge (adb)</a> shell.
</p>
<h3 id="RunTestsAnt">Quick build and run with Ant</h3>
<p>
@@ -316,57 +314,63 @@ $ android create test-project -m ../HelloAndroid -n HelloAndroidTest -p HelloAnd
You can update an existing test project to use this feature. To do this, use the
<code>android</code> tool with the <code>update test-project</code> option. This is described
in the section <a href="#UpdateTestProject">Updating a test project</a>.
+</p>
<h3 id="RunTestsDevice">Running tests on a device or emulator</h3>
<p>
- When you run tests from the command line with the ActivityManager (<code>am</code>)
- command-line tool, you get more options for choosing the tests to run than with any other
- method. You can select individual test methods, filter tests according to their annotation, or
- specify testing options. Since the test run is controlled entirely from a command line, you can
- customize your testing with shell scripts in various ways.
+ When you run tests from the command line with
+ <a href="{@docRoot}http://developer.android.com/guide/developing/tools/adb.html">
+ Android Debug Bridge (adb)</a>, you get more options for choosing the tests
+ to run than with any other method. You can select individual test methods, filter tests
+ according to their annotation, or specify testing options. Since the test run is controlled
+ entirely from a command line, you can customize your testing with shell scripts in various ways.
+</p>
+<p>
+ To run a test from the command line, you run <code>adb shell</code> to start a command-line
+ shell on your device or emulator, and then in the shell run the <code>am instrument</code>
+ command. You control <code>am</code> and your tests with command-line flags.
</p>
<p>
- You run the <code>am</code> tool on an Android device or emulator using the
- <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug Bridge</a>
- (<code>adb</code>) shell. When you do this, you use the ActivityManager
- <code>instrument</code> option to run your test application using an Android test runner
- (usually {@link android.test.InstrumentationTestRunner}). You set <code>am</code>
- options with command-line flags.
+ As a shortcut, you can start an <code>adb</code> shell, call <code>am instrument</code>, and
+ specify command-line flags all on one input line. The shell opens on the device or emulator,
+ runs your tests, produces output, and then returns to the command line on your computer.
</p>
<p>
- To run a test with <code>am</code>:
+ To run a test with <code>am instrument</code>:
</p>
<ol>
- <li>
- If necessary, re-build your main application and test application.
- </li>
- <li>
- Install your test application and main application Android package files
- (<code>.apk</code> files) to your current Android device or emulator</li>
- <li>
- At the command line, enter:
+ <li>
+ If necessary, rebuild your main application and test package.
+ </li>
+ <li>
+ Install your test package and main application Android package files
+ (<code>.apk</code> files) to your current Android device or emulator</li>
+ <li>
+ At the command line, enter:
<pre>
$ adb shell am instrument -w &lt;test_package_name&gt;/&lt;runner_class&gt;
</pre>
-<p>
- where <code>&lt;test_package_name&gt;</code> is the Android package name of your test
- application, and <code>&lt;runner_class&gt;</code> is the name of the Android test runner
- class you are using. The Android package name is the value of the <code>package</code>
- attribute of the <code>manifest</code> element in the manifest file
- (<code>AndroidManifest.xml</code>) of your test application. The Android test runner
- class is usually <code>InstrumentationTestRunner</code>.
-</p>
-<p>Your test results appear in <code>STDOUT</code>.</p>
- </li>
+ <p>
+ where <code>&lt;test_package_name&gt;</code> is the Android package name of your test
+ application, and <code>&lt;runner_class&gt;</code> is the name of the Android test
+ runner class you are using. The Android package name is the value of the
+ <code>package</code> attribute of the <code>manifest</code> element in the manifest file
+ (<code>AndroidManifest.xml</code>) of your test package. The Android test runner
+ class is usually {@link android.test.InstrumentationTestRunner}.
+ </p>
+ <p>
+ Your test results appear in <code>STDOUT</code>.
+ </p>
+ </li>
</ol>
<p>
- This operation starts an <code>adb</code> shell, then runs <code>am instrument</code> in it
+ This operation starts an <code>adb</code> shell, then runs <code>am instrument</code>
with the specified parameters. This particular form of the command will run all of the tests
- in your test application. You can control this behavior with flags that you pass to
+ in your test package. You can control this behavior with flags that you pass to
<code>am instrument</code>. These flags are described in the next section.
</p>
-<h2 id="AMSyntax">Using the Instrument Command</h2>
+<h2 id="AMSyntax">Using the am instrument Command</h2>
<p>
- The general syntax of the <code>am instrument</code> command is:
+ The general syntax of the <code>am instrument</code> command is:
</p>
<pre>
am instrument [flags] &lt;test_package&gt;/&lt;runner_class&gt;
@@ -391,11 +395,11 @@ $ adb shell am instrument -w &lt;test_package_name&gt;/&lt;runner_class&gt;
<code>&lt;test_package&gt;</code>
</td>
<td>
- The Android package name of the test application.
+ The Android package name of the test package.
</td>
<td>
The value of the <code>package</code> attribute of the <code>manifest</code>
- element in the test application's manifest file.
+ element in the test package's manifest file.
</td>
</tr>
<tr>
@@ -411,7 +415,7 @@ $ adb shell am instrument -w &lt;test_package_name&gt;/&lt;runner_class&gt;
</tr>
</table>
<p>
-The flags for <code>am instrument</code> are described in the following table:
+ The flags for <code>am instrument</code> are described in the following table:
</p>
<table>
<tr>
@@ -461,20 +465,21 @@ The flags for <code>am instrument</code> are described in the following table:
&lt;test_options&gt;
</td>
<td>
- Provides testing options , in the form of key-value pairs. The
+ Provides testing options as key-value pairs. The
<code>am instrument</code> tool passes these to the specified instrumentation class
via its <code>onCreate()</code> method. You can specify multiple occurrences of
- <code>-e &lt;test_options</code>. The keys and values are described in the next table.
+ <code>-e &lt;test_options&gt;</code>. The keys and values are described in the
+ section <a href="#AMOptionsSyntax">am instrument options</a>.
<p>
- The only instrumentation class that understands these key-value pairs is
- <code>InstrumentationTestRunner</code> (or a subclass). Using them with
+ The only instrumentation class that uses these key-value pairs is
+ {@link android.test.InstrumentationTestRunner} (or a subclass). Using them with
any other class has no effect.
</p>
</td>
</tr>
</table>
-<h3 id="AMOptionsSyntax">Instrument options</h3>
+<h3 id="AMOptionsSyntax">am instrument options</h3>
<p>
The <code>am instrument</code> tool passes testing options to
<code>InstrumentationTestRunner</code> or a subclass in the form of key-value pairs,
@@ -484,123 +489,127 @@ The flags for <code>am instrument</code> are described in the following table:
-e &lt;key&gt; &lt;value&gt;
</pre>
<p>
- Where applicable, a &lt;key&gt; may have multiple values separated by a comma (,).
+ Some keys accept multiple values. You specify multiple values in a comma-separated list.
For example, this invocation of <code>InstrumentationTestRunner</code> provides multiple
values for the <code>package</code> key:
+</p>
<pre>
-$ adb shell am instrument -w -e package com.android.test.package1,com.android.test.package2 com.android.test/android.test.InstrumentationTestRunner
+$ adb shell am instrument -w -e package com.android.test.package1,com.android.test.package2 \
+&gt; com.android.test/android.test.InstrumentationTestRunner
</pre>
<p>
The following table describes the key-value pairs and their result. Please review the
<strong>Usage Notes</strong> following the table.
</p>
<table>
-<tr>
- <th>Key</th>
- <th>Value</th>
- <th>Description</th>
-</tr>
-<tr>
- <td>
- <code>package</code>
- </td>
- <td>
- &lt;Java_package_name&gt;
- </td>
- <td>
- The fully-qualified <em>Java</em> package name for one of the packages in the test
- application. Any test case class that uses this package name is executed. Notice that this
- is not an <em>Android</em> package name; a test application has a single Android package
- name but may have several Java packages within it.
- </td>
-</tr>
-<tr>
- <td rowspan="2"><code>class</code></td>
- <td>&lt;class_name&gt;</td>
- <td>
- The fully-qualified Java class name for one of the test case classes. Only this test case
- class is executed.
- </td>
-</tr>
-<tr>
- <td>&lt;class_name&gt;<strong>#</strong>method name</td>
- <td>
- A fully-qualified test case class name, and one of its methods. Only this method is
- executed. Note the hash mark (#) between the class name and the method name.
- </td>
-</tr>
-<tr>
- <td><code>func</code></td>
- <td><code>true</code></td>
- <td>
- Runs all test classes that extend {@link android.test.InstrumentationTestCase}.
- </td>
-</tr>
-<tr>
- <td><code>unit</code></td>
- <td><code>true</code></td>
- <td>
- Runs all test classes that do <em>not</em> extend either
- {@link android.test.InstrumentationTestCase} or {@link android.test.PerformanceTestCase}.
- </td>
-</tr>
-<tr>
- <td><code>size</code></td>
- <td>[<code>small</code> | <code>medium</code> | <code>large</code>]
- </td>
- <td>
- Runs a test method annotated by size. The annotations are <code>@SmallTest</code>,
- <code>@MediumTest</code>, and <code>@LargeTest</code>.
- </td>
-</tr>
-<tr>
- <td><code>perf</code></td>
- <td><code>true</code></td>
- <td>
- Runs all test classes that implement {@link android.test.PerformanceTestCase}.
- When you use this option, also specify the <code>-r</code> flag for
- <code>am instrument</code>, so that the output is kept in raw format and not
- re-formatted as test results.
- </td>
-</tr>
-<tr>
- <td><code>debug</code></td>
- <td><code>true</code></td>
- <td>
- Runs tests in debug mode.
- </td>
-</tr>
-<tr>
- <td><code>log</code></td>
- <td><code>true</code></td>
- <td>
- Loads and logs all specified tests, but does not run them. The test
- information appears in <code>STDOUT</code>. Use this to verify combinations of other filters
- and test specifications.
- </td>
-</tr>
-<tr>
- <td><code>emma</code></td>
- <td><code>true</code></td>
- <td>
- Runs an EMMA code coverage analysis and writes the output to <code>/data//coverage.ec</code>
- on the device. To override the file location, use the <code>coverageFile</code> key that
- is described in the following entry.
- <p class="note">
- <strong>Note:</strong> This option requires an EMMA-instrumented build of the test
- application, which you can generate with the <code>coverage</code> target.
- </p>
- </td>
-</tr>
-<tr>
- <td><code>coverageFile</code></td>
- <td><code>&lt;filename&gt;</code></td>
- <td>
- Overrides the default location of the EMMA coverage file on the device. Specify this
- value as a path and filename in UNIX format. The default filename is described in the
- entry for the <code>emma</code> key.
- </td>
-</tr>
+ <tr>
+ <th>Key</th>
+ <th>Value</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>
+ <code>package</code>
+ </td>
+ <td>
+ &lt;Java_package_name&gt;
+ </td>
+ <td>
+ The fully-qualified <em>Java</em> package name for one of the packages in the test
+ application. Any test case class that uses this package name is executed. Notice that
+ this is not an <em>Android</em> package name; a test package has a single
+ Android package name but may have several Java packages within it.
+ </td>
+ </tr>
+ <tr>
+ <td rowspan="2"><code>class</code></td>
+ <td>&lt;class_name&gt;</td>
+ <td>
+ The fully-qualified Java class name for one of the test case classes. Only this test
+ case class is executed.
+ </td>
+ </tr>
+ <tr>
+ <td>&lt;class_name&gt;<strong>#</strong>method name</td>
+ <td>
+ A fully-qualified test case class name, and one of its methods. Only this method is
+ executed. Note the hash mark (#) between the class name and the method name.
+ </td>
+ </tr>
+ <tr>
+ <td><code>func</code></td>
+ <td><code>true</code></td>
+ <td>
+ Runs all test classes that extend {@link android.test.InstrumentationTestCase}.
+ </td>
+ </tr>
+ <tr>
+ <td><code>unit</code></td>
+ <td><code>true</code></td>
+ <td>
+ Runs all test classes that do <em>not</em> extend either
+ {@link android.test.InstrumentationTestCase} or
+ {@link android.test.PerformanceTestCase}.
+ </td>
+ </tr>
+ <tr>
+ <td><code>size</code></td>
+ <td>
+ [<code>small</code> | <code>medium</code> | <code>large</code>]
+ </td>
+ <td>
+ Runs a test method annotated by size. The annotations are <code>@SmallTest</code>,
+ <code>@MediumTest</code>, and <code>@LargeTest</code>.
+ </td>
+ </tr>
+ <tr>
+ <td><code>perf</code></td>
+ <td><code>true</code></td>
+ <td>
+ Runs all test classes that implement {@link android.test.PerformanceTestCase}.
+ When you use this option, also specify the <code>-r</code> flag for
+ <code>am instrument</code>, so that the output is kept in raw format and not
+ re-formatted as test results.
+ </td>
+ </tr>
+ <tr>
+ <td><code>debug</code></td>
+ <td><code>true</code></td>
+ <td>
+ Runs tests in debug mode.
+ </td>
+ </tr>
+ <tr>
+ <td><code>log</code></td>
+ <td><code>true</code></td>
+ <td>
+ Loads and logs all specified tests, but does not run them. The test
+ information appears in <code>STDOUT</code>. Use this to verify combinations of other
+ filters and test specifications.
+ </td>
+ </tr>
+ <tr>
+ <td><code>emma</code></td>
+ <td><code>true</code></td>
+ <td>
+ Runs an EMMA code coverage analysis and writes the output to
+ <code>/data//coverage.ec</code> on the device. To override the file location, use the
+ <code>coverageFile</code> key that is described in the following entry.
+ <p class="note">
+ <strong>Note:</strong> This option requires an EMMA-instrumented build of the test
+ application, which you can generate with the <code>coverage</code> target.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>coverageFile</code></td>
+ <td><code>&lt;filename&gt;</code></td>
+ <td>
+ Overrides the default location of the EMMA coverage file on the device. Specify this
+ value as a path and filename in UNIX format. The default filename is described in the
+ entry for the <code>emma</code> key.
+ </td>
+ </tr>
</table>
<strong><code>-e</code> Flag Usage Notes</strong>
<ul>
@@ -618,13 +627,13 @@ $ adb shell am instrument -w -e package com.android.test.package1,com.android.te
The <code>func</code> key and <code>unit</code> key are mutually exclusive.
</li>
</ul>
-<h3 id="RunTestExamples">Instrument examples</h3>
+<h3 id="RunTestExamples">Usage examples</h3>
<p>
-Here are some examples of using <code>am instrument</code> to run tests. They are based on
-the following structure:</p>
+The following sections provide examples of using <code>am instrument</code> to run tests.
+They are based on the following structure:</p>
<ul>
<li>
- The test application has the Android package name <code>com.android.demo.app.tests</code>
+ The test package has the Android package name <code>com.android.demo.app.tests</code>
</li>
<li>
There are three test classes:
@@ -647,35 +656,35 @@ the following structure:</p>
The test runner is {@link android.test.InstrumentationTestRunner}.
</li>
</ul>
-<h4>Running the Entire Test Application</h4>
+<h4>Running the entire test package</h4>
<p>
- To run all of the test classes in the test application, enter:
+ To run all of the test classes in the test package, enter:
</p>
<pre>
$ adb shell am instrument -w com.android.demo.app.tests/android.test.InstrumentationTestRunner
</pre>
-<h4>Running All Tests in a Test Case Class</h4>
+<h4>Running all tests in a test case class</h4>
<p>
To run all of the tests in the class <code>UnitTests</code>, enter:
</p>
<pre>
$ adb shell am instrument -w \
--e class com.android.demo.app.tests.UnitTests \
-com.android.demo.app.tests/android.test.InstrumentationTestRunner
+&gt; -e class com.android.demo.app.tests.UnitTests \
+&gt; com.android.demo.app.tests/android.test.InstrumentationTestRunner
</pre>
<p>
<code>am instrument</code> gets the value of the <code>-e</code> flag, detects the
<code>class</code> keyword, and runs all the methods in the <code>UnitTests</code> class.
</p>
-<h4>Selecting a Subset of Tests</h4>
+<h4>Selecting a subset of tests</h4>
<p>
- To run all of the tests in <code>UnitTests</code>, and the <code>testCamera</code> method in
- <code>FunctionTests</code>, enter:
+ To run all of the tests in <code>UnitTests</code>, and the <code>testCamera</code> method in
+ <code>FunctionTests</code>, enter:
</p>
<pre>
$ adb shell am instrument -w \
--e class com.android.demo.app.tests.UnitTests,com.android.demo.app.tests.FunctionTests#testCamera \
-com.android.demo.app.tests/android.test.InstrumentationTestRunner
+&gt; -e class com.android.demo.app.tests.UnitTests,com.android.demo.app.tests.FunctionTests#testCamera \
+&gt; com.android.demo.app.tests/android.test.InstrumentationTestRunner
</pre>
<p>
You can find more examples of the command in the documentation for
diff --git a/docs/html/guide/developing/tools/MonkeyDevice.jd b/docs/html/guide/developing/tools/MonkeyDevice.jd
new file mode 100644
index 0000000..34bbba9
--- /dev/null
+++ b/docs/html/guide/developing/tools/MonkeyDevice.jd
@@ -0,0 +1,1353 @@
+page.title=MonkeyDevice
+@jd:body
+<style>
+ h4.jd-details-title {background-color: #DEE8F1;}
+</style>
+<p>
+ A monkeyrunner class that represents a device or emulator accessible by the workstation running
+<code><a href="{@docRoot}guide/developing/tools/monkeyrunner_concepts.html">monkeyrunner</a></code>.
+</p>
+<p>
+ This class is used to control an Android device or emulator. The methods send UI events,
+ retrieve information, install and remove applications, and run applications.
+</p>
+<p>
+ You normally do not have to create an instance of <code>MonkeyDevice</code>. Instead, you
+ use
+<code><a href="{@docRoot}guide/developing/tools/MonkeyRunner.html#waitForConnection">
+MonkeyRunner.waitForConnection()</a></code> to create a new object from a connection to a device or
+emulator. For example, instead of
+using:</p>
+<pre>
+newdevice = MonkeyDevice()
+</pre>
+<p>
+ you would use:
+</p>
+<pre>
+newdevice = MonkeyRunner.waitForConnection()
+</pre>
+<h2>Summary</h2>
+ <table id="constants" class="jd-sumtable" style="background-color: white;">
+ <tr>
+ <th colspan="12" style="background-color: #E2E2E2">Constants</th>
+ </tr>
+ <tr class="api" style="background-color: white;">
+ <td class="jd-typecol"><em>string</em></td>
+ <td class="jd-linkcol"><a href="#ACTION_DOWN">DOWN</a></td>
+ <td class="jd-descrcol" width="100%">
+ Use this with the <code>type</code> argument of
+ <code><a href="#press">press()</a></code> or <code><a href="#touch">touch()</a>
+ </code>
+ to send a DOWN event.
+ </td>
+ </tr>
+ <tr class="api" style="background-color: white;">
+ <td class="jd-typecol"><em>string</em></td>
+ <td class="jd-linkcol"><a href="#ACTION_UP">UP</a></td>
+ <td class="jd-descrcol" width="100%">
+ Use this with the <code>type</code> argument of
+ <code><a href="#press">press()</a></code> or <code><a href="#touch">touch()</a>
+ </code>
+ to send an UP event.
+ </td>
+ </tr>
+ <tr class="api" style="background-color: white;">
+ <td class="jd-typecol"><em>string</em></td>
+ <td class="jd-linkcol"><a href="#ACTION_DOWN_AND_UP">DOWN_AND_UP</a></td>
+ <td class="jd-descrcol" width="100%">
+ Use this with the <code>type</code> argument of
+ <code><a href="#press">press()</a></code> or <code><a href="#touch">touch()</a>
+ </code>
+ to send a DOWN event immediately followed by an UP event.
+ </td>
+ </tr>
+ </table>
+<table id="pubmethods" class="jd-sumtable">
+ <tr>
+ <th colspan="12" style="background-color: #E2E2E2">Methods</th>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#broadcastIntent">broadcastIntent</a>
+ </span>
+ (<em>string</em> uri,
+ <em>string</em> action,
+ <em>string</em> data,
+ <em>string</em> mimetype,
+ <em>iterable</em> categories
+ <em>dictionary</em> extras,
+ <em>component</em> component,
+ <em>iterable</em> flags)
+ </nobr>
+ <div class="jd-descrdiv">
+ Broadcasts an Intent to this device, as if the Intent were coming from an
+ application.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#drag">drag</a>
+ </span>
+ (<em>tuple</em> start,
+ <em>tuple</em> end,
+ <em>float</em> duration,
+ <em>integer</em> steps)
+ </nobr>
+ <div class="jd-descrdiv">
+ Simulates a drag gesture (touch, hold, and move) on this device's screen.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>object</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#getProperty">getProperty</a>
+ </span>
+ (<em>string</em> key)
+ </nobr>
+ <div class="jd-descrdiv">
+ Given the name of a system environment variable, returns its value for this device.
+ The available variable names are listed in the <a href="#getProperty">
+ detailed description</a> of this method.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>object</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#getSystemProperty">getSystemProperty</a>
+ </span>
+ (<em>string</em> key)
+ </nobr>
+ <div class="jd-descrdiv">
+. The API equivalent of <code>adb shell getprop &lt;key&gt;. This is provided for use
+ by platform developers.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#installPackage">installPackage</a>
+ </span>
+ (<em>string</em> path)
+ </nobr>
+ <div class="jd-descrdiv">
+ Installs the Android application or test package contained in packageFile onto this
+ device. If the application or test package is already installed, it is replaced.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>dictionary</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#instrument">instrument</a>
+ </span>
+ (<em>string</em> className,
+ <em>dictionary</em> args)
+ </nobr>
+ <div class="jd-descrdiv">
+ Runs the specified component under Android instrumentation, and returns the results
+ in a dictionary whose exact format is dictated by the component being run. The
+ component must already be present on this device.
+ </div>
+ </td>
+ </tr>
+ <tr class="api">
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#press">press</a>
+ </span>
+ (<em>string</em> name,
+ <em>dictionary</em> type)
+ </nobr>
+ <div class="jd-descrdiv">
+ Sends the key event specified by type to the key specified by
+ keycode.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#reboot">reboot</a>
+ </span>
+ (<em>string</em> into)
+ </nobr>
+ <div class="jd-descrdiv">
+ Reboots this device into the bootloader specified by bootloadType.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#removePackage">removePackage</a>
+ </span>
+ (<em>string</em> package)
+ </nobr>
+ <div class="jd-descrdiv">
+ Deletes the specified package from this device, including its data and cache.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>object</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#shell">shell</a>
+ </span>
+ (<em>string</em> cmd)
+ </nobr>
+ <div class="jd-descrdiv">
+ Executes an <code>adb</code> shell command and returns the result, if any.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#startActivity">startActivity</a>
+ </span>
+ (<em>string</em> uri,
+ <em>string</em> action,
+ <em>string</em> data,
+ <em>string</em> mimetype,
+ <em>iterable</em> categories
+ <em>dictionary</em> extras,
+ <em>component</em> component,
+ <em>flags</em>)
+ </nobr>
+ <div class="jd-descrdiv">
+ Starts an Activity on this device by sending an Intent constructed from the
+ supplied arguments.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <code>
+ <a href="{@docRoot}guide/developing/tools/MonkeyImage.html">
+ MonkeyImage
+ </a>
+ </code>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#takeSnapshot">takeSnapshot</a>()
+ </span>
+ </nobr>
+ <div class="jd-descrdiv">
+ Captures the entire screen buffer of this device, yielding a
+ <code>
+ <a href="{@docRoot}guide/developing/tools/MonkeyImage.html">
+ MonkeyImage
+ </a>
+ </code> object containing a screen capture of the current display.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#touch">touch</a>
+ </span>
+ (<em>integer</em> x,
+ <em>integer</em> y,
+ <em>integer</em> type)
+ </nobr>
+ <div class="jd-descrdiv">
+ Sends a touch event specified by type to the screen location specified
+ by x and y.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#touch">type</a>
+ </span>
+ (<em>string</em> message)
+ </nobr>
+ <div class="jd-descrdiv">
+ Sends the characters contained in message to this device, as if they
+ had been typed on the device's keyboard. This is equivalent to calling
+ <code><a href="#press">press()</a></code> for each keycode in <code>message</code>
+ using the key event type <code><a href="#ACTION_DOWN_AND_UP"></a>DOWN_AND_UP</code>.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#touch">wake</a>
+ </span>
+ ()
+ </nobr>
+ <div class="jd-descrdiv">
+ Wakes the screen of this device.
+ </div>
+ </td>
+ </tr>
+</table>
+<!-- ========= ENUM CONSTANTS DETAIL ======== -->
+<h2>Constants</h2>
+<A NAME="ACTION_DOWN"></a>
+<div class="jd-details api">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>string</em>
+ </span>
+ DOWN
+ </h4>
+ <div class="jd-details-descr">
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ <code><a href="#press">press()</a></code> or
+ <code><a href="#press">touch()</a></code> value.
+ Specifies that a DOWN event type should be sent to the device, corresponding to
+ pressing down on a key or touching the screen.
+ </p>
+ </div>
+ </div>
+</div>
+<A NAME="ACTION_UP"></A>
+<div class="jd-details api">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>string</em>
+ </span>
+ UP
+ </h4>
+ <div class="jd-details-descr">
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ <code><a href="#press">press()</a></code> or
+ <code><a href="#press">touch()</a></code> value.
+ Specifies that an UP event type should be sent to the device, corresponding to
+ releasing a key or lifting up from the screen.
+ </p>
+ </div>
+ </div>
+</div>
+<A NAME="ACTION_DOWN_AND_UP"></A>
+
+<div class="jd-details api">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>string</em>
+ </span>
+ DOWN_AND_UP
+ </h4>
+ <div class="jd-details-descr">
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ <code><a href="#press">press()</a></code>,
+ <code><a href="#press">touch()</a></code> or
+ <code><a href="#type">type()</a></code> value.
+ Specifies that a DOWN event type followed by an UP event type should be sent to the
+ device, corresponding to typing a key or clicking the screen.
+ </p>
+ </div>
+ </div>
+</div>
+<!-- ========= METHOD DETAIL ======== -->
+<!-- Public methods -->
+<h2>Public Methods</h2>
+<A NAME="broadcastIntent"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">broadcastIntent</span>
+ <span class="normal">
+ (
+ <em>string</em> uri,
+ <em>string</em> action,
+ <em>string</em> data,
+ <em>string</em> mimetype,
+ <em>iterable</em> categories
+ <em>dictionary</em> extras,
+ <em>component</em> component,
+ <em>iterable</em> flags)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Broadcasts an Intent to this device, as if the Intent were coming from an
+ application. See {@link android.content.Intent Intent} for more information about the
+ arguments.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>uri</th>
+ <td>
+ The URI for the Intent.
+ (see {@link android.content.Intent#setData(android.net.Uri) Intent.setData()}).
+ </td>
+ </tr>
+ <tr>
+ <th>action</th>
+ <td>
+ The action for this Intent
+ (see {@link android.content.Intent#setAction(java.lang.String) Intent.setAction()}).
+ </td>
+ </tr>
+ <tr>
+ <th>data</th>
+ <td>
+ The data URI for this Intent
+ (see {@link android.content.Intent#setData(android.net.Uri) Intent.setData()}).
+ </td>
+ </tr>
+ <tr>
+ <th>mimetype</th>
+ <td>
+ The MIME type for the Intent
+ (see {@link android.content.Intent#setType(java.lang.String) Intent.setType()}).
+ </td>
+ </tr>
+ <tr>
+ <th>categories</th>
+ <td>
+ An iterable data structure containing strings that define categories for this
+ Intent
+ (see
+ {@link android.content.Intent#addCategory(java.lang.String) Intent.addCategory()}).
+ </td>
+ </tr>
+ <tr>
+ <th>extras</th>
+ <td>
+ A dictionary of extra data for this Intent
+ (see {@link android.content.Intent#putExtra(java.lang.String,java.lang.String)
+ Intent.putExtra()}
+ for an example).
+ <p>
+ The key for each dictionary item should be a <em>string</em>. The item's value
+ can be any simple or structured data type.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <th>component</th>
+ <td>
+ The component for this Intent (see {@link android.content.ComponentName}).
+ Using this argument will direct the Intent to a specific class within a specific
+ Android package.
+ </td>
+ </tr>
+ <tr>
+ <th>flags</th>
+ <td>
+ An iterable data structure containing flags that control how the Intent is handled
+ (see {@link android.content.Intent#setFlags(int) Intent.setFlags()}).
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="drag"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">drag</span>
+ <span class="normal">
+ (
+ <em>tuple</em> start,
+ <em>tuple</em> end,
+ <em>float</em> duration,
+ <em>integer</em> steps)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Simulates a drag gesture (touch, hold, and move) on this device's screen.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>start</th>
+ <td>
+ The starting point of the drag gesture, in the form of a <em>tuple</em>
+ (x,y) where x and y are <em>integers</em>.
+ </td>
+ </tr>
+ <tr>
+ <th>end</th>
+ <td>
+ The end point of the drag gesture, in the form of a <em>tuple</em> (x,y)
+ where x and y are <em>integers</em>.
+ </td>
+ </tr>
+ <tr>
+ <th>duration</th>
+ <td>The duration of the drag gesture in seconds. The default is 1.0 seconds.</td>
+ </tr>
+ <tr>
+ <th>steps</th>
+ <td>The number of steps to take when interpolating points. The default is 10.</td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="getProperty"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>object</em>
+ </span>
+ <span class="sympad">getProperty</span>
+ <span class="normal">
+ (<em>string</em> key)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Given the name of a system environment variable, returns its value for this device.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>key</th>
+ <td>
+ The name of the system environment variable. The available variable names are listed in
+ <a href="#table1">Table 1. Property variable names</a> at the end of this topic.
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ The value of the variable. The data format varies according to the variable requested.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<A NAME="getSystemProperty"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>object</em>
+ </span>
+ <span class="sympad">getSystemProperty</span>
+ <span class="normal">
+ (<em>string</em> key)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Synonym for <code><a href="#getProperty">getProperty()</a></code>.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>key</th>
+ <td>
+ The name of the system environment variable. The available variable names are listed in
+ <a href="#table1">Table 1. Property Variable Names</a>.
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ The value of the variable. The data format varies according to the variable requested.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<A NAME="installPackage"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">installPackage</span>
+ <span class="normal">
+ (<em>string</em> path)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Installs the Android application or test package contained in packageFile
+ onto this device. If the application or test package is already installed, it is
+ replaced.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>path</th>
+ <td>
+ The fully-qualified path and filename of the <code>.apk</code> file to install.
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="instrument"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>dictionary</em>
+ </span>
+ <span class="sympad">instrument</span>
+ <span class="normal">
+ (
+ <em>string</em> className,
+ <em>dictionary</em> args)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Runs the specified component with Android instrumentation, and returns the results
+ in a dictionary whose exact format is dictated by the component being run. The
+ component must already be present on this device.
+ </p>
+ <p>
+ Use this method to start a test case that uses one of Android's test case classes.
+ See <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing
+ Fundamentals</a> to learn more about unit testing with the Android testing
+ framework.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>className</th>
+ <td>
+ The name of an Android component that is already installed on this device, in the
+ standard form packagename/classname, where packagename is the
+ Android package name of a <code>.apk</code> file on this device, and
+ classname is the class name of an Android component (Activity,
+ ContentProvider, Service, or BroadcastReceiver) in that file. Both
+ packagename and classname must be fully qualified. See
+ {@link android.content.ComponentName} for more details.
+ </td>
+ </tr>
+ <tr>
+ <th>args</th>
+ <td>
+ A dictionary containing flags and their values. These are passed to the component as it
+ is started. If the flag does not take a value, set its dictionary value to an empty
+ string.
+ </td>
+ </tr>
+ </table>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ <p>
+ A dictionary containing the component's output. The contents of the dictionary
+ are defined by the component itself.
+ </p>
+ <p>
+ If you use {@link android.test.InstrumentationTestRunner} as the class name in
+ the componentName argument, then the result dictionary contains
+ the single key "stream". The value of "stream" is a <em>string</em> containing
+ the test output, as if <code>InstrumentationTestRunner</code> was run from the
+ command line. The format of this output is described in
+ <a href="{@docRoot}guide/developing/testing/testing_otheride.html">
+ Testing in Other IDEs</a>.
+ </p>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+</div>
+<A NAME="press"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">press</span>
+ <span class="normal">
+ (<em>string</em> name,
+ <em>integer</em> type)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Sends the key event specified by <code>type</code> to the key specified by
+ <code>keycode</code>.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>name</th>
+ <td>
+ The name of the keycode to send. See {@link android.view.KeyEvent} for a list of
+ keycode names. Use the keycode name, not its integer value.
+ </td>
+ </tr>
+ <tr>
+ <th>type</th>
+ <td>
+ The type of key event to send. The allowed values are <code><a href="#ACTION_DOWN">
+ DOWN</a></code>, <code><a href="#ACTION_UP">UP</a></code>, and
+ <code><a href="#ACTION_DOWN_AND_UP">DOWN_AND_UP</a></code>.
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="reboot"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">reboot</span>
+ <span class="normal">
+ (<em>string</em> bootloadType)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Reboots this device into the bootloader specified by <code>bootloadType</code>.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>into</th>
+ <td>
+ The type of bootloader to reboot into. The allowed values are
+ "bootloader", "recovery", or "None".
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="removePackage"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">removePackage</span>
+ <span class="normal">
+ (<em>string</em> package)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Deletes the specified package from this device, including its data and cache.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>package</th>
+ <td>
+ The Android package name of an <code>.apk</code> file on this device.
+ </td>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="shell"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>object</em>
+ </span>
+ <span class="sympad">shell</span>
+ <span class="normal">
+ (<em>string</em> cmd)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Executes an <code>adb</code> shell command and returns the result, if any.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>cmd</th>
+ <td>
+ The command to execute in the <code>adb</code> shell. The form of these commands is
+ described in the topic <a href="{@docRoot}guide/developing/tools/adb.html">Android
+ Debug Bridge</a>.
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ The results of the command, if any. The format of the results is determined by the
+ command.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<A NAME="startActivity"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">startActivity</span>
+ <span class="normal">
+ (
+ <em>string</em> uri,
+ <em>string</em> action,
+ <em>string</em> data,
+ <em>string</em> mimetype,
+ <em>iterable</em> categories
+ <em>dictionary</em> extras,
+ <em>component</em> component,
+ <em>iterable</em> flags)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Starts an Activity on this device by sending an Intent constructed from the
+ supplied arguments.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>uri</th>
+ <td>
+ The URI for the Intent.
+ (see {@link android.content.Intent#setData(android.net.Uri) Intent.setData()}).
+ </td>
+ </tr>
+ <tr>
+ <th>action</th>
+ <td>
+ The action for the Intent
+ (see {@link android.content.Intent#setAction(java.lang.String) Intent.setAction()}).
+ </td>
+ </tr>
+ <tr>
+ <th>data</th>
+ <td>
+ The data URI for the Intent
+ (see {@link android.content.Intent#setData(android.net.Uri) Intent.setData()}).
+ </td>
+ </tr>
+ <tr>
+ <th>mimetype</th>
+ <td>
+ The MIME type for the Intent
+ (see {@link android.content.Intent#setType(java.lang.String) Intent.setType()}).
+ </td>
+ </tr>
+ <tr>
+ <th>categories</th>
+ <td>
+ An iterable data structure containing strings that define categories for the
+ Intent
+ (see
+ {@link android.content.Intent#addCategory(java.lang.String) Intent.addCategory()}).
+ </td>
+ </tr>
+ <tr>
+ <th>extras</th>
+ <td>
+ A dictionary of extra data for the Intent
+ (see
+ {@link android.content.Intent#putExtra(java.lang.String,java.lang.String)
+ Intent.putExtra()}
+ for an example).
+ <p>
+ The key for each dictionary item should be a <em>string</em>. The item's value
+ can be any simple or structured data type.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <th>component</th>
+ <td>
+ The component for the Intent
+ (see {@link android.content.ComponentName}). Using this argument will direct the
+ Intent to a specific class within a specific Android package.
+ </td>
+ </tr>
+ <tr>
+ <th>flags</th>
+ <td>
+ An iterable data structure containing flags that control how the Intent is handled
+ (see {@link android.content.Intent#setFlags(int) Intent.setFlags()}).
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="takeSnapshot"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <code>
+ <a href="{@docRoot}guide/developing/tools/MonkeyImage.html">
+ MonkeyImage
+ </a>
+ </code>
+ </span>
+ <span class="sympad">takeSnapshot</span>
+ <span class="normal">
+ ()
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Captures the entire screen buffer of this device, yielding a
+ screen capture of the current display.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ A <a href="{@docRoot}guide/developing/tools/MonkeyImage.html">
+ MonkeyImage</a> object containing the image of the current display.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<A NAME="touch"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">touch</span>
+ <span class="normal">
+ (
+ <em>integer</em> x,
+ <em>integer</em> y,
+ <em>string</em> type)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Sends a touch event specified by type to the screen location specified
+ by x and y.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>x</th>
+ <td>
+ The horizontal position of the touch in actual device pixels, starting from the left of
+ the screen in its current orientation.
+ </td>
+ </tr>
+ <tr>
+ <th>y</th>
+ <td>
+ The vertical position of the touch in actual device pixels, starting from the top of
+ the screen in its current orientation.
+ </td>
+ </tr>
+ <tr>
+ <th>type</th>
+ <td>
+ The type of key event to send. The allowed values are <code><a href="#ACTION_DOWN">
+ DOWN</a></code>, <code><a href="#ACTION_UP">UP</a></code>, and
+ <code><a href="#ACTION_DOWN_AND_UP">DOWN_AND_UP</a></code>.
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="type"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">type</span>
+ <span class="normal">
+ (<em>string</em> message)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Sends the characters contained in message to this device, as if they
+ had been typed on the device's keyboard. This is equivalent to calling
+ <code><a href="#press">press()</a></code> for each keycode in <code>message</code>
+ using the key event type <code><a href="#ACTION_DOWN_AND_UP">DOWN_AND_UP</a></code>.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>message</th>
+ <td>
+ A string containing the characters to send.
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="wake"></A>
+<div class="jd-details api">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">wake</span>
+ <span class="normal">
+ ()
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Wakes the screen of this device.
+ </p>
+ </div>
+ </div>
+</div>
+<hr></hr>
+<h2>Appendix</h2>
+ <p class="table-caption" id="table1">
+ <strong>Table 1.</strong>Property variable names used with
+ <span class="sympad"><a href="#getProperty">getProperty()</a></span> and
+ <span class="sympad"><a href="#getSystemProperty">getSystemProperty()</a></span>.
+ </p>
+ <table>
+ <tr>
+ <th>
+ Property Group
+ </th>
+ <th>
+ Property
+ </th>
+ <th>
+ Description
+ </th>
+ <th>
+ Notes
+ </th>
+ </tr>
+ <tr>
+ <td rowspan="17"><code>build</code></td>
+ <td><code>board</code></td>
+ <td>Code name for the device's system board</td>
+ <td rowspan="17">
+ See {@link android.os.Build}
+ </td>
+ </tr>
+ <tr>
+ <td><code>brand</code></td>
+ <td>The carrier or provider for which the OS is customized.</td>
+ </tr>
+ <tr>
+ <td><code>device</code></td>
+ <td>The device design name.</td>
+ </tr>
+ <tr>
+ <td><code>fingerprint</code></td>
+ <td>A unique identifier for the currently-running build.</td>
+ </tr>
+ <tr>
+ <td><code>host</code></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><code>ID</code></td>
+ <td>A changelist number or label.</td>
+ </tr>
+ <tr>
+ <td><code>model</code></td>
+ <td>The end-user-visible name for the device.</td>
+ </tr>
+ <tr>
+ <td><code>product</code></td>
+ <td>The overall product name.</td>
+ </tr>
+ <tr>
+ <td><code>tags</code></td>
+ <td>Comma-separated tags that describe the build, such as "unsigned" and "debug".</td>
+ </tr>
+ <tr>
+ <td><code>type</code></td>
+ <td>The build type, such as "user" or "eng".</td>
+ </tr>
+ <tr>
+ <td><code>user</code></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><code>CPU_ABI</code></td>
+ <td>
+ The name of the native code instruction set, in the form CPU type plus
+ ABI convention.
+ </td>
+ </tr>
+ <tr>
+ <td><code>manufacturer</code></td>
+ <td>The product/hardware manufacturer.</td>
+ </tr>
+ <tr>
+ <td><code>version.incremental</code></td>
+ <td>
+ The internal code used by the source control system to represent this version
+ of the software.
+ </td>
+ </tr>
+ <tr>
+ <td><code>version.release</code></td>
+ <td>The user-visible name of this version of the software.</td>
+ </tr>
+ <tr>
+ <td><code>version.sdk</code></td>
+ <td>The user-visible SDK version associated with this version of the OS.</td>
+ </tr>
+ <tr>
+ <td><code>version.codename</code></td>
+ <td>
+ The current development codename, or "REL" if this version of the software has been
+ released.
+ </td>
+ </tr>
+ <tr>
+ <td rowspan="3"><code>display</code></td>
+ <td><code>width</code></td>
+ <td>The device's display width in pixels.</td>
+ <td rowspan="3">
+ See
+ {@link android.util.DisplayMetrics} for details.
+ </td>
+ </tr>
+ <tr>
+ <td><code>height</code></td>
+ <td>The device's display height in pixels.</td>
+ </tr>
+ <tr>
+ <td><code>density</code></td>
+ <td>
+ The logical density of the display. This is a factor that scales
+ DIP (Density-Independent Pixel) units to the device's resolution. DIP is adjusted so
+ that 1 DIP is equivalent to one pixel on a 160 pixel-per-inch display. For example,
+ on a 160-dpi screen, density = 1.0, while on a 120-dpi screen, density = .75.
+ <p>
+ The value does not exactly follow the real screen size, but is adjusted to
+ conform to large changes in the display DPI. See
+ {@link android.util.DisplayMetrics#density} for more details.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td rowspan="6"><code>am.current</code></td>
+ <td><code>package</code></td>
+ <td>The Android package name of the currently running package.</td>
+ <td rowspan="6">
+ The <code>am.current</code> keys return information about the currently-running
+ Activity.
+ </td>
+ </tr>
+ <tr>
+ <td><code>action</code></td>
+ <td>
+ The current activity's action. This has the same format as the <code>name</code>
+ attribute of the <code>action</code> element in a package manifest.
+ </td>
+ </tr>
+ <tr>
+ <td><code>comp.class</code></td>
+ <td>
+ The class name of the component that started the current Activity. See
+ <code><a href="#comppackage">comp.package</a></code> for more details.</td>
+ </tr>
+ <tr>
+ <td><a name="comppackage"><code>comp.package</code></a></td>
+ <td>
+ The package name of the component that started the current Activity. A component
+ is specified by a package name and the name of class that the package contains.
+ </td>
+ </tr>
+ <tr>
+ <td><code>data</code></td>
+ <td>The data (if any) contained in the Intent that started the current Activity.</td>
+ </tr>
+ <tr>
+ <td><code>categories</code></td>
+ <td>The categories specified by the Intent that started the current Activity.</td>
+ </tr>
+ <tr>
+ <td rowspan="3"><code>clock</code></td>
+ <td><code>realtime</code></td>
+ <td>
+ The number of milliseconds since the device rebooted, including deep-sleep
+ time.
+ </td>
+ <td rowspan="3">
+ See {@link android.os.SystemClock} for more information.
+ </td>
+ </tr>
+ <tr>
+ <td><code>uptime</code></td>
+ <td>
+ The number of milliseconds since the device rebooted, <em>not</em> including
+ deep-sleep time
+ </td>
+ </tr>
+ <tr>
+ <td><code>millis</code></td>
+ <td>current time since the UNIX epoch, in milliseconds.</td>
+ </tr>
+ </table>
diff --git a/docs/html/guide/developing/tools/MonkeyImage.jd b/docs/html/guide/developing/tools/MonkeyImage.jd
new file mode 100644
index 0000000..ae85cb5
--- /dev/null
+++ b/docs/html/guide/developing/tools/MonkeyImage.jd
@@ -0,0 +1,435 @@
+page.title=MonkeyImage
+@jd:body
+<style>
+ h4.jd-details-title {background-color: #DEE8F1;}
+</style>
+
+<p>
+ A monkeyrunner class to hold an image of the device or emulator's screen. The image is
+ copied from the screen buffer during a screenshot. This object's methods allow you to
+ convert the image into various storage formats, write the image to a file, copy parts of
+ the image, and compare this object to other <code>MonkeyImage</code> objects.
+</p>
+<p>
+ You do not need to create new instances of <code>MonkeyImage</code>. Instead, use
+<code><a href="{@docRoot}guide/developing/tools/MonkeyDevice.html#takeSnapshot">
+MonkeyDevice.takeSnapshot()</a></code> to create a new instance from a screenshot. For example, use:
+</p>
+<pre>
+newimage = MonkeyDevice.takeSnapshot()
+</pre>
+<h2>Summary</h2>
+<table id="pubmethods" class="jd-sumtable">
+ <tr>
+ <th colspan="12" style="background-color: #E2E2E2">Methods</th>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>string</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#convertToBytes">convertToBytes</a>
+ </span>
+ (<em>string</em> format)
+ </nobr>
+ <div class="jd-descrdiv">
+ Converts the current image to a particular format and returns it as a
+ <em>string</em> that you can then access as an <em>iterable</em> of binary bytes.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>tuple</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#getRawPixel">getRawPixel</a>
+ </span>
+ (<em>integer</em> x,
+ <em>integer</em> y)
+ </nobr>
+ <div class="jd-descrdiv">
+ Returns the single pixel at the image location (x,y), as an
+ a <em>tuple</em> of <em>integer</em>, in the form (a,r,g,b).
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>integer</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#getRawPixelInt">getRawPixelInt</a>
+ </span>
+ (<em>integer</em> x,
+ <em>integer</em> y)
+ </nobr>
+ <div class="jd-descrdiv">
+ Returns the single pixel at the image location (x,y), as
+ a 32-bit <em>integer</em>.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <code>
+ <a href="{@docRoot}guide/developing/tools/MonkeyImage.html">MonkeyImage</a>
+ </code>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#getSubImage">getSubImage</a>
+ </span>
+ (<em>tuple</em> rect)
+ </nobr>
+ <div class="jd-descrdiv">
+ Creates a new <code>MonkeyImage</code> object from a rectangular selection of the
+ current image.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>boolean</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#sameAs">sameAs</a>
+ </span>
+ (<code><a href="{@docRoot}guide/developing/tools/MonkeyImage.html">MonkeyImage</a></code>
+ other,
+ <em>float</em> percent)
+ </nobr>
+ <div class="jd-descrdiv">
+ Compares this <code>MonkeyImage</code> object to another and returns the result of
+ the comparison. The <code>percent</code> argument specifies the percentage
+ difference that is allowed for the two images to be "equal".
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>void</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#writeToFile">writeToFile</a>
+ </span>
+ (<em>string</em> path,
+ <em>string</em> format)
+ </nobr>
+ <div class="jd-descrdiv">
+ Writes the current image to the file specified by <code>filename</code>, in the
+ format specified by <code>format</code>.
+ </div>
+ </td>
+ </tr>
+</table>
+<!-- ========= METHOD DETAIL ======== -->
+<!-- Public methods -->
+<h2>Public Methods</h2>
+<A NAME="convertToBytes"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>string</em>
+ </span>
+ <span class="sympad">convertToBytes</span>
+ <span class="normal">
+ (
+ <em>string</em> format)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Converts the current image to a particular format and returns it as a <em>string</em>
+ that you can then access as an <em>iterable</em> of binary bytes.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>format</th>
+ <td>
+ The desired output format. All of the common raster output formats are supported.
+ The default value is "png" (Portable Network Graphics).
+ </td>
+ </tr>
+ </table>
+ </div>
+</div>
+</div>
+<A NAME="getRawPixel"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>tuple</em>
+ </span>
+ <span class="sympad">getRawPixel</span>
+ <span class="normal">
+ (<em>integer</em> x,
+ <em>integer</em> y)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Returns the single pixel at the image location (x,y), as an
+ a <em>tuple</em> of <em>integer</em>, in the form (a,r,g,b).
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>x</th>
+ <td>
+ The horizontal position of the pixel, starting with 0 at the left of the screen in the
+ orientation it had when the screenshot was taken.
+ </td>
+ </tr>
+ <tr>
+ <th>y</th>
+ <td>
+ The vertical position of the pixel, starting with 0 at the top of the screen in the
+ orientation it had when the screenshot was taken.
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ A tuple of integers representing the pixel, in the form (a,r,g,b) where
+ a is the alpha channel value, and r, g, and b are the red, green, and blue values,
+ respectively.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<A NAME="getRawPixelInt"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>tuple</em>
+ </span>
+ <span class="sympad">getRawPixelInt</span>
+ <span class="normal">
+ (<em>integer</em> x,
+ <em>integer</em> y)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Returns the single pixel at the image location (x,y), as an
+ an <em>integer</em>. Use this method to economize on memory.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>x</th>
+ <td>
+ The horizontal position of the pixel, starting with 0 at the left of the screen in the
+ orientation it had when the screenshot was taken.
+ </td>
+ </tr>
+ <tr>
+ <th>y</th>
+ <td>
+ The vertical position of the pixel, starting with 0 at the top of the screen in the
+ orientation it had when the screenshot was taken.
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ The a,r,g, and b values of the pixel as 8-bit values combined into a 32-bit
+ integer, with a as the leftmost 8 bits, r the next rightmost, and so forth.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<A NAME="getSubImage"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <code>
+ <a href="{@docRoot}guide/developing/tools/MonkeyImage.html">MonkeyImage</a>
+ </code>
+ </span>
+ <span class="sympad">getSubImage</span>
+ <span class="normal">
+ (<em>tuple</em> rect)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Creates a new <code>MonkeyImage</code> object from a rectangular selection of the
+ current image.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>rect</th>
+ <td>
+ A tuple (x, y, w, h) specifying the selection. x and y specify the 0-based pixel
+ position of the upper left-hand corner of the selection. w specifies the width of the
+ region, and h specifies its height, both in units of pixels.
+ <p>
+ The image's orientation is the same as the screen orientation at the time the
+ screenshot was made.
+ </p>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ A new <code>MonkeyImage</code> object containing the selection.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<A NAME="sameAs"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>boolean</em>
+ </span>
+ <span class="sympad">sameAs</span>
+ <span class="normal">
+ (
+ <code>
+ <a href="{@docRoot}guide/developing/tools/MonkeyImage.html">MonkeyImage</a>
+ </code> otherImage,
+ <em>float</em> percent
+ )
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Compares this <code>MonkeyImage</code> object to another and returns the result of
+ the comparison. The <code>percent</code> argument specifies the percentage
+ difference that is allowed for the two images to be "equal".
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>other</th>
+ <td>
+ Another <code>MonkeyImage</code> object to compare to this one.
+ </td>
+ </tr>
+ <tr>
+ <th>
+ percent
+ </th>
+ <td>
+ A float in the range 0.0 to 1.0, inclusive, indicating
+ the percentage of pixels that need to be the same for the method to return
+ <code>true</code>. The default is 1.0, indicating that all the pixels
+ must match.
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ Boolean <code>true</code> if the images match, or boolean <code>false</code> otherwise.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<A NAME="writeToFile"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">writeToFile</span>
+ <span class="normal">
+ (<em>string</em> filename,
+ <em>string</em> format)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Writes the current image to the file specified by <code>filename</code>, in the
+ format specified by <code>format</code>.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>path</th>
+ <td>
+ The fully-qualified filename and extension of the output file.
+ </td>
+ </tr>
+ <tr>
+ <th>
+ format
+ </th>
+ <td>
+ The output format to use for the file. If no format is provided, then the
+ method tries to guess the format from the filename's extension. If no
+ extension is provided and no format is specified, then the default format of
+ "png" (Portable Network Graphics) is used.
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
diff --git a/docs/html/guide/developing/tools/MonkeyRunner.jd b/docs/html/guide/developing/tools/MonkeyRunner.jd
new file mode 100644
index 0000000..871e06d
--- /dev/null
+++ b/docs/html/guide/developing/tools/MonkeyRunner.jd
@@ -0,0 +1,445 @@
+page.title=MonkeyRunner
+@jd:body
+<style>
+ h4.jd-details-title {background-color: #DEE8F1;}
+</style>
+<p>
+ A monkeyrunner class that contains static utility methods.
+</p>
+<h2>Summary</h2>
+<table id="pubmethods" class="jd-sumtable">
+ <tr>
+ <th colspan="12" style="background-color: #E2E2E2">Methods</th>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#alert">alert</a>
+ </span>
+ (<em>string</em> message,
+ <em>string</em> title,
+ <em>string</em> okTitle)
+ </nobr>
+ <div class="jd-descrdiv">
+ Displays an alert dialog to the process running the current
+ program.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>integer</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#choice">choice</a>
+ </span>
+ (<em>string</em> message,
+ <em>iterable</em> choices,
+ <em>string</em> title)
+ </nobr>
+ <div class="jd-descrdiv">
+ Displays a dialog with a list of choices to the process running the current program.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#help">help</a>
+ </span>
+ (<em>string</em> format)
+ </nobr>
+ <div class="jd-descrdiv">
+ Displays the monkeyrunner API reference in a style similar to that of Python's
+ <code>pydoc</code> tool, using the specified format.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <em>string</em>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#input">input</a>
+ </span>
+ (<em>string</em> message,
+ <em>string</em> initialValue,
+ <em>string</em> title,
+ <em>string</em> okTitle,
+ <em>string</em> cancelTitle)
+ </nobr>
+ <div class="jd-descrdiv">
+ Displays a dialog that accepts input.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ void
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#sleep">sleep</a>
+ </span>
+ (<em>float</em> seconds)
+ </nobr>
+ <div class="jd-descrdiv">
+ Pauses the current program for the specified number of seconds.
+ </div>
+ </td>
+ </tr>
+ <tr class="api" >
+ <td class="jd-typecol">
+ <nobr>
+ <code>
+ <a href="{@docRoot}guide/developing/tools/MonkeyDevice.html">MonkeyDevice</a>
+ </code>
+ </nobr>
+ </td>
+ <td class="jd-linkcol" width="100%">
+ <nobr>
+ <span class="sympad">
+ <a href="#waitForConnection">waitForConnection</a>
+ </span>
+ (<em>float</em> timeout,
+ <em>string</em> deviceId)
+ </nobr>
+ <div class="jd-descrdiv">
+ Tries to make a connection between the <code>monkeyrunner</code> backend and the
+ specified device or emulator.
+ </div>
+ </td>
+ </tr>
+</table>
+<!-- ========= METHOD DETAIL ======== -->
+<!-- Public methods -->
+<h2>Public Methods</h2>
+<A NAME="alert"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>string</em>
+ </span>
+ <span class="sympad">alert</span>
+ <span class="normal">
+ (
+ <em>string</em> message,
+ <em>string</em> title,
+ <em>string</em> okTitle)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Displays an alert dialog to the process running the current
+ program. The dialog is modal, so the program pauses until the user clicks the dialog's
+ button.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>message</th>
+ <td>
+ The message to display in the dialog.
+ </td>
+ </tr>
+ <tr>
+ <th>title</th>
+ <td>
+ The dialog's title. The default value is "Alert".
+ </td>
+ </tr>
+ <tr>
+ <th>okTitle</th>
+ <td>
+ The text displayed in the dialog button. The default value is "OK".
+ </td>
+ </tr>
+ </table>
+ </div>
+</div>
+</div>
+<A NAME="choice"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>integer</em>
+ </span>
+ <span class="sympad">choice</span>
+ <span class="normal">
+ (<em>string</em> message,
+ <em>iterable</em> choices,
+ <em>string</em> title)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Displays a dialog with a list of choices to the process running the current program. The
+ dialog is modal, so the program pauses until the user clicks one of the dialog's
+ buttons.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>message</th>
+ <td>
+ The prompt message displayed in the dialog.
+ </td>
+ </tr>
+ <tr>
+ <th>choices</th>
+ <td>
+ A Python iterable containing one or more objects that are displayed as strings. The
+ recommended form is an array of strings.
+ </td>
+ </tr>
+ <tr>
+ <th>
+ title
+ </th>
+ <td>
+ The dialog's title. The default is "Input".
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ If the user makes a selection and clicks the "OK" button, the method returns
+ the 0-based index of the selection within the iterable.
+ If the user clicks the "Cancel" button, the method returns -1.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<A NAME="help"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">help</span>
+ <span class="normal">
+ (<em>string</em> format)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Displays the monkeyrunner API reference in a style similar to that of Python's
+ <code>pydoc</code> tool, using the specified format.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>format</th>
+ <td>
+ The markup format to use in the output. The possible values are "text" for plain text
+ or "html" for HTML.
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="input"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <em>string</em>
+ </span>
+ <span class="sympad">input</span>
+ <span class="normal">
+ (<em>string</em> message
+ <em>string</em> initialValue,
+ <em>string</em> title,
+ <em>string</em> okTitle,
+ <em>string</em> cancelTitle)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Displays a dialog that accepts input and returns it to the program. The dialog is
+ modal, so the program pauses until the user clicks one of the dialog's buttons.
+ </p>
+ <p>
+ The dialog contains two buttons, one of which displays the okTitle value
+ and the other the cancelTitle value. If the user clicks the okTitle button,
+ the current value of the input box is returned. If the user clicks the cancelTitle
+ button, an empty string is returned.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>message</th>
+ <td>
+ The prompt message displayed in the dialog.
+ </td>
+ </tr>
+ <tr>
+ <th>initialValue</th>
+ <td>
+ The initial value to display in the dialog. The default is an empty string.
+ </td>
+ </tr>
+ <tr>
+ <th>title</th>
+ <td>
+ The dialog's title. The default is "Input".
+ </td>
+ </tr>
+ <tr>
+ <th>okTitle</th>
+ <td>
+ The text displayed in the okTitle button. The default is "OK".
+ </td>
+ </tr>
+ <tr>
+ <th>cancelTitle</th>
+ <td>
+ The text displayed in the cancelTitle button. The default is "Cancel".
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ If the user clicks the okTitle button, then the method returns the current value of
+ the dialog's input box. If the user clicks the cancelTitle button, the method returns
+ an empty string.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<A NAME="sleep"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ void
+ </span>
+ <span class="sympad">sleep</span>
+ <span class="normal">
+ (
+ <em>float</em> seconds
+ )
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Pauses the current program for the specified number of seconds.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>seconds</th>
+ <td>
+ The number of seconds to pause.
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</div>
+<A NAME="waitForConnection"></A>
+<div class="jd-details api ">
+ <h4 class="jd-details-title">
+ <span class="normal">
+ <code>
+ <a href="{@docRoot}guide/developing/tools/MonkeyDevice.html">MonkeyDevice</a>
+ </code>
+ </span>
+ <span class="sympad">waitForConnection</span>
+ <span class="normal">
+ (<em>float</em> timeout,
+ <em>string</em> deviceId)
+ </span>
+ </h4>
+ <div class="jd-details-descr">
+
+ <div class="jd-tagdata jd-tagdescr">
+ <p>
+ Tries to make a connection between the <code>monkeyrunner</code> backend and the
+ specified device or emulator.
+ </p>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Arguments</h5>
+ <table class="jd-tagtable">
+ <tr>
+ <th>timeout</th>
+ <td>
+ The number of seconds to wait for a connection. The default is to wait forever.
+ </td>
+ </tr>
+ <tr>
+ <th>
+ deviceId
+ </th>
+ <td>
+ A regular expression that specifies the serial number of the device or emulator. See
+ the topic
+ <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug Bridge</a>
+ for a description of device and emulator serial numbers.
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="jd-tagdata">
+ <h5 class="jd-tagtitle">Returns</h5>
+ <ul class="nolist">
+ <li>
+ A <code><a href="{@docRoot}guide/developing/tools/MonkeyDevice.html">MonkeyDevice</a></code>
+ instance for the device or emulator. Use this object to control and communicate with the
+ device or emulator.
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
diff --git a/docs/html/guide/developing/tools/avd.jd b/docs/html/guide/developing/tools/avd.jd
index acebb7e..ca197cf 100644
--- a/docs/html/guide/developing/tools/avd.jd
+++ b/docs/html/guide/developing/tools/avd.jd
@@ -11,16 +11,13 @@ page.title=Android Virtual Devices
hardware options, system image, and data storage.
<li>You create AVD configurations to model different device environments
in the Android emulator.</li>
- <li>The <code>android</code> tool offers a graphical Android AVD
- Manager and a command-line interface for creating AVDs.</li>
- </ul>
+ <li>You can launch a graphical Android AVD Manager either through Eclipse or
+through the <code>android</code> tool. The <code>android</code> tool also offers
+a command-line interface for creating and managing AVDs.</li> </ul>
<h2>In this document</h2>
<ol>
<li><a href="#creating">Creating an AVD</a>
<ol>
- <li><a href="#listingtargets">Listing targets</a></li>
- <li><a href="#selectingtarget">Selecting a target</a></li>
- <li><a href="#createavd">Creating the AVD</a></li>
<li><a href="#hardwareopts">Setting hardware emulation options</a></li>
<li><a href="#location">Default location of the AVD files</a></li>
</ol>
@@ -74,15 +71,12 @@ reference of emulator options, please see the <a
href="{@docRoot}guide/developing/tools/emulator.html">Emulator</a>
documentation. </p>
-<p>To create and manage AVDs, you use the <code>android</code> tool provided in
-the <code>tools/</code> directory of the Android SDK. The tool provides both a
-graphical AVD manager and a command-line interface that you can use to
-create AVDs. To access the graphical AVD manager, run the
-<code>android</code> tool without options. The sections below describe how to
-use the <code>android</code> command-line interface to create and manage AVDs.
-Note that some functionality, such as the capability to create an AVD with a
-custom hardware configuration, are only available through the command-line
-interface. </p>
+<p>The easiest way to create an AVD is to use the graphical AVD Manager, which
+you can launch from Eclipse or from the command line using the
+<code>android</code> tool. The <code>android</code> tool is provided in the
+<code>tools/</code> directory of the Android SDK. When you run the
+<code>android</code> tool without options, it launches the graphical AVD
+Manager.</p>
<p>For more information about how to work with AVDs from inside your development
environment, see <a
@@ -99,146 +93,51 @@ you need to create an AVD before you can run any application in the emulator
(even the Hello World application).</p>
</div>
</div>
-
-<p>To create an AVD, you use the <code>android</code> tool, a command-line
-utility available in the <code>&lt;sdk&gt;/tools/</code> directory. Managing
-AVDs is one of the two main function of the <code>android</code> tool (the other
-is creating and updating Android projects). Open a terminal window and change to
-the <code>&lt;sdk&gt;/tools/</code> directory, if needed</p>
-
-<p>To create each AVD, you issue the command <code>android create avd</code>,
-with options that specify a name for the new AVD and the system image you want
-to run on the emulator when the AVD is invoked. You can specify other options on
-the command line also, such as to create an emulated SD card for the new AVD, set
-the emulator skin to use, or set a custom location for the AVD's files.</p>
-
-<p>Here's the command-line usage for creating an AVD: </p>
-
-<pre>android create avd -n &lt;name&gt; -t &lt;targetID&gt; [-&lt;option&gt; &lt;value&gt;] ... </pre>
-
-<p>You can use any name you want for the AVD, but since you are likely to be
-creating multiple AVDs, you should choose a name that lets you recognize the
-general characteristics offered by the AVD. </p>
-
-<p>As shown in the usage above, you must use the <code>-t</code> (or
-<code>--target</code>) argument when creating a new AVD. The argument sets up a
-mapping between the AVD and the system image that you want to use whenever the
-AVD is invoked. You can specify any Android system image that is available in
-your local SDK &mdash; it can be the system image of a standard Android platform
-version or that of any SDK add-on. Later, when applications use the AVD, they'll
-be running on the system that you specify in the <code>-t</code> argument.<p>
-
-<p>To specify the system image to use, you refer to its <em>target ID</em>
-&mdash; an integer &mdash; as assigned by the <code>android</code> tool. The
-target ID is not derived from the system image name, version, or API Level, or
-other attribute, so you need to have the <code>android</code> tool list the
-available system images and the target ID of each, as described in the next
-section. You should do this <em>before</em> you run the <code>android create
-avd</code> command.
-</p>
-
-<h3 id="listingtargets">Listing targets</h3>
-
-<p>To generate a list of system image targets, use this command: </p>
-
-<pre>android list targets</pre>
-
-<p>The <code>android</code> tool scans the <code>&lt;sdk&gt;/platforms</code> and
-<code>&lt;sdk&gt;/add-ons</code> directories looking for valid system images and
-then generates the list of targets. Here's an example of the command output:
-</p>
-
-<pre>Available Android targets:
-id:1
- Name: Android 1.1
- Type: platform
- API level: 2
- Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
-id:2
- Name: Android 1.5
- Type: platform
- API level: 3
- Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
-id:3
- Name: Google APIs
- Type: add-on
- Vendor: Google Inc.
- Description: Android + Google APIs
- Based on Android 1.5 (API level 3)
- Libraries:
- * com.google.android.maps (maps.jar)
- API for Google Maps
- Skins: HVGA (default), HVGA-L, QVGA-P, HVGA-P, QVGA-L</pre>
-
-<h3 id="selectingtarget">Selecting a target</h3>
-
-<p>Once you have generated the list of targets available, you can look at the
-characteristics of each system image &mdash; name, API Level, external
-libraries, and so on &mdash; and determine which target is appropriate for the
-new AVD. </p>
-
-<p>Keep these points in mind when you are selecting a system image target for
-your AVD:</p>
-<ul>
-<li>The API Level of the target is important, because your application will not
-be able to run on a system image whose API Level is less than that required by
-your application, as specified in the <code>minSdkVersion</code> attribute of
-the application's manifest file. For more information about the relationship
-between system API Level and application <code>minSdkVersion</code>, see <a
-href="{@docRoot}guide/publishing/versioning.html#minsdkversion">Specifying
-Minimum System API Version</a>.
-<li>Creating at least one AVD that uses a target whose API Level is greater than
-that required by your application is strongly encouraged, because it allows you to
-test the forward-compatibility of your application. Forward-compatibility
-testing ensures that, when users who have downloaded your application receive a
-system update, your application will continue to function normally. </li>
-<li>If your application declares a <code>uses-library</code> element in its
-manifest file, the application can only run on a system image in which that
-external library is present. If you want your application to run on the AVD you
-are creating, check the application's <code>uses-library</code> element and
-select a system image target that includes that library.
-
-</ul>
-
-<h3 id="createavd">Creating the AVD</h3>
-
-<p>When you've selected the target you want to use and made a note of its ID,
-use the <code>android create avd</code> command to create the AVD, supplying the
-target ID as the <code>-t</code> argument. Here's an example that creates an
-AVD with name "my_android1.5" and target ID "2" (the standard Android 1.5
-system image in the list above): </p>
-
-<pre>android create avd -n my_android1.5 -t 2</pre>
-
-<p>If the target you selected was a standard Android system image ("Type:
-platform"), the <code>android</code> tool next asks you whether you want to
-create a custom hardware profile. </p>
-<pre>Android 1.5 is a basic Android platform.
-Do you wish to create a custom hardware profile [no]</pre>
-
-<p>If you want to set custom hardware emulation options for the AVD, enter
-"yes" and set values as needed. If you want to use the default hardware
-emulation options for the AVD, just press the return key (the default is "no").
-The <code>android</code> tool creates the AVD with name and system image mapping you
-requested, with the options you specified.
-
-<p class="note">If you are creating an AVD whose target is an SDK add-on, the
-<code>android</code> tool does not allow you to set hardware emulation options.
-It assumes that the provider of the add-on has set emulation options
-appropriately for the device that the add-on is modeling, and so prevents you
-from resetting the options. </p>
-<p>For a list of options you can use in the <code>android create avd</code>
-command, see the table in <a href="#options">Command-line options for AVDs</a>,
-at the bottom of
-this page. </p>
+<p>The easiest way to create an AVD is to use the graphical AVD Manager, but the
+<code>android</code> tool also offers a <a href="#options">command line option</a>.</p>
+<p>To create an AVD:</p>
+<ol>
+ <li>In Eclipse, choose <strong>Window &gt; Android SDK and AVD Manager</strong>. </li>
+ <p>Alternatively, you can launch the graphical AVD Manager by running the
+<code>android</code> tool with no options.</p>
+ <li>Select <strong>Virtual Devices</strong> in the left panel.</li>
+
+ <li>Click <strong>New</strong>. </li>
+
+<p>The <strong>Create New AVD</strong> dialog appears.</p> <a
+href="{@docRoot}images/developing/avd-dialog.png"><img
+src="{@docRoot}images/developing/avd-dialog.png" alt="AVD
+Dialog" /></a>
+
+ <li>Type the name of the AVD, such as "my_avd".</li>
+ <li>Choose a target. </li>
+<p>The target is the system image that you want to run on the emulator,
+from the set of platforms that are installed in your SDK environment. You can
+choose a version of the standard Android platform or an SDK add-on. For more
+information about how to add platforms to your SDK, see <a
+href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a>. </p>
+ <li>Optionally specify any additional settings: </li>
+ <dl>
+ <dt><em>SD Card</em></dt> <dd>The path to the SD card image to use with this
+AVD, or the size of a new SD card image to create for this AVD.</dd> </dl>
+<dt><em>Skin</em></dt>
+ <dd>The skin to use for this AVD, identified by name or dimensions.</dd>
+<dt><em>Hardware</em></dt>
+ <dd>The hardware emulation options for the device. For a list of the options, see
+<a href="#hardwareopts">Setting hardware emulation options</a>.</dd>
+ </dl>
+ <li>Click <strong>Create AVD</strong>.</li>
+</ol>
<h3 id="hardwareopts">Setting hardware emulation options</h3>
-<p>When are creating a new AVD that uses a standard Android system image ("Type:
-platform"), the <code>android</code> tool lets you set hardware emulation
-options for virtual device. The table below lists the options available and the
+<p>When you create a new AVD that uses a standard Android system image ("Type:
+platform"), the AVD Manager
+ lets you set hardware emulation
+options for your virtual device.
+The table below lists the options available and the
default values, as well as the names of properties that store the emulated
-hardware options in the AVD's configuration file (the config.ini file in the
+hardware options in the AVD's configuration file (the <code>config.ini</code> file in the
AVD's local directory). </p>
<table>
@@ -266,6 +165,7 @@ AVD's local directory). </p>
</tr>
<tr>
+
<td>Keyboard support</td>
<td>Whether the device has a QWERTY keyboard. Default value is "yes".</td>
<td>hw.keyboard</td>
@@ -299,6 +199,7 @@ AVD's local directory). </p>
<td>Maximum vertical camera pixels</td>
<td>Default value is "480".</td>
<td>hw.camera.maxVerticalPixels</td>
+
</tr>
<tr>
@@ -311,6 +212,7 @@ AVD's local directory). </p>
<td>Battery support</td>
<td>Whether the device can run on a battery. Default value is "yes".</td>
<td>hw.battery</td>
+
</tr>
<tr>
@@ -323,6 +225,7 @@ AVD's local directory). </p>
<td>Audio recording support</td>
<td>Whether the device can record audio. Default value is "yes".</td>
<td>hw.audioInput</td>
+
</tr>
<tr>
@@ -335,6 +238,7 @@ AVD's local directory). </p>
<td>SD Card support</td>
<td>Whether the device supports insertion/removal of virtual SD Cards. Default value is "yes".</td>
<td>hw.sdCard</td>
+
</tr>
<tr>
@@ -347,43 +251,55 @@ AVD's local directory). </p>
<td>Cache partition size</td>
<td>Default value is "66MB".</td>
<td>disk.cachePartition.size </td>
+
</tr>
<tr>
<td>Abstracted LCD density</td>
-<td>Sets the generalized density characteristic used by the AVD's screen. Default value is "160".</td>
+<td>Sets the generalized density characteristic used by the AVD's screen. Most
+skins come with a value (which you can modify), but if a skin doesn't provide
+its own value, the default is 160. </td>
<td>hw.lcd.density </td>
</tr>
+<tr>
+<td>Max VM application heap size</td>
+<td>The maximum heap size a Dalvik application might allocate before being
+killed by the system. Value is in megabytes. Most skins come with a value (which
+you can modify), but if a skin doesn't provide its own value, the default is
+16.</td>
+<td>vm.heapSize</td>
+</tr>
+
</table>
<h3 id="location">Default location of the AVD files</h3>
-<p>When you create an AVD, the <code>android</code> tool creates a dedicated directory for it
+<p>When you create an AVD, the AVD Manager creates a dedicated directory for it
on your development computer. The directory contains the AVD configuration file,
the user data image and SD card image (if available), and any other files
associated with the device. Note that the directory does not contain a system
image &mdash; instead, the AVD configuration file contains a mapping to the
system image, which it loads when the AVD is launched. </p>
-<p>The <code>android</code> tool also creates a &lt;AVD name&gt;.ini file for the AVD at the
-root of the .android/avd directory on your computer. The file specifies the
-location of the AVD directory and always remains at the root the .android
-directory.</p>
+<p>The AVD Manager also creates a <code>&lt;AVD name&gt;.ini</code> file for the
+AVD at the root of the <code>.android/avd</code> directory on your computer. The file
+specifies the location of the AVD directory and always remains at the root the
+.android directory.</p>
-<p>By default, the <code>android</code> tool creates the AVD directory inside
+<p>By default, the AVD Manager creates the AVD directory inside
<code>~/.android/avd/</code> (on Linux/Mac), <code>C:\Documents and
Settings\&lt;user&gt;\.android\</code> on Windows XP, and
<code>C:\Users\&lt;user&gt;\.android\</code> on Windows Vista.
If you want to use a custom location for the AVD directory, you
can do so by using the <code>-p &lt;path&gt;</code> option when
-you create the AVD: </p>
+you create the AVD (command line tool only): </p>
<pre>android create avd -n my_android1.5 -t 2 -p path/to/my/avd</pre>
-<p>If the .android directory is hosted on a network drive, we recommend using
+<p>If the <code>.android</code> directory is hosted on a network drive, we recommend using
the <code>-p</code> option to place the AVD directory in another location.
-The AVD's .ini file remains in the .android directory on the network
+The AVD's <code>.ini</code> file remains in the <code>.android</code> directory on the network
drive, regardless of the location of the AVD directory. </p>
<h2 id="managing">Managing AVDs</h2>
@@ -401,18 +317,15 @@ options for AVDs</a> at the bottom of this page. </p>
<h3 id="updating">Updating an AVD</h3>
-<p>If, for any reason, the platform/add-on root folder has its name changed (maybe because the user has installed an update of the platform/add-on) then the AVD will not be able to load the system image that it is mapped to. In this case, the <code>android list targets</code> command will produce this output:
-
-<pre>The following Android Virtual Devices could not be loaded:
-Name: foo
-Path: &lt;path&gt;/.android/avd/foo.avd
-Error: Invalid value in image.sysdir. Run 'android update avd -n foo' </pre>
-
-<p>To fix this error, use the <code>android update avd</code> command to recompute the path to the system images.</p>
+<p>
+If you rename or move the root directory of a platform (or add-on), an AVD configured to use that platform will no longer be able to load the system image properly. To fix the AVD, use the <strong>Repair...</strong> button in the AVD Manager. From the command line, you can also use the <code>android update avd</code> command to recompute the path to the system images.</p>
<h3 id="deleting">Deleting an AVD</h3>
-<p>You can use the <code>android</code> tool to delete an AVD. Here is the command usage:</p>
+<p>You can delete an AVD in the AVD Manager by selecting the
+AVD and clicking <strong>Delete</strong>.</p>
+
+<p>Alternatively, you can use the <code>android</code> tool to delete an AVD. Here is the command usage:</p>
<pre>android delete avd -n &lt;name&gt; </pre>
@@ -420,7 +333,21 @@ Error: Invalid value in image.sysdir. Run 'android update avd -n foo' </pre>
specified name deletes the AVD's directory and files. </p>
-<h2 id="options">Command-line options for AVDs</h2>
+<h2 id="options">Command-line options</h2>
+
+<p>You can use the <code>android</code> tool to create and manage AVDs.</p>
+
+<p>The command line for creating an AVD has the following syntax:</p>
+
+<pre>
+android create avd -n &lt;name&gt; -t &lt;targetID&gt; [-&lt;option&gt; &lt;value&gt;] ...
+</pre>
+
+<p>Here's an example that creates an AVD with the name "my_android2.2" and target ID "3":</p>
+
+<pre>
+android create avd -n my_android2.2 -t 3
+</pre>
<p>The table below lists the command-line options you can use with the
<code>android</code> tool. </p>
diff --git a/docs/html/guide/developing/tools/index.jd b/docs/html/guide/developing/tools/index.jd
index 6e9fde1..899c0dc 100644
--- a/docs/html/guide/developing/tools/index.jd
+++ b/docs/html/guide/developing/tools/index.jd
@@ -3,27 +3,27 @@ page.title=Tools Overview
<img src="{@docRoot}assets/images/android_wrench.png" alt="" align="right">
-<p>The Android SDK includes a variety of custom tools that help you develop mobile
-applications on the Android platform. The most important of these are the Android
-Emulator and the Android Development Tools plugin for Eclipse, but the SDK also
-includes a variety of other tools for debugging, packaging, and installing your
+<p>The Android SDK includes a variety of custom tools that help you develop mobile
+applications on the Android platform. The most important of these are the Android
+Emulator and the Android Development Tools plugin for Eclipse, but the SDK also
+includes a variety of other tools for debugging, packaging, and installing your
applications on the emulator. </p>
-
+
<dl>
<dt><a href="adt.html">Android Development Tools Plugin</a> (for the Eclipse IDE)</dt>
- <dd>The ADT plugin adds powerful extensions to the Eclipse integrated environment,
- making creating and debugging your Android applications easier and faster. If you
- use Eclipse, the ADT plugin gives you an incredible boost in developing Android
+ <dd>The ADT plugin adds powerful extensions to the Eclipse integrated environment,
+ making creating and debugging your Android applications easier and faster. If you
+ use Eclipse, the ADT plugin gives you an incredible boost in developing Android
applications.</dd>
<dt><a href="emulator.html">Android Emulator</a></dt>
- <dd>A QEMU-based device-emulation tool that you can use to design,
+ <dd>A QEMU-based device-emulation tool that you can use to design,
debug, and test your applications in an actual Android run-time environment. </dd>
<dt><a href="avd.html">Android Virtual Devices (AVDs)</a></dt>
<dd>Virtual device configurations that you create, to model device
characteristics in the Android Emulator. In each configuration, you can
specify the Android platform to run, the hardware options, and the
- emulator skin to use. Each AVD functions as an independent device with
+ emulator skin to use. Each AVD functions as an independent device with
it's own storage for user data, SD card, and so on. </dd>
<dt><a href="hierarchy-viewer.html">Hierarchy Viewer</a></dt>
@@ -37,64 +37,69 @@ applications on the emulator. </p>
efficiency.
</dd>
- <dt><a href="draw9patch.html">Draw 9-patch</a></dt>
- <dd>The Draw 9-patch tool allows you to easily create a
- {@link android.graphics.NinePatch} graphic using a WYSIWYG editor. It also previews stretched
- versions of the image, and highlights the area in which content is allowed.
- </dd>
+ <dt><a href="draw9patch.html">Draw 9-patch</a></dt>
+ <dd>The Draw 9-patch tool allows you to easily create a
+ {@link android.graphics.NinePatch} graphic using a WYSIWYG editor. It also previews stretched
+ versions of the image, and highlights the area in which content is allowed.
+ </dd>
- <dt><a href="ddms.html" >Dalvik Debug Monitor
+ <dt><a href="ddms.html" >Dalvik Debug Monitor
Service</a> (ddms)</dt>
- <dd>Integrated with Dalvik, the Android platform's custom VM, this tool
- lets you manage processes on an emulator or device and assists in debugging.
- You can use it to kill processes, select a specific process to debug,
- generate trace data, view heap and thread information, take screenshots
- of the emulator or device, and more. </dd>
-
+ <dd>Integrated with Dalvik, the Android platform's custom VM, this tool
+ lets you manage processes on an emulator or device and assists in debugging.
+ You can use it to kill processes, select a specific process to debug,
+ generate trace data, view heap and thread information, take screenshots
+ of the emulator or device, and more. </dd>
+
<dt><a href="adb.html" >Android Debug Bridge</a> (adb)</dt>
- <dd>The adb tool lets you install your application's .apk files on an
- emulator or device and access the emulator or device from a command line.
- You can also use it to link a standard debugger to application code running
+ <dd>The adb tool lets you install your application's .apk files on an
+ emulator or device and access the emulator or device from a command line.
+ You can also use it to link a standard debugger to application code running
on an Android emulator or device.</dd>
- <dt><a href="aapt.html">Android Asset
+ <dt><a href="aapt.html">Android Asset
Packaging Tool</a> (aapt)</dt>
- <dd>The aapt tool lets you create .apk files containing the binaries and
+ <dd>The aapt tool lets you create .apk files containing the binaries and
resources of Android applications.</dd>
- <dt><a href="aidl.html" >Android Interface
+ <dt><a href="aidl.html" >Android Interface
Description Language</a> (aidl)</dt>
<dd>Lets you generate code for an interprocess interface, such as what
a service might use.</dd>
<dt><a href="adb.html#sqlite">sqlite3</a></dt>
- <dd>Included as a convenience, this tool lets you access the SQLite data
+ <dd>Included as a convenience, this tool lets you access the SQLite data
files created and used by Android applications.</dd>
<dt><a href="traceview.html" >Traceview</a></dt>
- <dd> This tool produces graphical analysis views of trace log data that you
+ <dd> This tool produces graphical analysis views of trace log data that you
can generate from your Android application. </dd>
<dt><a href="othertools.html#mksdcard">mksdcard</a></dt>
- <dd>Helps you create a disk image that you can use with the emulator,
+ <dd>Helps you create a disk image that you can use with the emulator,
to simulate the presence of an external storage card (such as an SD card).</dd>
<dt><a href="othertools.html#dx">dx</a></dt>
- <dd>The dx tool rewrites .class bytecode into Android bytecode
+ <dd>The dx tool rewrites .class bytecode into Android bytecode
(stored in .dex files.)</dd>
- <dt><a href="monkey.html">UI/Application
+ <dt><a href="monkey.html">UI/Application
Exerciser Monkey</a></dt>
<dd>The Monkey is a program that runs on your emulator or device and generates pseudo-random
streams of user events such as clicks, touches, or gestures, as well as a number of system-
level events. You can use the Monkey to stress-test applications that you are developing,
in a random yet repeatable manner.</dd>
+ <dt><a href="monkeyrunner_concepts.html">monkeyrunner</a></dt>
+ <dd>
+ The monkeyrunner tool provides an API for writing Python programs that control an Android device
+ or emulator from outside of Android code.
+ </dd>
<dt><a href="othertools.html#android">android</a></dt>
<dd>A script that lets you manage AVDs and generate <a
- href="http://ant.apache.org/" title="Ant">Ant</a> build files that
+ href="http://ant.apache.org/" title="Ant">Ant</a> build files that
you can use to compile your Android applications. </dd>
-
+
<dt><a href="zipalign.html">zipalign</a></dt>
<dd>An important .apk optimization tool. This tool ensures that all uncompressed data starts
with a particular alignment relative to the start of the file. This should always be used
diff --git a/docs/html/guide/developing/tools/monkeyrunner_concepts.jd b/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
new file mode 100644
index 0000000..1838905
--- /dev/null
+++ b/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
@@ -0,0 +1,308 @@
+page.title=monkeyrunner
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li>
+ <a href="#SampleProgram">A Simple monkeyrunner Program</a>
+ </li>
+ <li>
+ <a href="#APIClasses">The monkeyrunner API</a>
+ </li>
+ <li>
+ <a href="#RunningMonkeyRunner">Running monkeyrunner</a>
+ </li>
+ <li>
+ <a href="#Help">monkeyrunner Built-in Help</a>
+ </li>
+ <li>
+ <a href="#Plugins">Extending monkeyrunner with Plugins</a>
+ </li>
+ </ol>
+ <h2>See Also</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Fundamentals</a>
+ </li>
+ </ol>
+ </div>
+</div>
+<p>
+ The monkeyrunner tool provides an API for writing programs that control an Android device
+ or emulator from outside of Android code. With monkeyrunner, you can write a Python program
+ that installs an Android application or test package, runs it, sends keystrokes to it,
+ takes screenshots of its user interface, and stores screenshots on the workstation. The
+ monkeyrunner tool is primarily designed to test applications and devices at the
+ functional/framework level and for running unit test suites, but you are free to use it for
+ other purposes.
+</p>
+<p>
+ The monkeyrunner tool is not related to the
+ <a href="{@docRoot}guide/developing/tools/monkey.html">UI/Application Exerciser Monkey</a>,
+ also known as the <code>monkey</code> tool. The <code>monkey</code> tool runs in an
+ <code><a href="{@docRoot}guide/developing/tools/adb.html">adb</a></code> shell directly on the
+ device or emulator and generates pseudo-random streams of user and system events. In comparison,
+ the monkeyrunner tool controls devices and emulators from a workstation by sending specific
+ commands and events from an API.
+</p>
+<p>
+ The monkeyrunner tool provides these unique features for Android testing:
+</p>
+<ul>
+ <li>
+ Multiple device control: The monkeyrunner API can apply one or more
+ test suites across multiple devices or emulators. You can physically attach all the devices
+ or start up all the emulators (or both) at once, connect to each one in turn
+ programmatically, and then run one or more tests. You can also start up an emulator
+ configuration programmatically, run one or more tests, and then shut down the emulator.
+ </li>
+ <li>
+ Functional testing: monkeyrunner can run an automated start-to-finish test of an Android
+ application. You provide input values with keystrokes or touch events, and view the results
+ as screenshots.
+ </li>
+ <li>
+ Regression testing - monkeyrunner can test application stability by running an application
+ and comparing its output screenshots to a set of screenshots that are known to be correct.
+ </li>
+ <li>
+ Extensible automation - Since monkeyrunner is an API toolkit, you can develop an entire
+ system of Python-based modules and programs for controlling Android devices. Besides using
+ the monkeyrunner API itself, you can use the standard Python
+ <code><a href="http://docs.python.org/library/os.html">os</a></code> and
+ <code><a href="http://docs.python.org/library/subprocess.html">subprocess</a></code>
+ modules to call Android tools such as
+ <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug Bridge</a>.
+ <p>
+ You can also add your own classes to the monkeyrunner API. This is described
+ in more detail in the section
+ <a href="#Plugins">Extending monkeyrunner with plugins</a>.
+ </p>
+ </li>
+</ul>
+<p>
+ The monkeyrunner tool uses <a href="http://www.jython.org/">Jython</a>, a
+ implementation of Python that uses the Java programming language. Jython allows the
+ monkeyrunner API to interact easily with the Android framework. With Jython you can
+ use Python syntax to access the constants, classes, and methods of the API.
+</p>
+
+<h2 id="SampleProgram">A Simple monkeyrunner Program</h2>
+<p>
+ Here is a simple monkeyrunner program that connects to a device, creating a
+ <code><a href="{@docRoot}guide/developing/tools/MonkeyDevice.html">MonkeyDevice</a></code>
+ object. Using the <code>MonkeyDevice</code> object, the program installs an Android application
+ package, runs one of its activities, and sends key events to the activity.
+ The program then takes a screenshot of the result, creating a
+ <code><a href="{@docRoot}guide/developing/tools/MonkeyImage.html">MonkeyImage</a></code> object.
+ From this object, the program writes out a <code>.png</code> file containing the screenshot.
+</p>
+<pre>
+# Imports the monkeyrunner modules used by this program
+from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
+
+# Connects to the current device, returning a MonkeyDevice object
+device = MonkeyRunner.waitForConnection()
+
+# Installs the Android package. Notice that this method returns a boolean, so you can test
+# to see if the installation worked.
+device.installPackage('myproject/bin/MyApplication.apk')
+
+# Runs an activity in the application
+device.startActivity(component='com.example.android.myapplication.MainActivity')
+
+# Presses the Menu button
+device.press('KEYCODE_MENU','DOWN_AND_UP')
+
+# Takes a screenshot
+result = device.takeSnapShot
+
+# Writes the screenshot to a file
+result.writeToFile('myproject/shot1.png','png')
+</pre>
+
+<h2 id="APIClasses">The monkeyrunner API</h2>
+<p>
+ The monkeyrunner API is contained in three modules in the package
+ <code>com.android.monkeyrunner</code>:
+</p>
+<ul>
+ <li>
+ <code><a href="{@docRoot}guide/developing/tools/MonkeyRunner.html">MonkeyRunner</a></code>:
+ A class of utility methods for monkeyrunner programs. This class provides a method for
+ connecting monkeyrunner to a device or emulator. It also provides methods for
+ creating UIs for a monkeyrunner program and for displaying the built-in help.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/developing/tools/MonkeyDevice.html">MonkeyDevice</a></code>:
+ Represents a device or emulator. This class provides methods for installing and
+ uninstalling packages, starting an Activity, and sending keyboard or touch events to an
+ application. You also use this class to run test packages.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/developing/tools/MonkeyImage.html">MonkeyImage</a></code>:
+ Represents a screen capture image. This class provides methods for capturing screens,
+ converting bitmap images to various formats, comparing two MonkeyImage objects, and
+ writing an image to a file.
+ </li>
+</ul>
+<p>
+ In a Python program, you access each class as a Python module. The monkeyrunner tool
+ does not import these modules automatically. To import a module, use the
+ Python <code>from</code> statement:
+</p>
+<pre>
+from com.android.monkeyrunner import &lt;module&gt;
+</pre>
+<p>
+ where <code>&lt;module&gt;</code> is the class name you want to import. You can import more
+ than one module in the same <code>from</code> statement by separating the module names with
+ commas.
+</p>
+<h2 id="RunningMonkeyRunner">Running monkeyrunner</h2>
+<p>
+ You can either run monkeyrunner programs from a file, or enter monkeyrunner statements in
+ an interactive session. You do both by invoking the <code>monkeyrunner</code> command
+ which is found in the <code>tools/</code> subdirectory of your SDK directory.
+ If you provide a filename as an argument, the <code>monkeyrunner</code> command
+ runs the file's contents as a Python program; otherwise, it starts an interactive session.
+</p>
+<p>
+ The syntax of the <code>monkeyrunner</code> command is
+</p>
+<pre>
+monkeyrunner -plugin &lt;plugin_jar&gt; &lt;program_filename&gt; &lt;program_options&gt;
+</pre>
+<p>
+Table 1 explains the flags and arguments.
+</p>
+<p class="table-caption" id="table1">
+ <strong>Table 1.</strong> <code>monkeyrunner</code> flags and arguments.</p>
+
+<table>
+ <tr>
+ <th>Argument</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>
+ <nobr>
+ <code>-plugin &lt;plugin_jar&gt;</code>
+ </nobr>
+ </td>
+ <td>
+ (Optional) Specifies a <code>.jar</code> file containing a plugin for monkeyrunner.
+ To learn more about monkeyrunner plugins, see
+ <a href="#Plugins">Extending monkeyrunner with plugins</a>. To specify more than one
+ file, include the argument multiple times.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <nobr>
+ <code>&lt;program_filename&gt;</code>
+ </nobr>
+ </td>
+ <td>
+ If you provide this argument, the <code>monkeyrunner</code> command runs the contents
+ of the file as a Python program. If the argument is not provided, the command starts an
+ interactive session.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>&lt;program_options&gt;</code>
+ </td>
+ <td>
+ (Optional) Flags and arguments for the program in &lt;program_file&gt;.
+ </td>
+ </tr>
+</table>
+<h2 id="Help">monkeyrunner Built-in Help</h2>
+<p>
+ You can generate an API reference for monkeyrunner by running:
+</p>
+<pre>
+monkeyrunner &lt;format&gt; help.py &lt;outfile&gt;
+</pre>
+<p>
+The arguments are:
+</p>
+ <ul>
+ <li>
+ <code>&lt;format&gt;</code> is either <code>text</code> for plain text output
+ or <code>html</code> for HTML output.
+ </li>
+ <li>
+ <code>&lt;outfile&gt;</code> is a path-qualified name for the output file.
+ </li>
+ </ul>
+<h2 id="Plugins">Extending monkeyrunner with Plugins</h2>
+<p>
+ You can extend the monkeyrunner API with classes you write in the Java programming language
+ and build into one or more <code>.jar</code> files. You can use this feature to extend the
+ monkeyrunner API with your own classes or to extend the existing classes. You can also use this
+ feature to initialize the monkeyrunner environment.
+</p>
+<p>
+ To provide a plugin to monkeyrunner, invoke the <code>monkeyrunner</code> command with the
+ <code>-plugin &lt;plugin_jar&gt;</code> argument described in
+ <a href="#table1">table 1</a>.
+</p>
+<p>
+ In your plugin code, you can import and extend the the main monkeyrunner classes
+ <code>MonkeyDevice</code>, <code>MonkeyImage</code>, and <code>MonkeyRunner</code> in
+ <code>com.android.monkeyrunner</code> (see <a href="#APIClasses">The monkeyrunner API</a>).
+</p>
+<p>
+ Note that plugins do not give you access to the Android SDK. You can't import packages
+ such as <code>com.android.app</code>. This is because monkeyrunner interacts with the
+ device or emulator below the level of the framework APIs.
+</p>
+<h3>The plugin startup class</h3>
+<p>
+ The <code>.jar</code> file for a plugin can specify a class that is instantiated before
+ script processing starts. To specify this class, add the key
+ <code>MonkeyRunnerStartupRunner</code> to the <code>.jar</code> file's
+ manifest. The value should be the name of the class to run at startup. The following
+ snippet shows how you would do this within an <code>ant</code> build script:
+</p>
+<pre>
+&lt;jar jarfile=&quot;myplugin&quot; basedir="&#36;&#123;build.dir&#125;&quot;&gt;
+&lt;manifest&gt;
+&lt;attribute name=&quot;MonkeyRunnerStartupRunner&quot; value=&quot;com.myapp.myplugin&quot;/&gt;
+&lt;/manifest&gt;
+&lt;/jar&gt;
+
+
+</pre>
+<p>
+ To get access to monkeyrunner's runtime environment, the startup class can implement
+ <code>com.google.common.base.Predicate&lt;PythonInterpreter&gt;</code>. For example, this
+ class sets up some variables in the default namespace:
+</p>
+<pre>
+package com.android.example;
+
+import com.google.common.base.Predicate;
+import org.python.util.PythonInterpreter;
+
+public class Main implements Predicate&lt;PythonInterpreter&gt; {
+ &#64;Override
+ public boolean apply(PythonInterpreter anInterpreter) {
+
+ /*
+ * Examples of creating and initializing variables in the monkeyrunner environment's
+ * namespace. During execution, the monkeyrunner program can refer to the variables "newtest"
+ * and "use_emulator"
+ *
+ */
+ anInterpreter.set("newtest", "enabled");
+ anInterpreter.set("use_emulator", 1);
+
+ return true;
+ }
+}
+</pre>
diff --git a/docs/html/guide/developing/tools/proguard.jd b/docs/html/guide/developing/tools/proguard.jd
new file mode 100644
index 0000000..6abbd36
--- /dev/null
+++ b/docs/html/guide/developing/tools/proguard.jd
@@ -0,0 +1,187 @@
+page.title=ProGuard
+@jd:body
+
+ <div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+
+ <ol>
+ <li><a href="#enabling">Enabling ProGuard</a></li>
+
+ <li><a href="#configuring">Configuring ProGuard</a></li>
+
+ <li>
+ <a href="#decoding">Decoding Obfuscated Stack Traces</a>
+
+ <ol>
+ <li><a href="#considerations">Debugging considerations for published
+ applications</a></li>
+ </ol>
+ </li>
+ </ol>
+
+ <h2>See also</h2>
+
+ <ol>
+ <li><a href="http://proguard.sourceforge.net/manual/introduction.html">ProGuard
+ Manual</a></li>
+
+ <li><a href="http://proguard.sourceforge.net/manual/retrace/introduction.html">ProGuard
+ ReTrace Manual</a></li>
+ </ol>
+ </div>
+ </div>
+
+ <p>The ProGuard tool shrinks, optimizes, and obfuscates your code by removing unused code and
+ renaming classes, fields, and methods with semantically obscure names. The result is a smaller
+ sized <code>.apk</code> file that is more difficult to reverse engineer. Because ProGuard makes your
+ application harder to reverse engineer, it is important that you use it
+ when your application utilizes features that are sensitive to security like when you are
+ <a href="{@docRoot}guide/publishing/licensing.html">Licensing Your Applications</a>.</p>
+
+ <p>ProGuard is integrated into the Android build system, so you do not have to invoke it
+ manually. ProGuard runs only when you build your application in release mode, so you do not
+ have to deal with obfuscated code when you build your application in debug mode.
+ Having ProGuard run is completely optional, but highly recommended.</p>
+
+ <p>This document describes how to enable and configure ProGuard as well as use the
+ <code>retrace</code> tool to decode obfuscated stack traces.</p>
+
+ <h2 id="enabling">Enabling ProGuard</h2>
+
+ <p>When you create an Android project, a <code>proguard.cfg</code> file is automatically
+ generated in the root directory of the project. This file defines how ProGuard optimizes and
+ obfuscates your code, so it is very important that you understand how to customize it for your
+ needs. The default configuration file only covers general cases, so you most likely have to edit
+ it for your own needs. See the following section about <a href="#configuring">Configuring ProGuard</a> for information on
+ customizing the ProGuard configuration file.</p>
+
+ <p>To enable ProGuard so that it runs as part of an Ant or Eclipse build, set the
+ <code>proguard.config</code> property in the <code>&lt;project_root&gt;/default.properties</code>
+ file. The path can be an absolute path or a path relative to the project's root.</p>
+<p>If you left the <code>proguard.cfg</code> file in its default location (the project's root directory),
+you can specify its location like this:</p>
+<pre class="no-pretty-print">
+proguard.config=proguard.cfg
+</pre>
+<p>
+You can also move the the file to anywhere you want, and specify the absolute path to it:
+</p>
+<pre class="no-pretty-print">
+proguard.config=/path/to/proguard.cfg
+</pre>
+
+
+ <p>When you build your application in release mode, either by running <code>ant release</code> or
+ by using the <em>Export Wizard</em> in Eclipse, the build system automatically checks to see if
+ the <code>proguard.config</code> property is set. If it is, ProGuard automatically processes
+ the application's bytecode before packaging everything into an <code>.apk</code> file. Building in debug mode
+ does not invoke ProGuard, because it makes debugging more cumbersome.</p>
+
+ <p>ProGuard outputs the following files after it runs:</p>
+
+ <dl>
+ <dt><code>dump.txt</code></dt>
+ <dd>Describes the internal structure of all the class files in the <code>.apk</code> file</dd>
+
+ <dt><code>mapping.txt</code></dt>
+ <dd>Lists the mapping between the original and obfuscated class, method, and field names.
+ This file is important when you receive a bug report from a release build, because it
+ translates the obfuscated stack trace back to the original class, method, and member names.
+ See <a href="#decoding">Decoding Obfuscated Stack Traces</a> for more information.</dd>
+
+ <dt><code>seeds.txt</code></dt>
+ <dd>Lists the classes and members that are not obfuscated</dd>
+
+ <dt><code>usage.txt</code></dt>
+ <dd>Lists the code that was stripped from the <code>.apk</code></dd>
+ </ul>
+
+ <p>These files are located in the following directories:</p>
+
+ <ul>
+ <li><code>&lt;project_root&gt;/bin/proguard</code> if you are using Ant.</li>
+
+ <li><code>&lt;project_root&gt;/proguard</code> if you are using Eclipse.</li>
+ </ul>
+
+
+ <p class="caution"><strong>Caution:</strong> Every time you run a build in release mode, these files are
+ overwritten with the latest files generated by ProGuard. Save a copy of them each time you release your
+ application in order to de-obfuscate bug reports from your release builds.
+ For more information on why saving these files is important, see
+ <a href="#considerations">Debugging considerations for published applications</a>.
+ </p>
+
+ <h2 id="configuring">Configuring ProGuard</h2>
+
+ <p>For some situations, the default configurations in the <code>proguard.cfg</code> file will
+ suffice. However, many situations are hard for ProGuard to analyze correctly and it might remove code
+ that it thinks is not used, but your application actually needs. Some examples include:</p>
+
+ <ul>
+ <li>a class that is referenced only in the <code>AndroidManifest.xml</code> file</li>
+
+ <li>a method called from JNI</li>
+
+ <li>dynamically referenced fields and methods</li>
+ </ul>
+
+ <p>The default <code>proguard.cfg</code> file tries to cover general cases, but you might
+ encounter exceptions such as <code>ClassNotFoundException</code>, which happens when ProGuard
+ strips away an entire class that your application calls.</p>
+
+ <p>You can fix errors when ProGuard strips away your code by adding a <code>-keep</code> line in
+ the <code>proguard.cfg</code> file. For example:</p>
+ <pre>
+-keep public class &lt;MyClass&gt;
+</pre>
+
+ <p>There are many options and considerations when using the <code>-keep</code> option, so it is
+ highly recommended that you read the <a href="http://proguard.sourceforge.net/manual/introduction.html">ProGuard
+ Manual</a> for more information about customizing your configuration file. The <a href=
+ "http://proguard.sourceforge.net/manual/usage.html#keepoverview">Overview of Keep options</a> and
+ <a href="http://proguard.sourceforge.net/index.html#/manual/examples.html">Examples section</a>
+ are particularly helpful. The <a href=
+ "http://proguard.sourceforge.net/manual/troubleshooting.html">Troubleshooting</a> section of the
+ ProGuard Manual outlines other common problems you might encounter when your code gets stripped
+ away.</p>
+
+ <h2 id="decoding">Decoding Obfuscated Stack Traces</h2>
+
+ <p>When your obfuscated code outputs a stack trace, the method names are obfuscated, which makes
+ debugging hard, if not impossible. Fortunately, whenever ProGuard runs, it outputs a
+ <code>&lt;project_root&gt;/bin/proguard/mapping.txt</code> file, which shows you the original
+ class, method, and field names mapped to their obfuscated names.</p>
+
+ <p>The <code>retrace.bat</code> script on Windows or the <code>retrace.sh</code> script on Linux
+ or Mac OS X can convert an obfuscated stack trace to a readable one. It is located in the
+ <code>&lt;sdk_root&gt;/tools/proguard/</code> directory. The syntax for executing the
+ <code>retrace</code> tool is:</p>
+ <pre>retrace.bat|retrace.sh [-verbose] mapping.txt [&lt;stacktrace_file&gt;]</pre>
+ <p>For example:</p>
+
+ <pre>retrace.bat -verbose mapping.txt obfuscated_trace.txt</pre>
+
+ <p>If you do not specify a value for <em>&lt;stacktrace_file&gt;</em>, the <code>retrace</code> tool reads
+ from standard input.</p>
+
+ <h3 id="considerations">Debugging considerations for published applications</h3>
+
+ <p>Save the <code>mapping.txt</code> file for every release that you publish to your users.
+ By retaining a copy of the <code>mapping.txt</code> file for each release build,
+ you ensure that you can debug a problem if a user encounters a bug and submits an obfuscated stack trace.
+ A project's <code>mapping.txt</code> file is overwritten every time you do a release build, so you must be
+ careful about saving the versions that you need.</p>
+
+ <p>For example, say you publish an application and continue developing new features of
+ the application for a new version. You then do a release build using ProGuard soon after. The
+ build overwrites the previous <code>mapping.txt</code> file. A user submits a bug report
+ containing a stack trace from the application that is currently published. You no longer have a way
+ of debugging the user's stack trace, because the <code>mapping.txt</code> file associated with the version
+ on the user's device is gone. There are other situations where your <code>mapping.txt</code> file can be overwritten, so
+ ensure that you save a copy for every release that you anticipate you have to debug.</p>
+
+ <p>How you save the <code>mapping.txt</code> file is your decision. For example, you can rename them to
+ include a version or build number, or you can version control them along with your source
+ code.</p> \ No newline at end of file
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 19f0f1d..545807e 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -110,7 +110,7 @@
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/resources/index.html">
<span class="en">Application Resources</span>
- </a> <span class="new">new!</span></div>
+ </a></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/resources/providing-resources.html">
<span class="en">Providing Resources</span>
@@ -120,14 +120,14 @@
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/resources/runtime-changes.html">
<span class="en">Handling Runtime Changes</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>guide/topics/resources/localization.html">
<span class="en">Localization</span>
</a></li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/resources/available-resources.html">
<span class="en">Resource Types</span>
- </a> <span class="new">new!</span></div>
+ </a></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/resources/animation-resource.html">Animation</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/resources/color-list-resource.html">Color State List</a></li>
@@ -147,11 +147,11 @@
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/data/data-storage.html">
<span class="en">Data Storage</span>
- </a> <span class="new">new!</span></div>
+ </a></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/data/backup.html">
<span class="en">Data Backup</span>
- </a> <span class="new">new!</span>
+ </a>
</li>
</ul>
</li>
@@ -220,9 +220,16 @@
<li><a style="color:gray;">Accelerometer</a></li>
</ul>
</li> -->
- <li><a href="<?cs var:toroot ?>guide/topics/location/index.html">
- <span class="en">Location and Maps</span>
- </a></li>
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>guide/topics/location/index.html">
+ <span class="en">Location and Maps</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>guide/topics/location/obtaining-user-location.html">
+ <span class="en">Obtaining User Location</span>
+ </a></li>
+ </ul>
+ </li>
<!--<li class="toggle-list">
<div><a style="color:gray;">Wireless Controls</a></div>
<ul>
@@ -239,7 +246,7 @@
<li class="toggle-list">
<div><a href="<?cs var:toroot?>guide/topics/search/index.html">
<span class="en">Search</span>
- </a> <span class="new">new!</span></div>
+ </a></div>
<ul>
<li><a href="<?cs var:toroot?>guide/topics/search/search-dialog.html">Using the Android Search Dialog</a></li>
<li><a href="<?cs var:toroot?>guide/topics/search/adding-recent-query-suggestions.html">Adding Recent Query Suggestions</a></li>
@@ -247,9 +254,45 @@
<li><a href="<?cs var:toroot?>guide/topics/search/searchable-config.html">Searchable Configuration</a></li>
</ul>
</li>
- <li><a href="<?cs var:toroot?>guide/topics/testing/testing_android.html">
- <span class="en">Testing and Instrumentation</span></a>
- <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot?>guide/topics/admin/device-admin.html">
+ <span class="en">Device Administration</span>
+ </a> <span class="new">new!</span>
+ </li>
+ <li class="toggle-list">
+ <div>
+ <a href="<?cs var:toroot?>guide/topics/testing/index.html">
+ <span class="en">Testing</span>
+ </a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot?>guide/topics/testing/testing_android.html">
+ <span class="en">Testing Fundamentals</span></a>
+ <span class="new">new!</span>
+ </li>
+ <li>
+ <a href="<?cs var:toroot?>guide/topics/testing/activity_testing.html">
+ <span class="en">Activity Testing</span></a>
+ <span class="new">new!</span>
+ </li>
+ <li>
+ <a href="<?cs var:toroot?>guide/topics/testing/contentprovider_testing.html">
+ <span class="en">Content Provider Testing</span></a>
+ <span class="new">new!</span>
+ </li>
+ <li>
+ <a href="<?cs var:toroot?>guide/topics/testing/service_testing.html">
+ <span class="en">Service Testing</span></a>
+ <span class="new">new!</span>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>guide/topics/testing/what_to_test.html">
+ <span class="en">What To Test</span></a>
+ <span class="new">new!</span>
+ </li>
+
+ </ul>
+ </li>
</ul>
</li>
@@ -296,18 +339,19 @@
<div>
<a href="<?cs var:toroot ?>guide/developing/testing/index.html">
<span class="en">Testing</span>
- </a> <span class="new">new!</span>
+ </a>
</div>
<ul>
<li>
<a href="<?cs var:toroot ?>guide/developing/testing/testing_eclipse.html">
<span class="en">Testing in Eclipse, with ADT</span>
- </a> <span class="new">new!</span>
+ </a>
</li>
+
<li>
<a href="<?cs var:toroot ?>guide/developing/testing/testing_otheride.html">
<span class="en">Testing in Other IDEs</span>
- </a> <span class="new">new!</span>
+ </a>
</li>
</ul>
</li>
@@ -322,8 +366,7 @@
<!--<li><a href="<?cs var:toroot ?>guide/developing/tools/adt.html">ADT Plugin</a></li>-->
<li><a href="<?cs var:toroot ?>guide/developing/tools/aidl.html">aidl</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/avd.html">AVDs</a></li>
- <li><a href="<?cs var:toroot ?>guide/developing/tools/bmgr.html">bmgr</a>
- <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>guide/developing/tools/bmgr.html">bmgr</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/ddms.html">ddms</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/othertools.html#dx">dx</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/draw9patch.html">Draw 9-Patch</a></li>
@@ -332,6 +375,35 @@
<li><a href="<?cs var:toroot ?>guide/developing/tools/layoutopt.html">layoutopt</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/othertools.html#mksdcard">mksdcard</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/monkey.html">Monkey</a></li>
+ <li class="toggle-list">
+ <div>
+ <a href="<?cs var:toroot?>guide/developing/tools/monkeyrunner_concepts.html">
+ <span class="en">monkeyrunner</span>
+ </a>
+ <span class="new">new!</span>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot?>guide/developing/tools/MonkeyDevice.html">
+ <span class="en">MonkeyDevice</span>
+ </a>
+ <span class="new">new!</span>
+ </li>
+ <li>
+ <a href="<?cs var:toroot?>guide/developing/tools/MonkeyImage.html">
+ <span class="en">MonkeyImage</span>
+ </a>
+ <span class="new">new!</span>
+ </li>
+ <li>
+ <a href="<?cs var:toroot?>guide/developing/tools/MonkeyRunner.html">
+ <span class="en">MonkeyRunner</span>
+ </a>
+ <span class="new">new!</span>
+ </li>
+ </ul>
+ </li>
+ <li><a href="<?cs var:toroot ?>guide/developing/tools/proguard.html">Proguard</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/adb.html#sqlite">sqlite3</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/traceview.html" >Traceview</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/zipalign.html" >zipalign</a></li>
@@ -371,6 +443,9 @@
<span class="zh-CN" style="display:none">应用程序版本控制</span>
<span class="zh-TW" style="display:none">應用程式版本設定</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>guide/publishing/licensing.html">
+ <span class="en">Licensing Your Applications</span>
+ </a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>guide/publishing/preparing.html">
<span class="en">Preparing to Publish</span>
<span class="de" style="display:none">Vorbereitung auf die Veröffentlichung</span>
@@ -400,7 +475,7 @@
<ul>
<li><a href="<?cs var:toroot ?>guide/practices/compatibility.html">
<span class="en">Compatibility</span>
- </a><span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>guide/practices/screens_support.html">
<span class="en">Supporting Multiple Screens</span>
</a></li>
@@ -438,6 +513,28 @@
</li>
<li>
+ <h2><span class="en">Web Applications</span>
+ </h2>
+ <ul>
+ <li><a href="<?cs var:toroot ?>guide/webapps/index.html">
+ <span class="en">Web Apps Overview</span>
+ </a> <span class="new">new!</span><!-- 11/1/10 --></li>
+ <li><a href="<?cs var:toroot ?>guide/webapps/targeting.html">
+ <span class="en">Targeting Screens from Web Apps</span>
+ </a> <span class="new">new!</span><!-- 11/1/10 --></li>
+ <li><a href="<?cs var:toroot ?>guide/webapps/webview.html">
+ <span class="en">Building Web Apps in WebView</span>
+ </a> <span class="new">new!</span><!-- 11/1/10 --></li>
+ <li><a href="<?cs var:toroot ?>guide/webapps/debugging.html">
+ <span class="en">Debugging Web Apps</span>
+ </a> <span class="new">new!</span><!-- 11/1/10 --></li>
+ <li><a href="<?cs var:toroot ?>guide/webapps/best-practices.html">
+ <span class="en">Best Practices for Web Apps</span>
+ </a> <span class="new">new!</span><!-- 11/1/10 --></li>
+ </ul>
+ </li>
+
+ <li>
<h2><span class="en">Appendix</span>
<span class="de" style="display:none">Anhang</span>
<span class="es" style="display:none">Apéndice</span>
@@ -453,10 +550,10 @@
</a></li>
<li><a href="<?cs var:toroot ?>guide/appendix/market-filters.html">
<span class="en">Market Filters</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>guide/appendix/install-location.html">
<span class="en">App Install Location</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>guide/appendix/media-formats.html">
<span class="en">Supported Media Formats</span>
</a></li>
diff --git a/docs/html/guide/practices/design/performance.jd b/docs/html/guide/practices/design/performance.jd
index f22d2d3..f5588ac 100644
--- a/docs/html/guide/practices/design/performance.jd
+++ b/docs/html/guide/practices/design/performance.jd
@@ -1,6 +1,30 @@
page.title=Designing for Performance
@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#intro">Introduction</a></li>
+ <li><a href="#optimize_judiciously">Optimize Judiciously</a></li>
+ <li><a href="#object_creation">Avoid Creating Objects</a></li>
+ <li><a href="#myths">Performance Myths</a></li>
+ <li><a href="#prefer_static">Prefer Static Over Virtual</a></li>
+ <li><a href="#internal_get_set">Avoid Internal Getters/Setters</a></li>
+ <li><a href="#use_final">Use Static Final For Constants</a></li>
+ <li><a href="#foreach">Use Enhanced For Loop Syntax</a></li>
+ <li><a href="#avoid_enums">Avoid Enums Where You Only Need Ints</a></li>
+ <li><a href="#package_inner">Use Package Scope with Inner Classes</a></li>
+ <li><a href="#avoidfloat">Use Floating-Point Judiciously</a> </li>
+ <li><a href="#library">Know And Use The Libraries</a></li>
+ <li><a href="#native_methods">Use Native Methods Judiciously</a></li>
+ <li><a href="#closing_notes">Closing Notes</a></li>
+</ol>
+
+</div>
+</div>
+
<p>An Android application will run on a mobile device with limited computing
power and storage, and constrained battery life. Because of
this, it should be <em>efficient</em>. Battery life is one reason you might
@@ -8,24 +32,6 @@ want to optimize your app even if it already seems to run "fast enough".
Battery life is important to users, and Android's battery usage breakdown
means users will know if your app is responsible draining their battery.</p>
-<p>This document covers these topics: </p>
-<ul>
- <li><a href="#intro">Introduction</a></li>
- <li><a href="#optimize_judiciously">Optimize Judiciously</a></li>
- <li><a href="#object_creation">Avoid Creating Objects</a></li>
- <li><a href="#myths">Performance Myths</a></li>
- <li><a href="#prefer_static">Prefer Static Over Virtual</a></li>
- <li><a href="#internal_get_set">Avoid Internal Getters/Setters</a></li>
- <li><a href="#use_final">Use Static Final For Constants</a></li>
- <li><a href="#foreach">Use Enhanced For Loop Syntax</a></li>
- <li><a href="#avoid_enums">Avoid Enums Where You Only Need Ints</a></li>
- <li><a href="#package_inner">Use Package Scope with Inner Classes</a></li>
- <li><a href="#avoidfloat">Use Floating-Point Judiciously</a> </li>
- <li><a href="#library">Know And Use The Libraries</a></li>
- <li><a href="#native_methods">Use Native Methods Judiciously</a></li>
- <li><a href="#closing_notes">Closing Notes</a></li>
-</ul>
-
<p>Note that although this document primarily covers micro-optimizations,
these will almost never make or break your software. Choosing the right
algorithms and data structures should always be your priority, but is
@@ -42,188 +48,39 @@ outside the scope of this document.</p>
<h2 id="optimize_judiciously">Optimize Judiciously</h2>
-<p>As you get started thinking about how to design your application, and as
-you write it, consider
-the cautionary points about optimization that Josh Bloch makes in his book
-<em>Effective Java</em>. Here's "Item 47: Optimize Judiciously", excerpted from
-the latest edition of the book with permission. Although Josh didn't have
-Android application development in mind when writing this section &mdash; for
-example, the <code style="color:black">java.awt.Component</code> class
-referenced is not available in Android, and Android uses the
-Dalvik VM, rather than a standard JVM &mdash; his points are still valid. </p>
-
-<blockquote>
-
-<p>There are three aphorisms concerning optimization that everyone should know.
-They are perhaps beginning to suffer from overexposure, but in case you aren't
-yet familiar with them, here they are:</p>
-
-<div style="padding-left:3em;padding-right:4em;">
-
-<p style="margin-bottom:.5em;">More computing sins are committed in the name of
-efficiency (without necessarily achieving it) than for any other single
-reason&mdash;including blind stupidity.</p>
-<p>&mdash;William A. Wulf <span style="font-size:80%;"><sup>1</sup></span></p>
-
-<p style="margin-bottom:.5em;">We should forget about small efficiencies, say
-about 97% of the time: premature optimization is the root of all evil. </p>
-<p>&mdash;Donald E. Knuth <span style="font-size:80%;"><sup>2</sup></span></p>
-
-
-<p style="margin-bottom:.5em;">We follow two rules in the matter of optimization:</p>
-<ul style="margin-bottom:0">
-<li>Rule 1. Don't do it.</li>
-<li>Rule 2 (for experts only). Don't do it yet &mdash; that is, not until you have a
-perfectly clear and unoptimized solution. </li>
-</ul>
-<p>&mdash;M. A. Jackson <span style="font-size:80%;"><sup>3</sup></span></p>
-</div>
-
-<p>All of these aphorisms predate the Java programming language by two decades.
-They tell a deep truth about optimization: it is easy to do more harm than good,
-especially if you optimize prematurely. In the process, you may produce software
-that is neither fast nor correct and cannot easily be fixed.</p>
-
-<p>Don't sacrifice sound architectural principles for performance.
-<strong>Strive to write good programs rather than fast ones.</strong> If a good
-program is not fast enough, its architecture will allow it to be optimized. Good
-programs embody the principle of <em>information hiding</em>: where possible,
-they localize design decisions within individual modules, so individual
-decisions can be changed without affecting the remainder of the system (Item
-13).</p>
-
-<p>This does <em>not</em> mean that you can ignore performance concerns until
-your program is complete. Implementation problems can be fixed by later
-optimization, but pervasive architectural flaws that limit performance can be
-impossible to fix without rewriting the system. Changing a fundamental facet of
-your design after the fact can result in an ill-structured system that is
-difficult to maintain and evolve. Therefore you must think about performance
-during the design process.</p>
-
-<p><strong>Strive to avoid design decisions that limit performance.</strong> The
-components of a design that are most difficult to change after the fact are
-those specifying interactions between modules and with the outside world. Chief
-among these design components are APIs, wire-level protocols, and persistent
-data formats. Not only are these design components difficult or impossible to
-change after the fact, but all of them can place significant limitations on the
-performance that a system can ever achieve.</p>
-
-<p><strong>Consider the performance consequences of your API design
-decisions.</strong> Making a public type mutable may require a lot of needless
-defensive copying (Item 39). Similarly, using inheritance in a public class
-where composition would have been appropriate ties the class forever to its
-superclass, which can place artificial limits on the performance of the subclass
-(Item 16). As a final example, using an implementation type rather than an
-interface in an API ties you to a specific implementation, even though faster
-implementations may be written in the future (Item 52).</p>
-
-<p>The effects of API design on performance are very real. Consider the <code
-style="color:black">getSize</code> method in the <code
-style="color:black">java.awt.Component</code> class. The decision that this
-performance-critical method was to return a <code
-style="color:black">Dimension</code> instance, coupled with the decision that
-<code style="color:black">Dimension</code> instances are mutable, forces any
-implementation of this method to allocate a new <code
-style="color:black">Dimension</code> instance on every invocation. Even though
-allocating small objects is inexpensive on a modern VM, allocating millions of
-objects needlessly can do real harm to performance.</p>
-
-<p>In this case, several alternatives existed. Ideally, <code
-style="color:black">Dimension</code> should have been immutable (Item 15);
-alternatively, the <code style="color:black">getSize</code> method could have
-been replaced by two methods returning the individual primitive components of a
-<code style="color:black">Dimension</code> object. In fact, two such methods
-were added to the Component API in the 1.2 release for performance reasons.
-Preexisting client code, however, still uses the <code
-style="color:black">getSize</code> method and still suffers the performance
-consequences of the original API design decisions.</p>
-
-<p>Luckily, it is generally the case that good API design is consistent with
-good performance. <strong>It is a very bad idea to warp an API to achieve good
-performance.</strong> The performance issue that caused you to warp the API may
-go away in a future release of the platform or other underlying software, but
-the warped API and the support headaches that come with it will be with you for
-life.</p>
-
-<p>Once you've carefully designed your program and produced a clear, concise,
-and well-structured implementation, <em>then</em> it may be time to consider
-optimization, assuming you're not already satisfied with the performance of the
-program.</p>
-
-<p>Recall that Jackson's two rules of optimization were "Don't do it," and "(for
-experts only). Don't do it yet." He could have added one more: <strong>measure
-performance before and after each attempted optimization.</strong> You may be
-surprised by what you find. Often, attempted optimizations have no measurable
-effect on performance; sometimes, they make it worse. The main reason is that
-it's difficult to guess where your program is spending its time. The part of the
-program that you think is slow may not be at fault, in which case you'd be
-wasting your time trying to optimize it. Common wisdom says that programs spend
-80 percent of their time in 20 percent of their code.</p>
-
-<p>Profiling tools can help you decide where to focus your optimization efforts.
-Such tools give you runtime information, such as roughly how much time each
-method is consuming and how many times it is invoked. In addition to focusing
-your tuning efforts, this can alert you to the need for algorithmic changes. If
-a quadratic (or worse) algorithm lurks inside your program, no amount of tuning
-will fix the problem. You must replace the algorithm with one that is more
-efficient. The more code in the system, the more important it is to use a
-profiler. It's like looking for a needle in a haystack: the bigger the haystack,
-the more useful it is to have a metal detector. The JDK comes with a simple
-profiler and modern IDEs provide more sophisticated profiling tools.</p>
-
-<p>The need to measure the effects of attempted optimization is even greater on
-the Java platform than on more traditional platforms, because the Java
-programming language does not have a strong <em>performance model</em>. The
-relative costs of the various primitive operations are not well defined. The
-"semantic gap" between what the programmer writes and what the CPU executes is
-far greater than in traditional statically compiled languages, which makes it
-very difficult to reliably predict the performance consequences of any
-optimization. There are plenty of performance myths floating around that turn
-out to be half-truths or outright lies.</p>
-
-<p>Not only is Java's performance model ill-defined, but it varies from JVM
-implementation to JVM implementation, from release to release, and from
-processor to processor. If you will be running your program on multiple JVM
-implementations or multiple hardware platforms, it is important that you measure
-the effects of your optimization on each. Occasionally you may be forced to make
-trade-offs between performance on different JVM implementations or hardware
-platforms.</p>
-
-<p>To summarize, do not strive to write fast programs &mdash; strive to write
-good ones; speed will follow. Do think about performance issues while you're
-designing systems and especially while you're designing APIs, wire-level
-protocols, and persistent data formats. When you've finished building the
-system, measure its performance. If it's fast enough, you're done. If not,
-locate the source of the problems with the aid of a profiler, and go to work
-optimizing the relevant parts of the system. The first step is to examine your
-choice of algorithms: no amount of low-level optimization can make up for a poor
-choice of algorithm. Repeat this process as necessary, measuring the performance
-after every change, until you're satisfied.</p>
-
-<p>&mdash;Excerpted from Josh Bloch's <em>Effective Java</em>, Second Ed.
-(Addison-Wesley, 2008).</em></p>
-
-<p style="font-size:80%;margin-bottom:0;"><sup>1</sup> Wulf, W. A Case Against
-the GOTO. <em>Proceedings of the 25th ACM National
-Conference</em> 2 (1972): 791–797.</p>
-<p style="font-size:80%;margin-bottom:0;"><sup>2</sup> Knuth, Donald. Structured
-Programming with go to Statements. <em>Computing
-Surveys 6</em> (1974): 261–301.</p>
-<p style="font-size:80%"><sup>3</sup> Jackson, M. A. <em>Principles of Program
-Design</em>, Academic Press, London, 1975.
-ISBN: 0123790506.</p>
-
-</blockquote>
-
-<p>One of the trickiest problems you'll face when micro-optimizing Android
-apps is that the "if you will be running your program on ... multiple hardware
-platforms" clause above is always true. And it's not even generally the case
-that you can say "device X is a factor F faster/slower than device Y".
-This is especially true if one of the devices is the emulator, or one of the
-devices has a JIT. If you want to know how your app performs on a given device,
-you need to test it on that device. Drawing conclusions from the emulator is
-particularly dangerous, as is attempting to compare JIT versus non-JIT
-performance: the performance <em>profiles</em> can differ wildly.</p>
+<p>This document is about Android-specific micro-optimization, so it assumes
+that you've already used profiling to work out exactly what code needs to be
+optimized, and that you already have a way to measure the effect (good or bad)
+of any changes you make. You only have so much engineering time to invest, so
+it's important to know you're spending it wisely.
+
+<p>(See <a href="#closing_notes">Closing Notes</a> for more on profiling and
+writing effective benchmarks.)
+
+<p>This document also assumes that you made the best decisions about data
+structures and algorithms, and that you've also considered the future
+performance consequences of your API decisions. Using the right data
+structures and algorithms will make more difference than any of the advice
+here, and considering the performance consequences of your API decisions will
+make it easier to switch to better implementations later (this is more
+important for library code than for application code).
+
+<p>(If you need that kind of advice, see Josh Bloch's <em>Effective Java</em>,
+item 47.)</p>
+
+<p>One of the trickiest problems you'll face when micro-optimizing an Android
+app is that your app is pretty much guaranteed to be running on multiple
+hardware platforms. Different versions of the VM running on different
+processors running at different speeds. It's not even generally the case
+that you can simply say "device X is a factor F faster/slower than device Y",
+and scale your results from one device to others. In particular, measurement
+on the emulator tells you very little about performance on any device. There
+are also huge differences between devices with and without a JIT: the "best"
+code for a device with a JIT is not always the best code for a device
+without.</p>
+
+<p>If you want to know how your app performs on a given device, you need to
+test on that device.</p>
<a name="object_creation"></a>
<h2>Avoid Creating Objects</h2>
@@ -566,3 +423,11 @@ of its way to do the hard work for you, and even detect some cases where you're
not measuring what you think you're measuring (because, say, the VM has
managed to optimize all your code away). We highly recommend you use Caliper
to run your own microbenchmarks.</p>
+
+<p>You may also find
+<a href="{@docRoot}guide/developing/tools/traceview.html">Traceview</a> useful
+for profiling, but it's important to realize that it currently disables the JIT,
+which may cause it to misattribute time to code that the JIT may be able to win
+back. It's especially important after making changes suggested by Traceview
+data to ensure that the resulting code actually runs faster when run without
+Traceview.
diff --git a/docs/html/guide/practices/design/responsiveness.jd b/docs/html/guide/practices/design/responsiveness.jd
index 8a4e7cf..a00e3aa 100644
--- a/docs/html/guide/practices/design/responsiveness.jd
+++ b/docs/html/guide/practices/design/responsiveness.jd
@@ -1,13 +1,44 @@
page.title=Designing for Responsiveness
@jd:body
-<p>It's possible to write code that wins every performance test in the world, but still sends users in a fiery rage when they try to use the application. These are the applications that aren't <em>responsive</em> enough &mdash; the ones that feel
-sluggish, hang or freeze for significant periods, or take too long to process
-input. </p>
+<div id="qv-wrapper">
+<div id="qv">
-<p>In Android, the system guards against applications that are insufficiently responsive for a period of time by displaying a dialog to the user, called the Application Not Responding (ANR) dialog. The user can choose to let the application continue, but the user won't appreciate having to act on this dialog every time he or she uses your application. So it's important to design responsiveness into your application, so that the system never has cause to display an ANR to the user. </p>
+<h2>In this document</h2>
+<ol>
+ <li><a href="#anr">What Triggers ANR?</a></li>
+ <li><a href="#avoiding">How to Avoid ANR</a></li>
+ <li><a href="#reinforcing">Reinforcing Responsiveness</a></li>
+</ol>
-<p>Generally, the system displays an ANR if an application cannot respond to user input. For example, if an application blocks on some I/O operation (frequently a network access), then the main application thread won't be able to process incoming user input events. After a time, the system concludes that the application has hung, and displays the ANR to give the user the option to kill it.
+</div>
+</div>
+
+<div class="figure">
+<img src="{@docRoot}images/anr.png" alt="Screenshot of ANR dialog box" width="240" height="320"/>
+<p><strong>Figure 1.</strong> An ANR dialog displayed to the user.</p>
+</div>
+
+<p>It's possible to write code that wins every performance test in the world,
+but still sends users in a fiery rage when they try to use the application.
+These are the applications that aren't <em>responsive</em> enough &mdash; the
+ones that feel sluggish, hang or freeze for significant periods, or take too
+long to process input. </p>
+
+<p>In Android, the system guards against applications that are insufficiently
+responsive for a period of time by displaying a dialog to the user, called the
+Application Not Responding (ANR) dialog, shown at right in Figure 1. The user
+can choose to let the application continue, but the user won't appreciate having
+to act on this dialog every time he or she uses your application. It's critical
+to design responsiveness into your application, so that the system never has
+cause to display an ANR dialog to the user. </p>
+
+<p>Generally, the system displays an ANR if an application cannot respond to
+user input. For example, if an application blocks on some I/O operation
+(frequently a network access), then the main application thread won't be able to
+process incoming user input events. After a time, the system concludes that the
+application is frozen, and displays the ANR to give the user the option to kill
+it. </p>
<p>Similarly, if your application spends too much time building an elaborate in-memory
structure, or perhaps computing the next move in a game, the system will
@@ -15,31 +46,17 @@ conclude that your application has hung. It's always important to make
sure these computations are efficient using the techniques above, but even the
most efficient code still takes time to run.</p>
-<p>In both of these cases, the fix is usually to create a child thread, and do
+<p>In both of these cases, the recommended approach is to create a child thread and do
most of your work there. This keeps the main thread (which drives the user
-interface event loop) running, and prevents the system from concluding your code
+interface event loop) running and prevents the system from concluding that your code
has frozen. Since such threading usually is accomplished at the class
level, you can think of responsiveness as a <em>class</em> problem. (Compare
this with basic performance, which was described above as a <em>method</em>-level
concern.)</p>
-<div class="sidebox-wrapper">
-<div class="sidebox">
-<img src="{@docRoot}images/anr.png" width="240" height="320" alt="Screenshot of ANR dialog box">
-<p style="margin-top:.5em;padding:.5em;">An ANR dialog displayed to the user.</p>
-</div>
-</div>
-
-<p>This document discusses how the Android system determines whether an application is
-not responding and provides guidelines for
-ensuring that your application is responsive. </p>
-
-<p>This document covers these topics: </p>
-<ul>
- <li><a href="#anr">What Triggers ANR?</a></li>
- <li><a href="#avoiding">How to Avoid ANR</a></li>
- <li><a href="#reinforcing">Reinforcing Responsiveness</a></li>
-</ul>
+<p>This document describes how the Android system determines whether an
+application is not responding and provides guidelines for ensuring that your
+application stays responsive. </p>
<h2 id="anr">What Triggers ANR?</h2>
@@ -48,8 +65,10 @@ and Window Manager system services. Android will display the ANR dialog
for a particular application when it detects one of the following
conditions:</p>
<ul>
- <li>No response to an input event (e.g. key press, screen touch) within 5 seconds</li>
- <li>A {@link android.content.BroadcastReceiver BroadcastReceiver} hasn't finished executing within 10 seconds</li>
+ <li>No response to an input event (e.g. key press, screen touch)
+ within 5 seconds</li>
+ <li>A {@link android.content.BroadcastReceiver BroadcastReceiver}
+ hasn't finished executing within 10 seconds</li>
</ul>
<h2 id="avoiding">How to Avoid ANR</h2>
@@ -80,6 +99,10 @@ responsive to input and thus avoid ANR dialogs caused by the 5 second input
event timeout. These same practices should be followed for any other threads
that display UI, as they are also subject to the same timeouts.</p>
+<p>You can use {@link android.os.StrictMode} to help find potentially
+long running operations such as network or database operations that
+you might accidentally be doing your main thread.</p>
+
<p>The specific constraint on IntentReceiver execution time emphasizes what
they were meant to do: small, discrete amounts of work in the background such
as saving a setting or registering a Notification. So as with other methods
diff --git a/docs/html/guide/practices/design/seamlessness.jd b/docs/html/guide/practices/design/seamlessness.jd
index a6c1641..dedc16f 100644
--- a/docs/html/guide/practices/design/seamlessness.jd
+++ b/docs/html/guide/practices/design/seamlessness.jd
@@ -1,6 +1,26 @@
page.title=Designing for Seamlessness
@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#drop">Don't Drop Data</a></li>
+ <li><a href="#expose">Don't Expose Raw Data</a></li>
+ <li><a href="#interrupt">Don't Interrupt the User</a></li>
+ <li><a href="#threads">Got a Lot to Do? Do it in a Thread</a></li>
+ <li><a href="#multiple-activities">Don't Overload a Single Activity Screen</a></li>
+ <li><a href="#themes">Extend System Themes</a></li>
+ <li><a href="#flexui">Design Your UI to Work with Multiple Screen Resolutions</a></li>
+ <li><a href="#network">Assume the Network is Slow</a></li>
+ <li><a href="#keyboard">Don't Assume Touchscreen or Keyboard</a></li>
+ <li><a href="#battery">Do Conserve the Device Battery</a></li>
+</ol>
+
+</div>
+</div>
+
<p>Even if your application is fast and responsive, certain design decisions can
still cause problems for users &mdash; because of unplanned interactions with
other applications or dialogs, inadvertent loss of data, unintended blocking,
@@ -42,20 +62,7 @@ system as just an even-larger federation of these components. This benefits you
by allowing you to integrate cleanly and seamlessly with other applications, and
so you should design your own code to return the favor.</p>
-<p>This document discusses common seamlessness problems and how to avoid them.
-It covers these topics: </p>
-<ul>
- <li><a href="#drop">Don't Drop Data</a></li>
- <li><a href="#expose">Don't Expose Raw Data</a></li>
- <li><a href="#interrupt">Don't Interrupt the User</a></li>
- <li><a href="#threads">Got a Lot to Do? Do it in a Thread</a></li>
- <li><a href="#multiple-activities">Don't Overload a Single Activity Screen</a></li>
- <li><a href="#themes">Extend System Themes</a></li>
- <li><a href="#flexui">Design Your UI to Work with Multiple Screen Resolutions</a></li>
- <li><a href="#network">Assume the Network is Slow</a></li>
- <li><a href="#keyboard">Don't Assume Touchscreen or Keyboard</a></li>
- <li><a href="#battery">Do Conserve the Device Battery</a></li>
-</ul>
+<p>This document discusses common seamlessness problems and how to avoid them.</p>
<h2 id="drop">Don't Drop Data</h2>
diff --git a/docs/html/guide/practices/screens_support.jd b/docs/html/guide/practices/screens_support.jd
index 2863fb2..7811d90 100644
--- a/docs/html/guide/practices/screens_support.jd
+++ b/docs/html/guide/practices/screens_support.jd
@@ -5,7 +5,7 @@ page.title=Supporting Multiple Screens
<div id="qv-wrapper">
<div id="qv">
- <h2>Multiple screens quickview: </h2>
+ <h2>Quickview</h2>
<ul>
<li>Android runs on devices that have different screen sizes and resolutions.</li>
<li>The screen on which your application is displayed can affect its user interface.</li>
@@ -35,7 +35,9 @@ page.title=Supporting Multiple Screens
<ol>
<li><code><a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></code></li>
<li><code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt;</a></code></li>
- <li><a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">Alternative Resources</a></li>
+ <li><a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
+Providing Alternative Resources</a></li>
<li><a href="{@docRoot}guide/developing/tools/avd.html">Android Virtual Devices</a></li>
</ol>
@@ -53,7 +55,7 @@ sizes and resolutions. </p>
<p>This document explains the screens-support features provided by the platform
and how you use them in your application. By following the practices described
here, you can easily create an application that displays properly on all
-supported device screens and that you can deploy to any device as a single .apk.
+supported device screens and that you can deploy to any device as a single {@code .apk}.
</p>
<p>If you have already developed and published an application for Android 1.5 or
@@ -63,10 +65,16 @@ and that are running Android 1.6 or later. In most cases, only minor adjustments
are needed, however you should make sure to <a href="#testing">test your
application</a> on all supported screens. </p>
+<p>Starting in Android 2.2, the platform includes support for extra high density screens
+(<em>xhdpi</em>), and starting in Android 2.3, the platform includes support for extra large screens
+(<em>xlarge</em>). If you've already followed the guidance in this document to support all other
+screen types, you should consider providing additional support for <em>xhdpi</em> and
+<em>xlarge</em> screens.</p>
+
<p>In particular, if you have an existing application that you would like to
-make available for users of devices with small screens (such as QVGA), please
-see <a href="#strategies">Strategies for Legacy Applications</a> for more
-information about how to do that. </p>
+make available on small screens (such as QVGA) or for which you would like to provide better support
+for extra large screens, please see <a href="#strategies">Strategies for Legacy Applications</a> for
+more information about how to do that. </p>
<h2 id="overview">Overview of Screens Support</h2>
@@ -82,11 +90,11 @@ screen-compatibility features.</p>
<dl>
<dt><em>Screen size</em></dt>
- <dd>Actual physical size, measured as the screen's diagonal.
+ <dd>Actual physical size, measured as the screen's diagonal.
- <p>For simplicity, Android collapses all actual screen sizes into three
-generalized sizes: large, normal, and small. Applications can provide custom
-layouts for each of these three sizes &mdash; the platform transparently handles
+ <p>For simplicity, Android collapses all actual screen sizes into four
+generalized sizes: small, normal, large, and extra large. Applications can provide custom
+layouts for each of these four sizes &mdash; the platform transparently handles
the rendering of the layouts at the actual screen size.</p></dd>
<dt><em>Aspect ratio</em></dt>
@@ -110,78 +118,106 @@ sometimes significantly more &mdash; pixels spread across the same area. The
density of a screen is important because, other things being equal, a UI element
(such as a button) whose height and width are defined in terms of screen pixels
will appear larger on the lower density screen and smaller on the higher density
-screen. </p>
+screen.</p>
- <p>For simplicity, Android collapses all actual screen densities into three
-generalized densities: high, medium, and low. Applications can provide custom
-resources for each of these three densities &mdash; the platform handles the
-scaling of the resources up or down to meet the actual screen density. </p></dd>
-<dt><em>Density-independent pixel (dip)</em></dt>
+ <p>For simplicity, Android collapses all actual screen densities into four
+generalized densities: low, medium, large, and extra large. Applications can provide custom
+resources for each of these densities &mdash; the platform handles any necessary
+scaling of the resources up or down to meet the specific screen density. </p></dd>
+<dt><em>Density-independent pixel (dp)</em></dt>
<dd>A virtual pixel unit that applications can use in defining their UI, to
-express layout dimensions or position in a density-independent way.
+express layout dimensions or position in a density-independent way.
<p>The density-independent pixel is equivalent to one physical pixel on a 160
dpi screen, the baseline density assumed by the platform (as described later in
this document). At run time, the platform transparently handles any scaling of
-the dip units needed, based on the actual density of the screen in use. The
-conversion of dip units to screen pixels is simple: <code>pixels = dips *
-(density / 160)</code>. For example, on 240 dpi screen, 1 dip would equal 1.5
-physical pixels. Using dip units to define your application's UI is highly
+the dp units needed, based on the actual density of the screen in use. The
+conversion of dp units to screen pixels is simple: <nobr><code>pixels = dps *
+(density / 160)</code></nobr>. For example, on 240 dpi screen, 1 dp would equal 1.5
+physical pixels. Using dp units to define your application's UI is highly
recommended, as a way of ensuring proper display of your UI on different
screens. </p></dd>
</dl>
-<h3 id="range">Range of Screens Supported</h3>
+<h3 id="range">Range of screens supported</h3>
-<p>Android 1.5 and earlier versions of the platform were designed to support a
-single screen configuration &mdash; HVGA (320x480) resolution on a 3.2" screen.
-Because the platform targeted just one screen, application developers could
-write their applications specifically for that screen, without needing to worry
-about how their applications would be displayed on other screens. </p>
-
-<p>Starting from Android 1.6, the platform adds support for multiple screen
+<p>Starting from Android 1.6, the platform provides support for multiple screen
sizes and resolutions, reflecting the many new types and sizes of devices on
-which the platform will run. This means that developers must design their
-applications for proper display on a range of devices and screens.</p>
+which the platform runs. If you are developing an application that will run
+on Android 1.6 or later, you can use the compatibility features of the Android
+platform to ensure that your application UI renders properly across the range of
+supported screen sizes and resolutions.</p>
-<p>To simplify the way application developers design their user interfaces for
-multiple devices, and to allow more devices to participate without impacting
+<p>To simplify the way that developers design their user interfaces for
+multiple devices and to allow more devices to participate without affecting
applications, the platform divides the range of actual supported screen sizes
and resolutions into:</p>
<ul>
-<li>A set of three generalized sizes: <em>large</em>, <em>normal</em>, and <em>small</em>, and </li>
-<li>A set of three generalized densities: high (<em>hdpi</em>), medium (<em>mdpi</em>), and low (<em>ldpi</em>)
+<li>A set of four generalized sizes: <em>small</em>, <em>normal</em>, <em>large</em>,
+and <em>xlarge</em></em>
+<li>A set of four generalized densities: <em>ldpi</em> (low), <em>mdpi</em> (medium),
+<em>hdpi</em> (high), and <em>xhdpi</em> (extra high)
</ul>
-<!--<p>Applications use to these generalized sizesThe to let you apply custom UI
-and enable/disable functionality according to the generalized class of screen,
-rather than by the specific screen. When you are developing your application,
-you use these generalized sizes and densities and Applications can use these
-generalized sizes and densities to tell the platform I will do it or you do it.
-Or a combination of both. -->
+<p class="note"><strong>Note:</strong> The <code>xhdpi</code> density category was added in
+Android 2.2 (API Level 8). The <em>xlarge</em> size category was added in Android 2.3 (API Level
+9).</p>
<p>Applications can provide custom resources (primarily layouts) for any of the
-three generalized sizes, if needed, and they can also provide resources
-(primarily drawables such as images) for any of the three generalized densities.
-Applications do not need to work with the actual physical size or density of the
-device screen. At run time, the platform handles the loading of the correct size
-or density resources, based on the generalized size or density of the current
-device screen, and adapts them to the actual pixel map of the screen.</p>
-
-<p>The table below lists some of the more common screens supported
-by Android and illustrates how the platform maps them to generalized screen
-configurations. Some devices use screens that are not specifically listed
-in the table &mdash; the platform maps those to the same set generalized
-screen configurations. </p>
-
-<p class="table-caption" id="screens-table"><strong>Table 1.</strong> Examples of
-device screens supported by Android.</p>
-
- <table id="screens-table" width="80%" style="margin-top:2em;">
+four generalized sizes and can provide resources (primarily drawables such as
+images) for any of the four generalized densities. Applications do not need to
+work with the actual physical size or density of the device screen. At run time,
+the platform handles the loading of the correct size or density resources, based
+on the generalized size or density of the current device screen, and adapts them
+to the actual pixel map of the screen.</p>
+
+<p>The generalized size/density configurations are arranged around a
+baseline configuration that is assigned a size of <em>normal</em> and a density of
+<em>mdpi</em> (medium). All applications written for Android 1.5 or earlier are (by
+definition) designed for the baseline HVGA screen used on the T-Mobile G1 and
+similar devices, which is size <em>normal</em> and density
+<em>mdpi</em>.</p>
+
+<p>Each generalized screen configuration spans a range of actual screen
+densities and physical sizes. For example, that means that multiple devices that
+report a screen size of <em>normal</em> might offer screens that differ slightly
+in actual size or aspect ratio. Similarly, devices that report a screen density
+of <em>hdpi</em> might offer screens with slightly different pixel densities.
+The platform makes these differences abstract, however &mdash; applications can
+offer UI designed for the generalized sizes and densities and let the system
+handle the actual rendering of the UI on the current device screen according to
+its characteristics. </p>
+
+
+<img src="{@docRoot}images/screens_support/screens-ranges.png" />
+<p class="img-caption"><strong>Figure 1.</strong>
+Illustration of how the Android platform maps actual screen densities and sizes
+to generalized density and size configurations. </p>
+
+<p>Although the platform lets your application provide layouts and resources for
+generalized size-density configurations, you do not necessarily need to do write
+custom code or provide custom resources for each of the nine supported
+configurations. The platform provides robust compatibility features, described
+in the sections below, that can handle most of the work of rendering your
+application on any device screen, provided that you've implemented your
+application UI properly. For more information about how to implement a UI that
+renders properly across device screens and platform versions, see
+<a href="#screen-independence">Best Practices for Screen Independence</a>.</p>
+
+<p>To help you test your applications, the Android SDK includes emulator skins
+that replicate the sizes and densities of actual device screens on which your
+application is likely to run. You can also modify the default size and density
+of the emulator skins to replicate the characteristics of any specific
+screen.</p>
+
+<p class="table-caption" id="screens-table"><strong>Table 1.</strong> Screen
+sizes and densities of emulator skins included in the Android SDK.</p>
+
+ <table id="screens-table">
<tbody>
<tr>
- <td></td>
+ <td style="border:none"></td>
<td style="background-color:#f3f3f3">
<nobr>Low density (120), <em>ldpi</em></nobr>
</td>
@@ -191,91 +227,59 @@ device screens supported by Android.</p>
<td style="background-color:#f3f3f3">
<nobr>High density (240), <em>hdpi</em><nobr>
</td>
+ <td style="background-color:#f3f3f3">
+ <nobr>Extra high density (320), <em>xhdpi</em><nobr>
+ </td>
</tr>
<tr>
<td style="background-color:#f3f3f3">
<em>Small</em> screen
</td>
- <td style="font-size:.9em;">
- <ul style="padding:0">
- <li style="margin: 0 0 0 1em;padding:.25em 0 0 0; font-size:.9em;">QVGA (240x320), <nobr>2.6"-3.0" diagonal</nobr></li>
- </ul>
+ <td style="font-size:.9em;">QVGA (240x320)</td>
</td>
<td></td>
<td></td>
+ <td></td>
</tr>
<tr>
<td style="background-color:#f3f3f3">
<em>Normal</em> screen
</td>
- <td style="font-size:.9em;">
- <ul style="padding:0">
- <li style="margin: 0 0 0 1em;padding:.25em 0 0 0; font-size:.9em;">WQVGA (240x400), <nobr>3.2"-3.5" diagonal</nobr></li>
- <li style="margin: 0 0 0 1em;padding:.25em 0 0 0; font-size:.9em;">FWQVGA (240x432), <nobr>3.5"-3.8" diagonal</nobr></li>
- </ul>
- </td>
- <td style="font-size:.9em;background-color:#FFE;">
- <ul style="padding:0">
- <li style="margin: 0 0 0 1em;padding:.25em 0 0 0; font-size:.9em;">HVGA (320x480), <nobr>3.0"-3.5" diagonal</nobr></li>
- </ul>
- </td>
- <td style="font-size:.9em;">
- <ul style="padding:0">
- <li style="margin: 0 0 0 1em;padding:.25em 0 0 0; font-size:.9em;">WVGA (480x800), <nobr>3.3"-4.0" diagonal</nobr></li>
- <li style="margin: 0 0 0 1em;padding:.25em 0 0 0; font-size:.9em;">FWVGA (480x854), <nobr>3.5"-4.0" diagonal</nobr></li>
- </ul>
- </td>
+ <td style="font-size:.9em;">WQVGA400 (240x400)<br>WQVGA432 (240x432)</td>
+ <td style="font-size:.9em;">HVGA (320x480)</td>
+ <td style="font-size:.9em;">WVGA800 (480x800)<br>WVGA854 (480x854)</td>
+ <td style="font-size:.9em;"></td>
</tr>
<tr>
<td style="background-color:#f3f3f3">
<em>Large</em> screen
</td>
<td></td>
- <td style="font-size:.9em;">
- <ul style="padding:0">
- <li style="margin: 0 0 0 1em;padding:.25em 0 0 0; font-size:.9em;">WVGA (480x800), <nobr>4.8"-5.5" diagonal</nobr></li>
- <li style="margin: 0 0 0 1em;padding:.25em 0 0 0; font-size:.9em;">FWVGA (480x854), <nobr>5.0"-5.8" diagonal</nobr></li>
- </ul>
+ <td style="font-size:.9em;">WVGA800* (480x800)<br>WVGA854* (480x854)</td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td style="background-color:#f3f3f3">
+ <em>Extra Large</em> screen
</td>
<td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td colspan="4" style="border:none;font-size:90%;">* To emulate this
+ configuration, specify a custom density of 160 when
+ creating an AVD that uses a WVGA800 or WVGA854 skin.
+ </td>
</tr>
- </tbody>
- </table>
-
-<p class="caption" style="margin-top:1em;margin-bottom:1.5em;"> </p>
-
-<p>As shown above, the various screen configurations are arranged around a
-<em>baseline screen</em> that is assigned a size of "normal" and a density of
-"medium". The HVGA screen is used as the baseline because all applications
-written against Android 1.5 or earlier are (by definition) written for the HVGA
-screen used on the T-Mobile G1 and similar devices.</p>
-
-<!-- <p>Note that each screen configuration spans a range of actual resolutions
-and physical screen sizes. For example, the The baseline configuration spans a
-range of actual screen sizes &mdash; from 3.0" to 3.5" diagonal &mdash; all with
-the same HVGA resolution. That means that the actual pixel density of devices in
-a single screen configuration can vary. </p>
-
-Because differences in density can affect the displayed size of UI elements
-declared in pixels, the framework provides a density-independent pixel (dip)
-unit that applications can use to declare UI dimensions, letting the platform
-automatically handle the scaling to the actual pixel density of the screen. When
-UI dimensions are declared in dip, the result is that they are displayed at the
-same physical size on all screens in a given configuration. </p> -->
-
-<p>Although the platform currently supports the nine possible size-density
-configurations listed in the table, you do not necessarily need to create custom
-resources for each one of them. The platform provides robust compatibility
-features, described in the sections below, that can handle most of the work of
-rendering your application on the current device screen, provided that the UI is
-properly implemented. For more information, see <a
-href="#screen-independence">Best Practices for Screen Independence</a>.</p>
-
-<!--
-<p>For an overview of the relative numbers of high (hdpi), medium (mdpi), and
-low (ldpi) density screens, see the <a
-href="{@docRoot}guide/resources/dashboard/screen-densities.html">Screen Densities dashboard</a>.</p>
--->
+</table>
+
+<p>For an overview of the relative numbers of high (hdpi), medium (mdpi), and
+low (ldpi) density screens in Android-powered devices available now, see the <a
+href="{@docRoot}resources/dashboard/screens.html">Screen Sizes and Densities</a> dashboard.</p>
+
<h3 id="support">How Android supports multiple screens</h3>
@@ -288,9 +292,9 @@ resources at run time is based on the alternative resources framework.
<p> If you want to use size- or density-specific layouts or drawables in your
application and you are not familiar with resource qualifiers or how the
-platform uses them, please read
+platform uses them, please read
<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
-Alternative Resources</a>.
+Providing Alternative Resources</a>.
</div>
</div>
@@ -303,19 +307,20 @@ to use them:</p>
<ul>
<li>The platform supports a set of resource qualifiers that let you provide
-size- and density-specific resources, if needed. The qualifiers for
-size-specific resources are <code>large</code>, <code>normal</code>, and
-<code>small</code>, and those for density-specific resources are
-<code>hdpi</code> (high), <code>mdpi</code> (medium), and <code>ldpi</code>
-(low). The qualifiers correspond to the generalized densities given in
-<a href="#range">Table 1</a>, above.</li>
- <li>The platform also provides a
+size- and density-specific resources, if needed. The qualifiers for
+size-specific resources are <code>small</code>, <code>normal</code>, <code>large</code>, and
+<code>xlarge</code>. Those for density-specific resources are <code>ldpi</code>
+(low), <code>mdpi</code> (medium), <code>hdpi</code> (high), and <code>xhdpi</code> (extra high).
+The qualifiers correspond to the generalized densities described in
+<a href="#range">Range of screens supported</a>, above.</li>
+ <li>The platform also provides a
<a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">
<code>&lt;supports-screens&gt;</code></a>
manifest element, whose attributes
-<code>android:largeScreens</code>, <code>android:normalScreens</code>, and
-<code>android:smallScreens</code> let you specify what generalized screen sizes
-your application supports. A fourth attribute, <code>android:anyDensity</code>,
+<code>android:smallScreens</code>, <code>android:normalScreens</code>,
+<code>android:largeScreens</code>, and <code>android:xlargeScreens</code> let you specify what
+generalized screen sizes
+your application supports. Another attribute, <code>android:anyDensity</code>,
lets you indicate whether or not your application includes built-in support for
multiple densities.</li>
</ul>
@@ -325,7 +330,7 @@ application, to ensure the best possible display on the current device
screen:</p>
<ol>
-<li><em>Pre-scaling of resources (such as image assets)</em>
+<li><em>Pre-scaling of resources (such as image assets)</em>
<p>Based on the density of the current screen, the platform automatically
loads any size- or density-specific resources from your application and displays
@@ -370,18 +375,18 @@ lower-density screen, coordinates are scaled down.<p>
<p>For more information, see the <code>android:anyDensity</code> attribute in
<a href="#attrs">Manifest attributes for screens support</a>.</p></li>
-<div class="sidebox-wrapper" xstyle="margin-bottom:2em;margin-top:.5em;width:90%;">
- <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
- <div id="qv-sub-rule">
- <img src="{@docRoot}assets/images/icon_market.jpg" style="float:left;margin:0;padding:0;">
- <p style="color:#669999;">Publishing to Small Screen Devices</p>
+<div class="sidebox-wrapper" xstyle="margin-bottom:2em;margin-top:.5em;width:90%;">
+ <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
+ <div id="qv-sub-rule">
+ <img src="{@docRoot}assets/images/icon_market.jpg" style="float:left;margin:0;padding:0;">
+ <p style="color:#669999;">Publishing to Small Screen Devices</p>
<p>To ensure the best experience for users on small-screen devices, Android
Market only shows applications that explicitly declare support for small
screens. If you developed an application on Android 1.5 or earlier and published
it on Android Market, you need to <a href="#testing">test your application</a>
-on small screens and then upload an updated version that explicitly
+on small screens and then upload an updated version that explicitly
<a href="#attrs">indicates support for small screens</a>. </p>
- </div>
+ </div>
</div>
<li><em>Compatibility-mode display on larger screen-sizes</em>
@@ -400,7 +405,7 @@ of scaling the application, however, the application's 320x480 interface will be
placed as a "postage stamp" in the larger 480x800 screen.</p>
<p>For more information, see the <code>android:anyDensity</code> attribute in
-<a href="#attrs">Manifest elements for screens support</a> and the
+<a href="#attrs">Manifest elements for screens support</a> and the
<a href="#compatibility-examples">Screen-Compatibility Examples</a>
section.</p></li>
</ol>
@@ -441,7 +446,7 @@ does this in three ways: </p>
<ul>
<li>Through pre-scaling of drawable resources (scaled at resource loading
time)</li>
-<li>Through auto-scaling of density-independent pixel (dip) values used in
+<li>Through auto-scaling of density-independent pixel (dp) values used in
layouts</li>
<li>Through auto-scaling of absolute pixel values used in the application (only
needed if the application has set <code>android:anyDensity="false"</code> in its
@@ -457,30 +462,42 @@ different.</p>
<div id=vi09 style=TEXT-ALIGN:left>
<img src="{@docRoot}images/screens_support/dip.png" style="padding-bottom:0;margin-bottom:0;" />
<p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0
-1em;"><strong>Figure 1.</strong> Examples of density independence on WVGA high
+1em;"><strong>Figure 2.</strong> Examples of density independence on WVGA high
density (left), HVGA medium density (center), and QVGA low density (right). </p>
</div>
<p>In most cases, you can take advantage of density independence in your
application simply by making sure that your layouts specify all dimension values
-in density-independent pixels (<code>dip</code> or <code>dp</code>) or
+in density-independent pixels (<code>dp</code> or <code>dp</code>) or
scale-independent pixels (<code>sip</code> or <code>sp</code>, for text only).
If you are using absolute pixel values in the application and manifest includes
<a href="#attrs"><code>android:anyDensity="true"</code></a>, you will also need
-to scale the pixel values. See <a href="#dips-pels">Converting from dips to
-pixels</a> for more information. </p>
+to scale the pixel values. See <a href="#dips-pels">Converting dp units to
+pixel units</a> for more information. </p>
<h3 id="attrs">Manifest attributes for screens support</h3>
-<p> Android 1.6 introduced a new manifest element,
+<p> Android 1.6 introduced a new manifest element,
<a href="{@docRoot}guide/topics/manifest/supports-screens-element.html"><code>&lt;supports-screens&gt;</code></a>,
whose attributes you can use to control the
display of your application on different classes of device screens, as listed
-below. The <code>smallScreens</code>, <code>normalScreens</code>, and
-<code>largeScreens</code> attributes correspond to the generalized screen sizes
-shown in <a href="#range">Table 1</a>, earlier in this document.</p>
-
+in table 2. The <code>smallScreens</code>, <code>normalScreens</code>, <code>largeScreens</code> and
+<code>xlargeScreens</code> attributes correspond to the generalized screen sizes
+described in <a href="#range">Range of screens supported</a>, earlier in this
+document. Notice that the default values for each attribute vary, depending
+on your minimum and targeted platform, as indicated in the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+android:minSdkVersion}</a> and <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+android:targetSdkVersion}</a> attributes of your <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a>
+manifest element.</p>
+
+<p class="table-caption" id="table2"><strong>Table 2.</strong> Summary of attributes for the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+&lt;supports-screens&gt;}</a> manifest element, including default values based on platform
+version.</p>
<table id="vrr8">
<tr>
<th>
@@ -489,6 +506,14 @@ shown in <a href="#range">Table 1</a>, earlier in this document.</p>
<th >
Description
</th>
+ <th>
+ Default value, when<br><nobr><code>minSdkVersion</code> or</nobr>
+<code>targetSdkVersion</code> is 4 or lower
+ </th>
+ <th>
+ Default value, when<br><nobr><code>minSdkVersion</code> or</nobr>
+<code>targetSdkVersion</code> is 5 or higher
+ </th>
</tr>
<tr>
<td>
@@ -497,10 +522,10 @@ shown in <a href="#range">Table 1</a>, earlier in this document.</p>
<td>
Whether or not the application UI is designed for use on
<em>small</em> screens &mdash; "<code>true</code>" if it is, and
-"<code>false</code>" if not. See <a href="#defaults">Default values for
-attributes</a> for information about the assumed value of this attribute, if not
-declared.
+"<code>false</code>" if not. </p>
</td>
+<td>"<code>false</code>"</td>
+<td>"<code>true</code>"</td>
</tr>
<tr>
<td>
@@ -509,8 +534,10 @@ declared.
<td>
Whether or not the application UI is designed for use on
<em>normal</em> screens &mdash; "<code>true</code>" if it is, and
-"<code>false</code>" if not. The default value is "<code>true</code>".
+"<code>false</code>" if not. The default value is always "<code>true</code>".
</td>
+<td>"<code>true</code>"</td>
+<td>"<code>true</code>"</td>
</tr>
<tr>
<td>
@@ -519,10 +546,10 @@ declared.
<td>
Whether or not the application UI is designed for use on
<em>large</em> screens &mdash; "<code>true</code>" if it is, and
-"<code>false</code>" if not. See <a href="#defaults">Default values for
-attributes</a> for information about the assumed value of this attribute, if not
-declared.
+"<code>false</code>" if not.
</td>
+<td>"<code>false</code>"</td>
+<td>"<code>true</code>"</td>
</tr>
<tr>
<td>
@@ -535,9 +562,13 @@ in different density environments &mdash; "<code>true</code>" if so, and
<ul>
<li>If set to "<code>true</code>", the platform disables its
density-compatibility features for all screen densities &mdash; specifically,
-the auto-scaling of absolute pixel units and math &mdash; and relies on the
-application to use density-independent pixel units and/or to manage the
-adaptation of pixel values according to density of the current screen. </li>
+the auto-scaling of absolute pixel units (<code>px</code>) and math &mdash; and
+relies on the application to use density-independent pixel units
+(<code>dp</code>) and/or math to manage the adaptation of pixel values according
+to density of the current screen. That is, as long as your application uses
+density-independent units (dp) for screen layout sizes, then it will perform
+properly on different densities when this attribute is set to
+"<code>true</code>".</li>
<li>If set to "<code>false</code>", the platform enables its
density-compatibility features for all screen densities. In this case, the
@@ -546,98 +577,156 @@ which it can layout and draw its UI as though against a medium-density screen
(160). The platform then transparently auto-scales the application's pixel units
and math as needed to match the actual device screen density. </li>
</ul>
- <p>See <a href="#defaults">Default values for attributes</a> for
-information about the assumed value of this attribute, if not declared.</p>
+<p>Note that the setting of this attribute affects density-compatibility only.
+It does not affect size-compatibility features such as display on a virtual
+baseline screen.</p>
</td>
+<td>"<code>false</code>"</td>
+<td>"<code>true</code>"</td>
+ </tr>
+ <tr>
+ <td colspan="4"><strong>Note:</strong> Android 2.3 (API Level 9) introduced a new
+attribute for the <code>&lt;supports-screens&gt;</code> element: <code>xlargeScreens</code>, shown
+below. It works the same as the other screen attributes above, but, if neither your
+<code>minSdkVersion</code> or <code>targetSdkVersion</code> are set to "9", the default value is
+"false" when your application is installed on a device running Android 2.3.</td>
+ </tr>
+ <tr>
+ <th>
+ Attribute
+ </th>
+ <th >
+ Description
+ </th>
+ <th>
+ Default value, when<br><nobr><code>minSdkVersion</code> or</nobr>
+<code>targetSdkVersion</code> is 8 or lower
+ </th>
+ <th>
+ Default value, when<br><nobr><code>minSdkVersion</code> or</nobr>
+<code>targetSdkVersion</code> is 9 or higher
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <code>android:xlargeScreens</code>
+ </td>
+ <td>
+ Whether or not the application UI is designed for use on
+<em>xlarge</em> screens &mdash; "<code>true</code>" if it is, and
+"<code>false</code>" if not.
+ </td>
+<td>"<code>false</code>"</td>
+<td>"<code>true</code>"</td>
</tr>
</table>
<p>In general, when you declare a screen-size attribute
-(<code>smallScreens</code>, <code>normalScreens</code>, or
-<code>largeScreens</code>) as "true", you are signaling to the platform that
-your application wants to manage its UI by itself, for all screen sizes, without
-the platform applying any size-compatibility behaviors (such as a virtual HVGA
-display area). If you declare a screen-size attribute as "false", you are
-signaling that your application is not designed for that screen size. The
-effects are conditioned by the screen size that your application does not
-support:</p>
-
+(<code>smallScreens</code>, <code>normalScreens</code>, <code>largeScreens</code>, or
+<code>xlargeScreens</code>) as "<code>true</code>", you are signaling to the
+platform that your application is designed to render properly on that screen
+size. As a result, the platform does not apply any size-compatibility features
+(such as a virtual HVGA display area). If you declare a screen-size attribute as
+"<code>false</code>", you are signaling that your application is <em>not</em>
+designed for that screen size. In this case, the platform <em>does</em> apply
+size-compatibility features, rendering the application in an HVGA baseline
+display area. If the current screen is larger than <em>normal</em> size, the
+platform renders the application in a virtual HVGA screen on the larger screen.
+See <a href="#compatibility-examples">Screen-Compatibility Examples</a> for an
+illustration of what an application looks like when displayed in a virtual HVGA
+screen.</p>
+
+<p>In other words, setting a <code>&lt;supports-screens&gt;</code> attribute to
+"<code>false</code>" tells the platform to enable it's compatibility features
+when displaying the application on a screen of that size <em>or any larger
+size</em>, if also disallowed. Otherwise, the platform gives the application a
+normal display area that can use the full device screen area, if
+appropriate.</p>
+
+<p>Android Market also makes use of the <code>&lt;supports-screens&gt;</code>
+attributes. It uses them to filter the application from devices whose screens
+are not supported by the application. Specifically, Android Market considers an
+application compatible with a device if the application supports a screen that
+is the same or smaller than the current device screen. Android Market filters
+the application if it disallows the device's screen size and does not support a
+smaller size. In general, Android does not provide downward size-compatibility
+features for applications.</p>
+
+<p>Here are some examples:</p>
+
<ul>
- <li>If you declare <code>largeScreens="false"</code>, your application can
-still be installed by users of devices with large screens. When run on a device
-with a large screen, this attribute value causes the platform to run the
-application in compatibility mode, rendering it in a baseline screen area
-(normal size, medium density) reserved on the larger screen. See
-<a href="#compatibility-examples">Screen-Compatibility Examples</a> for an
-illustration of what an application looks like when displayed in compatibility
-mode.</li>
- <li>If you declare <code>smallScreens="false"</code>, your application can
-still be installed by users of devices with small screens. However, this
-attribute value causes Android Market to filter your application from the list
-of applications available to such users. In effect, this prevents users from
-installing the application on small-screen devices. </li>
+ <li>Assume that you declare <code>smallScreens="false" normalScreens="true"
+largeScreens="false" xlargeScreens="false"</code> in your application's manifest. <p>Although the
+application is not designed for display on large or extra large screens, the platform can still
+run it successfully in <a href="#compatibility-examples">screen-compatibility
+mode</a>. Android Market shows the application to devices with
+<em>normal</em>, <em>large</em>, and <em>xlarge</em> size screens, but does filter it from
+<em>small</em> size screens, because the application provides no screen support at
+<em>small</em> size. Android's <a href="#compatibility-examples">screen-compatibility
+mode</a> mode does not provide support for screens that are smaller than those the
+application supports&mdash;it only provides support for screens that are larger. Thus,
+although the application declares "false" for <em>large</em> and <em>xlarge</em> screens,
+the application still functions, but runs in compatibility mode.</p></li>
+
+ <li>Assume that you declare <code>smallScreens="false" normalScreens="false"
+largeScreens="true" xlargeScreens="true"</code> in your application's manifest. <p>Android Market
+filters the application from users of devices with <em>small</em> and
+<em>normal</em> size screens. In effect, this prevents such users from
+installing the application.</p></li>
</ul>
-<p>If you declare the <code>android:anyDensity</code> attribute as "true", you
-are signaling to the platform that your application wants to manage its UI by
-itself, for all screen densities, using the actual screen dimensions and pixels.
-In this case, the application must ensure that it declares its UI dimensions
-using density-independent pixels and scales any actual pixel values or math by
-the scaling factor available from
-{@link android.util.DisplayMetrics#density android.util.DisplayMetrics.density}.</p>
+<p>If you declare the <code>android:anyDensity</code> attribute as
+"<code>true</code>", you are signaling to the platform that your application is
+designed to display properly on any screen density. In this case, the
+application must ensure that it declares its UI dimensions using
+density-independent pixels (<code>dp</code>) and scales any absolute pixel
+values (<code>px</code>) or math by the scaling factor available from {@link
+android.util.DisplayMetrics#density android.util.DisplayMetrics.density}. See <a
+href="#dips-pels">Converting dp units to pixel units</a> for an example.</p>
<p>Note that the setting of the <code>android:anyDensity</code> attribute does
not affect the platform's pre-scaling of drawable resources, such as bitmaps and
nine-patch images, which always takes place by default. </p>
-<p>The following example shows a manifest that declares support for large,
-normal, and small screens in any densities.</p>
-
-<pre>&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"&gt;
-
- &lt;supports-screens
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:largeScreens="true"
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:normalScreens="true"
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:smallScreens="true"
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:resizable="true"
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:anyDensity="true" /&gt;
- &lt;/manifest&gt;
+<p>The following example shows a manifest that declares support for small, normal, large, and
+ xlarge screens in any density.</p>
+
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ ...
+ &lt;supports-screens
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:largeScreens="true"
+ android:xlargeScreens="true"
+ android:anyDensity="true" /&gt;
+&lt;/manifest&gt;
</pre>
-
+<!-- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:resizeable="true" -->
<h4 id="defaults">
Default values for attributes
</h4>
<p>The default values for the <code>&lt;supports-screens&gt;</code> attributes
-differs, depending on the the value of the
+differ, depending on the the value of the
<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code>android:minSdkVersion</code></a>
attribute in the application's manifest, as well as on
-the value of <code>android:targetSdkVersion</code>, if declared:</p>
+the value of <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+android:targetSdkVersion}</a>, if declared.</p>
-<div>
- <ul>
- <li>
- If <code>android:minSdkVersion</code> or
-<code>android:targetSdkVersion</code> is "3" (Android 1.5) or lower, the default
-value for everything except android:normalScreens is <code>false</code>. If you
-are primarily targeting pre-Android 1.6 platforms but also want to support other
-densities/screen sizes, you need to set the appropriate attributes to
-<code>true</code>.
- </li>
- <li>
- If <code>android:minSdkVersion</code> or
-<code>android:targetSdkVersion</code> is "4" (Android 1.6) or higher, the
-default value for everything is <code>true</code>. If your application
-requires&nbsp;<span style=BACKGROUND-COLOR:#ffffff>Android 1.6 </span>features,
-but does not support these densities and/or screen sizes, you need to set the
-appropriate attributes to <code>false</code>.
- </li>
- <li>
- Note that <code>android:normalScreens</code> always defaults to
-<code>true</code>.
- </li>
- </ul>
-</div>
+<p>Above, <a href="#table2">table 2</a> indicates the default values for each attribute, based on
+the values you provide for the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+android:minSdkVersion}</a> and <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+android:targetSdkVersion}</a>, in the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a>
+element.</p>
+
+<p class="note"><strong>Note:</strong> If your application uses APIs introduced in Android 1.6 or
+higher, but does not support specific screen densities and/or screen sizes, you need to explicitly
+set the appropriate attributes to "<code>false</code>" (because most are "true", by default).</p>
<h3 id="qualifiers">Resource directory qualifiers for screen size and density</h3>
@@ -646,8 +735,8 @@ appropriate attributes to <code>false</code>.
of resources based on the characteristics of the screen on which your application
is running. You can use these qualifiers to provide size- and density-specific
resources in your application. For more information about the generalized sizes
-and densities that correspond to the qualifiers, see <a href="#range">Table
-1</a>, earlier in this document.</p>
+and densities that correspond to the qualifiers, see <a href="#range">Range
+of Screens Supported</a>, earlier in this document.</p>
<table>
<tr>
@@ -657,32 +746,39 @@ and densities that correspond to the qualifiers, see <a href="#range">Table
</tr>
<tr>
- <td rowspan="3">Size</td>
+ <td rowspan="4">Size</td>
<td><code>small</code></td>
- <td>Resources for small screens, such as QVGA low density.</td>
+ <td>Resources designed for <em>small</em> size screens.</td>
</tr>
<tr>
<td><code>normal</code></td>
- <td>Resources for normal (baseline configuration) screens, such as T-Mobile
-G1/HTC Magic screen size, or equivalent.</td>
+ <td>Resources designed for <em>normal</em> size screens.</td>
</tr>
<tr>
<td><code>large</code></td>
-<td>Resources for large screens. Typical example is a tablet like device.</td>
+<td>Resources designed for <em>large</em> size screens.</td>
+</tr>
+<tr>
+<td><code>xlarge</code></td>
+<td>Resources designed for <em>extra large</em> size screens.</td>
</tr>
<tr>
-<td rowspan="4">Density</td>
+<td rowspan="5">Density</td>
<td><code>ldpi</code></td>
-<td>Low-density resources, for 100 to 140 dpi screens.</td>
+<td>Resources designed for low-density (<em>ldpi</em>) screens.</td>
</tr>
<tr>
<td><code>mdpi</code></td>
-<td>Medium-density resources for 140 to 180 dpi screens.</td>
+<td>Resources designed for medium-density (<em>mdpi</em>) screens.</td>
</tr>
<tr>
<td><code>hdpi</code></td>
-<td>High-density resources for 190 to 250 dpi screens.</td>
+<td>Resources designed for high-density (<em>hdpi</em>) screens.</td>
+</tr>
+<tr>
+<td><code>xhdpi</code></td>
+<td>Resources designed for extra high-density (<em>xhdpi</em>) screens.</td>
</tr>
<tr>
<td><code>nodpi</code></td>
@@ -717,38 +813,41 @@ running on Android 1.5 (API Level 3). </td>
Note that the density and the screen size are independent parameters and are
interpreted by the system individually. For example, WVGA high density is
considered a normal screen because its physical size is about the same as one of
-T-Mobile G1. On the other hand, a WVGA medium density screen is considered a
+T-Mobile G1. On the other hand, a WVGA medium density screen is considered a
<i>large</i> screen &mdash; it offers the same resolution but at lower pixel
density, meaning that it is both physically larger than the baseline screen and
can display significantly more information than a normal screen size.
</p>
<p>Here is an example of the resource directory structure of an application that
-supports low and high density, and employs different layout schemes.</p>
+employs different layout schemes for different screen sizes and supports low and high density
+screens.</p>
-<pre>res/layout/my_layout.xml // layout for normal screen size
+<pre>
+res/layout/my_layout.xml // layout for normal screen size
res/layout-small/my_layout.xml // layout for small screen size
res/layout-large/my_layout.xml // layout for large screen size
res/layout-large-land/my_layout.xml // layout for large screen size in landscape mode
+res/layout-xlarge/my_layout.xml // layout for extra large screen size
-res/drawable-ldpi/my_icon.png // icon image for low density
-res/drawable-mdpi/dpi/my_icon.png // icon for medium density
-res/drawable-hdpi/my_icon.png // icon image for high density
+res/drawable-lhdpi/my_icon.png // image for low density
+res/drawable-mdpi/dpi/my_icon.png // image for medium density
+res/drawable-hdpi/my_icon.png // image for high density
res/drawable-nodpi/composite.xml // density independent resource
</pre>
<p>For more information about how to use resource qualifiers or how the platform
-selects them, please read
+selects them, please read
<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
-Alternative Resources</a>.</p>
+Providing Alternative Resources</a>.</p>
<h2 id="screen-independence">Best practices for Screen Independence</h2>
<p>The objective of supporting multiple screens is to create an application that
-can run properly on any display and function properly on any of the screen
-configurations listed in <a href="#range">Table 1</a> earlier in this document.
+can run properly on any display and function properly on any of the generalized
+screen configurations supported by the platform.
</p>
<p>You can easily ensure that your application will display properly on
@@ -756,10 +855,11 @@ different screens. Here is a quick checklist:</p>
<ol>
<li>
- Prefer wrap_content, fill_parent and the dip unit to px in XML layout files
+ Use {@code wrap_content}, {@code fill_parent}, or the {@code dp} unit (instead of {@code px}),
+when specifying dimensions in an XML layout file
</li>
<li>
- Avoid AbsoluteLayout
+ Do not use {@code AbsoluteLayout}
</li>
<li>
Do not use hard coded pixel values in your code
@@ -769,19 +869,19 @@ different screens. Here is a quick checklist:</p>
</li>
</ol>
-<h3 id="use-relative">1. Prefer wrap_content, fill_parent and the dip unit to
+<h3 id="use-relative">1. Use wrap_content, fill_parent, or the dp unit, instead of
absolute pixels<br> </h3>
<p>When defining the <code>layout_width</code> and <code>layout_height</code> of
views in an XML layout file, using <code>wrap_content</code>,
-<code>fill_parent</code> or the <code>dip</code> will guarantee that the view is
+<code>fill_parent</code> or the <code>dp</code> will guarantee that the view is
given an appropriate size on the current device screen. For instance, a view
-with a <code>layout_width="100dip"</code> will measure 100 pixels wide on an
+with a <code>layout_width="100dp"</code> will measure 100 pixels wide on an
HVGA@160 density display and 150 pixels on a WVGA@240 density display, but the
view will occupy approximately the same physical space. </p>
<p>Similarly, you should prefer the <code>sp</code> (scale-independent pixel,
-the scale factor depends on a user setting) or <code>dip</code> (if you don't
+the scale factor depends on a user setting) or <code>dp</code> (if you don't
want to allow the user to scale the text) to define font sizes.</p>
<h3 id="avoid-absolute">2. Avoid AbsoluteLayout </h3>
@@ -793,7 +893,7 @@ positions which might easily lead to user interfaces that do not work well on
different displays. Because of this, <code>AbsoluteLayout</code> was deprecated
in Android 1.5 (API Level 3). </p>
-<p>You can achieve much the same layout by using a
+<p>You can achieve much the same layout by using a
{@link android.widget.FrameLayout FrameLayout} instead, and setting
<code>layout_margin</code> attributes of the children. This approach is more
flexible and will yield better results on different screens.</p>
@@ -807,9 +907,9 @@ code in pixels. For instance, if <code>myView.getWidth()</code> returns 10, the
view is 10 pixels wide. In some cases, you may need to scale the pixel values
that you use in your code. The sections below provide more information. </p>
-<h4 id="dips-pels">Converting from dips to pixels</h4>
+<h4 id="dips-pels">Converting dp units to pixel units</h4>
-<p>In some cases, you will need to express dimensions in <code>dip</code> and
+<p>In some cases, you will need to express dimensions in <code>dp</code> and
then convert them to pixels. Imagine an application in which a scroll gesture is
recognized after the user's finger has moved by at least 16 pixels. On a
baseline screen, the user will have to move his finger by 16 pixels / 160
@@ -817,26 +917,26 @@ dpi = 1/10th of an inch (or 2.5 mm) before the gesture is recognized. On a
device with a high (240) density display, the user will move his finger by only
16 pixels / 240 dpi = 1/15th of an inch (or 1.7 mm.) The distance is much
shorter and the application thus appears more sensitive to the user. To fix this
-issue, the gesture threshold must be expressed in the code in <code>dip</code>
+issue, the gesture threshold must be expressed in the code in <code>dp</code>
and then converted to actual pixels.</p>
-<pre>// The gesture threshold expressed in dip
-private static final float GESTURE_THRESHOLD_DIP = 16.0f;
+<pre>// The gesture threshold expressed in dp
+private static final float GESTURE_THRESHOLD_DP = 16.0f;
-// Convert the dips to pixels
+// Convert the dps to pixels
final float scale = getContext().getResources().getDisplayMetrics().density;
-mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale + 0.5f);</span>
+mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);</span>
// Use mGestureThreshold as a distance in pixels
</pre>
-<p>The {@link android.util.DisplayMetrics#density android.util.DisplayMetrics.density}
+<p>The {@link android.util.DisplayMetrics#density android.util.DisplayMetrics.density}
field specifies the the scale factor you must use to
-convert dips to pixels according to the current screen density. You can access
+convert dps to pixels according to the current screen density. You can access
the current screen's metrics through a <code>Context</code> or
<code>Activity</code>. On a medium (160) density screen,
<code>DisplayMetrics.density</code> equals "1.0", whereas on a high (240)
-density screen it equals "1.5". You can refer to the documentation of the
+density screen it equals "1.5". You can refer to the documentation of the
{@link android.util.DisplayMetrics DisplayMetrics}
class for details.</p>
@@ -855,7 +955,7 @@ scroll threshold can be obtained as follows:</p>
<div style="float: right;background-color:#fff;margin: 0;padding: 20px 0 20px 20px;">
<img src="{@docRoot}images/screens_support/scale-test.png" style="padding:0;margin:0;">
-<p class="caption" style="margin:0;padding:0;"><strong>Figure 2.</strong> Comparison of pre-scaled and auto-scaled bitmaps.</p>
+<p class="caption" style="margin:0;padding:0;"><strong>Figure 3.</strong> Comparison of pre-scaled and auto-scaled bitmaps.</p>
</div>
<p>Even with the size- and density-compatibility features that the platform
@@ -886,7 +986,7 @@ platform assumes that the resources in that directory are designed for the
baseline medium density. It is not recommended that you put density-specific
resources such as images in the default directory.</p>
-<p>For more information about valid resource qualifiers, see
+<p>For more information about valid resource qualifiers, see
<a href="#qualifiers">Resource directory qualifiers</a>, earlier in this
document.</p>
@@ -930,7 +1030,7 @@ resource directory:</p>
<p style="margin-left:2em;"><code>res/drawable-nodpi/icon.png</code></p>
-<p>You can also take complete control of the scaling mechanism by using the
+<p>You can also take complete control of the scaling mechanism by using the
{@link android.graphics.BitmapFactory.Options BitmapFactory.Options} class,
which lets you define whether you want the bitmap to be pre-scaled and what the
density of the bitmap should be. For instance, if you are loading a bitmap from
@@ -938,16 +1038,16 @@ a web server, you may want to force the bitmap's density to be high density.
When pre-scaling is disabled, the resulting bitmap is in auto-scaling mode. The
bitmap is associated with a density (that you may or may not have specified
through the <code>BitmapFactory.Options</code>) which will be used to scale the
-bitmap on screen <em>at drawing time</em>.
+bitmap on screen <em>at drawing time</em>.
<p>Using auto-scaling instead of pre-scaling is more CPU expensive than
-pre-scaling but uses less memory. You can refer to the documentation of
-{@link android.graphics.BitmapFactory BitmapFactory},
-{@link android.graphics.Bitmap Bitmap}, and
+pre-scaling but uses less memory. You can refer to the documentation of
+{@link android.graphics.BitmapFactory BitmapFactory},
+{@link android.graphics.Bitmap Bitmap}, and
{@link android.graphics.Canvas Canvas} for more
information on auto-scaling.</p>
-<p>Figure 2, at right, demonstrates the results of the pre-scale and auto-scale
+<p>Figure 3, at right, demonstrates the results of the pre-scale and auto-scale
mechanisms when loading low (120), medium (160) and high (240) density bitmaps
on a baseline screen. The differences are subtle, because all of the bitmaps are
being scaled to match the current screen density, however the scaled bitmaps
@@ -958,7 +1058,7 @@ auto-scaled at draw time.</p>
<p>If you have already developed and published an Android application based on
Android 1.5 or earlier platform version, you need to consider how you will adapt
-your application so that it is deployable to </p>
+your application so that it is deployable to:</p>
<ul>
<li>Existing devices, which may be running Android 1.5 (or lower) platform
@@ -967,16 +1067,21 @@ version, as well as to </li>
screen sizes and resolutions</li>
</ul>
+<p class="note"><strong>Note:</strong> Even if your application targets Android 1.6 already, you
+should follow the same strategies below in order to support <em>xhdpi</em> and <em>xlarge</em>
+screens on Android 2.3 (API Level 9), while maintaining compatibility with older versions of
+the platform.</p>
+
<p>To support the newer devices and the different screens they use, you might
need to make some changes in your app, but at the same time your app may be very
stable and so you want to minimize the changes. There are a variety of ways that
you can extend your existing application to support new devices with multiple
screens <em>and</em> existing devices running older platform versions. You
should be able to make these changes to your application such that you can
-distribute a single .apk to any and all devices.</p>
+distribute a single {@code .apk} to all devices.</p>
<p>The recommended strategy is to develop against the most recent version of the
-platform you are targeting, and test on the minimum one you want to run on.
+platform you are targeting, and test on the minimum platform version you want to run on.
Here's how to do that:</p>
<ol>
@@ -984,39 +1089,41 @@ Here's how to do that:</p>
<code>android:minSdkVersion</code> attribute as it is. You <em>do not</em> need
to increment the value of the attribute to support new devices and multiple
screens. </li>
- <li>Extend compatibility for Android 1.6 (and higher) devices by adding
+ <li>Extend compatibility for Android 1.6 (and higher) devices by adding
a new attribute &mdash; <code>android:targetSdkVersion</code> &mdash; to the
<code>uses-sdk</code> element. Set the value of the attribute to
-"<code>4</code>". This allows your application to "inherit" the platform's
+<code>"4"</code>. [To support <em>xhdpi</em> and <em>xlarge</em> screens, set the value to
+<code>"9"</code>.] This allows your application to "inherit" the platform's
multiple screens support, even though it is technically using an earlier version
of the API. </li>
<li>Add an empty <code>&lt;supports-screens&gt;</code> element as a child of
<code>&lt;manifest&gt;</code>. If you need to enable size or density attributes
later, this is where you will add them.</li>
<li>Change your application's build properties, such that it compiles against
-the Android 1.6 (API Level 4) library, rather than against the Android 1.5 (or
+the Android 1.6 (API Level 4) library [or against Android 2.3 (API Level 9) to support
+<em>xhdpi</em> and <em>xlarge</em> screens], rather than against the Android 1.5 (or
earlier) library. You will not be able to compile your application against the
older platform because of the new manifest attribute. </li>
- <li>Set up AVDs for testing your application on Android 1.6 and higher
+ <li>Set up AVDs for testing your application on Android 1.6 [or Android 2.3] and higher
releases. Create AVDs that use the screen sizes and densities that you want to
-support. When you create the AVDs, make sure to select the Android 1.6 or higher
+support. When you create the AVDs, make sure to select the Android 1.6 [or Android 2.3] or higher
platform as the system image to run. For more information, see <a
href="#testing">How to Test Your Application on Multiple Screens</a>,
below.</li>
- <li>Set up AVDs for testing your application on Android 1.5 (or earlier
-platform). You need AVDs running the older platforms you are targeting, so that
+ <li>Set up AVDs for testing your application on older versions of the platform, as low as the
+version declared by your <code>android:minSdkVersion</code>. You need AVDs running the older
+platforms you are targeting, so that
you can test for compatibility and ensure that there are no functional
regressions. </li>
- <li>Compile your application against the Android 1.6 library and run it on the
+ <li>Compile your application against the Android 1.6 [or Android 2.3] library and run it on the
AVDs you created. Observe the way your application looks and runs, and test all
of the user interactions. </li>
<li>Debug any display or functional issues. For issues that you resolve in
your application code, <span style="color:red">make certain not to use any APIs
-introduced in API Level 4 or later</span>. If you are in doubt, refer to SDK
-reference documentation and look for the API Level specifier for the API you
-want to use. Using an API introduced in API Level 4 or later will mean that your
-application will no longer be compatible with devices running Android 1.5 or
-earlier.</li>
+introduced later than the version declared by your <code>android:minSdkVersion</code></span>. If you
+are in doubt, refer to SDK reference documentation and look for the API Level specifier for the API
+you want to use. Using newer APIs not supported by your minimum version will mean that your
+application will no longer be compatible with devices running on that version.</li>
<li>For resource-related issues, you can try resolving them by:
<ul>
<li>Adding a <code>anyDensity="false"</code> attribute to
@@ -1024,22 +1131,22 @@ earlier.</li>
scaling.</li>
<li>Creating any size- or density-specific resources you need and placing
them in directories tagged with the <a href="#qualifiers">correct
-qualifiers</a>. Qualifiers must be arranged in a proscribed order. See
+qualifiers</a>. Qualifiers must be arranged in a proscribed order. See
<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
-Alternative Resources</a> for more information. </li>
+Providing Alternative Resources</a> for more information. </li>
<li>Note that if you add size- or density-specific resource directories
tagged with any of the resource qualifiers listed in this document, you should
make sure to also tag those directories with the <code>v&lt;api-level&gt;</code>
-qualifier (for example, <code>-v4</code>). This ensures that those resources
+qualifier (for example, <code>-v4</code> to target API Level 4). This ensures that those resources
will be ignored when the application is run on Android 1.5 or lower platform
versions.</p></li>
</ul>
</li>
<li>If your application does not offer support (such as custom layouts) for
large screens and you want the platform to display your application in
-screen-compatibility mode on larger screens, add a
-<code>largeScreens="false"</code> attribute to the
-<code>&lt;supports-screens&gt;</code> element in the manifest. See
+screen-compatibility mode on larger screens, add the
+<code>largeScreens="false"</code> and <code>xlargeScreens="false"</code> attributes to the
+<code>&lt;supports-screens&gt;</code> element in the manifest. See
<a href="#compatibility-examples">Screen-Compatibility Examples</a> for
illustrations of how the platform displays your application in this case.</li>
<li>If your application does not offer support (such as custom layouts) for
@@ -1062,6 +1169,16 @@ function on a small-screen device. In many cases, the reduced screen area and
density mean that you may need to make tradeoffs in design, content, and
function on those devices. </p>
+<p>Also give extra attention to testing your application on an AVD that emulates an <em>xlarge</em>
+screen. Devices with extra large screens
+are tablet-sized or larger, so you should pay close attention to how usable your application is on
+such screens. You might want to design new layouts specifically for extra large screens, to address
+usability aspects such as the location and size of buttons in your UI. To test your application on
+an extra large screen, create an AVD targeted to Android 2.3 with a high resolution, such as 1280 x
+800, and the default density of 160dpi. This AVD will use any resources you've provided with the
+<code>xlarge</code> <a href="#qualifiers">resouce qualifier</a>.</p>
+
+
<h2 id="testing">How to Test Your Application on Multiple Screens</h2>
<p>Before publishing an application that supports multiple screens, you should
@@ -1076,22 +1193,22 @@ not. Once you've tested your application and found that it displays properly on
various screen sizes, you should make sure to add the corresponding size
attribute(s) to your application's manifest. -->
-<div id="f9.5" style="float:right;margin:0;padding:0;">
- <img src="{@docRoot}images/screens_support/avds-config.png" style="padding:0;margin:0;">
- <p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0 1em;"><strong>Figure 3.</strong>
+<div id="f9.5" class="figure" style="width:530px">
+ <img src="{@docRoot}images/screens_support/avds-config.png" />
+ <p class="img-caption"><strong>Figure 4.</strong>
A typical set of AVDs for testing screens support.</p>
</div>
<p>As a test environment for your applications, set up a series of AVDs that
emulate the screen sizes and densities you want to support. The Android SDK
-includes six emulator skins to get you started. You can use the Android AVD
+includes several emulator skins to get you started. You can use the Android AVD
Manager or the <code>android</code> tool to create AVDs that use the various
emulator skins and you can also set up custom AVDs to test densities other than
-the defaults. For general information about working with AVDs, see
+the defaults. For general information about working with AVDs, see
<a href="{@docRoot}guide/developing/tools/avd.html">Android Virtual
Devices</a>.</p>
-<p>The Android SDK provides a set of default emulator skins that you can use for
+<p>The Android SDK provides a set of default emulator skins that you can use for
testing. The skins are included as part of each Android platform that you can
install in your SDK. The Android 1.6 platform offers these default skins:</p>
@@ -1110,7 +1227,7 @@ install in your SDK. The Android 1.6 platform offers these default skins:</p>
</li>
</ul>
-<p>The Android 2.0 platform offers all of the Android 1.6 default skins,
+<p>The Android 2.0 platform offers all of the Android 1.6 default skins,
above, plus:</p>
<ul>
@@ -1143,52 +1260,29 @@ launching the emulator, for example:</p>
<p>Note that starting the emulator with the <code>-scale</code> option will
scale the entire emulator display, based on both the dpi of the skin and of your
-monitor. Using the default densities, the emulator skins included in the Android
-1.6 SDK will emulate the following screen sizes:</p>
-
-<ul>
- <li>
- QVGA, low density: 3.3"
- </li>
- <li>
- WQVGA, low density: 3.9"
- </li>
- <li>
- WQVGA432, low density: 4.1"
- </li>
- <li>
- HVGA, medium density: 3.6"
- </li>
- <li>
- WVGA800, high density: 3.9"
- </li>
- <li>
- WVGA854, high density: 4.1"
- </li>
-</ul>
+monitor. The default emulator skins included in the Android SDK are listed
+in <a href="#screens-table">Table 1</a>, earlier in this document.</p>
-<div style="float: right;background-color:#fff;margin: 0;padding: 20px 0 20px 20px;width:520px;">
- <img src="{@docRoot}images/screens_support/avd-density.png" style="padding:0;margin:0;">
- <p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0 1em; width:280px;"><strong>Figure 4.</strong>
+<div class="figure" style="width:324px">
+ <img src="{@docRoot}images/screens_support/avd-density.png" >
+ <p class="img-caption"><strong>Figure 5.</strong>
Resolution and density options that you can use, when creating an AVD using the AVD Manager.</p>
</div>
<p>You should also make sure to test your application on different physical
-screen sizes within a single size-density configuration. For example, according
-to <a href="#range">Table 1</a>, the minimum supported diagonal of QVGA is 2.8".
-To display this is on a 30" monitor you will need to adjust the value passed to
-<code>-scale</code> to 96*2.8/3.3 = 81dpi. You can also pass a float value to
-<code>-scale</code> to specify your own scaling factor:</p>
+screen sizes within a single size-density configuration. For example, to
+display this screen configuration on a 30" monitor you will need to adjust
+the value passed to <code>-scale</code> to 96*2.8/3.3 = 81dpi. You can also
+pass a float value to <code>-scale</code> to specify your own scaling factor:</p>
<pre>emulator -avd &lt;name&gt; -scale 0.6</pre>
<p>If you would like to test your application on a screen that uses a resolution
or density not supported by the built-in skins, you can either adjust an
-existing skin, or create an AVD
-that uses a custom resolution or density.</p>
+existing skin, or create an AVD that uses a custom resolution or density.</p>
<p>In the AVD Manager, you can specify a custom skin resolution or density in
-the Create New AVD dialog, as shown in Figure 4, at right.</p>
+the Create New AVD dialog, as shown in Figure 5, at right.</p>
<p>In the <code>android</code> tool, follow these steps to create an AVD with a
custom resolution or density:</p>
@@ -1203,13 +1297,13 @@ Here's an example:
<li>To specify a custom density for the skin, answer "yes" when asked whether
you want to create a custom hardware profile for the new AVD.</li>
<li>Continue through the various profile settings until the tool asks you to
-specify "Abstracted LCD density" (<em>hw.lcd.density</em>). Consult <a
-href="#range">Table 1</a>, earlier in this document, and enter the appropriate
-value. For example, enter "160" to use medium density for the WVGA800 screen.</li>
+specify "Abstracted LCD density" (<em>hw.lcd.density</em>). Enter an appropriate
+value, such as "120" for a low-density screen, "160" for a medium density screen,
+or "240" for a high-density screen.</li>
<li>Set any other hardware options and complete the AVD creation.</li>
</ol>
-<p>In the example above (WVGA medium density), the new AVD will emulate a 5.8"
+<p>In the example above (WVGA medium density), the new AVD will emulate a 5.8"
WVGA screen.</p>
<p>As an alternative to adjusting the emulator skin configuration, you can use
@@ -1224,21 +1318,21 @@ to the emulator command line when starting the AVD. For example, </p>
<p>This section provides examples of how the Android platform displays an
application written for the baseline screen configuration &mdash; HVGA (320x480)
resolution on a 3.2" screen &mdash; with all of the platform's size- and
-density-compatibility features enabled. That is, the examples show how
-the platform displays an application that doesn't provide built-in support
+density-compatibility features enabled. That is, the examples show how
+the platform displays an application that doesn't provide built-in support
for the screen on which it is being rendered, but which instead relies completely
on the platform.</p>
-<p>The platform's screen-compatibility features are designed to provide such
-an application with a virtual baseline screen environment against which to run,
-while at the same time ensuring for the user a physical display that is
+<p>The platform's screen-compatibility features are designed to provide such
+an application with a virtual baseline screen environment against which to run,
+while at the same time ensuring for the user a physical display that is
approximately the same as the baseline screen size and density. </p>
<p>Legacy applications that have not been modified to support multiple
-screens would be typical examples of such applications. In most cases,
+screens would be typical examples of such applications. In most cases,
you would want to add multiple-screens support to a legacy application and
publish an updated version, as described in <a href="#strategies">Strategies
-for Legacy Applications</a>. However, if you did not do so, the
+for Legacy Applications</a>. However, if you did not do so, the
platform still performs best-effort rendering of your application, as
illustrated below.</p>
@@ -1256,9 +1350,9 @@ density is low density (160 -&gt; 120 virtual dpi).
</li>
<li>
If the device's screen size is <em>small</em>, there are few options
-options for making Android 1.5 applications work well on such a screen, so
+options for making Android 1.5 applications work well on such a screen, so
Android Market will filter applications that are not known to support these
-screens from the device.
+screens from the device.
</li>
<li>
If the device's screen size is <em>large</em>, it limits the application's
diff --git a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
index 05f61be..6cb98e6 100644
--- a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
@@ -4,7 +4,7 @@ page.title=Activity and Task Design Guidelines
<div id="qv-wrapper">
<div id="qv">
-<h2>Activity and task design quickview</h2>
+<h2>Quickview</h2>
<ul>
<li>Activities are the main building blocks of Android applications. </li>
@@ -256,8 +256,8 @@ page.title=Activity and Task Design Guidelines
to be able go to a subsequent screen B and then use the BACK key to go
back to screen A, then the screen A needs to be implemented as an
activity. The one exception to this rule is if your application
- <a href=#taking_over_back_key title="takes control of the BACK key"
- takes control of the BACK key</a> and manages the navigation itself.
+ <a href="#taking_over_back_key">takes control of the BACK key</a> and manages the navigation
+itself.
</p>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design.jd b/docs/html/guide/practices/ui_guidelines/icon_design.jd
index 51ccfaf..389d5fa 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design.jd
@@ -4,7 +4,7 @@ page.title=Icon Design Guidelines, Android 2.0
<div id="qv-wrapper">
<div id="qv">
-<h2>Icon design quickview</h2>
+<h2>Quickview</h2>
<ul>
<li>You can use several types of icons in an Android application.</li>
@@ -35,25 +35,30 @@ page.title=Icon Design Guidelines, Android 2.0
</ol>
-<h2>See also</h2>
-
-<ol>
-<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
-Screens</a></li>
-<li><a href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon
-Templates Pack, v2.0 &raquo;</a></li>
-</ol>
-
<h2>Older versions</h2>
<ol>
<li style="margin-top:4px;"><a
href="{@docRoot}guide/practices/ui_guidelines/icon_design_1.html">Icon Design
Guidelines, Android 1.0</a></li>
+</ol>
+
+<h2>Downloads</h2>
+
+<ol>
+<li><a href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon
+Templates Pack, v2.0 &raquo;</a></li>
<li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
Templates Pack, v1.0 &raquo;</a></li>
</ol>
+<h2>See also</h2>
+
+<ol>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
+</ol>
+
</div>
</div>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_1.jd b/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
index 1c75843..995cfea 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
@@ -4,7 +4,7 @@ page.title=Icon Design Guidelines, Android 1.0
<div id="qv-wrapper">
<div id="qv">
-<h2>Icon design quickview</h2>
+<h2>Quickview</h2>
<ul>
<li>You can use several types of icons in an Android application.</li>
@@ -35,14 +35,19 @@ application can use the standard icons by referencing them as resources.</li>
</ol>
-<h2>See also</h2>
+<h2>Downloads</h2>
<ol>
-<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
<li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
Templates Pack, v1.0 &raquo;</a></li>
</ol>
+<h2>See also</h2>
+
+<ol>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
+</ol>
+
<h2>Newer versions</h2>
diff --git a/docs/html/guide/practices/ui_guidelines/menu_design.jd b/docs/html/guide/practices/ui_guidelines/menu_design.jd
index ebf8a4b..840ee66 100644
--- a/docs/html/guide/practices/ui_guidelines/menu_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/menu_design.jd
@@ -4,7 +4,7 @@ page.title=Menu Design Guidelines
<div id="qv-wrapper">
<div id="qv">
-<h2>Menu design quickview</h2>
+<h2>Quickview</h2>
<ul>
<li>An Options menu is for any commands that are global to the current activity. </li>
diff --git a/docs/html/guide/practices/ui_guidelines/widget_design.jd b/docs/html/guide/practices/ui_guidelines/widget_design.jd
index fc62fe6..e978069 100644
--- a/docs/html/guide/practices/ui_guidelines/widget_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/widget_design.jd
@@ -4,7 +4,7 @@ page.title=Widget Design Guidelines
<div id="qv-wrapper">
<div id="qv">
-<h2>Widget design quickview</h2>
+<h2>Quickview</h2>
<ul>
<li>Widgets have six standard sizes on the Home screen</li>
@@ -27,7 +27,7 @@ page.title=Widget Design Guidelines
<h2>See also</h2>
<ol>
-<li><a href="{@docRoot}guide/topics/appwidgets/index.html">AppWidgets</a> topic in the <em>Dev Guide</em></li>
+<li><a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a></li>
<li><a href="http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html">AppWidgets blog post</a></li>
</ol>
diff --git a/docs/html/guide/publishing/app-signing.jd b/docs/html/guide/publishing/app-signing.jd
index 34d9419..6758054 100644
--- a/docs/html/guide/publishing/app-signing.jd
+++ b/docs/html/guide/publishing/app-signing.jd
@@ -4,7 +4,7 @@ page.title=Signing Your Applications
<div id="qv-wrapper">
<div id="qv">
-<h2>Signing quickview</h2>
+<h2>Quickview</h2>
<ul>
<li>All Android apps <em>must</em> be signed</a></li>
diff --git a/docs/html/guide/publishing/licensing.jd b/docs/html/guide/publishing/licensing.jd
new file mode 100644
index 0000000..fc83ec0
--- /dev/null
+++ b/docs/html/guide/publishing/licensing.jd
@@ -0,0 +1,2376 @@
+page.title=Licensing Your Applications
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>Quickview</h2>
+ <ul>
+ <li>Licensing lets you protect your application on any device that includes Android Market.</li>
+ <li>Your app maintains control of how it enforces its licensing status. </li>
+ <li>Adding licensing to an app is straightforward, using the library available through the SDK.</li>
+ <li>The service is free and is available to all developers who publish on Android Market. </li>
+ </ul>
+
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#account">Setting Up A Publisher Account</a></li>
+ <li><a href="#dev-setup">Setting Up the Development Environment</a></li>
+ <li><a href="#app-integration">Integrating the LVL with Your Application</a>
+ <ol>
+ <li><a href="#add-library">Including the LVL</a></li>
+ <li><a href="#manifest-permission">Adding the licensing permission</a></li>
+ <li><a href="#impl-Policy">Implementing a Policy</a></li>
+ <li><a href="#impl-Obfuscator">Implementing an Obfuscator</a></li>
+ <li><a href="#impl-lc">Checking the license</a></li>
+ <li><a href="#impl-DeviceLimiter">Implementing a DeviceLimiter</a></li>
+ </ol></li>
+ <li><a href="#test-env">Setting Up the Test Environment</a>
+ <ol>
+ <li><a href="#test-response">Test responses</a></li>
+ <li><a href="#test-acct-setup">Test accounts</a></li>
+ <li><a href="#acct-signin">Signing in on a device or emulator</a></li>
+ </ol></li>
+ <li><a href="#app-obfuscation">Obfuscating Your Application</a></li>
+ <li><a href="#app-publishing">Publishing a Licensed Application</a></li>
+ <li><a href="#support">Where to Get Support</a></li>
+ </ol>
+
+ <h2>Appendix</h2>
+ <ol>
+ <li><a href="#lvl-summary">Summary of LVL Classes and Interfaces</a></li>
+ <li><a href="#server-response-codes">Server Response Codes</a></li>
+ <li><a href="#extras">Server Response Extras</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>Android Market offers a licensing service that lets you enforce licensing
+policies for paid applications that you publish through Android Market. With
+Android Market Licensing, your applications can query Android Market at run time to
+obtain their licensing status for the current user, then allow or disallow
+further use as appropriate. </p>
+
+<p>Using the service, you can apply a flexible licensing policy on an
+application-by-application basis &mdash; each application can enforce licensing
+in the way most appropriate for it. If necessary, an application can apply custom
+constraints based on the licensing status obtained from Android Market.
+For example, an application can check the licensing status and then apply custom
+constraints that allow the user to run it unlicensed for a specific number
+of times, or for a specific validity period. An application can also restrict use of the
+application to a specific device, in addition to any other constraints. </p>
+
+<p>The licensing service is a secure means of controlling access to your
+applications. When an application checks the licensing status, the Market server
+signs the licensing status response using a key pair that is uniquely associated
+with the publisher account. Your application stores the public key in its
+compiled <code>.apk</code> file and uses it to verify the licensing status
+response.</p>
+
+<p>Any application that you publish through Android Market can use the Android
+Market Licensing service. No special account or registration is needed.
+Additionally, because the service uses no dedicated framework APIs, you can add
+licensing to any legacy application that uses a minimum API level of 3 or
+higher.</p>
+
+<p>To help you add licensing to your application, the Android SDK provides
+library sources that you can include in your application project. The
+License Verification Library (LVL) handles all of
+the licensing-related communication with the Android Market client and the
+licensing service. With the LVL integrated, your application can determine its
+licensing status for the current user by simply calling a library checker method
+and implementing a callback that receives the status.</p>
+
+<p>This document explains how the licensing service works and how to add it to
+your application. </p>
+
+
+<h2 id="overview">Overview</h2>
+
+<p>Android Market Licensing is a network-based service that lets an application
+on an Android-powered device query a trusted licensing server, to determine
+whether the application is licensed to the current device user. After receiving
+the server response, the application can then allow or disallow further use of
+the application as needed. In the service, the role of the licensing server is
+to provide the license status for the current user; the application itself is
+responsible for querying the server and conditionally granting access to the
+application. </p>
+
+<h4>Application, Android Market client, and server</h4>
+
+<p>The licensing service is based on the capability of the Android Market server
+to determine whether a given user is licensed to use a given application. The
+server considers a user licensed if the user is recorded to have purchased the
+application, or if the application is available for free. To properly identify
+the user and determine the license status, the server requires information about
+the application and user &mdash; the application and the Android Market client
+work together to assemble the information and pass it to the server. </p>
+
+<p>In the licensing service, an application does not query the licensing server
+directly, but instead calls the Android Market client over remote IPC to
+initiate a license request. In the license request:</p>
+
+<ul>
+<li>The application provides its package name and a nonce that is later used to
+validate any response from the server, as well as a callback over which the
+response can be returned asynchronously.</li>
+<li>The Android Market client, which has greater permissions than the
+application, collects the necessary information about the user and the device,
+such as the device's primary Google account username, IMSI, and other
+information. It then sends the license check request to the server on behalf of
+the application.</li>
+<li>The server evaluates the request using all available information, attempting
+to establish the user's identity to a sufficient level of confidence. The server
+then checks the user identity against purchase records for the application and
+returns a license response, which the Android Market client returns to the
+application over the IPC callback.</li>
+</ul>
+
+<p>Notice that during a license check, the application does not manage any
+network connections or use any licensing related APIs in the Android platform.
+</p>
+
+<div class="figure" style="width:469px">
+<img src="{@docRoot}images/licensing_arch.png" alt=""/>
+<p class="img-caption"><strong>Figure 1.</strong> Your application initiates a
+license check through the LVL and the Android Market
+client, which handles communication with the Market server.</p>
+</div>
+
+<h4>License responses secured through public key cryptography</h4>
+
+<p>To ensure the integrity of each license query, the server signs the license
+response data using an RSA key pair that is shared exclusively between the
+server and the application publisher.</p>
+
+<p>The licensing service generates a single licensing key pair for each
+publisher account and exposes the public key in the account's profile page. The
+publisher copies the public key and embeds it in the application source code,
+then compiles and publishes the <code>.apk.</code> The server retains the
+private key internally and uses it to sign license responses for applications
+published on that account. </p>
+
+<p>When the application receives a signed response, it uses the embedded public
+key to verify the data. The use of public key cryptography in the licensing
+service makes it possible for the application to detect responses that have been
+tampered with or that are spoofed.</p>
+
+<h4>Use of licensing in your application</h4>
+
+<p>To use licensing in your application, add code to the application to
+initiate a license check request and handle the response when it is received.
+You can choose when, and how often, you want your application to check its
+license and you have full control over how it handles the response, verifies the
+signed response data, and enforces access controls. </p>
+
+<p>To simplify the process of adding support for licensing, download and
+integrate the Licensing Verification Library, described below. Integration is
+straightforward.</p>
+
+<p>When you are finished integrating the LVL, use a test environment
+provided by the publisher site to test your application's handling of server
+responses. </p>
+
+<p>Finally, publish the application <code>.apk</code> on Market using the
+normal process. If you previously used the copy-protection provided by Android
+Market, you can remove it from applications that use licensing. </p>
+
+<h4>Licensing Verification Library simplifies implementation</h4>
+
+<p>The Android SDK includes a License Verification Library (LVL) that you can
+download and use as the basis for your application's licensing implementation.
+The LVL greatly simplifies the process of adding licensing to your application
+and helps ensure a more secure, robust implementation for your application. The
+LVL provides internal classes that handle most of the standard operations of a
+license query, such as contacting Android Market to initiate a license request
+and verifying and validating the responses. It also exposes key interfaces that
+let you easily plug in your custom code for defining licensing policy and
+managing access as needed by your application. The key LVL interfaces are: </p>
+
+<ul>
+<li>Policy &mdash; your implementation determines whether to allow access to the
+application, based on the license response received from the server and any
+other data available (such as from a backend server associated with your
+application). The implementation can evaluate the various fields of the license
+response and apply other constraints, if needed. The implementation also lets
+you manage the handling of license checks that result in errors, such as network
+errors.</li>
+<li>LicenseCheckerCallback &mdash; your implementation manages access to the
+application, based on the result of the Policy's handling of the license
+response. Your implementation can manage access in any way needed, including
+displaying the license result in the UI or directing the user to purchase the
+application (if not currently licensed). </li>
+</ul>
+
+<p>To help you get started with a Policy, the LVL provides two fully complete
+Policy implementations that you can use without modification or adapt to your
+needs:</p>
+
+<ul>
+<li><a href="#ServerManagedPolicy">ServerManagedPolicy</a> is a flexible Policy
+that uses settings provided by the licensing server to manage response caching
+and access to the application while the device is offline (such as when the
+user is on an airplane). For most applications, the use of
+ServerManagedPolicy is highly recommended. </li>
+<li><a href="#StrictPolicy">StrictPolicy</a> is a restrictive Policy that
+does not cache any response data and allows the application access <em>only</em>
+when the server returns a licensed response.</li>
+</ul>
+
+<p>The LVL is available as a downloadable component of the Android SDK. The
+component includes both the LVL itself and an example application that shows how
+the library should be integrated with your application and how your application
+should manage response data, UI interaction, and error conditions. </p>
+
+<p>The LVL sources are provided as an Android <em>library project</em>, which
+means that you can maintain a single set of library sources and share them
+across multiple applications. A full test environment is also available through
+the SDK, so you can develop and test the licensing implementation in your
+applications before publishing them, even if you don't have access to a
+physical device.</p>
+
+<h4>Requirements and limitations</h4>
+
+<p>Android Market Licensing is designed to let you apply license controls to
+applications that you publish through Android Market. The service is not
+designed to let you control access to applications that are not published
+through Android Market or that are run on devices that do not offer the Android
+Market client. </p>
+
+<p>Here are some points to keep in mind as you implement licensing in your
+application: </p>
+
+<ul>
+<li>Only paid applications published through Market can use the
+service. </li>
+<li>An application can use the service only if the Android Market client is
+installed on its host device and the device is running Android 1.5 (API level 3)
+or higher.</li>
+<li>To complete a license check, the licensing server must be accessible over
+the network. You can implement license caching behaviors to manage access when
+there is no network connectivity. </li>
+<li>The security of your application's licensing controls ultimately relies on
+the design of your implementation itself. The service provides the building
+blocks that let you securely check licensing, but the actual enforcement and
+handling of the license are factors in your control. By following the best
+practices in this document, you can help ensure that your implementation will be
+secure.</li>
+<li>Adding licensing to an application does not affect the way the application
+functions when run on a device that does not offer Android Market.</li>
+<li>Licensing is currently for paid apps only, since free apps are considered
+licensed for all users. If your application is already published as free,
+you won't be able to upload a new version that uses licensing.</li>
+</ul>
+
+<h4>Replacement for copy protection</h4>
+
+<p>Android Market Licensing is a flexible, secure mechanism for controlling
+access to your applications. It effectively replaces the copy-protection
+mechanism offered on Android Market and gives you wider distribution
+potential for your applications. </p>
+
+<ul>
+<li>A limitation of the legacy copy-protection mechanism on Android Market is
+that applications using it can be installed only on compatible devices that
+provide a secure internal storage environment. For example, a copy-protected
+application cannot be downloaded from Market to a device that provides root
+access, and the application cannot be installed to a device's SD card. </li>
+<li>With Android Market licensing, you can move to a license-based model in
+which access is not bound to the characteristics of the host device, but to your
+publisher account on Android Market and the licensing policy that you define.
+Your application can be installed and controlled on any compatible device on
+any storage, including SD card.</li>
+</ul>
+
+<p>Although no license mechanism can completely prevent all unauthorized use,
+the licensing service lets you control access for most types of normal usage,
+across all compatible devices, locked or unlocked, that run Android 1.5 or
+higher version of the platform.</p>
+
+<p>The sections below describe how to add Android Market licensing to your
+applications. </p>
+
+<h2 id="account">Setting Up a Publisher Account</h2>
+
+<p>Android Market licensing lets you manage access to applications that
+users have downloaded from Android Market. To use licensing in an application,
+you need to have a publisher account on Android Market so that you can
+publish the application to users. </p>
+
+<p>If you don't already have a publisher account, you need to register for one
+using your Google account and agree to the terms of service. Once you are
+registered, you can upload applications at your convenience and begin debugging
+and testing your licensing implementation. For more information about publishing
+on Android Market, see <a
+href="{@docRoot}guide/publishing/publishing.html">Publishing Your
+Applications</a></p>
+
+<p>To register as an Android Market developer and set up your publisher account,
+visit the Android Market publisher site:</p>
+
+<p style="margin-left:2em;"><a
+href="http://market.android.com/publish">http://market.android.com/publish</a>
+</p>
+
+<p>If you already have a publisher account on Android Market, use your existing
+account to set up licensing. You <em>do not</em> need to register for a new
+account to support licensing (and doing so is not recommended, especially if you
+are adding licensing support to applications that you have already published).
+In all cases, if you have published applications, you manage licensing for those
+applications through the account on which the applications are published. </p>
+
+<p>Once your publisher account is set up, use the account to:</p>
+
+<ul>
+<li>Obtain a public key for licensing</li>
+<li>Debug and test an application's licensing implementation, prior to
+publishing the application</li>
+<li>Publish the applications to which you have added licensing support</li>
+</ul>
+
+<h4>Administrative settings for licensing</h4>
+
+<p>Once you are signed into your publisher account, you can manage several
+administrative controls for Android Market licensing. The controls are available
+in the Edit Profile page, in the "Licensing" panel, shown below. The controls
+let you: </p>
+
+<ul>
+<li>Set up multiple "test accounts", identified by email address. The licensing
+server allows users signed into test accounts on a device or emulator to send
+license checks and receive static test responses.</li>
+<li>Obtain the account's public key for licensing. When you are implementing
+licensing in an application, you must copy the public key string into the
+application.</li>
+<li>Configure static test responses that the server sends, when it receives a
+license check for an application uploaded to the publisher account, from a user
+signed in to the publisher account or a test account.</li>
+</ul>
+
+<div style="margin-bottom:2em;">
+
+<img src="{@docRoot}images/licensing_public_key.png" style="text-align:left;margin-bottom:0;" />
+<div style="margin:0 2em;padding:0"><strong>Figure 2.</strong> The Licensing
+panel of your account's Edit Profile page lets you manage administrative
+settings for licensing.</div>
+</div>
+
+<p>For more information about how to work with test accounts and static test
+responses, see <a href="#test-env">Setting Up a Testing Environment</a>, below.
+
+<h2 id="dev-setup">Setting Up the Development Environment</h2>
+
+<p>Once you've set up your publisher account on Android Market, the next step is
+to set up your development environment for licensing. </p>
+
+<p>Setting up your environment for licensing involves these tasks:</p>
+
+<ol>
+<li><a href="#download-sdk">Downloading the latest SDK</a>, if you haven't already done so </li>
+<li><a href="#runtime-setup">Setting up the runtime environment</a> for development</a></li>
+<li><a href="#download-lvl">Downloading the Market Licensing component</a> into your SDK </li>
+<li><a href="#lvl-setup">Setting up the Licensing Verification Library</a></li>
+<li><a href="#add-library">Including the LVL library project in your application</a></li>
+</ol>
+
+<p>The sections below describe these tasks. When you are done with setup,
+you can begin <a href="#app-integration">integrating the LVL into your applications</a>.</p>
+
+<p>To get started, you need to set up a proper runtime environment on which
+you can run, debug and test your application's implementation of license
+checking and enforcement. </p>
+
+
+<h3 id="download-sdk">Downloading the latest SDK</h3>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>Licensing sample application</h2>
+
+<p>To work with Android Market licensing, you need a functioning Android
+application to which you can add licensing support. </p>
+
+<p style="margin-top:.5em;">If you are new to Android
+and don't yet have a functioning application, the LVL component includes a sample
+application that you can set up as a new application project. The sample provides
+a complete, working example of how licensing works. For more information, see <a
+href="#download-lvl">Downloading the LVL</a>.</p>
+
+</div>
+</div>
+
+<p>If you haven't done so, you need to download the Android SDK before you can
+develop Android applications. The SDK provides the tools that you need to build
+and debug Android applications, including applications that use Android Market
+licensing. For complete information, including installation instructions, see
+the <a href="{@docRoot}sdk/index.html">Android SDK</a>. </p>
+
+<p>If you have already installed the SDK, make sure to update the
+SDK tools and ADT Plugin to the latest versions. You can update the SDK tools
+using the Android SDK and AVD Manager and ADT through <strong>Help</strong> &gt;
+<strong>Software Updates...</strong> in Eclipse. </p>
+
+<p>After you've installed the latest SDK and tools, set up your development
+environment as described below. </p>
+
+
+<h3 id="runtime-setup">Setting up the runtime environment</h3>
+
+<p>As described earlier, applications check licensing status not by contacting
+the licensing server directly, but by binding to a service provided by the
+Android Market application and initiating a license check request. The Android
+Market service then handles the direct communication with the licensing server
+and finally routes the response back to your application. To debug and test
+licensing in your application, you need to set up a runtime environment that
+includes the necessary Android Market service, so that your application is able
+to send license check requests to the licensing server. </p>
+
+<p>There are two types of runtime environment that you can use: </p>
+
+<ul>
+<li>An Android-powered device that includes the Android Market application, or</li>
+<li>An Android emulator running the Google APIs Add-on, API level 8 (release 2)
+or higher</li>
+</ul>
+
+<p>The sections below provide more information. </p>
+
+<h4 id="runtime-device">Running on a device</h4>
+
+<p>You can use an Android-powered device as the runtime environment for
+debugging and testing licensing on your application.</p>
+
+<p>The device you use must:</p>
+
+<ul>
+<li>Run a standard version of the Android 1.5 or later (API level
+3 or higher) platform, <em>and</em> </li>
+<li>Run a system image on which the Android Market client application
+is preinstalled. </li>
+</ul>
+
+<p>If Android Market is not preinstalled in the system image, your application won't
+be able to communicate with the Android Market licensing server. </p>
+
+<p>For general information about how to set up a device for use in developing
+Android applications, see <a
+href="{@docRoot}guide/developing/device.html">Developing on a Device</a>.</p>
+
+<h4 id="runtime-emulator">Running on an Android emulator</h4>
+
+<p>You can also use an Android emulator as your runtime
+environment for debugging and testing licensing.</p>
+
+<p>Because the standard Android platforms provided in the Android SDK <em>do
+not</em> include Android Market, you need to download the Google APIs Add-On
+platform, API Level 8 (or higher), from the SDK repository. After downloading
+the add-on, you need to create an AVD configuration that uses that system image.
+</p>
+
+<p>The Google APIs Add-On does not include the full Android Market client.
+However, it does provide: </p>
+
+<ul>
+<li>An Android Market background service that implements the
+ILicensingService remote interface, so that your application can
+send license checks over the network to the licensing server. </li>
+<li>A set of underlying account services that let you add an a Google account on
+the AVD and sign in using your publisher account or test account credentials.
+Signing in using your publisher or test account enables you to debug and test
+your application without having publish it. For more information see <a
+href="#acct-signin">Signing in to an authorized account</a>, below.</li>
+</ul>
+
+<p>Several versions of the add-on are available in the SDK repository, but only
+<strong>Google APIs Add-On, API 8 (release 2) or higher</strong> version of the
+add-on includes the necessary Android Market services. This means that you
+cannot use Google APIs Add-On API 7 or lower as a runtime environment for
+developing licensing on an emulator.</p>
+
+<div style="margin-bottom:2em;">
+
+<img src="{@docRoot}images/licensing_gapis_8.png" style="text-align:left;margin-bottom:0;" />
+<div style="margin:0 2em;padding:0"><strong>Figure 3.</strong> Google APIs
+Add-On, API 8 (release 2) or higher lets you debug and test your licensing
+implementation in an emulator.</div>
+</div>
+
+<p>To set up an emulator for adding licensing to an application, follow
+these steps: </p>
+
+<ol>
+ <li>Launch the Android SDK and AVD Manager. </li>
+ <li>In the <strong>Available Packages</strong> panel, select and download the
+SDK component "Google APIs (Google Inc.) - API Level 8" (or higher) from the SDK
+repository, as shown in the figure above.
+ <p>When the download is complete, use the Android SDK and AVD Manager to
+create a new AVD based on that component, described next.</p></li>
+ <li>In the <strong>Virtual
+Devices</strong> panel of the Android SDK and AVD Manager, click
+<strong>New</strong> and set the configuration details for the new AVD. </li>
+ <li>In the dialog that appears, assign a descriptive name to the AVD and then
+use the "Target" menu to choose the "Google APIs (Google Inc.) - API Level 8" as
+the system image to run on the new AVD. Set the other configuration details as
+needed and then click <strong>Create AVD</strong> to finish. The SDK tools
+create the new AVD configuration, which then appears in the list of available
+Android Virtual Devices.</li>
+</ol>
+
+<p>If you are not familiar with AVDs or how to use them, see <a
+href="{@docRoot}guide/developing/tools/avd.html">Android Virtual Devices</a>.</p>
+
+<h4 id="project-update">Updating your project configuration</h4>
+
+<p>After you set up a runtime environment that meets the requirements described
+above &mdash; either on an actual device or on an emulator &mdash; make sure to
+update your application project or build scripts as needed, so that your compiled
+<code>.apk</code> files that use licensing are deployed into that environment.
+In particular, if you are developing in Eclipse, make sure that you set up a
+Run/Debug Configuration that targets the appropriate device or AVD. </p>
+
+<p>You do not need to make any changes to your application's
+build configuration, provided that the project is already configured to compile
+against a standard Android 1.5 (API level 3) or higher library. For example:
+
+<ul>
+<li>If you have an existing application that is compiled against
+the Android 1.5 library, you do not need to make any changes to your
+build configuration to support licensing. The build target meets the minimum
+requirements for licensing, so you would continue building
+against the same version of the Android platform.</li>
+
+<li>Similarly, if you are building against Android 1.5 (API level 3) but
+are using an emulator running the Google APIs Add-On API 8 as the application's
+runtime environment, there is no need to change your application's build
+configuration. </li>
+</ul>
+
+<p>In general, adding licensing to an application should have no impact
+whatsoever on the application's build configuration.</p>
+
+
+<h3 id="download-lvl">Downloading the LVL</h3>
+
+<p>The License Verification Library (LVL) is a collection of helper classes that
+greatly simplify the work that you need to do to add licensing to your
+application. In all cases, we recommend that you download the LVL and use it as
+the basis for the licensing implementation in your application.</p>
+
+<p>The LVL is available as a downloadable component of the Android SDK. The
+component includes: </p>
+
+<ul>
+<li>The LVL sources, stored inside an Android library project. </li>
+<li>An example application called "sample" that depends on the LVL library
+project. The example illustrates how an application uses the library helper
+classes to check and enforce licensing.</li>
+</ul>
+
+<p>To download the LVL component into your development environment, use the
+Android SDK and AVD Manager. Launch the Android SDK and AVD Manager and then
+select the "Market Licensing" component, as shown in the figure below.
+Accept the terms and click <strong>Install Selected</strong> to begin the download. </p>
+
+<div style="margin-bottom:2em;">
+
+<img src="{@docRoot}images/licensing_package.png" style="text-align:left;margin-bottom:0;" />
+<div style="margin:0 2em;padding:0"><strong>Figure 4.</strong> The Market
+Licensing package contains the LVL and the LVL sample application. </div>
+</div>
+
+<p>When the download is complete, the Android SDK and AVD Manager installs both
+the LVL library project and the example application into these directories: </p>
+
+<p style="margin-left:2em"><code>&lt;<em>sdk</em>&gt;/market_licensing/library/</code>
+&nbsp;&nbsp;(the LVL library project)<br />
+<code>&lt;<em>sdk</em>&gt;/market_licensing/sample/</code>&nbsp;&nbsp;(the example
+application)</p>
+
+<p>If you aren't familiar with how to download components into your SDK, see the
+<a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a>
+document. </p>
+
+
+<h3 id="lvl-setup">Setting Up the Licensing Verification Library</h3>
+
+<p>After downloading the LVL to your computer, you need to set it up in your
+development environment, either as an Android library project or by
+copying (or importing) the library sources directly into your existing
+application package. In general, using the LVL as a library project is recommended,
+since it lets you reuse your licensing code across multiple applications and
+maintain it more easily over time. Note that the LVL is not designed to be
+compiled separately and added to an application as a static .jar file. </p>
+
+<h4>Moving the library sources to a new location</h4>
+
+<p>Because you will be customizing the LVL sources to some extent, you should
+make sure to <em>move or copy</em> the library sources (the entire
+directory at <code>&lt;<em>sdk</em>&gt;/market_licensing/library/</code>)
+to a working directory outside of the SDK. You should then use the relocated
+sources as your working set. If you are using a source-code management
+system, add and track the sources that are in the working location rather
+than those in default location in the SDK. </p>
+
+<p>Moving the library sources is important is because, when you later update the
+Market licensing package, the SDK installs the new files to the same location as
+the older files. Moving your working library files to a safe location ensures
+that your work won't be inadvertently overwritten should you download a new
+version of the LVL.</p>
+
+<h4>Creating the LVL as a library project</h4>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>Working with library projects</h2>
+
+<p>The LVL is provided as an Android library project, which means that you can
+share its code and resources across multiple applications. </p>
+
+<p style="margin-top:.5em;">If you aren't familiar with library projects or how
+to use them, read more in <a
+href="{@docRoot}guide/developing/eclipse-adt.html#libraryProject">Developing in
+Eclipse with ADT</a> or <a
+href="{@docRoot}guide/developing/other-ide.html#libraryProject">Developing in
+Other IDEs</a>, as appropriate for your environment.</p>
+
+</div>
+</div>
+
+<p>The recommended way of using the LVL is setting it up as a new Android
+<em>library project</em>. A library project is a type of development project
+that holds shared Android source code and resources. Other Android application
+projects can reference the library project and, at build time, include its
+compiled sources in their <code>.apk</code> files. In the context of licensing,
+this means that you can do most of your licensing development once, in a library
+project, then include the library sources in your various application projects.
+In this way, you can easily maintain a uniform implementation of licensing
+across all of your projects and maintain it centrally. </p>
+
+<p>The LVL is provided as a configured library project &mdash; once you have
+downloaded it, you can start using it right away. </p>
+
+<p>If you are working in Eclipse with ADT, you need to add the LVL to your
+workspace as a new development project, in the same way as you would a new
+application project. </p>
+
+<ol>
+<li>Use the New Project Wizard to create a new
+project from existing sources. Select the LVL's <code>library</code> directory
+(the directory containing the library's AndroidManifest.xml file) as the project
+root.</li>
+<li>When you are creating the library project, you can select any application
+name, package, and set other fields as needed. </li>
+<li>For the library's build target, select Android 1.5 (API level 3) or higher.</li>
+</ol>
+
+<p> When created, the project is
+predefined as a library project in its <code>default.properties</code> file, so
+no further configuration is needed. </p>
+
+<p>For more information about how to create an application project or work with
+library projects in Eclipse, see <a
+href="{@docRoot}guide/developing/eclipse-adt.html#CreatingAProject">Developing
+in Eclipse with ADT</a>.</p>
+
+<h4>Copying the LVL sources to your application</h4>
+
+<p>As an alternative to adding the LVL as a library project, you can copy the
+library sources directly into your application. To do so, copy (or import) the
+LVL's <code>library/src/com</code> directory into your application's
+<code>src/</code> directory.</p>
+
+<p>If you add the LVL sources directly to your application, you can skip the
+next section and start working with the library, as described in <a
+href="#app-integration"></a>.</p>
+
+
+<h3 id="add-library">Including the LVL library project sources in your
+application</h3>
+
+<p>If you want to use the LVL sources as a library project, you need to add a
+reference to the LVL library project in your application project properties. This tells
+build tools to include the LVL library project sources in your application at
+compile time. The process for adding a reference to a library project depends
+on your development environment, as described below.</p>
+
+<p> If you are developing in Eclipse with ADT, you should already have added the
+library project to your workspace, as described in the previous section. If you
+haven't done that already, do it now before continuing. </p>
+
+<p>Next, open the application's project properties window, as shown below.
+Select the "Android" properties group and click <strong>Add</strong>, then
+choose the LVL library project (com_android_vending_licensing) and click
+<strong>OK</strong>. For more information, see
+<a href="{@docRoot}guide/developing/eclipse-adt.html#libraryProject">Developing
+in Eclipse with ADT</a></p>
+
+<div style="margin-bottom:2em;">
+
+<img src="{@docRoot}images/licensing_add_library.png" style="text-align:left;margin-bottom:0;" />
+<div style="margin:0 2em;padding:0"><strong>Figure 5.</strong> If you are
+working in Eclipse with ADT, you can add the LVL library project to your
+application from the application's project properties.</div>
+</div>
+
+<p>If you are developing using the SDK command-line tools, navigate to the
+directory containing your application project and open the
+<code>default.properties</code> file. Add a line to the file that specifies the
+<code>android.library.reference.&lt;n&gt;</code> key and the path to the
+library. For example: </p>
+
+<pre>android.library.reference.1=path/to/library_project</pre>
+
+<p>Alternatively, you can use this command to update the project
+properties, including the reference to the library project:</p>
+
+<pre class="no-pretty-print" style="color:black">android update lib-project
+--target <em>&lt;target_ID&gt;</em> \
+--path <em>path/to/my/app_project</em> \
+--library <em>path/to/my/library_project</em>
+</pre>
+
+<p>For more information about working with library projects, see <a
+href="{@docRoot}guide/developing/eclipse-adt.html#libraryProject">Developing
+in Eclipse with ADT</a> or <a
+href="{@docRoot}guide/developing/other-ide.html#libraryProject">Developing in
+Other IDEs</a>, as appropriate for your environment.</p>
+
+
+<h2 id="app-integration">Integrating the LVL with Your Application</h2>
+
+<p>Once you've followed the steps above to set up a publisher account and
+development environment, you are ready to begin integrating the LVL with your
+application. </p>
+
+<p>Integrating the LVL with your application code involves these tasks:</p>
+
+<ol>
+<li><a href="#manifest-permission">Adding the licensing permission</a> your application's manifest.</li>
+<li><a href="#impl-Policy">Implementing a Policy</a> &mdash; you can choose one of the full implementations provided in the LVL or create your own.</li>
+<li><a href="#impl-Obfuscator">Implementing an Obfuscator</a>, if your Policy will cache any license response data. </li>
+<li><a href="#impl-lc">Adding code to check the license</a> in your application's main Activity</li>
+<li><a href="#impl-DeviceLimiter">Implementing a DeviceLimiter</a> (optional and not recommended for most applications)</li>
+</ol>
+
+<p>The sections below describe these tasks. When you are done with the
+integration, you should be able to compile your application successfully and you
+can begin testing, as described in <a href="#test-env">Setting Up the Test
+Environment</a>.</p>
+
+<p>For an overview of the full set of source files included in the LVL, see <a
+href="#lvl-summary">Summary of LVL Classes and Interfaces</a>.</p>
+
+
+<h3 id="manifest-permission">Adding the licensing permission to your
+AndroidManifest.xml</h3>
+
+<p>To use the Android Market application for sending a license check to the
+server, your application must request the proper permission,
+<code>com.android.vending.CHECK_LICENSE</code>. If your application does
+not declare the licensing permission but attempts to initiate a license check,
+the LVL throws a security exception.</p>
+
+<p>To request the licensing permission in your application, declare a <a
+href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><code>&lt;uses-permission&gt;</code></a>
+element as a child of <code>&lt;manifest&gt;</code>, as follows: </p>
+
+<p style="margin-left:2em;"><code>&lt;uses-permission
+android:name="com.android.vending.CHECK_LICENSE"&gt;</code></p>
+
+<p>For example, here's how the LVL sample application declares the permission:
+</p>
+
+<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
+
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" ..."&gt;
+ ...
+ &lt;!-- Devices &gt;= 3 have version of Android Market that supports licensing. --&gt;
+ &lt;uses-sdk android:minSdkVersion="3" /&gt;
+ &lt;!-- Required permission to check licensing. --&gt;
+ &lt;uses-permission android:name="com.android.vending.CHECK_LICENSE" /&gt;
+ ...
+&lt;/manifest&gt;
+</pre>
+
+<p class="note"><strong>Note:</strong> Currently, you cannot declare the
+<code>CHECK_LICENSE</code> permission in the LVL library project's manifest,
+because the SDK Tools will not merge it into the manifests of dependent
+applications. Instead, you must declare the permission in each dependent
+application's manifest. </p>
+
+
+<h3 id="impl-Policy">Implementing a Policy</h3>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>ServerManagedPolicy</h2>
+
+<p>The LVL includes a complete Policy implementation called ServerManagedPolicy
+that makes use of license-management settings provided by the Android Market
+server. </p>
+
+<p style="margin-top:.5em;">Use of ServerManagedPolicy as the basis for your
+Policy is strongly recommended. For more information, see <a
+href="#ServerManagedPolicy">ServerManagedPolicy</a> section, below.</p>
+
+</div>
+</div>
+
+<p>Android Market licensing service does not itself determine whether a
+given user with a given license should be granted access to your application.
+Rather, that responsibility is left to a Policy implementation that you provide
+in your application.</p>
+
+<p>Policy is an interface declared by the LVL that is designed to hold your
+application's logic for allowing or disallowing user access, based on the result
+of a license check. To use the LVL, your application <em>must</em> provide an
+implementation of Policy. </p>
+
+<p>The Policy interface declares two methods, <code>allowAccess()</code> and
+<code>processServerResponse()</code>, which are called by a LicenseChecker
+instance when processing a response from the license server. It also declares an
+enum called <code>LicenseResponse</code>, which specifies the license response
+value passed in calls to <code>processServerResponse()</code>. </p>
+
+<ul>
+<li><code>processServerResponse()</code> lets you preprocess the raw response
+data received from the licensing server, prior to determining whether to grant
+access.
+
+<p>A typical implementation would extract some or all fields from the license
+response and store the data locally to a persistent store, such as through
+{@link android.content.SharedPreferences} storage, to ensure that the data is
+accessible across application invocations and device power cycles. For example,
+a Policy would maintain the timestamp of last successful license check, the
+retry count, the license validity period, and similar information in a
+persistent store, rather than resetting the values each time the application is
+launched.</p>
+
+<p>When storing response data locally, the Policy must ensure that the data is
+obfuscated (see <a href="#impl-Obfuscator">Implementing an Obfuscator</a>,
+below).</p></li>
+
+<li><code>allowAccess()</code> determines whether to grant the user access to
+your application, based on any available license response data (from the
+licensing server or from cache) or other application-specific information. For
+example, your implementation of <code>allowAccess()</code> could take into
+account additional criteria, such as usage or other data retrieved from a
+backend server. In all cases, an implementation of <code>allowAccess()</code>
+should only return <code>true</code> if the user is licensed to use the
+application, as determined by the licensing server, or if there is a transient
+network or system problem that prevents the license check from completing. In
+such cases, your implementation can maintain a count of retry responses and
+provisionally allow access until the next license check is complete.</li>
+
+</ul>
+
+<p>To simplify the process of adding licensing to your application and to
+provide an illustration of how a Policy should be designed, the LVL includes
+two full Policy implementations that you can use without modification or
+adapt to your needs:</p>
+
+<ul>
+<li><a href="#ServerManagedPolicy">ServerManagedPolicy</a>, a flexible Policy
+that uses server-provided settings and cached responses to manage access across
+varied network conditions, and</li>
+<li><a href="#StrictPolicy">StrictPolicy</a>, which does not cache any response
+data and allows access <em>only</em> if the server returns a licensed
+response.</li>
+</ul>
+
+<p>For most applications, the use of ServerManagedPolicy is highly
+recommended. ServerManagedPolicy is the LVL default and is integrated with
+the LVL sample application.</p>
+
+
+<h4 id="custom-policies">Guidelines for custom policies</h4>
+
+<p>In your licensing implementation, you can use one of the complete policies
+provided in the LVL (ServerManagedPolicy or StrictPolicy) or you can create a
+custom policy. For any type of custom policy, there are several important design
+points to understand and account for in your implementation.</p>
+
+<p>The licensing server applies general request limits to guard against overuse
+of resources that could result in denial of service. When an application exceeds
+the request limit, the licensing server returns a 503 response, which gets
+passed through to your application as a general server error. This means that no
+license response will be available to the user until the limit is reset, which
+can affect the user for an indefinite period.</p>
+
+<p>If you are designing a custom policy, we recommend that the Policy:
+<ol>
+<!-- <li>Limits the number of points at which your app calls for a license check
+to the minimum. </li> -->
+<li>Caches (and properly obfuscates) the most recent successful license response
+in local persistent storage.</li>
+<li>Returns the cached response for all license checks, for as long as the
+cached response is valid, rather than making a request to the licensing server.
+Setting the response validity according to the server-provided <code>VT</code>
+extra is highly recommended. See <a href="#extras">Server Response Extras</a>
+for more information.</li>
+<li>Uses an exponential backoff period, if retrying any requests the result in
+errors. Note that the Android Market client automatically retries failed
+requests, so in most cases there is no need for your Policy to retry them.</li>
+<li>Provides for a "grace period" that allows the user to access your
+application for a limited time or number of uses, while a license check is being
+retried. The grace period benefits the user by allowing access until the next
+license check can be completed successfully and it benefits you by placing a
+hard limit on access to your application when there is no valid license response
+available.</li>
+</ol>
+
+<p>Designing your Policy according to the guidelines listed above is critical,
+because it ensures the best possible experience for users while giving you
+effective control over your application even in error conditions. </p>
+
+<p>Note that any Policy can use settings provided by the licensing server to
+help manage validity and caching, retry grace period, and more. Extracting the
+server-provided settings is straightforward and making use of them is highly
+recommended. See the ServerManagedPolicy implementation for an example of how to
+extract and use the extras. For a list of server settings and information about
+how to use them, see <a href="#extras">Server Response Extras</a> in the
+Appendix of this document.</p>
+
+<h4 id="ServerManagedPolicy">ServerManagedPolicy</h4>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>Server Response Extras</h2>
+
+<p>For certain types of licensing responses, the licensing server appends extra
+settings to the responses, to help the application manage licensing effectively.
+</p>
+
+<p style="margin-top:.5em;">See <a href="#extras">Server Response Extras</a> for
+a list of settings and <code>ServerManagedPolicy.java</code> for information
+about how a Policy can use the extras.</p>
+
+</div>
+</div>
+
+<p>The LVL includes a full and recommended implementation of the Policy
+interface called ServerManagedPolicy. The implementation is integrated with the
+LVL classes and serves as the default Policy in the library. </p>
+
+<p>ServerManagedPolicy provides all of the handling for license and retry
+responses. It caches all of the response data locally in a
+{@link android.content.SharedPreferences} file, obfuscating it with the
+application's Obfuscator implementation. This ensures that the license response
+data is secure and persists across device power cycles. ServerManagedPolicy
+provides concrete implementations of the interface methods
+<code>processServerResponse()</code> and <code>allowAccess()</code> and also
+includes a set of supporting methods and types for managing license
+responses.</p>
+
+<p>Importantly, a key feature of ServerMangedPolicy is its use of
+server-provided settings as the basis for managing licensing across an
+application's refund period and through varying network and error conditions.
+When an application contacts the Android Market server for a license check, the
+server appends several settings as key-value pairs in the extras field of certain
+license response types. For example, the server provides recommended values for the
+application's license validity period, retry grace period, and maximum allowable
+retry count, among others. ServerManagedPolicy extracts the values from the
+license response in its <code>processServerResponse()</code> method and checks
+them in its <code>allowAccess()</code> method. For a list of the server-provided
+settings used by ServerManagedPolicy, see <a href="#extras">Server Response
+Extras</a> in the Appendix of this document.</p>
+
+<p>For convenience, best performance, and the benefit of using license settings
+from the Android Market server, <strong>using ServerManagedPolicy as your
+licensing Policy is strongly recommended</strong>. </p>
+
+<p>If you are concerned about the security of license response data that is
+stored locally in SharedPreferences, you can use a stronger obfuscation
+algorithm or design a stricter Policy that does not store license data. The LVL
+includes an example of such a Policy &mdash; see <a
+href="#StrictPolicy">StrictPolicy</a> for more information.</p>
+
+<p>To use ServerManagedPolicy, simply import it to your Activity, create an
+instance, and pass a reference to the instance when constructing your
+LicenseChecker. See <a href="#lc-lcc">Instantiate LicenseChecker and
+LicenseCheckerCallback</a> for more information. </p>
+
+<h4 id="StrictPolicy">StrictPolicy</h4>
+
+<p>The LVL includes an alternative full implementation of the Policy interface
+called StrictPolicy. The StrictPolicy implementation provides a more restrictive
+Policy than ServerManagedPolicy, in that it does not allow the user to access
+the application unless a license response is received from the server at the
+time of access that indicates that the user is licensed.</p>
+
+<p>The principal feature of StrictPolicy is that it does not store <em>any</em>
+license response data locally, in a persistent store. Because no data is stored,
+retry requests are not tracked and cached responses can not be used to fulfill
+license checks. The Policy allows access only if:</p>
+
+<ul>
+<li>The license response is received from the licensing server, and </li>
+<li>The license response indicates that the user is licensed to access the
+application. </li>
+</ul>
+
+<p>Using StrictPolicy is appropriate if your primary concern is to ensure that,
+in all possible cases, no user will be allowed to access the application unless
+the user is confirmed to be licensed at the time of use. Additionally, the
+Policy offers slightly more security than ServerManagedPolicy &mdash; since
+there is no data cached locally, there is no way a malicious user could tamper
+with the cached data and obtain access to the application.</p>
+
+<p>At the same time, this Policy presents a challenge for normal users, since it
+means that they won't be able to access the application when there is no network
+(cell or wi-fi) connection available. Another side-effect is that your
+application will send more license check requests to the server, since using a
+cached response is not possible.</p>
+
+<p>Overall, this policy represents a tradeoff of some degree of user convenience
+for absolute security and control over access. Consider the tradeoff carefully
+before using this Policy.</p>
+
+<p>To use StrictPolicy, simply import it to your Activity, create an instance,
+and pass a reference to it when constructing your LicenseChecker. See
+<a href="#lc-lcc">Instantiate LicenseChecker and LicenseCheckerCallback</a>
+for more information. </p>
+
+<h3 id="impl-Obfuscator">Implementing an Obfuscator</h3>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>AESObfuscator</h2>
+
+<p>The LVL includes a full Obfuscator implementation in the
+<code>AESObfuscator.java</code> file. The Obfuscator uses AES encryption to
+obfuscate/unobfuscate data. If you are using a Policy (such as
+ServerManagedPolicy) that caches license response data, using AESObfuscator as
+basis for your Obfuscator implementation is highly recommended. </p>
+
+</div>
+</div>
+
+<p>A typical Policy implementation needs to save the license response data for
+an application to a persistent store, so that it is accessible across
+application invocations and device power cycles. For example, a Policy would
+maintain the timestamp of the last successful license check, the retry count,
+the license validity period, and similar information in a persistent store,
+rather than resetting the values each time the application is launched. The
+default Policy included in the LVL, ServerManagedPolicy, stores license response
+data in a {@link android.content.SharedPreferences} instance, to ensure that the
+data is persistent. </p>
+
+<p>Because the Policy will use stored license response data to determine whether
+to allow or disallow access to the application, it <em>must</em> ensure that any
+stored data is secure and cannot be reused or manipulated by a root user on a
+device. Specifically, the Policy must always obfuscate the data before storing
+it, using a key that is unique for the application and device. Obfuscating using
+a key that is both application-specific and device-specific is critical, because
+it prevents the obfuscated data from being shared among applications and
+devices.</p>
+
+<p>The LVL assists the application with storing its license response data in a
+secure, persistent manner. First, it provides an Obfuscator
+interface that lets your application supply the obfuscation algorithm of its
+choice for stored data. Building on that, the LVL provides the helper class
+PreferenceObfuscator, which handles most of the work of calling the
+application's Obfuscator class and reading and writing the obfuscated data in a
+SharedPreferences instance. </p>
+
+<p>The LVL provides a full Obfuscator implementation called
+AESObfuscator that uses AES encryption to obfuscate data. You can
+use AESObfuscator in your application without modification or you
+can adapt it to your needs. For more information, see the next section.</p>
+
+
+<h4 id="AESObfuscator">AESObfuscator</h4>
+
+<p>The LVL includes a full and recommended implementation of the Obfuscator
+interface called AESObfuscator. The implementation is integrated with the
+LVL sample application and serves as the default Obfuscator in the library. </p>
+
+<p>AESObfuscator provides secure obfuscation of data by using AES to
+encrypt and decrypt the data as it is written to or read from storage.
+The Obfuscator seeds the encryption using three data fields provided
+by the application: </p>
+
+<ol>
+<li>A salt &mdash; an array of random bytes to use for each (un)obfuscation. </li>
+<li>An application identifier string, typically the package name of the application.</li>
+<li>A device identifier string, derived from as many device-specific sources
+as possible, so as to make it as unique.</li>
+</ol>
+
+<p>To use AESObfuscator, first import it to your Activity. Declare a private
+static final array to hold the salt bytes and initialize it to 20 randomly
+generated bytes.</p>
+
+<pre> ...
+ // Generate 20 random bytes, and put them here.
+ private static final byte[] SALT = new byte[] {
+ -46, 65, 30, -128, -103, -57, 74, -64, 51, 88, -95,
+ -45, 77, -117, -36, -113, -11, 32, -64, 89
+ };
+ ...
+</pre>
+
+<p>Next, declare a variable to hold a device identifier and generate a value for
+it in any way needed. For example, the sample application included in the LVL
+queries the system settings for the
+<code>android.Settings.Secure.ANDROID_ID</code>, which is unique to each device.
+</p>
+
+<p>Note that, depending on the APIs you use, your application might need to
+request additional permissions in order to acquire device-specific information.
+For example, to query the {@link android.telephony.TelephonyManager} to obtain
+the device IMEI or related data, the application will also need to request the
+<code>android.permission.READ_PHONE_STATE</code> permission in its manifest.</p>
+
+<p>Before requesting new permissions for the <em>sole purpose</em> of acquiring
+device-specific information for use in your Obfuscator, consider
+how doing so might affect your application or its filtering on Android Market
+(since some permissions can cause the SDK build tools to add
+the associated <code>&lt;uses-feature&gt;</code>).</p>
+
+<p>Finally, construct an instance of AESObfuscator, passing the salt,
+application identifier, and device identifier. You can construct the instance
+directly, while constructing your Policy and LicenseChecker. For example:</p>
+
+<pre> ...
+ // Construct the LicenseChecker with a Policy.
+ mChecker = new LicenseChecker(
+ this, new ServerManagedPolicy(this,
+ new AESObfuscator(SALT, getPackageName(), deviceId)),
+ BASE64_PUBLIC_KEY // Your public licensing key.
+ );
+ ...
+</pre>
+
+<p>For a complete example, see MainActivity in the LVL sample application.</p>
+
+
+<h3 id="impl-lc">Checking the license from your application's main Activity</h3>
+
+<p>Once you've implemented a Policy for managing access to your application, the
+next step is to add a license check to your application, which initiates a query
+to the licensing server if needed and manages access to the application based on
+the license response. All of the work of adding the license check and handling
+the response takes place in your main {@link android.app.Activity} source file.
+</p>
+
+<p>To add the license check and handle the response, you must:</p>
+
+<ol>
+ <li><a href="#imports">Add imports</a></li>
+ <li><a href="#lc-impl">Implement LicenseCheckerCallback</a> as a private inner class</li>
+ <li><a href="#thread-handler">Create a Handler</a> for posting from LicenseCheckerCallback to the UI thread</li>
+ <li><a href="#lc-lcc">Instantiate LicenseChecker</a> and LicenseCheckerCallback</li>
+ <li><a href="#check-access">Call checkAccess()</a> to initiate the license check</li>
+ <li><a href="#account-key">Embed your public key</a> for licensing</li>
+ <li><a href="#handler-cleanup">Call your LicenseChecker's onDestroy() method</a> to close IPC connections.</li>
+</ol>
+
+<p>The sections below describe these tasks. </p>
+
+<h4 id="lc-overview">Overview of license check and response</h4>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>Example: MainActivity</h2>
+
+<p>The sample application included with the LVL provides a full example of how
+to initiate a license check and handle the result, in the
+<code>MainActivity.java</code> file.</p>
+
+</div>
+</div>
+
+<p>In most cases, you should add the license check to your application's main
+{@link android.app.Activity}, in the <code>onCreate()</code> method. This
+ensures that when the user launches your application directly, the license check
+will be invoked immediately. In some cases, you can add license checks in other
+locations as well. For example, if your application includes multiple Activity
+components that other applications can start by {@link android.content.Intent},
+you could add license checks in those Activities.</p>
+
+<p>A license check consists of two main actions: </p>
+
+<ul>
+<li>A call to a method to initiate the license check &mdash; in the LVL, this is
+a call to the <code>checkAccess()</code> method of a LicenseChecker object that
+you construct.</li>
+<li>A callback that returns the result of the license check. In the LVL, this is
+a <code>LicenseCheckerCallback</code> interface that you implement. The
+interface declares two methods, <code>allow()</code> and
+<code>dontAllow()</code>, which are invoked by the library based on to the
+result of the license check. You implement those two methods with whatever logic
+you need, to allow or disallow the user access to your application. Note that
+these methods do not determine <em>whether</em> to allow access &mdash; that
+determination is the responsibility of your Policy implementation. Rather, these
+methods simply provide the application behaviors for <em>how</em> to allow and
+disallow access (and handle application errors).</li>
+</ul>
+
+<div style="margin-bottom:2em;">
+
+<img src="{@docRoot}images/licensing_flow.png" style="text-align:left;margin-bottom:0;margin-left:3em;" />
+<div style="margin:.5em 0 1.5em 2em;padding:0"><strong>Figure 6.</strong> Overview of a
+typical license check interaction.</div>
+</div>
+
+<p>The diagram above illustrates how a typical license check takes place: </p>
+
+<ol>
+<li>Code in the application's main Activity instantiates LicenseCheckerCallback
+and LicenseChecker objects. When constructing LicenseChecker, the code passes in
+{@link android.content.Context}, a Policy implementation to use, and the
+publisher account's public key for licensing as parameters. </li>
+<li>The code then calls the <code>checkAccess()</code> method on the
+LicenseChecker object. The method implementation calls the Policy to determine
+whether there is a valid license response cached locally, in
+{@link android.content.SharedPreferences}.
+<ul>
+<li>If so, the <code>checkAccess()</code> implementation calls
+<code>allow()</code>.</li>
+<li>Otherwise, the LicenseChecker initiates a license check request that is sent
+to the licensing server.</li>
+</ul>
+</li>
+<li>When a response is received, LicenseChecker creates a LicenseValidator that
+verifies the signed license data and extracts the fields of the response, then
+passes them to your Policy for further evaluation.
+ <ul>
+ <li>If the license is valid, the Policy caches the response in
+SharedPreferences and notifies the validator, which then calls the
+<code>allow()</code> method on the LicenseCheckerCallback object. </li>
+ <li>If the license not valid, the Policy notifies the validator, which calls
+the <code>dontAllow()</code> method on LicenseCheckerCallback. </li>
+ </ul>
+</li>
+<li>In case of a recoverable local or server error, such as when the network is
+not available to send the request, LicenseChecker passes a RETRY response to
+your Policy's <code>processServerResponse()</code> method. </li>
+<li>In case of a application error, such as when the application attempts to
+check the license of an invalid package name, LicenseChecker passes an error
+response to the LicenseCheckerCallback's <code>applicationError()</code>
+method. </li>
+</ol>
+
+<p>Note that, in addition to initiating the license check and handling the
+result, which are described in the sections below, your application also needs
+to provide a <a href="#impl-Policy">Policy implementation</a> and, if the Policy
+stores response data (such as ServerManagedPolicy), an <a
+href="#impl-Obfuscator">Obfuscator</a> implementation. </p>
+
+
+<h4 id="imports">Add imports</h4>
+
+<p>First, open the class file of the application's main Activity and import
+LicenseChecker and LicenseCheckerCallback from the LVL package.</p>
+
+<pre> import com.android.vending.licensing.LicenseChecker;
+ import com.android.vending.licensing.LicenseCheckerCallback;</pre>
+
+<p>If you are using the default Policy implementation provided with the LVL,
+ServerManagedPolicy, import it also, together with the AESObfuscator. If you are
+using a custom Policy or Obfuscator, import those instead. </p>
+
+<pre> import com.android.vending.licensing.ServerManagedPolicy;
+ import com.android.vending.licensing.AESObfuscator;</pre>
+
+<h4 id="lc-impl">Implement LicenseCheckerCallback as a private inner class</h4>
+
+<p>LicenseCheckerCallback is an interface provided by the LVL for handling
+result of a license check. To support licensing using the LVL, you must
+implement LicenseCheckerCallback and
+its methods to allow or disallow access to the application.</p>
+
+<p>The result of a license check is always a call to one of the
+LicenseCheckerCallback methods, made based on the validation of the response
+payload, the server response code itself, and any additional processing provided
+by your Policy. Your application can implement the methods in any way needed. In
+general, it's best to keep the methods simple, limiting them to managing UI
+state and application access. If you want to add further processing of license
+responses, such as by contacting a backend server or applying custom constraints,
+you should consider incorporating that code into your Policy, rather than
+putting it in the LicenseCheckerCallback methods. </p>
+
+<p>In most cases, you should declare your implementation of
+LicenseCheckerCallback as a private class inside your application's main
+Activity class. </p>
+
+<p>Implement the <code>allow()</code> and <code>dontAllow()</code> methods as
+needed. To start with, you can use simple result-handling behaviors in the
+methods, such as displaying the license result in a dialog. This helps you get
+your application running sooner and can assist with debugging. Later, after you
+have determined the exact behaviors you want, you can add more complex handling.
+</p>
+
+<p>Some suggestions for handling unlicensed responses in
+<code>dontAllow()</code> include: </p>
+
+<ul>
+<li>Display a "Try again" dialog to the user, including a button to initiate a
+new license check. </li>
+<li>Display a "Purchase this application" dialog, including a button that
+deep-links the user to the application's details page on Market, from which the
+use can purchase the application. For more information on how to set up such
+links, see <a
+href="{@docRoot}guide/publishing/publishing.html#marketintent">Using Intents to
+Launch the Market Application on a Device</a>. </li>
+<li>Display a Toast notification that indicates that the features of the
+application are limited because it is not licensed. </li>
+</ul>
+
+<p>The example below shows how the LVL sample application implements
+LicenseCheckerCallback, with methods that display the license check result in a
+dialog. </p>
+
+<pre> private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
+ public void allow() {
+ if (isFinishing()) {
+ // Don't update UI if Activity is finishing.
+ return;
+ }
+ // Should allow user access.
+ displayResult(getString(R.string.allow));
+ }
+
+ public void dontAllow() {
+ if (isFinishing()) {
+ // Don't update UI if Activity is finishing.
+ return;
+ }
+ displayResult(getString(R.string.dont_allow));
+ // Should not allow access. An app can handle as needed,
+ // typically by informing the user that the app is not licensed
+ // and then shutting down the app or limiting the user to a
+ // restricted set of features.
+ // In this example, we show a dialog that takes the user to Market.
+ showDialog(0);
+ }
+ }
+</pre>
+
+<p>Additionally, you should implement the <code>applicationError()</code>
+method, which the LVL calls to let your application handle errors that are not
+retryable. For a list of such errors, see <a
+href="#server-response-codes">Server Response Codes</a> in the Appendix of this
+document. You can implement the method in any way needed. In most cases, the
+method should log the error code and call <code>dontAllow()</code>.</p>
+
+<h4 id="thread-handler">Create a Handler for posting from LicenseCheckerCallback
+to the UI thread</h4>
+
+<p>During a license check, the LVL passes the request to the Android Market
+application, which handles communication with the licensing server. The LVL
+passes the request over asynchronous IPC (using {@link android.os.Binder}) so
+the actual processing and network communication do not take place on a thread
+managed by your application. Similarly, when the Android Market application
+receives the result, it invokes a callback method over IPC, which in turn
+executes in an IPC thread pool in your application's process.</p>
+
+<p>The LicenseChecker class manages your application's IPC communication with
+the Android Market application, including the call that sends the request and
+the callback that receives the response. LicenseChecker also tracks open license
+requests and manages their timeouts. </p>
+
+<p>So that it can handle timeouts properly and also process incoming responses
+without affecting your application's UI thread, LicenseChecker spawns a
+background thread at instantiation. In the thread it does all processing of
+license check results, whether the result is a response received from the server
+or a timeout error. At the conclusion of processing, the LVL calls your
+LicenseCheckerCallback methods from the background thread. </p>
+
+<p>To your application, this means that:</p>
+
+<ol>
+<li>Your LicenseCheckerCallback methods will be invoked, in many cases, from a
+background thread.</li>
+<li>Those methods won't be able to update state or invoke any processing in the
+UI thread, unless you create a Handler in the UI thread and have your callback
+methods post to the Handler.</li>
+</ol>
+
+<p>If you want your LicenseCheckerCallback methods to update the UI thread,
+instantiate a {@link android.os.Handler} in the main Activity's
+{@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} method,
+as shown below. In this example, the LVL sample application's
+LicenseCheckerCallback methods (see above) call <code>displayResult()</code> to
+update the UI thread through the Handler's
+{@link android.os.Handler#post(java.lang.Runnable) post()} method.</p>
+
+<pre>private Handler mHandler;
+
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ ...
+ mHandler = new Handler();
+ }
+</pre>
+
+<p>Then, in your LicenseCheckerCallback methods, you can use Handler methods to
+post Runnable or Message objects to the Handler. Here's how the sample
+application included in the LVL posts a Runnable to a Handler in the UI thread
+to display the license status.</p>
+
+<pre> private void displayResult(final String result) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ mStatusText.setText(result);
+ setProgressBarIndeterminateVisibility(false);
+ mCheckLicenseButton.setEnabled(true);
+ }
+ });
+ }
+</pre>
+
+<h4 id="lc-lcc">Instantiate LicenseChecker and LicenseCheckerCallback</h4>
+
+<p>In the main Activity's
+{@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} method,
+create private instances of LicenseCheckerCallback and LicenseChecker. You must
+instantiate LicenseCheckerCallback first, because you need to pass a reference
+to that instance when you call the contructor for LicenseChecker. </p>
+
+<p>When you instantiate LicenseChecker, you need to pass in these parameters:</p>
+
+<ul>
+<li>The application {@link android.content.Context}</li>
+<li>A reference to the Policy implementation to use for the license check. In
+most cases, you would use the default Policy implementation provided by the LVL,
+ServerManagedPolicy. </li>
+<li>The String variable holding your publisher account's public key for
+licensing. </li>
+</ul>
+
+<p>If you are using ServerManagedPolicy, you won't need to access the class
+directly, so you can instantiate it in the LicenseChecker constructor,
+as shown in the example below. Note that you need to pass a reference to a new
+Obfuscator instance when you construct ServerManagedPolicy.</p>
+
+<p>The example below shows the instantiation of LicenseChecker and
+LicenseCheckerCallback from the <code>onCreate()</code> method of an Activity
+class. </p>
+
+<pre>public class MainActivity extends Activity {
+ ...
+ private LicenseCheckerCallback mLicenseCheckerCallback;
+ private LicenseChecker mChecker;
+
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ...
+ // Construct the LicenseCheckerCallback. The library calls this when done.
+ mLicenseCheckerCallback = new MyLicenseCheckerCallback();
+
+ // Construct the LicenseChecker with a Policy.
+ mChecker = new LicenseChecker(
+ this, new ServerManagedPolicy(this,
+ new AESObfuscator(SALT, getPackageName(), deviceId)),
+ BASE64_PUBLIC_KEY // Your public licensing key.
+ );
+ ...
+ }
+}
+</pre>
+
+
+<p>Note that LicenseChecker calls the LicenseCheckerCallback methods from the UI
+thread <em>only</em> if there is valid license response cached locally. If the
+license check is sent to the server, the callbacks always originate from the
+background thread, even for network errors. </p>
+
+
+<h4 id="check-access">Call checkAccess() to initiate the license check</h4>
+
+<p>In your main Activity, add a call to the <code>checkAccess()</code> method of the
+LicenseChecker instance. In the call, pass a reference to your
+LicenseCheckerCallback instance as a parameter. If you need to handle any
+special UI effects or state management before the call, you might find it useful
+to call <code>checkAccess()</code> from a wrapper method. For example, the LVL
+sample application calls <code>checkAccess()</code> from a
+<code>doCheck()</code> wrapper method:</p>
+
+<pre> &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ...
+ // Call a wrapper method that initiates the license check
+ doCheck();
+ ...
+ }
+ ...
+ private void doCheck() {
+ mCheckLicenseButton.setEnabled(false);
+ setProgressBarIndeterminateVisibility(true);
+ mStatusText.setText(R.string.checking_license);
+ mChecker.checkAccess(mLicenseCheckerCallback);
+ }
+</pre>
+
+
+<h4 id="account-key">Embed your public key for licensing</h4>
+
+<p>For each publisher account, the Android Market service automatically
+generates a 2048-bit RSA public/private key pair that is used exclusively for
+licensing. The key pair is uniquely associated with the publisher account and is
+shared across all applications that are published through the account. Although
+associated with a publisher account, the key pair is <em>not</em> the same as
+the key that you use to sign your applications (or derived from it).</p>
+
+<p>The Android Market publisher site exposes the public key for licensing to any
+developer signed in to the publisher account, but it keeps the private key
+hidden from all users in a secure location. When an application requests a
+license check for an application published in your account, the licensing server
+signs the license response using the private key of your account's key pair.
+When the LVL receives the response, it uses the public key provided by the
+application to verify the signature of the license response. </p>
+
+<p>To add licensing to an application, you must obtain your publisher account's
+public key for licensing and copy it into your application. Here's how to find
+your account's public key for licensing:</p>
+
+<ol>
+<li>Go to the Android Market <a
+href="http://market.android.com/publish">publisher site</a> and sign in.
+Make sure that you sign in to the account from which the application you are
+licensing is published (or will be published). </li>
+<li>In the account home page, locate the "Edit profile" link and click it. </li>
+<li>In the Edit Profile page, locate the "Licensing" pane, shown below. Your
+public key for licensing is given in the "Public key" text box. </p>
+</ol>
+
+<p>To add the public key to your application, simply copy/paste the key string
+from the text box into your application as the value of the String variable
+<code>BASE64_PUBLIC_KEY</code>. When you are copying, make sure that you have
+selected the entire key string, without omitting any characters. </p>
+
+<p>Here's an example from the LVL sample application:</p>
+
+<pre> public class MainActivity extends Activity {
+ private static final String BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG ... "; //truncated for this example
+ ...
+ }
+</pre>
+
+<h4 id="handler-cleanup">Call your LicenseChecker's onDestroy() method
+to close IPC connections</h4>
+
+<p>Finally, to let the LVL clean up before your application
+{@link android.content.Context} changes, add a call to the LicenseChecker's
+<code>onDestroy()</code> method from your Activity's
+{@link android.app.Activity#onDestroy()} implementation. The call causes the
+LicenseChecker to properly close any open IPC connection to the Android Market
+application's ILicensingService and removes any local references to the service
+and handler.</p>
+
+<p>Failing to call the LicenseChecker's <code>onDestroy()</code> method
+can lead to problems over the lifecycle of your application. For example, if the
+user changes screen orientation while a license check is active, the application
+{@link android.content.Context} is destroyed. If your application does not
+properly close the LicenseChecker's IPC connection, your application will crash
+when the response is received. Similarly, if the user exits your application
+while a license check is in progress, your application will crash when the
+response is received, unless it has properly called the
+LicenseChecker's <code>onDestroy()</code> method to disconnect from the service.
+</p>
+
+<p>Here's an example from the sample application included in the LVL, where
+<code>mChecker</code> is the LicenseChecker instance:</p>
+
+<pre> &#64;Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mChecker.onDestroy();
+ ...
+ }
+</pre>
+
+<p>If you are extending or modifying LicenseChecker, you might also need to call
+the LicenseChecker's <code>finishCheck()</code> method, to clean up any open IPC
+connections.</p>
+
+<h3 id="impl-DeviceLimiter">Implementing a DeviceLimiter</h3>
+
+<p>In some cases, you might want your Policy to limit the number of actual
+devices that are permitted to use a single license. This would prevent a user
+from moving a licensed application onto a number of devices and using the
+application on those devices under the same account ID. It would also prevent a
+user from "sharing" the application by providing the account information
+associated with the license to other individuals, who could then sign in to that
+account on their devices and access the license to the application. </p>
+
+<p>The LVL supports per-device licensing by providing a
+<code>DeviceLimiter</code> interface, which declares a single method,
+<code>allowDeviceAccess()</code>. When a LicenseValidator is handling a response
+from the licensing server, it calls <code>allowDeviceAccess()</code>, passing a
+user ID string extracted from the response.</p>
+
+<p>If you do not want to support device limitation, <strong>no work is
+required</strong> &mdash; the LicenseChecker class automatically uses a default
+implementation called NullDeviceLimiter. As the name suggests, NullDeviceLimiter
+is a "no-op" class whose <code>allowDeviceAccess()</code> method simply returns
+a <code>LICENSED</code> response for all users and devices. </p>
+
+<div style="border-left:4px solid #FFCF00;margin:1em;padding: 0 0 0 .5em">
+<p><strong>Caution:</strong> Per-device licensing is <em>not recommended for
+most applications</em> because:</p>
+<ul>
+<li>It requires that you provide a backend server to manage a users and devices
+mapping, and </li>
+<li>It could inadvertently result in a user being denied access to an
+application that they have legitimately purchased on another device.</li>
+</ul>
+</div>
+
+
+<h2 id="test-env">Setting Up the Testing Environment</h2>
+
+<p>The Android Market publisher site provides configuration tools that let you
+and others test licensing on your application before it is published. As you are
+implementing licensing, you can make use of the publisher site tools to test
+your application's Policy and handling of different licensing responses and
+error conditions.</p>
+
+<p>The main components of the test environment for licensing include: </p>
+
+<ul>
+<li>A "Test response" configuration in your publisher account that lets you
+set the static licensing response returned, when the server processes a
+license check for an application uploaded to the publisher account, from a user
+signed in to the publisher account or a test account.</li>
+<li>An optional set of test accounts that will receive the static test
+response when they check the license of an application that you have uploaded
+(regardless whether the application is published or not).</li>
+<li>A runtime environment for the application that includes the Android Market
+application or Google APIs Add-On, on which the user is signed in to the
+publisher account or one of the test accounts.</li>
+</ul>
+
+<p>Setting up the test environment properly involves:</p>
+
+<ol>
+<li><a href="#test-response">Setting static test responses</a> that are returned by the licensing server.</li>
+<li><a href="#test-acct-setup">Setting up test accounts</a> as needed.</li>
+<li><a href="#acct-signin">Signing in</a> properly to an emulator or device, before initiating a license check test.</li>
+</ol>
+
+<p>The sections below provide more information.</p>
+
+
+<h3 id="test-response">Setting test responses for license checks</h3>
+
+<p>Android Market provides a configuration setting in your publisher account
+that lets you override the normal processing of a license check and return a
+specified static response code. The setting is for testing only and applies
+<em>only</em> to license checks for applications that you have uploaded, made by
+any user signed in to an emulator or device using the credentials of the
+publisher account or a registered test account. For other users, the server
+always processes license checks according to normal rules. </p>
+
+<p>To set a test response for your account, sign in to your publisher account
+and click "Edit Profile". In the Edit Profile page, locate the Test Response
+menu in the Licensing panel, shown below. You can select from the full set of
+valid server response codes to control the response or condition you want to
+test in your application.</p>
+
+<p>In general, you should make sure to test your application's licensing
+implementation with every response code available in the Test Response menu.
+For a description of the codes, see <a href="#server-response-codes">Server
+Response Codes</a> in the Appendix of this document.</p>
+
+<div style="margin-bottom:2em;" id="licensing_test_response">
+
+<img src="{@docRoot}images/licensing_test_response.png" style="text-align:left;margin-bottom:0;" />
+<div style="margin:0 2em;padding:0"><strong>Figure 7.</strong> The Licensing
+panel of your account's Edit Profile page, showing the Test Accounts field and the
+Test Response menu.</div>
+</div>
+
+<p>Note that the test response that you configure applies account-wide &mdash;
+that is, it applies not to a single application, but to <em>all</em>
+applications associated with the publisher account. If you are testing multiple
+applications at once, changing the test response will affect all of those
+applications on their next license check (if the user is signed into
+the emulator or device using the publisher account or a test account).</p>
+
+<p>Before you can successfully receive a test response for a license check,
+you must sign in to the device or emulator on which the application
+is installed, and from which it is querying the server. Specifically, you must
+sign using either your publisher account or one of the test accounts that you
+have set up. For more information about test accounts, see the next section.</p>
+
+<p>See <a href="#server-response-codes">Server Response Codes</a> for a list of
+test responses available and their meanings. </p>
+
+
+<h3 id="test-acct-setup">Setting up test accounts</h3>
+
+<p>In some cases, you might want to let multiple teams of developers test
+licensing on applications that will ultimately be published through your
+publisher account, but without giving them access to your publisher account's
+sign-in credentials. To meet that need, the Android Market publisher site lets
+you set up one or more optional <em>test accounts</em> &mdash; accounts that are
+authorized to query the licensing server and receive static test responses from
+your publisher account.</p>
+
+<p>Test accounts are standard Google accounts that you register on your
+publisher account, such that they will receive the test response for
+applications that you have uploaded. Developers can then sign in to their
+devices or emulators using the test account credentials and initiate license
+checks from installed applications. When the licensing server receives a license
+check from a user of a test account, it returns the static test response
+configured for the publisher account. </p>
+
+<p>Necessarily, there are limitations on the access and permissions given to
+users signed in through test accounts, including:</p>
+
+<ul>
+<li>Test account users can query the licensing server only for applications that
+are already uploaded to the publisher account. </li>
+<li>Test account users do not have permission to upload applications to your
+publisher account.</li>
+<li>Test account users do not have permission to set the publisher account's
+static test response.</li>
+</ul>
+
+<p>The table below summarizes the differences in capabilities, between the
+publisher account, a test account, and any other account.</p>
+
+<p class="table-caption" id="acct-types-table"><strong>Table 1.</strong>
+Differences in account types for testing licensing.</p>
+
+<table>
+<tr>
+<th>Account Type</th>
+<th>Can check license before upload?</th>
+<th>Can receive test response?</th>
+<th>Can set test response?</th>
+</tr>
+
+<tr>
+<td>Publisher account</td>
+<td>Yes</td>
+<td>Yes</td>
+<td>Yes</td>
+</tr>
+
+<tr>
+<td>Test account</td>
+<td>No</td>
+<td>Yes</td>
+<td>No</td>
+</tr>
+
+<tr>
+<td>Other</td>
+<td>No</td>
+<td>No</td>
+<td>No</td>
+</tr>
+</table>
+
+<h4 id="reg-test-acct">Registering test accounts on the publisher account</h4>
+
+<p>To get started, you need to register each test account in your publisher
+account. As shown in <a href="#licensing_test_response">Figure 7</a>, above, you
+register test accounts in the Licensing panel of your publisher account's Edit
+Profile page. Simply enter the accounts as a comma-delimited list and click
+<strong>Save</strong> to save your profile changes.</p>
+
+<p>You can use any Google account as a test account. If you want to own and
+control the test accounts, you can create the accounts yourself and distribute
+the credentials to your developers or testers.</p>
+
+<h4 id="test-app-upload">Handling application upload and distribution for test
+account users</h4>
+
+<p>As mentioned above, users of test accounts can only receive static test
+responses for applications that are uploaded to the publisher account. Since
+those users do not have permission to upload applications, as the publisher you
+will need to work with those users to collect apps for upload and distribute
+uploaded apps for testing. You can handle collection and distribution in any way
+that is convenient. </p>
+
+<p>Once an application is uploaded and becomes known to the licensing server,
+developers and testers can continue modify the application in their local
+development environment, without having to upload new versions. You only need to
+upload a new version if the local application increments the
+<code>versionCode</code> attribute in the manifest file. </p>
+
+<h4 id="test-key">Distributing your public key to test account users</h4>
+
+<p>The licensing server handles static test responses in the normal way,
+including signing the license response data, adding extras parameters, and so
+on. To support developers who are implementing licensing using test accounts,
+rather than the publisher account, you will need to distribute
+your public key to them. Developers without access to the publisher site do not
+have access to your public key, and without the key they won't be able to
+verify license responses. </p>
+
+<p>Note that if you decide to generate a new licensing key pair for your account
+for some reason, you need to notify all users of test accounts. For
+testers, you can embed the new key in the application package and distribute it
+to users. For developers, you will need to distribute the new key to them
+directly. </p>
+
+
+<h3 id="acct-signin">Signing in to an authorized account in the runtime
+environment</h3>
+
+<p>The licensing service is designed to determine whether a given user is
+licensed to use a given application &mdash; during a license check, the Android
+Market application gathers the user ID from the primary account on the system
+and sends it to the server, together with the package name of the application
+and other information. However, if there is no user information available, the
+license check cannot succeed, so the Android Market application terminates the
+request and returns an error to the application. </p>
+
+<p>During testing, to ensure that your application can successfully query the
+licensing server, you must make sure that you sign in to an account <em>on the
+device or emulator</em> using:</p>
+
+<ul>
+<li>The credentials of a publisher account, or</li>
+<li>The credentials of a test account that is registered with a publisher
+account</li>
+</ul>
+
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>Signing in to a Google account on an emulator</h2>
+
+<p>If you are testing licensing on an emulator, you need to sign in to a Google
+account on the emulator. If you do not see an option to create a new Google
+account, the problem might be that your AVD is running a standard Android system
+image, rather than the Google APIs Add-On, API 8 (release 2) or higher. </p>
+
+<p style="margin-top:.5em;">For more information, see <a
+href="#runtime-setup">Setting up the runtime environment</a>, above.</p>
+
+</div>
+</div>
+
+<p>Signing in using a publisher account offers the advantage of letting your
+applications receive static test responses even before the applications are
+uploaded to the publisher site.</p>
+
+<p>If you are part of a larger organization or are working with external groups
+on applications that will be published through your site, you will more likely
+want to distribute test accounts instead, then use those to sign in during
+testing. </p>
+
+<p>To sign in on a device or emulator, follow the steps below. The preferred
+approach is to sign in as the primary account &mdash; however, if there are
+other accounts already in use on the device or emulator, you can create an
+additional account and sign in to it using the publisher or test account
+credentials. </p>
+
+<ol>
+<li>Open Settings &gt; Accounts &amp; sync</li>
+<li>Select <strong>Add Account</strong> and choose to add a "Google" account.
+</li>
+<li>Select <strong>Next</strong> and then <strong>Sign in</strong>.</li>
+<li>Enter the username and password of either the publisher account or a test
+account that is registered in the publisher account.</li>
+<li>Select <strong>Sign in</strong>. The system signs you in to the new
+account.</li>
+</ol>
+
+<p>Once you are signed in, you can begin testing licensing in your application
+(if you have completed the LVL integration steps above). When your application
+initiates a license check, it will receive a response containing the static test
+response configured on the publisher account. </p>
+
+<p>Note that, if you are using an emulator, you will need to sign in to the
+publisher account or test account each time you wipe data when restarting the
+emulator.</p>
+
+<div style="margin:2em 1em 1em 1em;">
+
+<img src="{@docRoot}images/licensing_device_signin.png" style="text-align:left;" />
+<div style="margin:.25em 1.25em;padding:0"><strong>Figure 8.</strong> Example of
+setting up a Google account on a device or emulator.</div>
+</div>
+
+<h2 id="app-obfuscation">Obfuscating Your Application</h2>
+
+<p>To ensure the security of your application, particularly for a paid
+application that uses licensing and/or custom constraints and protections, it's
+very important to obfuscate your application code. Properly obfuscating your
+code makes it more difficult for a malicious user to decompile the application's
+bytecode, modify it &mdash; such as by removing the license check &mdash;
+and then recompile it.</p>
+
+<p>Several obfuscator programs are available for Android applications, including
+<a href="http://proguard.sourceforge.net/">ProGuard</a>, which also offers
+code-optimization features. The use of ProGuard or a similar program to obfuscate
+your code is <em>strongly recommended</em> for all applications that use Android
+Market Licensing. </p>
+
+<h2 id="app-publishing">Publishing a Licensed Application</h2>
+
+<p>When you are finished testing your license implementation, you are ready to
+publish the application on Android Market. Follow the normal steps to <a
+href="{@docRoot}guide/publishing/preparing.html">prepare</a>, <a
+href="{@docRoot}guide/publishing/app-signing.html">sign</a>, and then <a
+href="{@docRoot}guide/publishing/publishing.html">publish the application</a>.
+</p>
+
+<h4>Removing Copy Protection</h4>
+
+<p>After uploading your licensed application, remember to remove copy protection
+from the application, if it is currently used. To check and remove copy
+protection, sign in to the publisher site and go the application's upload
+details page. In the Publishing options section, make sure that the Copy
+Protection radio button selection is "Off".</p>
+
+<h4>Considerations for Free Apps</h4>
+
+<p>Licensing is currently supported only for paid applications. If you already
+published your application as free, you won't be able to upload an updated
+version that includes licensing (that is, an application that uses the same
+package name and that includes the <a href="#manifest-permission">licensing
+permission</a>). Here are some points to keep in mind:</p>
+
+<ul>
+<li>If you want to offer a free version of your application that provides a
+reduced feature set (or that offers the full feature set for trial period), the
+free version of your application must not include the licensing permission and
+must use a different package name than the paid version of the app.</li>
+<li>If you want to offer a paid version of your free application that uses
+licensing, you can do so under a new package name.</li>
+</ul>
+
+<h2 id="support">Where to Get Support</h2>
+
+<p>If you have questions or encounter problems while implementing or deploying
+publishing in your applications, please use the support resources listed in the
+table below. By directing your queries to the correct forum, you can get the
+support you need more quickly. </p>
+
+<p class="table-caption"><strong>Table 2.</strong> Developer support resources
+for Android Market Licensing Service.</p>
+
+<table>
+
+<tr>
+<th>Support Type</th>
+<th>Resource</th>
+<th>Range of Topics</th>
+</tr>
+<tr>
+<td rowspan="2">Development and testing issues</td>
+<td>Google Groups: <a
+href="http://groups.google.com/group/android-developers">android-developers</a>
+</td>
+<td rowspan="2">LVL download and integration, library projects, Policy
+questions, user experience ideas, handling of responses, Obfuscator, IPC, test
+environment setup</td>
+</tr>
+<tr>
+<td>Stack Overflow: <a
+href="http://stackoverflow.com/questions/tagged/android">http://stackoverflow.com/questions/tagged/android</a></td>
+</tr>
+<tr>
+<td rowspan="2">Accounts, publishing, and deployment issues</td>
+<td><a href="http://www.google.com/support/forum/p/Android+Market">Android
+Market Help Forum</a></td>
+<td rowspan="2">Publisher accounts, licensing key pair, test accounts, server
+responses, test responses, application deployment and results</td>
+</tr>
+<tr>
+<td><a
+href="http://market.android.com/support/bin/answer.py?answer=186113">Market
+Licensing Support FAQ</a></td>
+</tr>
+<tr>
+<td>LVL issue tracker</td>
+<td><a href="http://code.google.com/p/marketlicensing/issues/">Marketlicensing
+project issue tracker</a></td>
+<td>Bug and issue reports related specifically to the LVL source code classes
+and interface implementations</td>
+</tr>
+
+</table>
+
+<p>For general information about how to post to the groups listed above, see <a
+href="{@docRoot}resources/community-groups.html">Developer Forums</a> document
+in the Resources tab.</p>
+
+<h2 id="lvl-summary">Summary of LVL Classes and Interfaces</h2>
+
+<p>The table below lists all of the source files in the License Verification
+Library (LVL) available through the Android SDK. All of the files are part of
+the <code>com.android.vending.licensing</code> package.</p>
+
+<p class="table-caption"><strong>Table A-1.</strong> Summary of LVL library
+classes and interfaces.</p>
+
+<div style="width:99%">
+<table width="100%">
+
+<tr>
+<th width="15%">Category</th>
+<th width="20%">Name</th>
+<th width="100%">Description</th>
+</tr>
+
+<tr>
+<td rowspan="2">License check and result</td>
+<td>LicenseChecker</td>
+<td>Class that you instantiate (or subclass) to initiate a license check.</td>
+</tr>
+<tr>
+<td><em>LicenseCheckerCallback</em></td>
+<td>Interface that you implement to handle result of the license check.</td>
+</tr>
+
+<tr>
+<td rowspan="3" width="15%">Policy</td>
+<td width="20%"><em>Policy</em></td>
+<td width="100%">Interface that you implement to determine whether to allow
+access to the application, based on the license response. </td>
+</tr>
+<tr>
+<td>ServerManagedPolicy</td>
+<td width="100%">Default Policy implementation. Uses settings provided by the
+licensing server to manage local storage of license data, license validity,
+retry.</td>
+</tr>
+<tr>
+<td>StrictPolicy</td>
+<td>Alternative Policy implementation. Enforces licensing based on a direct
+license response from the server only. No caching or request retry.</td>
+</tr>
+
+<tr>
+<td rowspan="2" width="15%">Data obfuscation <br><em>(optional)</em></td>
+<td width="20%"><em>Obfuscator</em></td>
+<td width="100%">Interface that you implement if you are using a Policy (such as
+ServerManagedPolicy) that caches license response data in a persistent store.
+Applies an obfuscation algorithm to encode and decode data being written or
+read.</td>
+</tr>
+<tr>
+<td>AESObfuscator</td>
+<td>Default Obfuscator implementation that uses AES encryption/decryption
+algorithm to obfuscate/unobfuscate data.</td>
+</tr>
+
+<tr>
+<td rowspan="2" width="15%">Device limitation<br><em>(optional)</em></td>
+<td width="20%"><em>DeviceLimiter</em></td>
+<td width="100%">Interface that you implement if you want to restrict use of an
+application to a specific device. Called from LicenseValidator. Implementing
+DeviceLimiter is not recommended for most applications because it requires a
+backend server and may cause the user to lose access to licensed applications,
+unless designed with care.</td>
+</tr>
+<tr>
+<td>NullDeviceLimiter</td>
+<td>Default DeviceLimiter implementation that is a no-op (allows access to all
+devices).</td>
+</tr>
+
+<tr>
+<td rowspan="6" width="15%">Library core, no integration needed</td>
+<td width="20%">ResponseData</td>
+<td width="100%">Class that holds the fields of a license response.</td>
+</tr>
+<tr>
+<td>LicenseValidator</td>
+<td>Class that decrypts and verifies a response received from the licensing
+server.</td>
+</tr>
+<tr>
+<td>ValidationException</td>
+<td>Class that indicates errors that occur when validating the integrity of data
+managed by an Obfuscator.</td>
+</tr>
+<tr>
+<td>PreferenceObfuscator</td>
+<td>Utility class that writes/reads obfuscated data to the system's
+{@link android.content.SharedPreferences} store.</td>
+</tr>
+<tr>
+<td><em>ILicensingService</em></td>
+<td>One-way IPC interface over which a license check request is passed to the
+Android Market client.</td>
+</tr>
+<tr>
+<td><em>ILicenseResultListener</em></td>
+<td>One-way IPC callback implementation over which the application receives an
+asynchronous response from the licensing server.</td>
+</tr>
+
+</table>
+</div>
+
+
+<h2 id="server-response-codes">Server Response Codes</h2>
+
+<p>The table below lists all of the license response codes supported by the
+licensing server. In general, an application should handle all of these response
+codes. By default, the LicenseValidator class in the LVL provides all of the
+necessary handling of these response codes for you. </p>
+
+<p class="table-caption"><strong>Table A-2.</strong> Summary of response codes
+returned by the Android Market server in a license response.</p>
+
+<table>
+
+<tr>
+<th>Response Code</th>
+<th>Description</th>
+<th>Signed?</th>
+<th>Extras</th>
+<th>Comments</th>
+</tr>
+<tr>
+<td>LICENSED</td>
+<td>The application is licensed to the user. The user has purchased the
+application or the application is free.</td>
+<td>Yes</td>
+<td><code>VT</code>,&nbsp;<code>GT</code>, <code>GR</code></td>
+<td><em>Allow access according to Policy constraints.</em></td>
+</tr>
+<tr>
+<td>LICENSED_OLD_KEY</td>
+<td>The application is licensed to the user, but there is an updated application
+version available that is signed with a different key. </td>
+<td>Yes </td>
+<td><code>VT</code>, <code>GT</code>, <code>GR</code>, <code>UT</code></td>
+<td><em>Optionally allow access according to Policy constraints.</em>
+<p style="margin-top:.5em;">Can indicate that the key pair used by the installed
+application version is invalid or compromised. The application can allow access
+if needed or inform the user that an upgrade is available and limit further use
+until upgrade.</p>
+</td>
+</tr>
+<tr>
+<td>NOT_LICENSED</td>
+<td>The application is not licensed to the user.</td>
+<td>No</td>
+<td></td>
+<td><em>Do not allow access.</em></td>
+</tr>
+<tr>
+<td>ERROR_CONTACTING_SERVER</td>
+<td>Local error &mdash; the Android Market application was not able to reach the
+licensing server, possibly because of network availability problems. </td>
+<td>No</td>
+<td></td>
+<td><em>Retry the license check according to Policy retry limits.</em></td>
+</tr>
+<tr>
+<td>ERROR_SERVER_FAILURE</td>
+<td>Server error &mdash; the server could not load the publisher account's key
+pair for licensing.</td>
+<td>No</td>
+<td></td>
+<td><em>Retry the license check according to Policy retry limits.</em>
+</td>
+</tr>
+<tr>
+<td>ERROR_INVALID_PACKAGE_NAME</td>
+<td>Local error &mdash; the application requested a license check for a package
+that is not installed on the device. </td>
+<td>No </td>
+<td></td>
+<td><em>Do not retry the license check.</em>
+<p style="margin-top:.5em;">Typically caused by a development error.</p>
+</td>
+</tr>
+<tr>
+<td>ERROR_NON_MATCHING_UID</td>
+<td>Local error &mdash; the application requested a license check for a package
+whose UID (package, user ID pair) does not match that of the requesting
+application. </td>
+<td>No </td>
+<td></td>
+<td><em>Do not retry the license check.</em>
+<p style="margin-top:.5em;">Typically caused by a development error.</p>
+</td>
+</tr>
+<tr>
+<td>ERROR_NOT_MARKET_MANAGED</td>
+<td>Server error &mdash; the application (package name) was not recognized by
+Android Market. </td>
+<td>No</td>
+<td></td>
+<td><em>Do not retry the license check.</em>
+<p style="margin-top:.5em;">Can indicate that the application was not published
+through Android Market or that there is an development error in the licensing
+implementation.</p>
+</td>
+</tr>
+
+</table>
+
+
+<h2 id="extras">Server Response Extras</h2>
+
+<p>The licensing server includes several settings in certain types of license
+responses, to assist the application and its Policy in managing access to the
+application across the 24-hour refund period and other conditions. Specifically,
+the server provides recommended values for the application's license validity
+period, retry grace period, maximum allowable retry count, and other settings.
+The server appends the settings as key-value pairs in the license response
+"extras" field. </p>
+
+<p>Any Policy implementation can extract the extras settings from the license
+response and use them as needed. The LVL default Policy implementation, <a
+href="#ServerManagedPolicy">ServerManagedPolicy</a>, serves as a working
+implementation and an illustration of how to obtain, store, and use the
+settings. </p>
+
+<p class="table-caption"><strong>Table A-3.</strong> Summary of
+license-management settings supplied by the Android Market server in a license
+response.</p>
+
+<table>
+<tr>
+<th>Extra</th><th>Description</th>
+</tr>
+
+<tr>
+ <td>VT</td>
+ <td>License validity timestamp. Specifies the date/time at which the current
+(cached) license response expires and must be rechecked on the licensing server.
+ </td>
+</tr>
+<tr>
+ <td>GT</td>
+ <td>Grace period timestamp. Specifies the end of the period during which a
+Policy may allow access to the application, even though the response status is
+RETRY. <p>The value is managed by the server, however a typical value would be 5
+or more days.</p></td>
+</tr>
+<tr>
+ <td>GR</td>
+ <td>Maximum retries count. Specifies how many consecutive RETRY license checks
+the Policy should allow, before denying the user access to the application.
+<p>The value is managed by the server, however a typical value would be "10" or
+higher.</p></td>
+</tr>
+<tr>
+ <td>UT</td>
+ <td>Update timestamp. Specifies the day/time when the most recent update to
+this application was uploaded and published. <p>The server returns this extra
+only for LICENSED_OLD_KEYS responses, to allow the Policy to determine how much
+time has elapsed since an update was published with new licensing keys before
+denying the user access to the application. </p></td>
+</tr>
+
+</table>
+
+<p>The sections below provide more information about the server-provided
+settings and how to use them. </p>
+
+<h4>License validity period</h4>
+
+<p>The Android Market licensing server sets a license validity period for all
+downloaded applications. The period expresses the interval of time over which an
+application's license status should be considered as unchanging and cacheable by
+a licensing Policy in the application. The licensing server includes the
+validity period in its response to all license checks, appending an
+end-of-validity timestamp to the response as an extra under the key "VT". A
+Policy can extract the VT key value and use it to conditionally allow access to
+the application without rechecking the license, until the validity period
+expires. </p>
+
+<p>The license validity signals to a licensing Policy when it must recheck the
+licensing status with the licensing server. It is <em>not</em> intended to imply
+whether an application is actually licensed for use. That is, when an
+application's license validity period expires, this does not mean that the
+application is no longer licensed for use &mdash; rather, it indicates only that
+the Policy must recheck the licensing status with the server. It follows that,
+as long as the license validity period is not expired, it is acceptable for the
+Policy to cache the initial license status locally and return the cached license
+status instead of sending a new license check to the server.</p>
+
+<p>The licensing server manages the validity period as a means of helping the
+application properly enforce licensing across the refund period offered by
+Android Market for paid applications. It sets the validity period based on
+whether the application was purchased and, if so, how long ago. Specifically,
+the server sets a validity period as follows:</p>
+
+<ul>
+<li>For a paid application, the server sets the initial license validity period
+so that the license response remains valid for as long as the application is
+refundable. A licensing Policy in the application may cache the
+result of the initial license check and does not need to recheck the license
+until the validity period has expired.</li>
+<li>When an application is no longer refundable, the server
+sets a longer validity period &mdash; typically a number of days. </li>
+<li>For a free application, the server sets the validity period to a very high
+value (<code>long.MAX_VALUE</code>). This ensures that, provided the Policy has
+cached the validity timestamp locally, it will not need to recheck the
+license status of the application in the future.</li>
+</ul>
+
+<p>The ServerManagedPolicy implementation uses the extracted timestamp
+(<code>mValidityTimestamp</code>) as a primary condition for determining whether
+to recheck the license status with the server before allowing the user access to
+the application. </p>
+
+<h4>Retry period and maximum retry count</h4>
+
+<p>In some cases, system or network conditions can prevent an application's
+license check from reaching the licensing server, or prevent the server's
+response from reaching the Android Market client application. For example, the
+user might launch an application when there is no cell network or data
+connection available &mdash; such as when on an airplane &mdash; or when the
+network connection is unstable or the cell signal is weak. </p>
+
+<p>When network problems prevent or interrupt a license check, the Android
+Market client notifies the application by returning a "RETRY" response code to
+the Policy's <code>processServerResponse()</code> method. In the case of system
+problems, such as when the application is unable to bind with Android Market's
+ILicensingService implementation, the LicenseChecker library itself calls the
+Policy <code>processServerResonse()</code> method with a "RETRY" response code.
+</p>
+
+<p>In general, the RETRY response code is a signal to the application that an
+error has occurred that has prevented a license check from completing.
+
+<p>The Android Market server helps an application to manage licensing under
+error conditions by setting a retry "grace period" and a recommended maximum
+retries count. The server includes these values in all license check responses,
+appending them as extras under the keys "GT" and "GR". </p>
+
+<p>The application Policy can extract the GT and GR extras and use them to
+conditionally allow access to the application, as follows:</p>
+
+<ul>
+<li>For a license check that results in a RETRY response, the Policy should
+cache the RETRY response code and increment a count of RETRY responses.</li>
+<li>The Policy should allow the user to access the application, provided that
+either the retry grace period is still active or the maximum retries count has
+not been reached.</li>
+</ul>
+
+<p>The ServerManagedPolicy uses the server-supplied GT and GR values as
+described above. The example below shows the conditional handling of the retry
+responses in the <code>allow()</code> method. The count of RETRY responses is
+maintained in the <code>processServerResponse()</code> method, not shown. </p>
+
+
+<pre> public boolean allowAccess() {
+ long ts = System.currentTimeMillis();
+ if (mLastResponse == LicenseResponse.LICENSED) {
+ // Check if the LICENSED response occurred within the validity timeout.
+ if (ts &lt;= mValidityTimestamp) {
+ // Cached LICENSED response is still valid.
+ return true;
+ }
+ } else if (mLastResponse == LicenseResponse.RETRY &amp;&amp;
+ ts &lt; mLastResponseTime + MILLIS_PER_MINUTE) {
+ // Only allow access if we are within the retry period or we haven't used up our
+ // max retries.
+ return (ts &lt;= mRetryUntil || mRetryCount &lt;= mMaxRetries);
+ }
+ return false;
+ }</pre>
+
diff --git a/docs/html/guide/publishing/preparing.jd b/docs/html/guide/publishing/preparing.jd
index c1c6351..45a5b77 100644
--- a/docs/html/guide/publishing/preparing.jd
+++ b/docs/html/guide/publishing/preparing.jd
@@ -1,20 +1,6 @@
page.title=Preparing to Publish: A Checklist
@jd:body
-<!--
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>In this document</h2>
-
-<ol>
-<li><a href=""></a></li>
-</ol>
-
-</div>
-</div>
--->
-
<p>Publishing an application means testing it, packaging it appropriately, and
making it available to users of Android-powered mobile devices.</p>
@@ -34,26 +20,28 @@ Applications</a> document. </p>
<div class="special">
-<p>Before you consider your application ready for release:</p>
+<p><a href="#releaseready">Before you consider your application ready for release</a>:</p>
<ol>
<li>Test your application extensively on an actual device </li>
<li>Consider adding an End User License Agreement in your application</li>
+<li>Consider adding licensing support</li>
<li>Specify an icon and label in the application's manifest</li>
<li>Turn off logging and debugging and clean up data/files</li>
</ol>
-<p>Before you do the final compile of your application:</p>
+<p><a href="#finalcompile">Before you do the final compile of your application</a>:</p>
-<ol start="5">
+<ol start="6">
<li>Version your application</li>
<li>Obtain a suitable cryptographic key</li>
<li>Register for a Maps API Key, if your application is using MapView elements</li>
</ol>
-<p><em>Compile your application...</em></p>
-<p>After compiling your application:</p>
-<ol start="8">
+<p><a href="#compile">Compile your application</a></p>
+
+<p><a href="#post-compile">After you compile your application</a>:</p>
+<ol start="9">
<li>Sign your application</li>
<li>Test your compiled application</li>
</ol>
@@ -101,7 +89,19 @@ application</h3>
<p>To protect your person, organization, and intellectual property, you may want
to provide an End User License Agreement (EULA) with your application.
-<h3 id="iconlabel">3. Specify an icon and label in the application's manifest</h3>
+<h3 id="eula">3. Consider adding support for Android Market Licensing</h3>
+
+<p>If you are publishing a paid application through Android Market, consider
+adding support for Android Market Licensing. Licensing lets you control access
+to your application based on whether the current user has purchased it.
+Using Android Market Licensing is optional.
+
+<p>For complete information about Android Market Licensing Service and how to
+use it in your application, see <a
+href="{@docRoot}guide/publishing/licensing.html">Licensing Your
+Applications</a>.</p>
+
+<h3 id="iconlabel">4. Specify an icon and label in the application's manifest</h3>
<p>The icon and label that you specify in an application's manifest are
important because they are displayed to users as your application's icon and
@@ -116,7 +116,7 @@ display the icon and label to users. </p>
<p>As regards the design of your icon, you should try to make it match as much
as possible the style used by the built-in Android applications.</p>
-<h3 id="logging">4. Turn off logging and debugging and clean up data/files</h3>
+<h3 id="logging">5. Turn off logging and debugging and clean up data/files</h3>
<p>For release, you should make sure that debug facilities are turned off and
that debug and other unnecessary data/files are removed from your application
@@ -133,7 +133,7 @@ code.</li>
<h2 id="finalcompile">Before you do the final compile of your application</h2>
-<h3 id="versionapp">5. Version your application</h3>
+<h3 id="versionapp">6. Version your application</h3>
<p>Before you compile your application, you must make sure that you have defined
a version number for your application, specifying an appropriate value for both
@@ -152,7 +152,7 @@ element in the application's manifest file, using appropriate values. </p>
application, see <a href="{@docRoot}guide/publishing/versioning.html">Versioning
Your Applications</a>.</p>
-<h3 id="cryptokey">6. Obtain a suitable cryptographic key</h3>
+<h3 id="cryptokey">7. Obtain a suitable cryptographic key</h3>
<p>If you have read and followed all of the preparation steps up to this point,
your application is compiled and ready for signing. Inside the .apk, the
@@ -173,7 +173,7 @@ elements.</li>
<li>Sign your application for release, later in the preparation process</li>
</ul>
-<h3 id="mapsApiKey">7. Register for a Maps API Key, if your application is using
+<h3 id="mapsApiKey">8. Register for a Maps API Key, if your application is using
MapView elements</h3>
<div class="sidebox-wrapper">
@@ -229,9 +229,9 @@ to download Maps data. </li>
you can compile your application for release.</p>
-<h2 id="post-compile">After compiling your application</h2>
+<h2 id="post-compile">After you compile your application</h2>
-<h3 id="signapp">8. Sign your application</h3>
+<h3 id="signapp">9. Sign your application</h3>
<p>Sign your application using your private key and then
align it with the {@code zipalign} tool. Signing your application
@@ -239,7 +239,7 @@ correctly is critically important. Please see
<a href="{@docRoot}guide/publishing/app-signing.html">Signing Your
Applications</a> for complete information. </p>
-<h3 id="testapp">9. Test your compiled and signed application</h3>
+<h3 id="testapp">10. Test your compiled and signed application</h3>
<p>Before you release your compiled application, you should thoroughly test it
on the target mobile device (and target network, if possible). In particular,
diff --git a/docs/html/guide/publishing/publishing.jd b/docs/html/guide/publishing/publishing.jd
index 0c087ef..af1ea74 100644
--- a/docs/html/guide/publishing/publishing.jd
+++ b/docs/html/guide/publishing/publishing.jd
@@ -4,7 +4,7 @@ page.title=Publishing Your Applications
<div id="qv-wrapper">
<div id="qv">
-<h2>Publishing quickview</h2>
+<h2>Quickview</h2>
<ul>
<li>You can publish your application using a hosted service such as Android Market or through a web server.</li>
@@ -18,7 +18,8 @@ page.title=Publishing Your Applications
<ol>
<li><a href="#overview">Publishing on Android Market</a>
<ol>
- <li><a href="#marketupgrade">Publishing Updates on Android Market</a>
+ <li><a href="#marketupgrade">Publishing Updates on Android Market</a></li>
+ <li><a href="#marketLicensing">Using Android Market Licensing Service</a></li>
<li><a href="#marketintent">Using Intents to Launch the Market Application</a></li>
</ol></li>
<!--
@@ -30,6 +31,7 @@ page.title=Publishing Your Applications
<h2>See also</h2>
<ol>
+<li><a href="{@docRoot}guide/publishing/licensing.html">Licensing Your Applications</a></li>
<li><a href="{@docRoot}guide/publishing/preparing.html">Preparing to Publish</a></li>
</ol>
@@ -59,7 +61,7 @@ the .apk. Your application is now ready for publishing. </p>
<p>The sections below provide information about publishing your Android
application to mobile device users.</p>
-<h2 id="market">Publishing on Android Market</h2>
+<h2 id="overview">Publishing on Android Market</h2>
<p>Android Market is a hosted service that makes it easy for users to find and
download Android applications to their Android-powered devices, and makes it
@@ -121,7 +123,26 @@ certificate do <em>not</em> match those of the existing version, Market will
consider it a new application and will not offer it to users as an update.</p>
+<h3 id="marketLicensing">Using Android Market Licensing Service</h3>
+<p>Android Market offers a licensing service that lets you enforce licensing
+policies for paid applications that you publish through Android Market. With
+Android Market Licensing, your applications can query Android Market at run time
+to obtain their licensing status for the current user, then allow or disallow
+further use as appropriate. Using the service, you can apply a flexible
+licensing policy on an application-by-application basis &mdash; each
+application can enforce its licensing status in the way most appropriate
+for it. </p>
+
+<p>Any application that you publish through Android Market can use the Android
+Market Licensing Service. The service uses no dedicated framework APIs, you can
+add licensing to any legacy application that uses a minimum API level of 3 or
+higher.</p>
+
+<p>For complete information about Android Market Licensing Service and how to
+use it in your application, see <a
+href="{@docRoot}guide/publishing/licensing.html">Licensing Your
+Applications</a>.</p>
<h3 id="marketintent">Using Intents to Launch the Market Application on
diff --git a/docs/html/guide/publishing/versioning.jd b/docs/html/guide/publishing/versioning.jd
index 1d55f8a..b646247 100644
--- a/docs/html/guide/publishing/versioning.jd
+++ b/docs/html/guide/publishing/versioning.jd
@@ -4,7 +4,7 @@ page.title=Versioning Your Applications
<div id="qv-wrapper">
<div id="qv">
-<h2>Versioning quickview</h2>
+<h2>Quickview</h2>
<ul>
<li>Your application <em>must</em> be versioned</a></li>
diff --git a/docs/html/guide/samples/index.jd b/docs/html/guide/samples/index.jd
index 2f3ac5e..bd9ea52 100644
--- a/docs/html/guide/samples/index.jd
+++ b/docs/html/guide/samples/index.jd
@@ -3,99 +3,13 @@ page.title=Sample Code
@jd:body
-<p>Sometimes, the best way to learn how things are done is to look at some code.
-Here, you can browse the source of some sample Android applications that are included
-in the Android SDK.</p>
+<script type="text/javascript">
+ window.location = toRoot + "resources/samples/index.html";
+</script>
-<p>Each version of the Android platform available for the SDK includes a full set of sample
-applications (which may vary between different versions of the platform).
-You can find the samples in your SDK at:</p>
+<p><strong>This document has moved. Please go to <a
+href="http://developer.android.com/resources/samples/index.html">List of Sample
+Apps</a>.</strong></p>
-<p style="margin-left:2em">
-<code><em>&lt;sdk&gt;</em>/platforms/android-<em>&lt;version&gt;</em>/samples/</code>
-</p>
-
-<p>You can easily create new Android projects with these samples, modify them
-if you'd like, then run them on an emulator or device. For example, to create
-a project for the API Demos app from Eclipse,
-start a new Android Project, select "Create project from existing source", then select
-{@code ApiDemos} in the {@code samples/} directory. To create the API Demos project
-using the {@code android} tool, execute:</p>
-<pre>
-android update project -s -n API Demos -t <em>&lt;target_ID></em> -p <em>&lt;path-to-platform></em>/samples/ApiDemos/
-</pre>
-
-<p>The pages below provide an overview of each sample application (available with most
-platforms) and allow you to view the source files in your browser. </p>
-
-<div class="special">
- <p>Some of the samples in this listing are not yet available in the
- SDK. While we work to update the SDK, you can
- <a href="{@docRoot}shareables/latest_samples.zip">download the latest samples</a> as a ZIP
- archive.</p>
-</div>
-
-<dl>
-
- <dt><a href="{@docRoot}resources/samples/ApiDemos/index.html">API Demos</a></dt>
- <dd>A variety of small applications that demonstrate an extensive collection of
- framework topics.</dd>
-
- <dt><a href="{@docRoot}resources/samples/BackupRestore/index.html">Backup and Restore</a></dt>
- <dd>An simple example that illustrates a few different ways for an application to
- implement support for the Android data backup and restore mechanism.</dd>
-
- <dt><a href="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat</a></dt>
- <dd>An application for two-way text messaging over Bluetooth.</dd>
-
- <dt><a href="{@docRoot}resources/samples/ContactManager/index.html">Contact Manager</a></dt>
- <dd>An application that demonstrates how to query the system contacts provider
- using the <code>ContactsContract</code> API, as
- well as insert contacts into a specific account.</dd>
-
- <dt><a href="{@docRoot}resources/samples/Home/index.html">Home</a></dt>
- <dd>A home screen replacement application.</dd>
-
- <dt><a href="{@docRoot}resources/samples/JetBoy/index.html">JetBoy</a></dt>
- <dd>JetBoy is a game that demonstrates the SONiVOX JET interactive music technology,
- with {@link android.media.JetPlayer}.</dd>
-
- <dt><a href="{@docRoot}resources/samples/LunarLander/index.html">Lunar Lander</a></dt>
- <dd>A classic Lunar Lander game.</dd>
-
- <dt><a href="{@docRoot}resources/samples/MultiResolution/index.html">Multiple Resolutions</a></dt>
- <dd>A sample application that shows how to use resource directory qualifiers to
- provide different resources for different screen configurations.</dd>
-
- <dt><a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a></dt>
- <dd>An application for saving notes. Similar (but not identical) to the
- <a href="{@docRoot}resources/tutorials/notepad/index.html">Notepad tutorial</a>.</dd>
-
- <dt><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a></dt>
- <dd>A sample application that demonstrates Android's search framework,
- including how to provide search suggestions for Quick Search Box.</dd>
-
- <dt><a href="{@docRoot}resources/samples/Snake/index.html">Snake</a></dt>
- <dd>An implementation of the classic game "Snake."</dd>
-
- <dt><a href="{@docRoot}resources/samples/SoftKeyboard/index.html">Soft Keyboard</a></dt>
- <dd>An example of writing an input method for a software keyboard.</dd>
-
- <dt><a href=""{@docRoot}resources/samples/Wiktionary/index.html">Wiktionary</a></dt>
- <dd>An example of creating interactive widgets for display on the Android
- home screen.</dd>
-
- <dt><a href="{@docRoot}resources/samples/WiktionarySimple/index.html">Wiktionary (Simplified)</a></dt>
- <dd>A simple Android home screen widgets example.</dd>
-
-</dl>
-
-
-<div class="special">
-<p>For more sample applications, check out
-<a href="http://code.google.com/p/apps-for-android/">apps-for-android</a>, a
-collection of open source applications that demonstrate various Android APIs.
-</p>
-</div>
diff --git a/docs/html/guide/topics/admin/device-admin.jd b/docs/html/guide/topics/admin/device-admin.jd
new file mode 100644
index 0000000..fda716a
--- /dev/null
+++ b/docs/html/guide/topics/admin/device-admin.jd
@@ -0,0 +1,532 @@
+page.title=Device Administration
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>In this document</h2>
+ <ol>
+<li><a href="#overview">Device Administration API Overview</a>
+ <ol>
+ <li><a href="#how">How does it work?</a></li>
+ <li><a href="#policies">Policies</a></li>
+ </ol>
+ </li>
+ <li><a href="#sample">Sample Application</a></li>
+ <li><a href="#developing">Developing a Device Administration Application</a>
+ <ol>
+ <li><a href="#manifest">Creating the manifest</a></li>
+ <li><a href="#code">Implementing the code</a></li>
+ </ol>
+ </li>
+
+ </ol>
+
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.app.admin.DeviceAdminReceiver}</li>
+ <li>{@link android.app.admin.DevicePolicyManager}</li>
+ <li>{@link android.app.admin.DeviceAdminInfo}</li>
+ </ol>
+</div>
+</div>
+
+<p>Android 2.2 introduces support for enterprise applications by offering the
+Android Device Administration API. The Device Administration API provides device
+administration features at the system level. These APIs allow you to create
+security-aware applications that are useful in enterprise settings, in which IT
+professionals require rich control over employee devices. For example, the
+built-in Android Email application has leveraged the new APIs to improve
+Exchange support. Through the Email application, Exchange administrators can
+enforce password policies &mdash; including alphanumeric passwords or numeric
+PINs &mdash; across devices. Administrators can also remotely wipe (that is,
+restore factory defaults on) lost or stolen handsets. Exchange users can sync
+their email and calendar data.</p>
+
+<p>This document is intended for developers who want to develop enterprise
+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>
+
+
+<h2 id="overview">Device Administration API Overview</h2>
+
+<p>Here are examples of the types of applications that might use the Device Administration API:</p>
+<ul>
+ <li>Email clients.</li>
+ <li>Security applications that do remote wipe.</li>
+ <li>Device management services and applications.</li>
+</ul>
+
+<h3 id="how">How does it work?</h3>
+<p>You use the Device Administration API to write device admin applications that users
+install on their devices. The device admin application enforces the desired
+policies. Here's how it works:</p> <ul>
+ <li>A system administrator writes a device admin application that enforces
+remote/local device security policies. These policies could be hard-coded into
+the app, or the application could dynamically fetch policies from a third-party
+server. </li>
+<li>The application is installed on users' devices. Android does
+not currently have an automated provisioning solution. Some of the ways a sysadmin might
+distribute the application to users are as follows:
+<ul>
+<li>Android Market.</li>
+<li>Enabling non-market installation.</li>
+<li>Distributing the application through other means, such as email or websites.</li>
+
+</ul>
+
+
+</li>
+ <li>The system prompts the user to enable the device admin application. How
+and when this happens depends on how the application is implemented.</li>
+<li>Once users enable the device admin application, they are subject to
+its policies. Complying with those policies typically confers benefits, such as
+access to sensitive systems and data.</li>
+</ul>
+<p>If users do not enable the device admin app, it remains on the device, but in an inactive state. Users will not be subject to its policies, and they will conversely not get any of the application's benefits&mdash;for example, they may not be able to sync data.</p>
+<p>If a user fails to comply with the policies (for example, if a user sets a
+password that violates the guidelines), it is up to the application to decide
+how to handle this. However, typically this will result in the user not being
+able to sync data.</p>
+<p>If a device attempts to connect to a server that requires policies not
+supported in the Device Administration API, the connection will not
+be allowed. The Device Administration API does not currently allow partial
+provisioning. In other words, if a device (for example, a legacy device) does
+not support all of the stated policies, there is no way to allow the
+device to connect.</p>
+<p>If a device contains multiple enabled admin applications, the strictest policy is
+enforced. There is no way to target a particular admin
+application.</p>
+<p>To uninstall an existing device admin application, users need to
+first unregister the application as an administrator. </p>
+
+
+<h3 id="policies">Policies</h3>
+
+<p>In an enterprise setting, it's often the case that employee devices must
+adhere to a strict set of policies that govern the use of the device. The
+Device Administration API supports the policies listed in Table 1.
+Note that the Device Administration API currently only supports passwords for screen
+lock:</p>
+<p class="table-caption"><strong>Table 1.</strong> Policies supported by the Device Administration API.</p>
+<table border="1">
+ <tr>
+ <th>Policy</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>Password enabled</td>
+ <td>Requires that devices ask for PIN or passwords.</td>
+ </tr>
+ <tr>
+ <td>Minimum password length</td>
+ <td>Set the required number of characters for the password. For example, you
+can require PIN or passwords to have at least six characters. </td> </tr>
+ <tr>
+ <td>Alphanumeric password required</td>
+ <td>Requires that passwords have a
+combination of letters and numbers. They may include symbolic characters.
+ </td>
+ </tr>
+ <tr>
+ <td>Maximum failed password attempts </td>
+ <td>Specifies how many times a user can enter the wrong password before the
+device wipes its data. The Device Administration API also allows administrators to
+remotely reset the device to factory defaults. This secures data in case the
+device is lost or stolen.</td>
+ </tr>
+ <tr>
+ <td>Maximum inactivity time lock</td>
+ <td>Sets the length of time since the user last touched the screen or
+pressed a button before the device locks the screen. When this happens, users
+need to enter their PIN or passwords again before they can use their devices and
+access data. The value can be between 1 and 60 minutes.</td> </tr>
+</table>
+
+<h4>Other features</h4>
+
+<p>In addition to supporting the policies listed in the above table, the Device
+Administration API lets you do the following:</p> <ul>
+ <li>Prompt user to set a new password.</li>
+ <li>Lock device immediately.</li>
+ <li>Wipe the device's data (that is, restore the device to its factory defaults).</li>
+</ul>
+
+
+<h2 id="sample">Sample Application</h2>
+
+<p>The examples used in this document are based on the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/
+android/apis/app/DeviceAdminSample.html">Device Administration API
+sample</a>, which is included in the SDK samples. For information on downloading and
+installing the SDK samples, see <a
+href="{@docRoot}resources/samples/get.html">
+Getting the Samples</a>. Here is the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/
+android/apis/app/DeviceAdminSample.html">complete code</a> for
+the sample. </p>
+<p>The
+sample application offers a demo of device admin features. It presents users
+with a user interface that lets them enable the device admin application. Once
+they've enabled the application, they can use the buttons in the user interface
+to do the following:</p>
+<ul>
+ <li>Set password quality.</li>
+ <li>Specify the minimum length for the user's password.</li>
+ <li>Set the password. If the password does not conform to the specified
+policies, the system returns an error.</li>
+ <li>Set how many failed password attempts can occur before the device is wiped
+(that is, restored to factory settings).</li>
+ <li>Set the maximum amount of inactive time that can elapse before the device
+locks.</li>
+ <li>Make the device lock immediately.</li>
+ <li>Wipe the device's data (that is, restore factory settings).</li>
+</ul>
+
+<img src="{@docRoot}images/admin/device-admin-app.png"/>
+<p class="img-caption"><strong>Figure 1.</strong> Screenshot of the Sample Application</p>
+
+
+
+<h2 id="developing">Developing a Device Administration Application</h2>
+
+<p>System administrators can use the Device Administration API to write an application
+that enforces remote/local device security policy enforcement. This section
+summarizes the steps involved in creating a device administration
+application.</p>
+
+<h3 id="manifest">Creating the manifest</h3>
+
+<p>To use the Device Administration API, the application's
+manifest must include the following:</p>
+<ul>
+ <li>A subclass of {@link android.app.admin.DeviceAdminReceiver} that includes the following:
+ <ul>
+ <li>The {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission.</li>
+ <li>The ability to respond to the {@link android.app.admin.DeviceAdminReceiver#ACTION_DEVICE_ADMIN_ENABLED}
+intent, expressed in the manifest as an intent filter.</li>
+ </ul>
+ </li>
+ <li>A declaration of security policies used in metadata.</li>
+</ul>
+<p>Here is an excerpt from the Device Administration sample manifest:</p>
+<pre>&lt;activity android:name=&quot;.app.DeviceAdminSample$Controller&quot;
+        android:label=&quot;&#64;string/activity_sample_device_admin&quot;&gt;
+  &lt;intent-filter&gt;
+        &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
+        &lt;category android:name=&quot;android.intent.category.SAMPLE_CODE&quot; /&gt;
+    &lt;/intent-filter&gt;
+&lt;/activity&gt;
+
+&lt;receiver android:name=&quot;.app.DeviceAdminSample&quot;
+          android:label=&quot;&#64;string/sample_device_admin&quot;
+          android:description=&quot;&#64;string/sample_device_admin_description&quot;
+          android:permission=&quot;android.permission.BIND_DEVICE_ADMIN&quot;&gt;
+    &lt;meta-data android:name=&quot;android.app.device_admin&quot;
+               android:resource=&quot;&#64;xml/device_admin_sample&quot; /&gt;
+    &lt;intent-filter&gt;
+        &lt;action android:name=&quot;android.app.action.DEVICE_ADMIN_ENABLED&quot; /&gt;
+    &lt;/intent-filter&gt;
+&lt;/receiver&gt;</pre>
+
+ <p>Note that:</p>
+<ul>
+ <li>The activity in the sample application is an {@link android.app.Activity}
+subclass called <code>Controller</code>. The syntax
+<code>&quot;.app.DeviceAdminSample$Controller&quot;</code> indicates that
+<code>Controller</code> is an inner class that is nested inside the
+<code>DeviceAdminSample</code> class. Note that an Activity does not need to be
+an inner class; it just is in this example.</li>
+
+<li>The following attributes refer to string resources that for the sample application reside in
+<code>ApiDemos/res/values/strings.xml</code>. For more information about resources, see
+<a
+href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.
+<ul>
+<li><code>android:label=&quot;@string/activity_sample_device_admin&quot;</code> refers to the
+user-readable label for the activity.</li>
+
+<li><code>android:label=&quot;@string/sample_device_admin&quot;</code> refers to the
+user-readable label for the permission.</li>
+
+<li><code>android:description=&quot;@string/sample_device_admin_description&quot;</code> refers to
+the user-readable description of the permission. A descripton is typically longer and more
+informative than
+a label.</li>
+</ul>
+
+
+<li><code>android:permission=&quot;android.permission.BIND_DEVICE_ADMIN&quot;
+</code> is a permission that a {@link android.app.admin.DeviceAdminReceiver} subclass must
+have, to ensure that only the system can interact with the receiver (no application can be granted this permission). This
+prevents other applications from abusing your device admin app.</li>
+<li><code>android.app.action.DEVICE_ADMIN_ENABLED</code> is the the primary
+action that a {@link android.app.admin.DeviceAdminReceiver} subclass must handle to be
+allowed to manage a device. This is set to the receiver when the user enables
+the device admin app. Your code typically handles this in
+{@link android.app.admin.DeviceAdminReceiver#onEnabled onEnabled()}. To be supported, the receiver must also
+require the {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission so that other applications
+cannot abuse it. </li>
+<li>When a user enables the device admin application, that gives the receiver
+permission to perform actions in response to the broadcast of particular system
+events. When suitable event arises, the application can impose a policy. For
+example, if the user attempts to set a new password that doesn't meet the policy
+requirements, the application can prompt the user to pick a different password
+that does meet the requirements.</li>
+
+ <li><code>android:resource=&quot;&#64;xml/device_admin_sample&quot;</code>
+declares the security policies used in metadata. The metadata provides additional
+information specific to the device administrator, as parsed by the {@link
+android.app.admin.DeviceAdminInfo} class. Here are the contents of
+<code>device_admin_sample.xml</code>:</li>
+</ul>
+<pre>&lt;device-admin xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
+ &lt;uses-policies&gt;
+ &lt;limit-password /&gt;
+ &lt;watch-login /&gt;
+ &lt;reset-password /&gt;
+ &lt;force-lock /&gt;
+ &lt;wipe-data /&gt;
+ &lt;/uses-policies&gt;
+&lt;/device-admin&gt;
+</pre>
+<p> In designing your device administration application, you don't need to
+include all of the policies, just the ones that are relevant for your app.
+</p>
+For more discussion of the manifest file, see the <a
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">Android Developers Guide</a>.
+
+
+
+<h3 id="code">Implementing the code</h3>
+
+<p>The Device Administration API includes the following classes:</p>
+<dl>
+ <dt>{@link android.app.admin.DeviceAdminReceiver}</dt>
+ <dd>Base class for implementing a device administration component. This class provides
+a convenience for interpreting the raw intent actions that are sent by the
+system. Your Device Administration application must include a
+{@link android.app.admin.DeviceAdminReceiver} subclass.</dd>
+ <dt>{@link android.app.admin.DevicePolicyManager}</dt>
+<dd>A class for managing policies enforced on a device. Most clients of
+this class must have published a {@link android.app.admin.DeviceAdminReceiver} that the user
+has currently enabled. The {@link android.app.admin.DevicePolicyManager} manages policies for
+one or more {@link android.app.admin.DeviceAdminReceiver} instances</dd>
+ <dt>{@link android.app.admin.DeviceAdminInfo}</dt>
+<dd>This class is used to specify metadata
+for a device administrator component.</dd>
+</dl>
+<p>These classes provide the foundation for a fully functional device administration application.
+The rest of this section describes how you use the {@link
+android.app.admin.DeviceAdminReceiver} and
+{@link android.app.admin.DevicePolicyManager} APIs to write a device admin application.</p>
+
+<h4 id="receiver">Subclassing DeviceAdminReceiver</h4>
+<p>To create a device admin application, you must subclass
+{@link android.app.admin.DeviceAdminReceiver}. The {@link android.app.admin.DeviceAdminReceiver} class
+consists of a series of callbacks that are triggered when particular events
+occur.</p>
+<p>In its {@link android.app.admin.DeviceAdminReceiver} subclass, the sample application
+simply displays a {@link android.widget.Toast} notification in response to particular
+events. For example:</p>
+<pre>public class DeviceAdminSample extends DeviceAdminReceiver {
+
+...
+ &#64;Override
+    public void onEnabled(Context context, Intent intent) {
+        showToast(context, &quot;Sample Device Admin: enabled&quot;);
+    }
+
+    &#64;Override
+    public CharSequence onDisableRequested(Context context, Intent intent) {
+        return &quot;This is an optional message to warn the user about disabling.&quot;;
+    }
+
+    &#64;Override
+    public void onDisabled(Context context, Intent intent) {
+        showToast(context, &quot;Sample Device Admin: disabled&quot;);
+    }
+
+    &#64;Override
+    public void onPasswordChanged(Context context, Intent intent) {
+        showToast(context, &quot;Sample Device Admin: pw changed&quot;);
+    }
+
+ void showToast(Context context, CharSequence msg) {
+ Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+ }
+...
+}</pre>
+
+<h4 id="enabling">Enabling the application</h4>
+<p>One of the major events a device admin application has to handle is the user
+enabling the application. The user must explicitly enable the application for
+the policies to be enforced. If the user chooses not to enable the application
+it will still be present on the device, but its policies will not be enforced, and the user will not
+get any of the application's benefits.</p>
+<p>The process of enabling the application begins when the user performs an
+action that triggers the {@link android.app.admin.DevicePolicyManager#ACTION_ADD_DEVICE_ADMIN}
+intent. In the
+sample application, this happens when the user clicks the <strong>Enable
+Admin</strong> button. </p>
+<p>When the user clicks the <strong>Enable Admin</strong> button, the display
+changes to prompt the user to enable the device admin application, as shown in figure
+2.</p>
+
+<img src="{@docRoot}images/admin/device-admin-activate-prompt.png"/>
+<p class="img-caption"><strong>Figure 2.</strong> Sample Application: Activating the Application</p>
+<p>Below is the code that gets executed when the user clicks the <strong>Enable
+Admin</strong> button shown in figure 1. </p>
+
+<pre> private OnClickListener mEnableListener = new OnClickListener() {
+ public void onClick(View v) {
+ // Launch the activity to have the user enable our admin.
+        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
+ intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+ mDeviceAdminSample);
+        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
+               &quot;Additional text explaining why this needs to be added.&quot;);
+        startActivityForResult(intent, RESULT_ENABLE);
+ }
+};
+
+...
+// This code checks whether the device admin app was successfully enabled.
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case RESULT_ENABLE:
+ if (resultCode == Activity.RESULT_OK) {
+ Log.i(&quot;DeviceAdminSample&quot;, &quot;Administration enabled!&quot;);
+            } else {
+                Log.i(&quot;DeviceAdminSample&quot;, &quot;Administration enable FAILED!&quot;);
+            }
+            return;
+    }
+    super.onActivityResult(requestCode, resultCode, data);
+}</pre>
+
+<p>The line
+<code>intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+mDeviceAdminSample)</code> states that <code>mDeviceAdminSample</code> (which is
+a {@link android.app.admin.DeviceAdminReceiver} component) is the target policy.
+This line invokes the user interface shown in figure 2, which guides users through
+adding the device administrator to the system (or allows them to reject it).</p>
+
+<p>When the application needs to perform an operation that is contingent on the
+device admin application being enabled, it confirms that the application is
+active. To do this it uses the {@link android.app.admin.DevicePolicyManager} method
+{@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()}. Notice that the {@link android.app.admin.DevicePolicyManager}
+method {@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()} takes a {@link android.app.admin.DeviceAdminReceiver}
+component as its argument:</p>
+<pre>
+DevicePolicyManager mDPM;
+...
+boolean active = mDPM.isAdminActive(mDeviceAdminSample);
+if (active) {
+ // Admin app is active, so do some admin stuff
+               ...
+} else {
+ // do something else
+}
+</pre>
+
+<h3 id="admin_ops">Managing policies</h3>
+<p>{@link android.app.admin.DevicePolicyManager} is a public class for managing policies
+enforced on a device. {@link android.app.admin.DevicePolicyManager} manages policies for one
+or more {@link android.app.admin.DeviceAdminReceiver} instances. </p>
+<p>You get a handle to the {@link android.app.admin.DevicePolicyManager} as follows: </p>
+<pre>
+DevicePolicyManager mDPM =
+ (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
+</pre>
+<p>This section describes how to use {@link android.app.admin.DevicePolicyManager} to perform
+ administrative tasks:</p>
+<ul>
+ <li><a href="#pwd">Set password policies</a></li>
+ <li><a href="#lock">Set device lock</a></li>
+ <li><a href="#wipe">Perform data wipe</a></li>
+</ul>
+
+<h4 id="pwd">Set password policies</h4>
+<p>{@link android.app.admin.DevicePolicyManager} includes APIs for setting and enforcing the
+device password policy. In the Device Administration API, the password only applies to
+screen lock. This section describes common password-related tasks.</p>
+
+<h5>Set a password for the device</h5>
+<p>This code displays a user interface prompting the user to set a password:</p>
+<pre>Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
+startActivity(intent);
+</pre>
+
+<h5>Set the password quality</h5>
+<p>The password quality can be one of the following {@link android.app.admin.DevicePolicyManager} constants: </p>
+<dl>
+ <dt>{@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_ALPHABETIC}</dt><dd>The user must enter a
+password containing at least alphabetic (or other symbol) characters.</dd>
+ <dt>{@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_ALPHANUMERIC}</dt><dd>The user must enter a
+password containing at least <em>both</em> numeric <em>and</em> alphabetic (or
+other symbol) characters.</dd>
+ <dt>{@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_NUMERIC}</dt><dd>The user must enter a password
+containing at least numeric characters.</dd>
+ <dt>{@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_SOMETHING}</dt><dd>The policy requires some kind
+of password, but doesn't care what it is.</dd>
+ <dt>{@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}</dt><dd>
+ The policy has no requirements for the password. </dd>
+</dl>
+<p>For example, this is how you would set the password policy to require an alphanumeric password:</p>
+<pre>
+DevicePolicyManager mDPM;
+ComponentName mDeviceAdminSample;
+...
+mDPM.setPasswordQuality(mDeviceAdminSample, DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
+</pre>
+
+<h5>Set the minimum password length</h5>
+<p>You can specify that a password must be at least the specified minimum
+length. For example:</p>
+<pre>DevicePolicyManager mDPM;
+ComponentName mDeviceAdminSample;
+int pwLength;
+...
+mDPM.setPasswordMinimumLength(mDeviceAdminSample, pwLength);
+</pre>
+
+<h5>Set maximum failed password attempts</h5>
+<p>You can set the maximum number of allowed failed password attempts before the
+device is wiped (that is, reset to factory settings). For example:</p>
+<pre>DevicePolicyManager mDPM;
+ComponentName mDeviceAdminSample;
+int maxFailedPw;
+ ...
+mDPM.setMaximumFailedPasswordsForWipe(mDeviceAdminSample, maxFailedPw);</pre>
+
+<h4 id="lock">Set device lock</h4>
+<p>You can set the maximum period of user inactivity that can occur before the
+device locks. For example:</p>
+<pre>
+DevicePolicyManager mDPM;
+ComponentName mDeviceAdminSample;
+...
+long timeMs = 1000L*Long.parseLong(mTimeout.getText().toString());
+mDPM.setMaximumTimeToLock(mDeviceAdminSample, timeMs);
+</pre>
+<p>You can also programmatically tell the device to lock immediately:</p>
+<pre>
+DevicePolicyManager mDPM;
+mDPM.lockNow();</pre>
+
+<h4 id="wipe">Perform data wipe</h4>
+
+<p>You can use the {@link android.app.admin.DevicePolicyManager} method
+{@link android.app.admin.DevicePolicyManager#wipeData wipeData()} to reset the device to factory settings. This is useful
+if the device is lost or stolen. Often the decision to wipe the device is the
+result of certain conditions being met. For example, you can use
+{@link android.app.admin.DevicePolicyManager#setMaximumFailedPasswordsForWipe setMaximumFailedPasswordsForWipe()} to state that a device should be
+wiped after a specific number of failed password attempts.</p>
+<p>You wipe data as follows:</p>
+<pre>
+DevicePolicyManager mDPM;
+mDPM.wipeData(0);</pre>
+<p>The {@link android.app.admin.DevicePolicyManager#wipeData wipeData()} method takes as its parameter a bit mask of
+additional options. Currently the value must be 0. </p>
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index 7a8dd59..3de5627 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -3,12 +3,14 @@ page.title=App Widgets
<div id="qv-wrapper">
<div id="qv">
- <h2>Key classes</h2>
- <ol>
- <li>{@link android.appwidget.AppWidgetProvider}</li>
- <li>{@link android.appwidget.AppWidgetProviderInfo}</li>
- <li>{@link android.appwidget.AppWidgetManager}</li>
- </ol>
+ <h2>Quickview</h2>
+ <ul>
+ <li>App Widgets provide users access to some of your application features
+directly from the Home screen (without the need to launch an activity)</li>
+ <li>App Widgets are backed by a special kind of broadcast receiver that handles the App
+Widget lifecycle</li>
+ </ul>
+
<h2>In this document</h2>
<ol>
<li><a href="#Basics">The Basics</a></li>
@@ -28,6 +30,13 @@ page.title=App Widgets
</li>
</ol>
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.appwidget.AppWidgetProvider}</li>
+ <li>{@link android.appwidget.AppWidgetProviderInfo}</li>
+ <li>{@link android.appwidget.AppWidgetManager}</li>
+ </ol>
+
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design
diff --git a/docs/html/guide/topics/data/backup.jd b/docs/html/guide/topics/data/backup.jd
index 4279d7d..6c02031 100644
--- a/docs/html/guide/topics/data/backup.jd
+++ b/docs/html/guide/topics/data/backup.jd
@@ -240,7 +240,7 @@ Backup Service Key is ignored.</p>
<h2 id="BackupAgent">Extending BackupAgent</h2>
<p>Most applications shouldn't need to extend the {@link android.app.backup.BackupAgent} class
-directly, but should instead <a href="BackupAgentHelper">extend BackupAgentHelper</a> to take
+directly, but should instead <a href="#BackupAgentHelper">extend BackupAgentHelper</a> to take
advantage of the built-in helper classes that automatically backup and restore your files. However,
you might want to extend {@link android.app.backup.BackupAgent} directly if you need to:</p>
<ul>
@@ -262,7 +262,7 @@ create your table and insert the data during a restore operation.</li>
<p>If you don't need to perform any of the tasks above and want to back up complete files from
{@link android.content.SharedPreferences} or <a
href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal storage</a>, you
-should skip to <a href="BackupAgentHelper">Extending BackupAgentHelper</a>.</p>
+should skip to <a href="#BackupAgentHelper">Extending BackupAgentHelper</a>.</p>
@@ -576,8 +576,8 @@ helpers.</p>
<h3 id="SharedPreferences">Backing up SharedPreferences</h3>
-<p>When you instantiate a {@link android.app.backup.SharedPreferencesBackupHelper}, you must the
-name of one or more {@link android.content.SharedPreferences} files.</p>
+<p>When you instantiate a {@link android.app.backup.SharedPreferencesBackupHelper}, you must
+include the name of one or more {@link android.content.SharedPreferences} files.</p>
<p>For example, to back up a {@link android.content.SharedPreferences} file named
"user_preferences", a complete backup agent using {@link android.app.backup.BackupAgentHelper} looks
diff --git a/docs/html/guide/topics/data/data-storage.jd b/docs/html/guide/topics/data/data-storage.jd
index 293a057..e20d1ed 100644
--- a/docs/html/guide/topics/data/data-storage.jd
+++ b/docs/html/guide/topics/data/data-storage.jd
@@ -115,7 +115,7 @@ public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
&#64;Override
- protected void onCreate(Bundle state){
+ protected void onCreate(Bundle state){
super.onCreate(state);
. . .
@@ -374,7 +374,7 @@ android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase) onCreate()} me
can execute a SQLite command to create tables in the database. For example:</p>
<pre>
-public class MyDbOpenHelper extends SQLiteOpenHelper {
+public class DictionaryOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final String DICTIONARY_TABLE_NAME = "dictionary";
diff --git a/docs/html/guide/topics/fundamentals.jd b/docs/html/guide/topics/fundamentals.jd
index f780e7c..a095087 100644
--- a/docs/html/guide/topics/fundamentals.jd
+++ b/docs/html/guide/topics/fundamentals.jd
@@ -3,14 +3,6 @@ page.title=Application Fundamentals
<div id="qv-wrapper">
<div id="qv">
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.app.Activity}</li>
-<li>{@link android.app.Service}</li>
-<li>{@link android.content.BroadcastReceiver}</li>
-<li>{@link android.content.ContentProvider}</li>
-<li>{@link android.content.Intent}</li>
-</ol>
<h2>In this document</h2>
<ol>
@@ -43,6 +35,16 @@ page.title=Application Fundamentals
<li><a href="#proclife">Processes and lifecycles</a></li>
</ol></li>
</ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.app.Activity}</li>
+<li>{@link android.app.Service}</li>
+<li>{@link android.content.BroadcastReceiver}</li>
+<li>{@link android.content.ContentProvider}</li>
+<li>{@link android.content.Intent}</li>
+</ol>
+
</div>
</div>
@@ -770,9 +772,9 @@ return to what that instance was doing before the new intent arrived.
</p>
<p>
-For more on launch modes, see the description of the
-<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
-element.
+For more on launch modes, see the description of the <code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">&lt;activity&gt;</a></code>
+element.
</p>
diff --git a/docs/html/guide/topics/intents/intents-filters.jd b/docs/html/guide/topics/intents/intents-filters.jd
index bd1d694..5905214 100644
--- a/docs/html/guide/topics/intents/intents-filters.jd
+++ b/docs/html/guide/topics/intents/intents-filters.jd
@@ -3,15 +3,6 @@ page.title=Intents and Intent Filters
<div id="qv-wrapper">
<div id="qv">
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.content.Intent}</li>
-<li>{@link android.content.IntentFilter}</li>
-<li>{@link android.app.Activity}</li>
-<li>{@link android.app.Service}</li>
-<li>{@link android.content.BroadcastReceiver}</li>
-<li>{@link android.content.pm.PackageManager}</li>
-</ol>
<h2>In this document</h2>
<ol>
@@ -22,6 +13,15 @@ page.title=Intents and Intent Filters
<li style="margin-left: 2em"><a href="#imatch">Using intent matching</a></li>
<li><a href="#npex">Note Pad Example</a></li>
</ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.content.Intent}</li>
+<li>{@link android.content.IntentFilter}</li>
+<li>{@link android.content.BroadcastReceiver}</li>
+<li>{@link android.content.pm.PackageManager}</li>
+</ol>
+
</div>
</div>
diff --git a/docs/html/guide/topics/location/index.jd b/docs/html/guide/topics/location/index.jd
index e988ecb..5f98902 100644
--- a/docs/html/guide/topics/location/index.jd
+++ b/docs/html/guide/topics/location/index.jd
@@ -4,94 +4,63 @@ page.title=Location and Maps
<div id="qv-wrapper">
<div id="qv">
- <h2>Location and Maps quickview</h2>
+ <h2>Quickview</h2>
<ul>
- <li>Android provides a location framework that your application can use to determine the device's location and bearing and register for updates.</li>
- <li>A Google Maps external library is available that lets you display and manage Maps data.</li>
+ <li>Android provides a location framework that your application can use to determine the
+device's location and bearing and register for updates</li>
+ <li>A Google Maps external library is available that lets you display and manage Maps data</li>
</ul>
- <h2>In this document</h2>
+
+ <h2>Topics</h2>
<ol>
- <li><a href="#location">Location Services</a></li>
- <li><a href="#maps">Google Maps External Library</a></li>
+ <li><a href="{@docRoot}guide/topics/location/obtaining-user-location.html">Obtaining User
+Location</a></li>
</ol>
+
<h2>See Also</h2>
<ol>
- <li><a href="http://code.google.com/android/add-ons/google-apis/index.html">Google APIs add-on download&raquo;</a></li>
+ <li><a
+href="http://code.google.com/android/add-ons/google-apis/maps-overview.html">Google
+Maps External Library &raquo;</a></li>
</ol>
</div>
</div>
-<p>Location- and maps-based applications and services are compelling for mobile device users. You can build these capabilities into your applications using the classes of the {@link android.location} package and the Google Maps external library. The sections below provide details. </p>
+<p>Location and maps-based applications are compelling for mobile device users. You
+can build these capabilities into your applications using the classes of the {@link
+android.location} package and the Google Maps external library. The sections below provide details.
+</p>
<h2 id="location">Location Services</h2>
<p>Android gives your applications access to the location services supported by
-the device through the classes in the <code>android.location</code> package. The
+the device through the classes in the {@code android.location} package. The
central component of the location framework is the
-{@link android.location.LocationManager} system service, which provides an API to
-determine location and bearing if the underlying device (if it supports location
-capabilities). </p>
+{@link android.location.LocationManager} system service, which provides APIs to
+determine location and bearing of the underlying device (if available). </p>
-<p>As with other system services, you do not instantiate a LocationManager directly.
-Rather, you request an LocationManager instance from the system by calling
-{@link android.content.Context#getSystemService(String) getSystemService(Context.LOCATION_SERVICE)}.
-The method returns a handle to a new LocationManager instance.</p>
+<p>As with other system services, you do not instantiate a {@link android.location.LocationManager}
+directly. Rather, you request an instance from the system by calling
+{@link android.content.Context#getSystemService(String)
+getSystemService(Context.LOCATION_SERVICE)}. The method returns a handle to a new {@link
+android.location.LocationManager} instance.</p>
-<p>Once your application has a handle to a LocationManager instance, your application
-will be able to do three things:</p>
+<p>Once your application has a {@link android.location.LocationManager}, your application
+is able to do three things:</p>
<ul>
- <li>Query for the list of all LocationProviders known to the
- LocationManager for its last known location.</li>
- <li>Register/unregister for periodic updates of current location from a
- LocationProvider (specified either by Criteria or name).</li>
- <li>Register/unregister for a given Intent to be fired if the device comes
- within a given proximity (specified by radius in meters) of a given
- lat/long.</li>
+ <li>Query for the list of all {@link android.location.LocationProvider}s for the last known
+user location.</li>
+ <li>Register/unregister for periodic updates of the user's current location from a
+ location provider (specified either by criteria or name).</li>
+ <li>Register/unregister for a given {@link android.content.Intent} to be fired if the device
+comes within a given proximity (specified by radius in meters) of a given lat/long.</li>
</ul>
-<p>However, during initial development in the emulator, you may not have access to real
-data from a real location provider (Network or GPS). In that case, it may be necessary to
-spoof some data for your application using a mock location provider.</p>
-
-<p class="note"><strong>Note:</strong> If you've used mock LocationProviders in
-previous versions of the SDK, you can no longer provide canned LocationProviders
-in the /system/etc/location directory. These directories will be wiped during boot-up.
-Please follow the new procedures outlined below.</p>
-
-<h3>Providing Mock Location Data</h3>
-
-<p>When testing your application on the Android emulator, there are a couple different
-ways to send it some mock location data: you can use the DDMS tool or the "geo" command
-option in the emulator console.</p>
-
-<h4 id="ddms">Using DDMS</h4>
-<p>With the DDMS tool, you can simulate location data a few different ways:</p>
-<ul>
- <li>Manually send individual longitude/latitude coordinates to the device.</li>
- <li>Use a GPX file describing a route for playback to the device.</li>
- <li>Use a KML file describing individual placemarks for sequenced playback to the device.</li>
-</ul>
-<p>For more information on using DDMS to spoof location data, see the
-<a href="{@docRoot}guide/developing/tools/ddms.html#emulator-control">Using DDMS guide</a>.
-
-<h4 id="geo">Using the "geo" command in the emulator console</h4>
-<p>Launch your application in the Android emulator and open a terminal/console in
-your SDK's <code>/tools</code> directory. Connect to the emulator console. Now you can use:</p>
-<ul><li><code>geo fix</code> to send a fixed geo-location.
- <p>This command accepts a longitude and latitude in decimal degrees, and
- an optional altitude in meters. For example:</p>
- <pre>geo fix -121.45356 46.51119 4392</pre>
- </li>
- <li><code>geo nmea</code> to send an NMEA 0183 sentence.
- <p>This command accepts a single NMEA sentence of type '$GPGGA' (fix data) or '$GPRMC' (transit data).
- For example:</p>
- <pre>geo nmea $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62</pre>
- </li>
-</ul>
+<p>For more information, read the guide to <a
+href="{@docRoot}guide/topics/location/obtaining-user-location.html">Obtaining User
+Location</a>.</p>
-<p>For information about how to connect to the emulator console, see
-<a href="{@docRoot}guide/developing/tools/emulator.html#console">Using the Emulator Console</a>.</p>
<h2 id="maps">Google Maps External Library</h2>
@@ -128,9 +97,9 @@ Google APIs add-on, visit</p>
<p style="margin-left:2em;"><a
href="http://code.google.com/android/add-ons/google-apis">http://code.google.com/android/add-ons/google-apis</a></p>
-<p>For your convenience, the Google APIs add-on is also included in the Android
-SDK. <!-- To learn now to use the Maps external library in your application, see
-[[Using External Libraries]].--></p>
+<p>For your convenience, the Google APIs add-on is also available as a downloadable component from
+the Android SDK and AVD Manager (see <a href="{@docRoot}sdk/adding-components.html">Adding SDK
+Components</a>).</p>
<p class="note"><strong>Note:</strong> In order to display Google Maps data in a
MapView, you must register with the Google Maps service and obtain a Maps API
diff --git a/docs/html/guide/topics/location/obtaining-user-location.jd b/docs/html/guide/topics/location/obtaining-user-location.jd
new file mode 100644
index 0000000..bc782d2
--- /dev/null
+++ b/docs/html/guide/topics/location/obtaining-user-location.jd
@@ -0,0 +1,454 @@
+page.title=Obtaining User Location
+parent.title=Location and Maps
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>Quickview</h2>
+ <ul>
+ <li>The Network Location Provider provides good location data without using GPS</li>
+ <li>Obtaining user location can consume a lot of battery, so be careful how
+long you listen for updates</li>
+ </ul>
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#Challenges">Challenges in Determining User Location</a></li>
+ <li><a href="#Updates">Requesting Location Updates</a>
+ <ol>
+ <li><a href="#Permission">Requesting User Permissions</a></li>
+ </ol>
+ </li>
+ <li><a href="#BestPerformance">Defining a Model for the Best Performance</a>
+ <ol>
+ <li><a href="#Flow">Flow for obtaining user location</a></li>
+ <li><a href="#StartListening">Deciding when to start listening for updates</a></li>
+ <li><a href="#FastFix">Getting a fast fix with the last known location</a></li>
+ <li><a href="#StopListening">Deciding when to stop listening for updates</a></li>
+ <li><a href="#BestEstimate">Maintaining a current best estimate</a></li>
+ <li><a href="#Adjusting">Adjusting the model to save battery and data exchange</a></li>
+ </ol>
+ </li>
+ <li><a href="#MockData">Providing Mock Location Data</a></li>
+ </ol>
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.location.LocationManager}</li>
+ <li>{@link android.location.LocationListener}</li>
+ </ol>
+</div>
+</div>
+
+ <p>Knowing where the user is allows your application to be smarter and deliver
+better information to the user. When developing a location-aware application for Android, you can
+utilize GPS and Android's Network Location Provider to acquire the user location. Although
+GPS is most accurate, it only works outdoors, it quickly consumes battery power, and doesn't return
+the location as quickly as users want. Android's Network Location Provider determines user location
+using cell tower and Wi-Fi signals, providing location information in a way that
+works indoors and outdoors, responds faster, and uses less battery power. To obtain the user
+location in your application, you can use both GPS and the Network Location Provider, or just
+one.</p>
+
+
+<h2 id="Challenges">Challenges in Determining User Location</h2>
+
+<p>Obtaining user location from a mobile device can be complicated. There are several reasons
+why a location reading (regardless of the source) can contain errors and be inaccurate.
+Some sources of error in the user location include:</p>
+
+<ul>
+ <li><b>Multitude of location sources</b>
+ <p>GPS, Cell-ID, and Wi-Fi can each provide a clue to users location. Determining which to use
+and trust is a matter of trade-offs in accuracy, speed, and battery-efficiency.</p>
+ </li>
+ <li><b>User movement</b>
+ <p>Because the user location changes, you must account for movement by re-estimating user
+location every so often.</p>
+ </li>
+ <li><b>Varying accuracy</b>
+ <p>Location estimates coming from each location source are not consistent in their
+accuracy. A location obtained 10 seconds ago from one source might be more accurate than the newest
+location from another or same source.</p>
+ </li>
+</ul>
+
+ <p>These problems can make it difficult to obtain a reliable user location reading. This
+document provides information to help you meet these challenges to obtain a reliable location
+reading. It also provides ideas that you can use in your
+application to provide the user with an accurate and responsive geo-location experience.</p>
+
+
+<h2 id="Updates">Requesting Location Updates</h2>
+
+ <p>Before addressing some of the location errors described above, here is an introduction to
+how you can obtain user location on Android.</p>
+
+ <p>Getting user location in Android works by means of callback. You indicate that you'd
+like to receive location updates from the {@link android.location.LocationManager} ("Location
+Manager") by calling {@link android.location.LocationManager#requestLocationUpdates
+requestLocationUpdates()}, passing it a
+{@link android.location.LocationListener}. Your {@link android.location.LocationListener} must
+implement several callback methods that the Location Manager calls when the user location
+changes or when the status of the service changes.</p>
+
+<p>For example, the following code shows how to define a {@link android.location.LocationListener}
+and request location updates:
+ </p>
+
+<pre>
+// Acquire a reference to the system Location Manager
+LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
+
+// Define a listener that responds to location updates
+LocationListener locationListener = new LocationListener() {
+ public void onLocationChanged(Location location) {
+ // Called when a new location is found by the network location provider.
+ makeUseOfNewLocation(location);
+ }
+
+ public void onStatusChanged(String provider, int status, Bundle extras) {}
+
+ public void onProviderEnabled(String provider) {}
+
+ public void onProviderDisabled(String provider) {}
+ };
+
+// Register the listener with the Location Manager to receive location updates
+locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
+</pre>
+
+ <p>The first parameter in {@link
+android.location.LocationManager#requestLocationUpdates requestLocationUpdates()} is the type of
+location provider to use (in this case, the Network Location Provider for cell tower and Wi-Fi
+based location). You can control the frequency at which your listener receives updates
+with the second and third parameter&mdash;the second is the minimum time interval between
+notifications and the third is the minimum change in distance between notifications&mdash;setting
+both to zero requests location notifications as frequently as possible. The last parameter is your
+{@link android.location.LocationListener}, which receives callbacks for location updates.</p>
+
+<p>To request location updates from the GPS provider,
+substitute <code>GPS_PROVIDER</code> for <code>NETWORK_PROVIDER</code>. You can also request
+location updates from both the GPS and the Network Location Provider by calling {@link
+android.location.LocationManager#requestLocationUpdates requestLocationUpdates()} twice&mdash;once
+for <code>NETWORK_PROVIDER</code> and once for <code>GPS_PROVIDER</code>.</p>
+
+
+<h3 id="Permission">Requesting User Permissions</h3>
+
+<p>In order to receive location updates from <code>NETWORK_PROVIDER</code> or
+<code>GPS_PROVIDER</code>, you must request user permission by declaring either the {@code
+ACCESS_COARSE_LOCATION} or {@code ACCESS_FINE_LOCATION} permission, respectively, in your Android
+manifest file. For example:</p>
+
+<pre>
+&lt;manifest ... &gt;
+ &lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /&gt;
+ ...
+&lt;/manifest&gt;
+</pre>
+
+<p>Without these permissions, your application will fail at runtime when requesting
+location updates.</p>
+
+<p class="note"><strong>Note:</strong> If you are using both <code>NETWORK_PROVIDER</code> and
+<code>GPS_PROVIDER</code>, then you need to request only the {@code ACCESS_FINE_LOCATION}
+permission, because it includes permission for both providers. (Permission for {@code
+ACCESS_COARSE_LOCATION} includes permission only for <code>NETWORK_PROVIDER</code>.)</p>
+
+
+<h2 id="BestPerformance">Defining a Model for the Best Performance</h2>
+
+ <p>Location-based applications are now commonplace, but due to the less than optimal
+accuracy, user movement, the multitude of methods to obtain the location, and the desire to conserve
+battery, getting user location is complicated. To overcome the obstacles of obtaining a good user
+location while preserving battery power, you must define a consistent model that specifies how your
+application obtains the user location. This model includes when you start and stop listening for
+updates and when to use cached location data.</p>
+
+
+ <h3 id="Flow">Flow for obtaining user location</h3>
+
+ <p>Here's the typical flow of procedures for obtaining the user location:</p>
+
+ <ol>
+ <li>Start application.</li>
+ <li>Sometime later, start listening for updates from desired location providers.</li>
+ <li>Maintain a "current best estimate" of location by filtering out new, but less accurate
+fixes.</li>
+ <li>Stop listening for location updates.</li>
+ <li>Take advantage of the last best location estimate.</li>
+ </ol>
+
+ <p>Figure 1 demonstrates this model in a timeline that visualizes the period in which an
+application is listening for location updates and the events that occur during that time.</p>
+
+<img src="{@docRoot}images/location/getting-location.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> A timeline representing the window in which an
+application listens for location updates.</p>
+
+ <p>This model of a window&mdash;during which location updates are received&mdash;frames many of
+the decisions you need to make when adding location-based services to your application.</p>
+
+
+ <h3 id="StartListening">Deciding when to start listening for updates</h3>
+
+ <p>You might want to start listening for location updates as soon as your application starts, or
+only after users activate a certain feature. Be aware that long windows of listening for location
+fixes can consume a lot of battery power, but short periods might not allow for sufficient
+accuracy.</p>
+
+ <p>As demonstrated above, you can begin listening for updates by calling {@link
+android.location.LocationManager#requestLocationUpdates requestLocationUpdates()}:</p>
+
+<pre>
+LocationProvider locationProvider = LocationManager.NETWORK_PROVIDER;
+// Or, use GPS location data:
+// LocationProvider locationProvider = LocationManager.GPS_PROVIDER;
+
+locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);
+</pre>
+
+
+ <h3 id="FastFix">Getting a fast fix with the last known location</h3>
+
+ <p>The time it takes for your location listener to receive the first location fix is often too
+long for users wait. Until a more accurate location is provided to your location listener, you
+should utilize a cached location by calling {@link
+android.location.LocationManager#getLastKnownLocation}:</p>
+<pre>
+LocationProvider locationProvider = LocationManager.NETWORK_PROVIDER;
+// Or use LocationManager.GPS_PROVIDER
+
+Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
+</pre>
+
+
+ <h3 id="StopListening">Deciding when to stop listening for updates</h3>
+
+ <p>The logic of deciding when new fixes are no longer necessary might range from very simple to
+very complex depending on your application. A short gap between when the location is acquired and
+when the location is used, improves the accuracy of the estimate. Always beware that listening for a
+long time consumes a lot of battery power, so as soon as you have the information you need, you
+should stop
+listening for updates by calling {@link android.location.LocationManager#removeUpdates}:</p>
+<pre>
+// Remove the listener you previously added
+locationManager.removeUpdates(locationListener);
+</pre>
+
+
+ <h3 id="BestEstimate">Maintaining a current best estimate</h3>
+
+ <p>You might expect that the most recent location fix is the most accurate.
+However, because the accuracy of a location fix varies, the most recent fix is not always the best.
+You should include logic for choosing location fixes based on several criteria. The criteria also
+varies depending on the use-cases of the application and field testing.</p>
+
+ <p>Here are a few steps you can take to validate the accuracy of a location fix:</p>
+ <ul>
+ <li>Check if the location retrieved is significantly newer than the previous estimate.</li>
+ <li>Check if the accuracy claimed by the location is better or worse than the previous
+estimate.</li>
+ <li>Check which provider the new location is from and determine if you trust it more.</li>
+ </ul>
+
+ <p>An elaborate example of this logic can look something like this:</p>
+
+<pre>
+private static final int TWO_MINUTES = 1000 * 60 * 2;
+
+/** Determines whether one Location reading is better than the current Location fix
+ * @param location The new Location that you want to evaluate
+ * @param currentBestLocation The current Location fix, to which you want to compare the new one
+ */
+protected boolean isBetterLocation(Location location, Location currentBestLocation) {
+ if (currentBestLocation == null) {
+ // A new location is always better than no location
+ return true;
+ }
+
+ // Check whether the new location fix is newer or older
+ long timeDelta = location.getTime() - currentBestLocation.getTime();
+ boolean isSignificantlyNewer = timeDelta &gt; TWO_MINUTES;
+ boolean isSignificantlyOlder = timeDelta &lt; -TWO_MINUTES;
+ boolean isNewer = timeDelta > 0;
+
+ // If it's been more than two minutes since the current location, use the new location
+ // because the user has likely moved
+ if (isSignificantlyNewer) {
+ return true;
+ // If the new location is more than two minutes older, it must be worse
+ } else if (isSignificantlyOlder) {
+ return false;
+ }
+
+ // Check whether the new location fix is more or less accurate
+ int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
+ boolean isLessAccurate = accuracyDelta &gt; 0;
+ boolean isMoreAccurate = accuracyDelta &lt; 0;
+ boolean isSignificantlyLessAccurate = accuracyDelta &gt; 200;
+
+ // Check if the old and new location are from the same provider
+ boolean isFromSameProvider = isSameProvider(location.getProvider(),
+ currentBestLocation.getProvider());
+
+ // Determine location quality using a combination of timeliness and accuracy
+ if (isMoreAccurate) {
+ return true;
+ } else if (isNewer &amp;&amp; !isLessAccurate) {
+ return true;
+ } else if (isNewer &amp;&amp; !isSignificantlyLessAccurate &amp;&amp; isFromSameProvider) {
+ return true;
+ }
+ return false;
+}
+
+/** Checks whether two providers are the same */
+private boolean isSameProvider(String provider1, String provider2) {
+ if (provider1 == null) {
+ return provider2 == null;
+ }
+ return provider1.equals(provider2);
+}
+</pre>
+
+
+ <h3 id="Adjusting">Adjusting the model to save battery and data exchange</h3>
+
+ <p>As you test your application, you might find that your model for providing good location and
+good performance needs some adjustment. Here are some things you might change to find a good
+balance between the two.</p>
+
+ <h4>Reduce the size of the window</h4>
+
+ <p>A smaller window in which you listen for location updates means less interaction with GPS and
+network location services, thus, preserving battery life. But it also allows for fewer locations
+from which to choose a best estimate.</p>
+
+ <h4>Set the location providers to return updates less frequently</h4>
+
+ <p>Reducing the rate at which new updates appear during the window can also improve battery
+efficiency, but at the cost of accuracy. The value of the trade-off depends on how your
+application is used. You can reduce the rate of updates by increasing the parameters in {@link
+android.location.LocationManager#requestLocationUpdates requestLocationUpdates()} that specify the
+interval time and minimum distance change.</p>
+
+ <h4>Restrict a set of providers</h4>
+
+ <p>Depending on the environment where your application is used or the desired level of accuracy,
+you might choose to use only the Network Location Provider or only GPS, instead of both. Interacting
+with only one of the services reduces battery usage at a potential cost of accuracy.</p>
+
+
+ <h2>Common application cases</h2>
+
+ <p>There are many reasons you might want to obtain the user location in your application. Below
+are a couple scenarios in which you can use the user location to enrich your application. Each
+scenario also describes good practices for when you should start and stop listening for the
+location, in order to get a good reading and help preserve battery life.</p>
+
+
+ <h3>Tagging user-created content with a location</h3>
+
+ <p>You might be creating an application where user-created content is tagged with a location.
+Think of users sharing their local experiences, posting a review for a restaurant, or recording some
+content that can be augmented with their current location. A model of how this
+interaction might happen, with respect to the location services, is visualized in figure 2.</p>
+
+ <img src="{@docRoot}images/location/content-tagging.png" alt="" />
+<p class="img-caption"><strong>Figure 2.</strong> A timeline representing the window in which
+the user location is obtained and listening stops when the user consumes the current location.</p>
+
+ <p>This lines up with the previous model of how user location is obtained in code (figure 1). For
+best location accuracy, you might choose to start listening for location updates when users begin
+creating
+the content or even when the application starts, then stop listening for updates when content is
+ready to be posted or recorded. You might need to consider how long a typical task of creating the
+content takes and judge if this duration allows for efficient collection of a location estimate.</p>
+
+
+ <h3>Helping the user decide on where to go</h3>
+
+ <p>You might be creating an application that attempts to provide users with a set
+of options about where to go. For example, you're looking to provide a list of nearby restaurants,
+stores, and entertainment and the order of recommendations changes depending on the user
+location.</p>
+
+ <p>To accommodate such a flow, you might choose to:</p>
+ <ul>
+ <li>Rearrange recommendations when a new best estimate is obtained</li>
+ <li>Stop listening for updates if the order of recommendations has stabilized</li>
+ </ul>
+
+ <p>This kind of model is visualized in figure 3.</p>
+
+ <img src="{@docRoot}images/location/where-to-go.png" alt="" />
+<p class="img-caption"><strong>Figure 3.</strong> A timeline representing the window in which a
+dynamic set of data is updated each time the user location updates.</p>
+
+
+
+
+<h2 id="MockData">Providing Mock Location Data</h2>
+
+<p>As you develop your application, you'll certainly need to test how well your model for obtaining
+user location works. This is most easily done using a real Android-powered device. If, however, you
+don't have a device, you can still test your location-based features by mocking location data in
+the Android emulator. There are three different ways to send your application mock location
+data: using Eclipse, DDMS, or the "geo" command in the emulator console.</p>
+
+<p class="note"><strong>Note:</strong> Providing mock location data is injected as GPS location
+data, so you must request location updates from <code>GPS_PROVIDER</code> in order for mock location
+data to work.</p>
+
+<h3 id="MockEclipse">Using Eclipse</h3>
+
+<p>Select <b>Window</b> &gt; <b>Show View</b> &gt; <b>Other</b> &gt; <b>Emulator Control</b>.</p>
+
+<p>In the Emulator Control panel, enter GPS coordinates under Location Controls as individual
+lat/long coordinates, with a GPX file for route playback, or a KML file for multiple place marks.
+(Be sure that you have a device selected in the Devices panel&mdash;available from <b>Window</b>
+&gt; <b>Show View</b> &gt; <b>Other</b> &gt; <b>Devices</b>.)</p>
+
+
+<h3 id="MockDdms">Using DDMS</h3>
+
+<p>With the DDMS tool, you can simulate location data a few different ways:</p>
+<ul>
+ <li>Manually send individual longitude/latitude coordinates to the device.</li>
+ <li>Use a GPX file describing a route for playback to the device.</li>
+ <li>Use a KML file describing individual place marks for sequenced playback to the device.</li>
+</ul>
+
+<p>For more information on using DDMS to spoof location data, see the
+<a href="{@docRoot}guide/developing/tools/ddms.html#emulator-control">Using DDMS guide</a>.
+
+
+<h3 id="MockGeo">Using the "geo" command in the emulator console</h3>
+
+<p>To send mock location data from the command line:</p>
+
+<ol>
+ <li>Launch your application in the Android emulator and open a terminal/console in your SDK's
+<code>/tools</code> directory.</li>
+ <li>Connect to the emulator console:
+<pre>telnet localhost <em>&lt;console-port&gt;</em></pre></li>
+ <li>Send the location data:</p>
+ <ul><li><code>geo fix</code> to send a fixed geo-location.
+ <p>This command accepts a longitude and latitude in decimal degrees, and
+ an optional altitude in meters. For example:</p>
+ <pre>geo fix -121.45356 46.51119 4392</pre>
+ </li>
+ <li><code>geo nmea</code> to send an NMEA 0183 sentence.
+ <p>This command accepts a single NMEA sentence of type '$GPGGA' (fix data) or '$GPRMC' (transit
+ data).
+ For example:</p>
+ <pre>geo nmea $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62</pre>
+ </li>
+ </ul>
+ </li>
+</ol>
+
+<p>For information about how to connect to the emulator console, see
+<a href="{@docRoot}guide/developing/tools/emulator.html#console">Using the Emulator Console</a>.</p>
diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd
index de8ca6d..e030a4c 100644
--- a/docs/html/guide/topics/manifest/activity-element.jd
+++ b/docs/html/guide/topics/manifest/activity-element.jd
@@ -336,10 +336,10 @@ it can also be set as a raw string.
</p></dd>
<dt><a name="lmode"></a>{@code android:launchMode}</dt>
-<dd>An instruction on how the activity should be launched. There are four modes
+<dd>An instruction on how the activity should be launched. There are four modes
that work in conjunction with activity flags ({@code FLAG_ACTIVITY_*} constants)
-in {@link android.content.Intent} objects to determine what should happen when
-the activity is called upon to handle an intent. They are:
+in {@link android.content.Intent} objects to determine what should happen when
+the activity is called upon to handle an intent. They are:</p>
<p style="margin-left: 2em">"{@code standard}"
<br>"{@code singleTop}"
@@ -351,56 +351,110 @@ The default mode is "{@code standard}".
</p>
<p>
-The modes fall into two main groups, with "{@code standard}" and
-"{@code singleTop}" activities on one side, and "{@code singleTask}" and
-"{@code singleInstance}" activities on the other. An activity with the
-"{@code standard}" or "{@code singleTop}" launch mode can be instantiated
-multiple times. The instances can belong to any task and can be located
-anywhere in the activity stack. Typically, they're launched into the task
-that called
+As shown in the table below, the modes fall into two main groups, with
+"{@code standard}" and "{@code singleTop}" activities on one side, and
+"{@code singleTask}" and "{@code singleInstance}" activities on the other.
+An activity with the "{@code standard}" or "{@code singleTop}" launch mode
+can be instantiated multiple times. The instances can belong to any task
+and can be located anywhere in the activity stack. Typically, they're
+launched into the task that called
<code>{@link android.content.Context#startActivity startActivity()}</code>
-(unless the Intent object contains a
-<code>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</code>
-instruction, in which case a different task is chosen &mdash; see the
+(unless the Intent object contains a
+<code>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</code>
+instruction, in which case a different task is chosen &mdash; see the
<a href="#aff">taskAffinity</a> attribute).
</p>
<p>
-In contrast, "{@code singleTask}" and "{@code singleInstance}" activities
-can only begin a task. They are always at the root of the activity stack.
-Moreover, the device can hold only one instance of the activity at a time
+In contrast, "<code>singleTask</code>" and "<code>singleInstance</code>" activities
+can only begin a task. They are always at the root of the activity stack.
+Moreover, the device can hold only one instance of the activity at a time
&mdash; only one such task.
</p>
<p>
The "{@code standard}" and "{@code singleTop}" modes differ from each other
-in just one respect: Every time there's new intent for a "{@code standard}"
-activity, a new instance of the class is created to respond to that intent.
+in just one respect: Every time there's a new intent for a "{@code standard}"
+activity, a new instance of the class is created to respond to that intent.
Each instance handles a single intent.
-Similarly, a new instance of a "{@code singleTop}" activity may also be
-created to handle a new intent. However, if the target task already has an
-existing instance of the activity at the top of its stack, that instance
-will receive the new intent (in an
+Similarly, a new instance of a "{@code singleTop}" activity may also be
+created to handle a new intent. However, if the target task already has an
+existing instance of the activity at the top of its stack, that instance
+will receive the new intent (in an
<code>{@link android.app.Activity#onNewIntent onNewIntent()}</code> call);
a new instance is not created.
-In other circumstances &mdash; for example, if an existing instance of the
-"{@code singleTop}" activity is in the target task, but not at the top of
-the stack, or if it's at the top of a stack, but not in the target task
+In other circumstances &mdash; for example, if an existing instance of the
+"{@code singleTop}" activity is in the target task, but not at the top of
+the stack, or if it's at the top of a stack, but not in the target task
&mdash; a new instance would be created and pushed on the stack.
-</p>
+</p>
<p>
-The "{@code singleTask}" and "{@code singleInstance}" modes also differ from
-each other in only one respect: A "{@code singleTask}" activity allows other
-activities to be part of its task. It's at the root of the activity stack,
-but other activities (necessarily "{@code standard}" and "{@code singleTop}"
-activities) can be launched into the same task. A "{@code singleInstance}"
-activity, on the other hand, permits no other activities to be part of its
-task. It's the only activity in the task. If it starts another activity,
-that activity is assigned to a different task &mdash; as if {@code
+The "{@code singleTask}" and "{@code singleInstance}" modes also differ from
+each other in only one respect: A "{@code singleTask}" activity allows other
+activities to be part of its task. It's always at the root of its task, but
+other activities (necessarily "{@code standard}" and "{@code singleTop}"
+activities) can be launched into that task. A "{@code singleInstance}"
+activity, on the other hand, permits no other activities to be part of its task.
+It's the only activity in the task. If it starts another activity, that
+activity is assigned to a different task &mdash; as if {@code
FLAG_ACTIVITY_NEW_TASK} was in the intent.
</p>
+<table>
+<tr>
+<th>Use Cases</th>
+<th>Launch Mode</th>
+<th>Multiple Instances?</th>
+<th>Comments</th>
+</tr>
+<tr>
+<td rowspan="2" style="width:20%;">Normal launches for most activities</td>
+<td>"<code>standard</code>"</td>
+<td>Yes</td>
+<td>Default. The system always creates a new instance of the activity in the
+target task and routes the intent to it.</td>
+</tr>
+<tr>
+<td>"<code>singleTop</code>"</td>
+<td>Conditionally</td>
+<td>If an instance of the activity already exists at the top of the target task,
+the system routes the intent to that instance through a call to its {@link
+android.app.Activity#onNewIntent onNewIntent()} method, rather than creating a
+new instance of the activity.</td>
+</tr>
+<tr>
+<td rowspan="2">Specialized launches<br>
+<em>(not recommended for general use)</em></td>
+<td>"<code>singleTask</code>"</td>
+<td>No</td>
+<td>The system creates the activity at the root of a new task and routes the
+intent to it. However, if an instance of the activity already exists, the system
+routes the intent to existing instance through a call to its {@link
+android.app.Activity#onNewIntent onNewIntent()} method, rather than creating a
+new one.</td>
+</tr>
+<tr>
+<td>"<code>singleInstance</code>"</td>
+<td>No</td>
+<td>Same as "<code>singleTask"</code>, except that the system doesn't launch any
+other activities into the task holding the instance. The activity is always the
+single and only member of its task.</td>
+</tr>
+</table>
+
+<p>As shown in the table above, <code>standard</code> is the default mode and is
+appropriate for most types of activities. <code>SingleTop</code> is also a
+common and useful launch mode for many types of activities. The other modes
+&mdash; <code>singleTask</code> and <code>singleInstance</code> &mdash; are
+<span style="color:red">not appropriate for most applications</span>,
+since they result in an interaction model that is likely to be unfamiliar to
+users and is very different from most other applications.
+
+<p>Regardless of the launch mode that you choose, make sure to test the usability
+of the activity during launch and when navigating back to it from
+other activities and tasks using the BACK key. </p>
+
<p>For more information on launch modes and their interaction with Intent
flags, see the
<a href="{@docRoot}guide/topics/fundamentals.html#acttask">Activities and
diff --git a/docs/html/guide/topics/manifest/application-element.jd b/docs/html/guide/topics/manifest/application-element.jd
index 786223f..9ac07fd 100644
--- a/docs/html/guide/topics/manifest/application-element.jd
+++ b/docs/html/guide/topics/manifest/application-element.jd
@@ -3,8 +3,7 @@ page.title=&lt;application&gt;
<dl class="xml">
<dt>syntax:</dt>
-<dd><pre class="stx">&lt;application android:<a href="#clear">allowClearUserData</a>=["true" | "false"]
- android:<a href="#reparent">allowTaskReparenting</a>=["true" | "false"]
+<dd><pre class="stx">&lt;application android:<a href="#reparent">allowTaskReparenting</a>=["true" | "false"]
android:<a href="#agent">backupAgent</a>="<i>string</i>"
android:<a href="#debug">debuggable</a>=["true" | "false"]
android:<a href="#desc">description</a>="<i>string resource</i>"
@@ -49,12 +48,6 @@ cannot be overridden by the components.</dd>
<dt>attributes</dt>
<dd><dl class="attr">
-<dt><a name="clear"></a>{@code android:allowClearUserData}</dt>
-<dd>Whether or not users are given the option to remove user data &mdash;
-"{@code true}" if they are, and "{@code false}" if not. If the value is
-"{@code true}", as it is by default, the application manager includes an
-option that allows users to clear the data.</dd>
-
<dt><a name="reparent"></a>{@code android:allowTaskReparenting}</dt>
<dd>Whether or not activities that the application defines can move from
the task that started them to the task they have an affinity for when that task
diff --git a/docs/html/guide/topics/manifest/manifest-element.jd b/docs/html/guide/topics/manifest/manifest-element.jd
index a35c5a1..7f21e6b 100644
--- a/docs/html/guide/topics/manifest/manifest-element.jd
+++ b/docs/html/guide/topics/manifest/manifest-element.jd
@@ -159,6 +159,9 @@ multiple SD cards can be used with the same device.</li>
storage. However, the system will not allow the user to move the application to external storage if
this attribute is set to {@code internalOnly}, which is the default setting.</p>
+<p>Read <a href="{@docRoot}guide/appendix/install-location.html">App Install Location</a> for
+more information about using this attribute (including how to maintain backward compatibility).</p>
+
<p>Introduced in: API Level 8.</p>
@@ -173,7 +176,7 @@ this attribute is set to {@code internalOnly}, which is the default setting.</p>
<p>
<dt>see also:</dt>
-<dd><a href="{@docRoot}guide/appendix/install-location.html">App Install Location</a><br/>
+<dd>
<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
</dl>
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index 4066daa..b5b30f6 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -5,9 +5,9 @@ page.title=&lt;uses-feature&gt;
<dt>syntax:</dt>
<dd>
-<pre class="stx">&lt;uses-feature android:<a href="#glEsVersion">glEsVersion</a>="<em>integer</em>"
- android:<a href="#name">name</a>="<em>string</em>"
- android:<a href="#required">required</a>=["true" | "false"] /&gt;</pre>
+<pre class="stx">&lt;uses-feature android:<a href="#name">name</a>="<em>string</em>"
+ android:<a href="#required">required</a>=["true" | "false"]
+ android:<a href="#glEsVersion">glEsVersion</a>="<em>integer</em>" /&gt;</pre>
</dd>
<dt>contained in:</dt>
@@ -18,8 +18,8 @@ href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a
<img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
<div id="qv-sub-rule">
<img src="{@docRoot}assets/images/icon_market.jpg" style="float:left;margin:0;padding:0;">
- <p style="color:#669999;">Android Market and &lt;uses-feature&gt; elements</p>
- <p>Android Market filters the applications that are visible to users, so
+ <p style="color:#669999;">Android Market and <code style="color:#669999;">&lt;uses-feature&gt;</code> elements</p>
+ <p style="margin-top:1em;">Android Market filters the applications that are visible to users, so
that users can see and download only those applications that are compatible with their
devices. One of the ways Market filters applications is by feature compatibility.</p>
@@ -27,70 +27,82 @@ devices. One of the ways Market filters applications is by feature compatibility
<code>&lt;uses-feature&gt;</code> elements in each application's manifest, to
establish the app's feature needs. Market then shows or hides the application to
each user, based on a comparison with the features available on the user's
-device. For more information, see <a
-href="{@docRoot}guide/appendix/market-filters.html">Market Filters</a>.</p>
+device. </p>
-<p style="margin-top:1em;">By specifying the features your application requires,
+<p style="margin-top:1em;">By specifying the features that your application requires,
you enable Android Market to present your application only to users whose
devices meet the application's feature requirements, rather than presenting it
to all users. </p>
+
+<p style="margin-top:1em;" class="caution">For important information about how
+Android Market uses features as the basis for filtering, please read <a
+href="#market-feature-filtering">Android Market and Feature-Based Filtering</a>,
+below.</p>
</div>
</div>
<dt>description:</dt>
-<dd>This element declares a specific feature used by the application. Android
-provides some features that may not be equally supported by all Android devices.
-In a manner similar to the <a
-href="uses-sdk-element.html">{@code &lt;uses-sdk>}</a> element, this element
-allows an application to specify which device-variable features it uses. For
-example, an application might specify that it requires a camera with auto-focus
-capabilities.</p>
-
-<p>Declaring a {@code &lt;uses-feature>} element is informational only, meaning
+<dd>Declares a single hardware or software feature that is used by the
+application.
+
+<p>The purpose of a <code>&lt;uses-feature&gt;</code> declaration is to inform
+any external entity of the set of hardware and software features on which your
+application depends. The element offers a <code>required</code> attribute that
+lets you specify whether your application requires and cannot function without
+the declared feature, or whether it prefers to have the feature but can function
+without it. Because feature support can vary across Android devices, the
+<code>&lt;uses-feature&gt;</code> element serves an important role in letting an
+application describe the device-variable features that it uses.</p>
+
+<p>The set of available features that your application declares corresponds to
+the set of feature constants made available by the Android {@link
+android.content.pm.PackageManager}, which are listed for
+convenience in the <a href="#features-reference">Features Reference</a> tables
+at the bottom of this document.
+
+<p>You must specify each feature in a separate <code>&lt;uses-feature&gt;</code>
+element, so if your application requires multiple features, it would declare
+multiple <code>&lt;uses-feature&gt;</code> elements. For example, an application
+that requires both Bluetooth and camera features in the device would declare
+these two elements:</p>
+
+<pre>
+&lt;uses-feature android:name="android.hardware.bluetooth" />
+&lt;uses-feature android:name="android.hardware.camera" />
+</pre>
+
+<p>In general, you should always make sure to declare
+<code>&lt;uses-feature&gt;</code> elements for all of the features that your
+application requires.</p>
+
+<p>Declared <code>&lt;uses-feature></code> elements are informational only, meaning
that the Android system itself does not check for matching feature support on
-the device before installing an application. However, note that other services
+the device before installing an application. However, other services
(such as Android Market) or applications may check your application's
-{@code &lt;uses-feature>} declarations as part of handling or interacting
+<code>&lt;uses-feature></code> declarations as part of handling or interacting
with your application. For this reason, it's very important that you declare all of
the features (from the list below) that your application uses. </p>
<p>For some features, there may exist a specfic attribute that allows you to define
a version of the feature, such as the version of Open GL used (declared with
-<a href="#glEsVersion">{@code glEsVersion}</a>). Other features that either do or do not
+<a href="#glEsVersion"><code>glEsVersion</code></a>). Other features that either do or do not
exist for a device, such as a camera, are declared using the
-<a href="#name">{@code name}</a> attribute.</p>
+<a href="#name"><code>name</code></a> attribute.</p>
-<p>Any software or hardware features that may vary among Android-powered devices
-will be listed on this page among the attributes below. If you see any features
-here that you use in your application, you should include a
-{@code &lt;uses-feature>} element for each one. For example, if your
-application uses the device camera, then you should include the following in
-your {@code AndroidManifest.xml}:</p>
-<pre>
-&lt;uses-feature android:name="android.hardware.camera" />
-</pre>
+<p>Although the <code>&lt;uses-feature></code> element is only activated for
+devices running API Level 4 or higher, it is recommended to include these
+elements for all applications, even if the <a href="uses-sdk-element.html#min"><code>minSdkVersion</code></a>
+is "3" or lower. Devices running older versions of the platform will simply
+ignore the element.</p>
-<p>If you declare {@code android.hardware.camera} this way, then your application is considered
-compatible with all devices that include a camera. If your application also uses auto-focus
-features, then you also need to include a
-{@code &lt;uses-feature>} element that declares the {@code android.hardware.camera.autofocus}
-feature. Also note that you must still request the {@link android.Manifest.permission#CAMERA
-CAMERA} permission. Requesting the permission grants your application access to the
-appropriate hardware and software, while declaring the features used by
-your application ensures proper device compatibility.</p>
-
-<p>Although the {@code &lt;uses-feature>} element is only activated for devices running
-API Level 4 or higher, it is safe to include this for applications that declare
-a <a href="uses-sdk-element.html#min">{@code minSdkVersion}</a>
-of "3" or lower. Devices running older versions of the platform
-will simply ignore this element, but newer devices will recognize it and enforce
-installation restrictions based on whether the device supports the feature.</p>
-
-<p class="note"><strong>Note:</strong>
-For each feature required by your application, you must include a new {@code
-&lt;uses-feature>} element. Multiple features cannot be declared in one
-instance of this element.</p>
+<p class="note"><strong>Note:</strong> When declaring a feature, remember
+that you must also request permissions as appropriate. For example, you must
+still request the {@link android.Manifest.permission#CAMERA}
+permission before your application can access the camera API. Requesting the
+permission grants your application access to the appropriate hardware and
+software, while declaring the features used by your application ensures proper
+device compatibility.</p>
</dd>
@@ -99,7 +111,35 @@ instance of this element.</p>
<dd>
<dl class="attr">
- <dt><a name="glEsVersion"></a>{@code android:glEsVersion}</dt>
+
+ <dt><a name="name"></a><code>android:name</code></dt>
+ <dd>Specifies a single hardware or software feature used by the application,
+as a descriptor string. Valid descriptor values are listed in the <a
+href="#hw-features">Hardware features</a> and <a href="#sw-features">Software
+features</a> tables, below. </dd>
+
+ <dt><a name="required"></a><code>android:required</code></dt> <!-- added in api level 5 -->
+ <dd>Boolean value that indicates whether the application requires
+ the feature specified in <code>android:name</code>.
+
+<ul>
+<li>When you declare <code>"android:required="true"</code> for a feature,
+you are specifying that the application <em>cannot function, or is not
+designed to function</em>, when the specified feature is not present on the
+device. </li>
+
+<li>When you declare <code>"android:required="false"</code> for a feature, it
+means that the application <em>prefers to use the feature</em> if present on
+the device, but that it <em>is designed to function without the specified
+feature</em>, if necessary. </li>
+
+</ul>
+
+<p>The default value for <code>android:required</code> if not declared is
+<code>"true"</code>.</p>
+ </dd>
+
+ <dt><a name="glEsVersion"></a><code>android:glEsVersion</code></dt>
<dd>The OpenGL ES version required by the application. The higher 16 bits
represent the major number and the lower 16 bits represent the minor number. For
example, to specify OpenGL ES version 2.0, you would set the value as
@@ -125,110 +165,6 @@ only specify the numerically lowest version of OpenGL ES that it requires. (It
can check at run-time whether a higher level of OpenGL ES is available.)</p>
</dd>
- <dt><a name="name"></a>{@code android:name}</dt>
- <dd>The name of a feature required by the application.
- The value must be one of the following accepted strings:
-
- <table>
- <tr>
- <th>Feature</th>
- <th>Attribute Value</th>
- <th>Description</th>
- </tr><tr>
- <td rowspan="2">Camera</td>
- <td>{@code android.hardware.camera}</td>
- <td>The application requires a camera.</td>
- </tr><tr>
- <td colspan="2">
- <strong>Note:</strong> Any application that requests the
- {@link android.Manifest.permission#CAMERA} permission but does <em>not</em>
- declare any camera features with the {@code &lt;uses-feature>} element will be assumed
- to use all camera features (auto-focus and flash). Thus, the application will not
- be compatible with devices that do not support all camera features. Please use
- {@code &lt;uses-feature>} to declare only the camera features that your
- application does need. For instance, if you request the
- {@link android.Manifest.permission#CAMERA} permission, but you do not need auto-focus or
- flash, then declare only the {@code android.hardware.camera} feature&mdash;the other
- camera features that you do not request will no longer be assumed as required.
- </td>
- </tr><tr>
- <td>Camera auto-focus</td>
- <td>{@code android.hardware.camera.autofocus}</td>
- <td>The application requires a camera with auto-focus capability.
- As a prerequisite, {@code android.hardware.camera} must also be declared
- with a separate {@code &lt;uses-feature>} element.
- </td>
- </tr><tr>
- <td>Camera flash</td>
- <td>{@code android.hardware.camera.flash}</td>
- <td>The application requires a camera with a flash.
- As a prerequisite, both {@code android.hardware.camera} and {@code
- android.hardware.camera.autofocus} must also be declared
- with separate {@code &lt;uses-feature>} elements.
- </td>
- </tr><tr>
- <td>Light sensor</td>
- <td>{@code android.hardware.sensor.light}</td>
- <td>The application requires a device with a light sensor.
- </td>
- </tr><tr>
- <td>Live Wallpaper</td>
- <td>{@code android.software.live_wallpaper}</td>
- <td>The application uses or provides Live Wallpapers and should be installed only on devices that support Live Wallpapers.
- </td>
- </tr><tr>
- <td>Proximity sensor</td>
- <td>{@code android.hardware.sensor.proximity}</td>
- <td>The application requires a device with a proximity sensor.
- </td>
- </tr><tr>
- <td>Multitouch screen</td>
- <td>{@code android.hardware.touchscreen.multitouch}</td>
- <td>The application requires a device that supports multitouch.
- </td>
- </tr><tr>
- <td>Telephony</td>
- <td>{@code android.hardware.telephony}</td>
- <td>The application requires a device that includes a telephony radio with data
- communication services.
- </td>
- </tr><tr>
- <td>CDMA telephony</td>
- <td>{@code android.hardware.telephony.cdma}</td>
- <td>The application requires a device that includes a CDMA telephony radio. As a
- prerequisite, {@code android.hardware.telephony} must also be declared
- with a separate {@code &lt;uses-feature>} element.
- </td>
- </tr><tr>
- <td>GSM telephony</td>
- <td>{@code android.hardware.telephony.gsm}</td>
- <td>The application requires a device that includes a GSM telephony radio. As a
- prerequisite, {@code android.hardware.telephony} must also be declared
- with a separate {@code &lt;uses-feature>} element.
- </td>
- </tr>
- </table>
- </dd>
-
- <dt><a name="required"></a>{@code android:required}</dt> <!-- added in api level 5 -->
- <dd>Indicates whether the feature is required by the application. This is
- {@code true} by default. <strong>You should not use this attribute for most cases.</strong>
- </p>
-
- <p>The only situation in which you should set this attribute {@code false} is when your
- application requests the {@link android.Manifest.permission#CAMERA} permission, but will degrade
- gracefully and perform without failure if the device does not have a camera. In this situation,
- you must declare the {@code android.hardware.camera} feature and set the {@code required}
- attribute {@code false}. This is necessary because the {@link
- android.Manifest.permission#CAMERA} permission will automatically turn on the requirement for
- all camera features. So if your application uses this permission but is still compatible with
- devices without a camera, then you must set the {@code required} attribute {@code false} for
- {@code android.hardware.camera} or else it will not install on devices without a camera. Note
- that, while the permission will enable the requirement for <em>all</em> camera features, you
- only need to off the requirement for the basic camera feature.</p>
-
- </dd>
-
</dl>
</dd>
@@ -239,8 +175,728 @@ can check at run-time whether a higher level of OpenGL ES is available.)</p>
<dt>see also:</dt>
<dd>
<ul>
+ <li>{@link android.content.pm.PackageManager}</li>
+ <li>{@link android.content.pm.FeatureInfo}</li>
<li>{@link android.content.pm.ConfigurationInfo}</li>
+ <li><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><code>&lt;uses-permission&gt;</code></a></li>
+ <li><a href="{@docRoot}guide/appendix/market-filters.html">Android Market Filters</a></li>
</ul>
</dd>
</dl>
+
+
+<h2 id="market-feature-filtering">Android Market and Feature-Based Filtering</h2>
+
+<p>Android Market filters the applications that are visible to users, so that
+users can see and download only those applications that are compatible with
+their devices. One of the ways Market filters applications is by feature
+compatibility.</p>
+
+<p>To determine an application's feature compatibility with a given user's
+device, the Android Market service compares:</p>
+
+<ul>
+<li>Features required by the application &mdash; an application declares features in
+<code>&lt;uses-feature&gt;</code> elements in its manifest <br/>with...</li>
+<li>Features available on the device, in hardware or software &mdash;
+a device reports the features it supports as read-only system properties.</li>
+</ul>
+
+<p>To ensure an accurate comparison of features, the Android Package Manager
+provides a shared set of feature constants that both applications and devices
+use to declare feature requirements and support. The available feature constants
+are listed in the <a href="#features-reference">Features Reference</a> tables at
+the bottom of this document, and in the class documentation for {@link
+android.content.pm.PackageManager}.</p>
+
+<p>When the user launches the Market application, the application queries the
+Package Manager for the list of features available on the device by calling
+{@link android.content.pm.PackageManager#getSystemAvailableFeatures()}. The
+Market application then passes the features list up to the Android Market
+service when establishing the session for the user.</p>
+
+<p>Each time you upload an application to the Android Market Publisher Site,
+Android Market scans the application's manifest file. It looks for
+<code>&lt;uses-feature&gt;</code> elements and evaluates them in combination
+with other elements, in some cases, such as <code>&lt;uses-sdk&gt;</code> and
+<code>&lt;uses-permission&gt;</code> elements. After establishing the
+application's set of required features, it stores that list internally as
+metadata associated with the application <code>.apk</code> and the application
+version. </p>
+
+<p>When a user searches or browses for applications using the Android Market
+application, the service compares the features needed by each application with
+the features available on the user's device. If all of an application's required
+features are present on the device, Android Market allows the user to see the
+application and potentially download it. If any required feature is not
+supported by the device, Android Market filters the application so that it is
+not visible to the user and not available for download. </p>
+
+<p>Because the features you declare in <code>&lt;uses-feature&gt;</code>
+elements directly affect how Android Market filters your application, it's
+important to understand how Android Market evaluates the application's manifest
+and establishes the set of required features. The sections below provide more
+information. </p>
+
+<h3 id="declared">Filtering based on explicitly declared features</h3>
+
+<p>An explicitly declared feature is one that your application declares in a
+<code>&lt;uses-feature&gt;</code> element. The feature declaration can include
+an <code>android:required=["true" | "false"]</code> attribute (if you are
+compiling against API level 5 or higher), which lets you specify whether the
+application absolutely requires the feature and cannot function properly without
+it (<code>"true"</code>), or whether the application prefers to use the feature
+if available, but is designed to run without it (<code>"false"</code>).</p>
+
+<p>Android Market handles explictly declared features in this way: </p>
+
+<ul>
+<li>If a feature is explicitly declared as being required, Android Market adds
+the feature to the list of required features for the application. It then
+filters the application from users on devices that do not provide that feature.
+For example:
+<pre>&lt;uses-feature android:name="android.hardware.camera" android:required="true" /&gt;</pre></li>
+<li>If a feature is explicitly declared as <em>not</em> being required, Android
+Market <em>does not</em> add the feature to the list of required features. For
+that reason, an explicity declared non-required feature is never considered when
+filtering the application. Even if the device does not provide the declared
+feature, Android Market will still consider the application compatible with the
+device and will show it to the user, unless other filtering rules apply. For
+example:
+<pre>&lt;uses-feature android:name="android.hardware.camera" android:required="false" /&gt;</pre></li>
+<li>If a feature is explicitly declared, but without an
+<code>android:required</code> attribute, Android Market assumes that the feature
+is required and sets up filtering on it. </li>
+</ul>
+
+<p>In general, if your application is designed to run on Android 1.6 and earlier
+versions, the <code>android:required</code> attribute is not available in the
+API and Android Market assumes that any and all
+<code>&lt;uses-feature&gt;</code> declarations are required. </p>
+
+<p class="note"><strong>Note:</strong> By declaring a feature explicitly and
+including an <code>android:required="false"</code> attribute, you can
+effectively disable all filtering on Android Market for the specified feature.
+</p>
+
+
+<h3 id="implicit">Filtering based on implicit features</h3>
+
+<p>An <em>implicit</em> feature is one that an application requires in order to
+function properly, but which is <em>not</em> declared in a
+<code>&lt;uses-feature&gt;</code> element in the manifest file. Strictly
+speaking, every application should <em>always</em> declare all features that it
+uses or requires, so the absence of a declaration for a feature used by an
+application should be considered an error. However, as a safeguard for users and
+developers, Android Market looks for implicit features in each application and
+sets up filters for those features, just as it would do for an explicitly
+declared feature. </p>
+
+<p>An application might require a feature but not declare it because: </p>
+
+<ul>
+<li>The application was compiled against an older version of the Android library
+(Android 1.5 or earlier) and the <code>&lt;uses-feature&gt;</code> element was
+not available.</li>
+<li>The developer incorrectly assumed that the feature would be present on all
+devices and a declaration was unnecessary.</li>
+<li>The developer omitted the feature declaration accidentally.</li>
+<li>The developer declared the feature explicitly, but the declaration was not
+valid. For example, a spelling error in the <code>&lt;uses-feature&gt;</code>
+element name or an unrecognized string value for the
+<code>android:name</code> attribute would invalidate the feature declaration.
+</li>
+</ul>
+
+<p>To account for the cases above, Android Market attempts to discover an
+application's implied feature requirements by examining <em>other elements</em>
+declared in the manifest file, specifically,
+<code>&lt;uses-permission&gt;</code> elements.</p>
+
+<p>If an application requests hardware-related permissions, Android Market
+<em>assumes that the application uses the underlying hardware features and
+therefore requires those features</em>, even though there might be no
+corresponding to <code>&lt;uses-feature&gt;</code> declarations. For such
+permissions, Android Market adds the underlying hardware features to the
+metadata that it stores for the application and sets up filters for them.</p>
+
+<p>For example, if an application requests the <code>CAMERA</code> permission
+but does not declare a <code>&lt;uses-feature&gt;</code> element for
+<code>android.hardware.camera</code>, Android Market considers that the
+application requires a camera and should not be shown to users whose devices do
+not offer a camera.</p>
+
+<p>If you don't want Android Market to filter based on a specific implied
+feature, you can disable that behavior. To do so, declare the feature explicitly
+in a <code>&lt;uses-feature&gt;</code> element and include an
+<code>android:required="false"</code> attribute. For example, to disable
+filtering derived from the <code>CAMERA</code> permission, you would declare
+the feature as shown below.</p>
+
+<pre>&lt;uses-feature android:name="android.hardware.camera" android:required="false" /&gt;</pre>
+
+<p class="caution">It's important to understand that the permissions that you
+request in <code>&lt;uses-permission&gt;</code> elements can directly affect how
+Android Market filters your application. The reference section <a
+href="permissions-features">Permissions that Imply Feature Requirements</a>,
+below, lists the full set of permissions that imply feature requirements and
+therefore trigger filtering.</p>
+
+<h3 id="bt-permission-handling">Special handling for Bluetooth feature</h3>
+
+<p>Android Market applies slightly different rules than described above, when
+determining filtering for Bluetooth.</p>
+
+<p>If an application declares a Bluetooth permission in a
+<code>&lt;uses-permission&gt;</code> element, but does not explicitly declare
+the Bluetooth feature in a <code>&lt;uses-feature&gt;</code> element, Android
+Market checks the version(s) of the Android platform on which the application is
+designed to run, as specified in the <code>&lt;uses-sdk&gt;</code> element. </p>
+
+<p>As shown in the table below, Android Market enables filtering for the
+Bluetooth feature only if the application declares its lowest or targeted
+platform as Android 2.0 (API level 5) or higher. However, note that Android
+market applies the normal rules for filtering when the application explicitly
+declares the Bluetooth feature in a <code>&lt;uses-feature&gt;</code> element.
+</p>
+
+<p class="caption"><strong>Table 1.</strong> How Android Market determines the
+Bluetooth feature requirement for an application that requests a Bluetooth
+permission but does not declare the Bluetooth feature in a
+<code>&lt;uses-feature&gt;</code> element.</p>
+
+<table style="margin-top:1em;">
+<tr>
+<th><nobr>If <code>minSdkVersion</code> is ...</nobr></th>
+<th><nobr>or <code>targetSdkVersion</code> is</nobr></th>
+<th>Result</th>
+</tr>
+<tr>
+<td><nobr>&lt;=4 (or uses-sdk is not declared)</nobr></td>
+<td>&lt;=4</td>
+<td>Android Market <em>will not</em> filter the application from any devices
+based on their reported support for the <code>android.hardware.bluetooth</code>
+feature.</td>
+</tr>
+<tr>
+<td>&lt;=4</td>
+<td>&gt;=5</td>
+<td rowspan="2">Android Market filters the application from any devices that
+do not support the <code>android.hardware.bluetooth</code> feature (including
+older releases).</td>
+</tr>
+<tr>
+<td>&gt;=5</td>
+<td>&gt;=5</td>
+</tr>
+</table>
+
+<p>The examples below illustrate the different filtering effects, based on how
+Android Market handles the Bluetooth feature. </p>
+
+<dl>
+<dt>In first example, an application that is designed to run on older API levels
+declares a Bluetooth permission, but does not declare the Bluetooth feature in a
+<code>&lt;uses-feature&gt;</code> element.</dt>
+<dd><em>Result:</em> Android Market does not filter the application from any device.</dd>
+</dl>
+
+<pre>&lt;manifest ...>
+...
+ &lt;uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ &lt;uses-sdk android:minSdkVersion="3" />
+...
+&lt;/manifest></pre>
+
+<dl>
+<dt>In the second example, below, the same application also declares a target
+API level of "5". </dt>
+<dd><em>Result:</em> Android Market now assumes that the feature is required and
+will filter the application from all devices that do not report Bluetooth support,
+including devices running older versions of the platform. </dd>
+</dl>
+
+<pre>&lt;manifest ...>
+...
+ &lt;uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ &lt;uses-sdk android:minSdkVersion="3" android:targetSdkVersion="5" />
+...
+&lt;/manifest></pre>
+
+<dl>
+<dt>Here the same application now specifically declares the Bluetooth feature.</dt>
+<dd><em>Result:</em> Identical to the previous example (filtering is applied).</dd>
+</dl>
+
+<pre>&lt;manifest ...>
+...
+ &lt;uses-feature android:name="android.hardware.bluetooth" />
+ &lt;uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ &lt;uses-sdk android:minSdkVersion="3" android:targetSdkVersion="5" />
+...
+&lt;/manifest></pre>
+
+<dl>
+<dt>Finally, in the case below, the same application adds an
+<code>android:required="false"</code> attribute.</dt>
+<dd><em>Result:</em> Android Market disables filtering based on Bluetooth
+feature support, for all devices.</dd>
+</dl>
+
+<pre>&lt;manifest ...>
+...
+ &lt;uses-feature android:name="android.hardware.bluetooth" android:required="false" />
+ &lt;uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ &lt;uses-sdk android:minSdkVersion="3" android:targetSdkVersion="5" />
+...
+&lt;/manifest></pre>
+
+
+
+<h3>Testing the features required by your application</h3>
+
+<p>You can use the <code>aapt</code> tool, included in the Android SDK, to
+determine how Android Market will filter your application, based on its declared
+features and permissions. To do so, run <code>aapt</code> with the <code>dump
+badging</code> command. This causes <code>aapt</code> to parse your
+application's manifest and apply the same rules as used by Android Market to
+determine the features that your application requires. </p>
+
+<p>To use the tool, follow these steps: </p>
+
+<ol>
+<li>First, build and export your application as an unsigned <code>.apk</code>.
+If you are developing in Eclipse with ADT, right-click the project and select
+<strong>Android Tools</strong> &gt; <strong>Export Unsigned Application
+Package</strong>. Select a destination filename and path and click
+<strong>OK</strong>. </li>
+<li>Next, locate the <code>aapt</code> tool, if it is not already in your PATH.
+If you are using SDK Tools r8 or higher, you can find <code>aapt</code> in the
+<code>&lt;<em>SDK</em>&gt;/platform-tools/</code> directory.
+<p class="note"><strong>Note:</strong> You must use the version of
+<code>aapt</code> that is provided for the latest Platform-Tools component available. If
+you do not have the latest Platform-Tools component, download it using the <a
+href="{@docRoot}sdk/adding-components.html">Android SDK and AVD Manager</a>.
+</p></li>
+<li>Run <code>aapt</code> using this syntax: </li>
+</ol>
+
+<pre>$ aapt dump badging &lt;<em>path_to_exported_.apk</em>&gt;</pre>
+
+<p>Here's an example of the command output for the second Bluetooth example, above: </p>
+
+<pre>$ ./aapt dump badging BTExample.apk
+package: name='com.example.android.btexample' versionCode='' versionName=''
+<strong>uses-permission:'android.permission.BLUETOOTH_ADMIN'</strong>
+<strong>uses-feature:'android.hardware.bluetooth'</strong>
+sdkVersion:'3'
+targetSdkVersion:'5'
+application: label='BT Example' icon='res/drawable/app_bt_ex.png'
+launchable activity name='com.example.android.btexample.MyActivity'label='' icon=''
+uses-feature:'android.hardware.touchscreen'
+main
+supports-screens: 'small' 'normal' 'large'
+locales: '--_--'
+densities: '160'
+</pre>
+
+
+<h2 id=features-reference>Features Reference</h2>
+
+<p>The tables below provide reference information about hardware and software
+features and the permissions that can imply them on Android Market. </p>
+
+<h3 id="hw-features">Hardware features</h3>
+
+<p>The table below describes the hardware feature descriptors supported by the
+most current platform release. To signal that your application uses or requires
+a hardware feature, declare each value in a <code>android:name</code> attribute
+in a separate <code>&lt;uses-feature&gt;</code> element. </p>
+
+ <table>
+ <tr>
+ <th>Feature Type</th>
+ <th>Feature Descriptor</th>
+ <th>Description</th>
+ <th>Comments</th>
+ </tr>
+ <tr>
+ <td>Audio</td>
+ <td><code>android.hardware.audio.low_latency</td>
+ <td>The application uses a low-latency audio pipeline on the device and
+is sensitive to delays or lag in sound input or output.</td>
+<td>
+</td>
+ </tr>
+ <tr>
+ <td>Bluetooth</td>
+ <td><code>android.hardware.bluetooth</td>
+ <td>The application uses Bluetooth radio features in the device.</td>
+<td>
+</td>
+ </tr>
+ <tr>
+ <td rowspan="4">Camera</td>
+ <td><code>android.hardware.camera</code></td>
+ <td>The application uses the device's camera. If the device supports
+ multiple cameras, the application uses the camera that facing
+ away from the screen.</td>
+ <td></td>
+ </tr>
+<tr>
+ <td><code>android.hardware.camera.autofocus</code></td>
+ <td>Subfeature. The application uses the device camera's autofocus capability.</td>
+ <td rowspan="3">If declared with the <code>"android:required="true"</code>
+attribute, these subfeatures implicitly declare the
+<code>android.hardware.camera</code> parent feature. </td>
+</tr>
+<tr>
+ <td><code>android.hardware.camera.flash</code></td>
+ <td>Subfeature. The application uses the device camera's flash.</td>
+</tr>
+<tr>
+ <td><code>android.hardware.camera.front</code></td>
+ <td>Subfeature. The application uses a front-facing camera on the device.</td>
+</tr>
+
+<tr>
+ <td rowspan="3">Location</td>
+ <td><code>android.hardware.location</code></td>
+ <td>The application uses one or more features on the device for determining
+location, such as GPS location, network location, or cell location.</td>
+ <td></td>
+</tr>
+<tr>
+ <td><code>android.hardware.location.network</code></td>
+ <td>Subfeature. The application uses coarse location coordinates obtained from
+a network-based geolocation system supported on the device.</td>
+ <td rowspan="2">If declared with the <code>"android:required="true"</code>
+attribute, these subfeatures implicitly declare the
+<code>android.hardware.location</code> parent feature. </td>
+</tr>
+<tr>
+ <td><code>android.hardware.location.gps</code></td>
+ <td>Subfeature. The application uses precise location coordinates obtained
+from a Global Positioning System receiver on the device. </td>
+</tr>
+<tr>
+ <td>Microphone</td>
+ <td><code>android.hardware.microphone</code></td>
+ <td>The application uses a microphone on the device.
+ </td>
+ <td></td>
+</tr>
+<tr>
+ <td>Near Field Communications</td>
+ <td><code>android.hardware.nfc</td>
+ <td>The application uses NFC radio features in the device.</td>
+ <td></td>
+</tr>
+<tr>
+ <td rowspan="6">Sensors</td>
+ <td><code>android.hardware.sensor.accelerometer</code></td>
+ <td>The application uses motion readings from an accelerometer on the
+device.</td>
+ <td></td>
+</tr>
+<tr>
+ <td><code>android.hardware.sensor.barometer</code></td>
+ <td>The application uses the device's barometer.</td>
+ <td></td>
+</tr>
+<tr>
+ <td><code>android.hardware.sensor.compass</code></td>
+ <td>The application uses directional readings from a magnetometer (compass) on
+the device.</td>
+ <td></td>
+</tr>
+<tr>
+ <td><code>android.hardware.sensor.gyroscope</code></td>
+ <td>The application uses the device's gyroscope sensor.</td>
+ <td></td>
+</tr>
+<tr>
+ <td><code>android.hardware.sensor.light</code></td>
+ <td>The application uses the device's light sensor.</td>
+ <td></td>
+</tr>
+<tr>
+ <td><code>android.hardware.sensor.proximity</code></td>
+ <td>The application uses the device's proximity sensor.</td>
+ <td></td>
+</tr>
+<tr>
+ <td rowspan="2">SIP/VOIP</td>
+ <td><code>android.hardware.sip</code></td>
+ <td>The application uses SIP service on the device.
+ </td>
+ <td></td>
+</tr>
+<tr>
+ <td><code>android.hardware.sip.voip</code></td>
+ <td>Subfeature. The application uses SIP-based VOIP service on the device.
+ </td>
+ <td>If declared with the <code>"android:required="true"</code> attribute, this
+subfeature implicitly declares the <code>android.hardware.sip</code>
+parent feature.</td>
+</tr>
+
+<tr>
+ <td rowspan="3">Telephony</td>
+ <td><code>android.hardware.telephony</code></td>
+ <td>The application uses telephony features on the device, such as telephony
+radio with data communication services.</td>
+ <td></td>
+</tr>
+<tr>
+ <td><code>android.hardware.telephony.cdma</code></td>
+ <td>Subfeature. The application uses CDMA telephony radio features on the
+device. </td>
+ <td rowspan="2">If declared with the <code>"android:required="true"</code>
+attribute, these subfeatures implicitly declare the
+<code>android.hardware.telephony</code> parent feature. </td>
+</tr>
+<tr>
+ <td><code>android.hardware.telephony.gsm</code></td>
+ <td>Subfeature. The application uses GSM telephony radio features on the
+device.</td>
+</tr>
+
+<tr>
+ <td rowspan="4">Touchscreen</td>
+ <td><code>android.hardware.touchscreen</code></td>
+ <td>The application uses touchscreen capabilities on the device.</td>
+ <td></td>
+</tr>
+<tr>
+ <td><code>android.hardware.touchscreen.multitouch</code></td>
+ <td>Subfeature. The application uses basic two-point multitouch capabilities on the device
+screen.</td>
+ <td>If declared with the <code>"android:required="true"</code> attribute, this
+subfeature implicitly declares the <code>android.hardware.touchscreen</code>
+parent feature. </td>
+</tr>
+<tr>
+ <td><code>android.hardware.touchscreen.multitouch.distinct</code></td>
+ <td>Subfeature. The application uses advanced multipoint multitouch
+capabilities on the device screen, such as for tracking two or more points fully
+independently.</td>
+ <td rowspan="2">If declared with the <code>"android:required="true"</code> attribute, this
+subfeature implicitly declares the
+<code>android.hardware.touchscreen.multitouch</code> parent feature. </td>
+</tr>
+<tr>
+ <td><code>android.hardware.touchscreen.multitouch.jazzhand</code></td>
+ <td>Subfeature. The application uses advanced multipoint multitouch
+capabilities on the device screen, for tracking up to five points fully
+independently.</td>
+</tr>
+
+<tr>
+ <td>Wifi</td>
+ <td><code>android.hardware.wifi</code></td>
+ <td>The application uses 802.11 networking (wifi) features on the device.</td>
+ <td></td>
+</tr>
+
+ </table>
+
+<h3 id="sw-features">Software features</h3>
+
+<p>The table below describes the software feature descriptors supported by the
+most current platform release. To signal that your application uses or requires
+a software feature, declare each value in a <code>android:name</code> attribute
+in a separate <code>&lt;uses-feature&gt;</code> element. </p>
+
+
+ <table>
+ <tr>
+ <th>Feature</th>
+ <th>Attribute Value</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>Live Wallpaper</td>
+ <td><code>android.software.live_wallpaper</code></td>
+ <td>The application uses or provides Live Wallpapers.
+ </td>
+ </tr>
+ </table>
+
+
+<h3 id="permissions">Permissions that Imply Feature Requirements</h3>
+
+<p>Some feature constants listed in the tables above were made available to
+applications <em>after</em> the corresponding API; for example, the
+<code>android.hardware.bluetooth</code> feature was added in Android 2.2 (API
+level 8), but the bluetooth API that it refers to was added in Android 2.0 (API
+level 5). Because of this, some apps were able to use the API before they had
+the ability to declare that they require the API via the
+<code>&lt;uses-feature&gt;</code> system. </p>
+
+<p>To prevent those apps from being made available unintentionally, Android
+Market assumes that certain hardware-related permissions indicate that the
+underlying hardware features are required by default. For instance, applications
+that use Bluetooth must request the <code>BLUETOOTH</code> permission in a
+<code>&lt;uses-permission&gt;</code> element &mdash; for legacy apps, Android
+Market assumes that the permission declaration means that the underlying
+<code>android.hardware.bluetooth</code> feature is required by the application
+and sets up filtering based on that feature. </p>
+
+<p>The table below lists permissions that imply feature requirements
+equivalent to those declared in <code>&lt;uses-feature&gt;</code> elements. Note
+that <code>&lt;uses-feature&gt;</code> declarations, including any declared
+<code>android:required</code> attribute, always take precedence over features
+implied by the permissions below. </p>
+
+<p>For any of the permissions below, you can disable filtering based on the
+implied feature by explicitly declaring the implied feature explicitly, in a
+<code>&lt;uses-feature&gt;</code> element, with an
+<code>android:required="false"</code> attribute. For example, to disable any
+filtering based on the <code>CAMERA</code> permission, you would add this
+<code>&lt;uses-feature&gt;</code> declaration to the manifest file:</p>
+
+<pre>&lt;uses-feature android:name="android.hardware.camera" android:required="false" /&gt;</pre>
+
+<table id="permissions-features" >
+ <tr>
+ <th>Category</th>
+ <th>This Permission...</th>
+ <th>Implies This Feature Requirement</th>
+ <!-- <th>Comments</th> -->
+ </tr>
+
+
+<tr>
+ <td rowspan="2">Bluetooth</td>
+ <td><code>BLUETOOTH</code></td>
+ <td><code>android.hardware.bluetooth</code>
+<p>(See <a href="#bt-permission-handling">Special handling for Bluetooth feature</a> for details.)</p></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>BLUETOOTH_ADMIN</code></td>
+ <td><code>android.hardware.bluetooth</code></td>
+<!-- <td></td> -->
+</tr>
+
+<tr>
+ <td>Camera</td>
+ <td><code>CAMERA</code></td>
+ <td><code>android.hardware.camera</code> <em>and</em>
+<br><code>android.hardware.camera.autofocus</code></td>
+<!-- <td></td> -->
+</tr>
+
+<tr>
+ <td rowspan="5">Location</td>
+ <td><code>ACCESS_MOCK_LOCATION</code></td>
+ <td><code>android.hardware.location</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>ACCESS_LOCATION_EXTRA_COMMANDS</code></td>
+ <td><code>android.hardware.location</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>INSTALL_LOCATION_PROVIDER</code></td>
+ <td><code>android.hardware.location</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>ACCESS_COARSE_LOCATION</code></td>
+ <td><code>android.hardware.location.network</code> <em>and</em>
+<br><code>android.hardware.location</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>ACCESS_FINE_LOCATION</code></td>
+ <td><code>android.hardware.location.gps</code> <em>and</em>
+<br><code>android.hardware.location</code></td>
+<!-- <td></td> -->
+</tr>
+
+<tr>
+ <td>Microphone</td>
+ <td><code>RECORD_AUDIO</code></td>
+ <td><code>android.hardware.microphone</code></td>
+<!-- <td></td> -->
+</tr>
+
+<tr>
+ <td rowspan="11">Telephony</td>
+ <td><code>CALL_PHONE</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>CALL_PRIVILEGED</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+
+<tr>
+ <td><code>MODIFY_PHONE_STATE</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>PROCESS_OUTGOING_CALLS</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>READ_SMS</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>RECEIVE_SMS</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>RECEIVE_MMS</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>RECEIVE_WAP_PUSH</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>SEND_SMS</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>WRITE_APN_SETTINGS</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>WRITE_SMS</code></td>
+ <td><code>android.hardware.telephony</code></td>
+<!-- <td></td> -->
+</tr>
+
+<tr>
+ <td rowspan="3">Wifi</td>
+ <td><code>ACCESS_WIFI_STATE</code></td>
+ <td><code>android.hardware.wifi</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>CHANGE_WIFI_STATE</code></td>
+ <td><code>android.hardware.wifi</code></td>
+<!-- <td></td> -->
+</tr>
+<tr>
+ <td><code>CHANGE_WIFI_MULTICAST_STATE</code></td>
+ <td><code>android.hardware.wifi</code></td>
+<!-- <td></td> -->
+</tr>
+</table> \ No newline at end of file
diff --git a/docs/html/guide/topics/manifest/uses-permission-element.jd b/docs/html/guide/topics/manifest/uses-permission-element.jd
index aec765c..085b9f0 100644
--- a/docs/html/guide/topics/manifest/uses-permission-element.jd
+++ b/docs/html/guide/topics/manifest/uses-permission-element.jd
@@ -2,6 +2,38 @@ page.title=&lt;uses-permission&gt;
@jd:body
<dl class="xml">
+
+ <div class="sidebox-wrapper">
+ <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
+ <div id="qv-sub-rule">
+ <img src="{@docRoot}assets/images/icon_market.jpg" style="float:left;margin:0;padding:0;">
+ <p style="color:#669999;"><code style="color:#669999;">&lt;uses-permission&gt;</code> and filtering on Android Market. </p>
+
+<p style="margin-top:1em;">In some cases, the permissions that you request
+through <code>&lt;uses-permission&gt;</code> can affect how
+your application is filtered by Android Market.</p>
+
+<p style="margin-top:1em;">If you request a hardware-related permission &mdash;
+<code>CAMERA</code>, for example &mdash; Android Market assumes that your
+application requires the underlying hardware feature and filters the application
+from devices that do not offer it.</p>
+
+<p style="margin-top:1em;">To control filtering, always explicitly declare
+hardware features in <code>&lt;uses-feature&gt;</code> elements, rather than
+relying on Android Market to "discover" the requirements in
+<code>&lt;uses-permission&gt;</code> elements. Then, if you want to disable
+filtering for a particular feature, you can add a
+<code>android:required="false"</code> attribute to the
+<code>&lt;uses-feature&gt;</code> declaration.</p>
+
+<p style="margin-top:1em;" class="caution">For a list of permissions that imply
+hardware features, see the documentation for the <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html#permissions-features">
+<code>&lt;uses-feature&gt;</code></a> element.</p>
+</div>
+</div>
+
+
<dt>syntax:</dt>
<dd><pre class="stx">&lt;uses-permission android:<a href="#nm">name</a>="<i>string</i>" /&gt;</pre></dd>
@@ -10,7 +42,7 @@ page.title=&lt;uses-permission&gt;
<dt>description:</dt>
<dd>Requests a permission that the application must be granted in
-order for it to operate correctly. Permissions are granted when the
+order for it to operate correctly. Permissions are granted by the user when the
application is installed, not while it's running.
<p>
@@ -38,6 +70,11 @@ a permission name typically includes the package name as a prefix.</dd>
<dd>API Level 1</dd>
<dt>see also:</dt>
-<dd><code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code></dd>
+<dd>
+<ul>
+ <li><code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code></li>
+ <li><code><a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature&gt;</a></code></li>
+</ul>
+</dd>
</dl>
diff --git a/docs/html/guide/topics/media/index.jd b/docs/html/guide/topics/media/index.jd
index 96c500c..558d453 100644
--- a/docs/html/guide/topics/media/index.jd
+++ b/docs/html/guide/topics/media/index.jd
@@ -4,7 +4,7 @@ page.title=Audio and Video
<div id="qv-wrapper">
<div id="qv">
-<h2>Audio/Video quickview</h2>
+<h2>Quickview</h2>
<ul>
<li>Audio playback and record</li>
<li>Video playback</li>
@@ -12,14 +12,6 @@ page.title=Audio and Video
<li>Built-in codecs for a variety of media. See <a href="{@docRoot}guide/appendix/media-formats.html">Android Supported Media Formats</a></li>
</ul>
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.media.MediaPlayer MediaPlayer} (all available formats)</li>
-<li>{@link android.media.MediaRecorder MediaRecorder} (all available formats)</li>
-<li>{@link android.media.JetPlayer JetPlayer} (playback, JET content)</li>
-<li>{@link android.media.SoundPool SoundPool} (sound management)</li>
-</ol>
-
<h2>In this document</h2>
<ol>
<li><a href="#playback.html">Audio and Video Playback</a>
@@ -32,6 +24,14 @@ page.title=Audio and Video
<li><a href="#capture">Audio Capture</a></li>
</ol>
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.media.MediaPlayer MediaPlayer}</li>
+<li>{@link android.media.MediaRecorder MediaRecorder}</li>
+<li>{@link android.media.JetPlayer JetPlayer}</li>
+<li>{@link android.media.SoundPool SoundPool}</li>
+</ol>
+
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a></li>
diff --git a/docs/html/guide/topics/providers/content-providers.jd b/docs/html/guide/topics/providers/content-providers.jd
index 30f8d8c..2a84c26 100644
--- a/docs/html/guide/topics/providers/content-providers.jd
+++ b/docs/html/guide/topics/providers/content-providers.jd
@@ -3,12 +3,6 @@ page.title=Content Providers
<div id="qv-wrapper">
<div id="qv">
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.content.ContentProvider}</li>
-<li>{@link android.content.ContentResolver}</li>
-<li>{@link android.database.Cursor}</li>
-</ol>
<h2>In this document</h2>
<ol>
@@ -18,6 +12,13 @@ page.title=Content Providers
<li><a href="#creating">Creating a content provider</a></li>
<li><a href="#urisum">Content URI summary</a></li>
</ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.content.ContentProvider}</li>
+<li>{@link android.content.ContentResolver}</li>
+<li>{@link android.database.Cursor}</li>
+</ol>
</div>
</div>
@@ -779,7 +780,7 @@ Use the {@link android.net.Uri Uri} methods to help determine what is being
requested. Here is the general format for each type:</p></li>
<ul>
-<li><p>For a single record:&nbsp;&nbsp;&nbsp; {@code vnd.android.cursor.item/vnd.<em>yourcompanyname.contenttype</em}</p>
+<li><p>For a single record:&nbsp;&nbsp;&nbsp; {@code vnd.android.cursor.item/vnd.<em>yourcompanyname.contenttype</em>}</p>
<p>For example, a request for train record 122, like this URI,</p>
<p style="margin-left: 2em">{@code content://com.example.transportationprovider/trains/122}</p>
@@ -837,8 +838,8 @@ For example if the ContentProvider subclass is AutoInfoProvider, the
</p>
<pre>
-&lt;provider name="com.example.autos.AutoInfoProvider"
- authorities="com.example.autos.autoinfoprovider"
+&lt;provider android:name="com.example.autos.AutoInfoProvider"
+ android:authorities="com.example.autos.autoinfoprovider"
. . . /&gt
&lt;/provider&gt;
</pre>
@@ -890,8 +891,8 @@ For third-party applications, this should be a fully-qualified class name
(reduced to lowercase) to ensure uniqueness. The authority is declared in
the {@code &lt;provider&gt;} element's {@code authorities} attribute:</p>
-<pre>&lt;provider name=".TransportationProvider"
- authorities="com.example.transportationprovider"
+<pre>&lt;provider android:name=".TransportationProvider"
+ android:authorities="com.example.transportationprovider"
. . . &gt;</pre></li>
<li><p>The path that the content provider uses to determine what kind of data is
diff --git a/docs/html/guide/topics/resources/available-resources.jd b/docs/html/guide/topics/resources/available-resources.jd
index 09c55a5..19babee 100644
--- a/docs/html/guide/topics/resources/available-resources.jd
+++ b/docs/html/guide/topics/resources/available-resources.jd
@@ -18,23 +18,6 @@ of application resource that you can provide in your resources directory ({@code
<p>Here's a brief summary of each resource type:</p>
-<div class="sidebox-wrapper">
-<div class="sidebox">
-<h2>{@code R.id} Is Not a Resource</h2>
-
-<p>You will often use an {@code R.id} integer to handle {@link android.view.View} objects in
-your UI. Although the {@code id} is a subclass of the {@code R} class, it is not considered a
-"resource" because it is not a reference to an externalized application resource. The {@code id}
-is simply a unique identifier that allows you to handle elements in your UI by instantiating
-objects with {@link android.app.Activity#findViewById(int) findViewById()}.</p>
-
-<p>For information about using {@code R.id} with your UI, see <a
-href="{@docRoot}guide/topics/ui/declaring-layout.html#attributes">Declaring Layout</a>.</p>
-
-</div>
-</div>
-
-
<dl>
<dt><a href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a></dt>
<dd>Define pre-determined animations.<br/>
diff --git a/docs/html/guide/topics/resources/color-list-resource.jd b/docs/html/guide/topics/resources/color-list-resource.jd
index 449b66f..b20915c 100644
--- a/docs/html/guide/topics/resources/color-list-resource.jd
+++ b/docs/html/guide/topics/resources/color-list-resource.jd
@@ -55,7 +55,6 @@ In XML: <code>@[<em>package</em>:]color/<em>filename</em></code>
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_selected=["true" | "false"]
- android:state_active=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
diff --git a/docs/html/guide/topics/resources/drawable-resource.jd b/docs/html/guide/topics/resources/drawable-resource.jd
index d8de16a..9ebed56 100644
--- a/docs/html/guide/topics/resources/drawable-resource.jd
+++ b/docs/html/guide/topics/resources/drawable-resource.jd
@@ -12,38 +12,63 @@ parent.link=available-resources.html
</div>
</div>
-<p>A drawable resource is a general concept for a graphic that you
-can retrieve with {@link android.content.res.Resources#getDrawable(int)}
-and draw on the screen. There are several different types of drawables:</p>
+<p>A drawable resource is a general concept for a graphic that can be drawn to the screen and which
+you can retrieve with APIs such as {@link android.content.res.Resources#getDrawable(int)} or apply
+to another XML resource with attributes such as {@code android:drawable} and {@code android:icon}.
+There are several different types of drawables:</p>
<dl>
<dt><a href="#Bitmap">Bitmap File</a><dt>
<dd>A bitmap graphic file ({@code .png}, {@code .jpg}, or {@code .gif}).
- A {@link android.graphics.drawable.BitmapDrawable}.</dd>
+ Creates a {@link android.graphics.drawable.BitmapDrawable}.</dd>
<dt><a href="#NinePatch">Nine-Patch File</a></dt>
<dd>A PNG file with stretchable regions to allow image resizing based on content ({@code
-.9.png}). A {@link android.graphics.drawable.NinePatchDrawable}.</dd>
-<!-- <dt><a href="#BitmapAlias">Bitmap Alias</a><dt>
- <dd>An alias for a drawable.</dd> -->
+.9.png}). Creates a {@link android.graphics.drawable.NinePatchDrawable}.</dd>
+ <dt><a href="#LayerList">Layer List</a></dt>
+ <dd>A Drawable that manages an array of other Drawables. These are drawn in array order, so the
+element with the largest index is be drawn on top. Creates a {@link
+android.graphics.drawable.LayerDrawable}.</dd>
<dt><a href="#StateList">State List</a></dt>
<dd>An XML file that references different bitmap graphics
for different states (for example, to use a different image when a button is pressed).
- A {@link android.graphics.drawable.StateListDrawable}.</dd>
- <dt><a href="#Color">Color</a></dt>
- <dd>A resource defined in XML that specifies a rectangle of color, with
- optionally rounded corners. A {@link android.graphics.drawable.PaintDrawable}.</dd>
- <dt><a href="#Shape">Shape</a></dt>
+ Creates a {@link android.graphics.drawable.StateListDrawable}.</dd>
+ <dt><a href="#LevelList">Level List</a></dt>
+ <dd>An XML file that defines a Drawable that manages a number of alternate Drawables, each
+assigned a maximum numerical value. Creates a {@link
+android.graphics.drawable.LevelListDrawable}.</dd>
+ <dt><a href="#Transition">Transition Drawable</a></dt>
+ <dd>An XML file that defines a Drawable that can cross-fade between two drawable resources.
+Creates a {@link android.graphics.drawable.TransitionDrawable}.</dd>
+ <dt><a href="#Clip">Clip Drawable</a></dt>
+ <dd>An XML file that defines a drawable that clips another Drawable based on this Drawable's
+current level value. Creates a {@link android.graphics.drawable.ClipDrawable}.</dd>
+ <dt><a href="#Scale">Scale Drawable</a></dt>
+ <dd>An XML file that defines a drawable that changes the size of another Drawable based on its
+current level value. Creates a {@link android.graphics.drawable.ScaleDrawable}</dd>
+ <dt><a href="#Shape">Shape Drawable</a></dt>
<dd>An XML file that defines a geometric shape, including colors and gradients.
- A {@link android.graphics.drawable.ShapeDrawable}.</dd>
+ Creates a {@link android.graphics.drawable.ShapeDrawable}.</dd>
</dl>
-<p>Documentation for the {@link android.graphics.drawable.AnimationDrawable} resource
-is in the <a href="animation-resource.html">Animation Resource</a> document.</p>
+<p>Also see the <a href="animation-resource.html">Animation Resource</a> document for how to
+create an {@link android.graphics.drawable.AnimationDrawable}.</p>
+
+<p class="note"><strong>Note:</strong> A <a
+href="{@docRoot}guide/topics/resources/more-resources.html#Color">color resource</a> can also be
+used as a drawable in XML. For example, when creating a <a href="#StateList">state list
+drawable</a>, you can reference a color resource for the {@code android:drawable} attribute ({@code
+android:drawable="@color/green"}).</p>
+
+
+
-<h2 id="Bitmap">Bitmap File</h2>
+<h2 id="Bitmap">Bitmap</h2>
-<p>A basic bitmap image. Android supports basic bitmap files in a few different formats:
+<p>A bitmap image. Android supports bitmap files in a three formats:
{@code .png} (preferred), {@code .jpg} (acceptable), {@code .gif} (discouraged).</p>
+<p>You can reference a bitmap file directly, using the filename as the resource ID, or create an
+alias resource ID in XML.</p>
+
<p class="note"><strong>Note:</strong> Bitmap files may be automatically optimized with lossless
image compression by the <a href="{@docRoot}guide/developing/tools/aapt.html">aapt</a> tool. For
example, a true-color PNG that does not require more than 256 colors may be converted to an 8-bit
@@ -52,11 +77,18 @@ memory. So be aware that the image binaries placed in this directory can change
you plan on reading an image as a bit stream in order to convert it to a bitmap, put your images in
the <code>res/raw/</code> folder instead, where they will not be optimized.</p>
+
+<h3 id="BitmapFile">Bitmap File</h3>
+
+<p>A bitmap file is a {@code .png}, {@code .jpg}, or {@code .gif} file. Android creates a {@link
+android.graphics.drawable.Drawable}
+resource for any of these files when you save them in the {@code res/drawable/} directory.</p>
+
<dl class="xml">
<dt>file location:</dt>
<dd><code>res/drawable/<em>filename</em>.png</code> ({@code .png}, {@code .jpg}, or {@code .gif})<br/>
-The filename will be used as the resource ID.</dd>
+The filename is used as the resource ID.</dd>
<dt>compiled resource datatype:</dt>
<dd>Resource pointer to a {@link android.graphics.drawable.BitmapDrawable}.</dd>
@@ -68,15 +100,16 @@ In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
</dd>
<dt>example:</dt>
-<dd>With an image saved at <code>res/drawable/myimage.png</code>, this layout XML will apply
+
+<dd>With an image saved at <code>res/drawable/myimage.png</code>, this layout XML applies
the image to a View:
<pre>
&lt;ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- <strong>android:src="@drawable/myimage"</strong> />
+ android:src="@drawable/myimage" />
</pre>
-<p>This application code will retrieve the image as a {@link
+<p>The following application code retrieves the image as a {@link
android.graphics.drawable.Drawable}:</p>
<pre>
Resources res = {@link android.content.Context#getResources()};
@@ -97,50 +130,218 @@ Drawable drawable = res.{@link android.content.res.Resources#getDrawable(int) ge
+<h3 id="XmlBitmap">XML Bitmap</h3>
+<p>An XML bitmap is a resource defined in XML that points to a bitmap file. The effect is an alias for a
+raw bitmap file. The XML can specify additional properties for the bitmap such as dithering and tiling.</p>
+<p class="note"><strong>Note:</strong> You can use a {@code &lt;bitmap&gt;} element as a child of
+an {@code &lt;item&gt;} element. For
+example, when creating a <a href="#StateList">state list</a> or <a href="#LayerList">layer list</a>,
+you can exclude the {@code android:drawable}
+attribute from an {@code &lt;item&gt;} element and nest a {@code &lt;bitmap&gt;} inside it
+that defines the drawable item.</p>
-<h2 id="NinePatch">Nine-Patch File</h2>
+<dl class="xml">
+
+<dt>file location:</dt>
+<dd><code>res/drawable/<em>filename</em>.xml</code><br/>
+The filename is used as the resource ID.</dd>
+
+<dt>compiled resource datatype:</dt>
+<dd>Resource pointer to a {@link android.graphics.drawable.BitmapDrawable}.</dd>
+
+<dt>resource reference:</dt>
+<dd>
+In Java: <code>R.drawable.<em>filename</em></code></li><br/>
+In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
+</dd>
+
+<dt>syntax:</dt>
+<dd>
+<pre class="stx">
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;<a href="#bitmap-element">bitmap</a>
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@[package:]drawable/<em>drawable_resource</em>"
+ android:antialias=["true" | "false"]
+ android:dither=["true" | "false"]
+ android:filter=["true" | "false"]
+ android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
+ "fill_vertical" | "center_horizontal" | "fill_horizontal" |
+ "center" | "fill" | "clip_vertical" | "clip_horizontal"]
+ android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] /&gt;
+</pre>
+</dd>
+
+
+<dt>elements:</dt>
+<dd>
+<dl class="tag-list">
+
+ <dt id="bitmap-element"><code>&lt;bitmap&gt;</code></dt>
+ <dd>Defines the bitmap source and its properties.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>xmlns:android</code></dt>
+ <dd><em>String</em>. Defines the XML namespace, which must be
+ <code>"http://schemas.android.com/apk/res/android"</code>. This is required only if the
+<code>&lt;bitmap&gt;</code> is the root element&mdash;it is not needed when the
+<code>&lt;bitmap&gt;</code> is nested inside an <code>&lt;item&gt;</code>.</dd>
+ <dt><code>android:src</code></dt>
+ <dd><em>Drawable resource</em>. <strong>Required</strong>. Reference to a drawable
+resource.</dd>
+ <dt><code>android:antialias</code></dt>
+ <dd><em>Boolean</em>. Enables or disables antialiasing.</dd>
+ <dt><code>android:dither</code></dt>
+ <dd><em>Boolean</em>. Enables or disables dithering of the bitmap if the bitmap does not
+have the same pixel configuration as the screen (for instance: a ARGB 8888 bitmap with an RGB 565
+screen).</dd>
+ <dt><code>android:filter</code></dt>
+ <dd><em>Boolean</em>. Enables or disables bitmap filtering. Filtering is used when the
+bitmap is shrunk or stretched to smooth its apperance.</dd>
+ <dt><code>android:gravity</code></dt>
+ <dd><em>Keyword</em>. Defines the gravity for the bitmap. The gravity indicates where to
+position the drawable in its container if the bitmap is smaller than the container.
+ <p>Must be one or more (separated by '|') of the following constant values:</p>
+<table>
+<tr><th>Value</th><th>Description</th></tr>
+<tr><td><code>top</code></td>
+<td>Put the object at the top of its container, not changing its size.</td></tr>
+<tr><td><code>bottom</code></td>
+<td>Put the object at the bottom of its container, not changing its size. </td></tr>
+<tr><td><code>left</code></td>
+<td>Put the object at the left edge of its container, not changing its size. </td></tr>
+<tr><td><code>right</code></td>
+<td>Put the object at the right edge of its container, not changing its size. </td></tr>
+<tr><td><code>center_vertical</code></td>
+<td>Place object in the vertical center of its container, not changing its size. </td></tr>
+<tr><td><code>fill_vertical</code></td>
+<td>Grow the vertical size of the object if needed so it completely fills its container. </td></tr>
+<tr><td><code>center_horizontal</code></td>
+<td>Place object in the horizontal center of its container, not changing its size. </td></tr>
+<tr><td><code>fill_horizontal</code></td>
+<td>Grow the horizontal size of the object if needed so it completely fills its container.
+</td></tr>
+<tr><td><code>center</code></td>
+<td>Place the object in the center of its container in both the vertical and horizontal axis, not
+changing its size. </td></tr>
+<tr><td><code>fill</code></td>
+<td>Grow the horizontal and vertical size of the object if needed so it completely fills its
+container. This is the default.</td></tr>
+<tr><td><code>clip_vertical</code></td>
+<td>Additional option that can be set to have the top and/or bottom edges of the child clipped to
+its container's bounds. The clip is based on the vertical gravity: a top gravity clips the
+bottom edge, a bottom gravity clips the top edge, and neither clips both edges.
+</td></tr>
+<tr><td><code>clip_horizontal</code></td>
+<td>Additional option that can be set to have the left and/or right edges of the child clipped to
+its container's bounds. The clip is based on the horizontal gravity: a left gravity clips
+the right edge, a right gravity clips the left edge, and neither clips both edges.
+</td></tr>
+</table>
+ </dd>
+ <dt><code>android:tileMode</code></dt>
+ <dd><em>Keyword</em>. Defines the tile mode. When the tile mode is enabled, the bitmap is
+repeated. Gravity is ignored when the tile mode is enabled.
+ <p>Must be one of the following constant values:</p>
+<table>
+<tr><th>Value</th><th>Description</th></tr>
+<tr><td><code>disabled</code></td>
+<td>Do not tile the bitmap. This is the default value.</td></tr>
+<tr><td><code>clamp</code></td>
+<td>Replicates the edge color if the shader draws outside of its original bounds</td></tr>
+<tr><td><code>repeat</code></td>
+<td>Repeats the shader's image horizontally and vertically.</td></tr>
+<tr><td><code>mirror</code></td>
+<td>Repeats the shader's image horizontally and vertically, alternating mirror images so that
+adjacent images always seam.</td></tr>
+</table>
+
+ </dd>
+ </dl>
+ </dd>
+
+</dl>
+</dd> <!-- end elements and attributes -->
+
+<dt>example:</dt>
+<dd>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/icon"
+ android:tileMode="repeat" /&gt;
+</pre>
+
+</dd>
+
+<dt>see also:</dt>
+<dd>
+<ul>
+ <li>{@link android.graphics.drawable.BitmapDrawable}</li>
+ <li><a href="{@docRoot}guide/topics/resources/providing-resources.html#AliasResources">Creating
+alias resources</a>
+</ul>
+</dd>
+
+</dl>
+
+
+
+
+
+
+<h2 id="NinePatch">Nine-Patch</h2>
<p>A {@link android.graphics.NinePatch} is a PNG image in which you can define stretchable regions
-that Android will scale when content within the View exceeds the normal image bounds. You will
+that Android scales when content within the View exceeds the normal image bounds. You
typically assign this type of image as the background of a View that has at least one dimension set
to {@code "wrap_content"}, and when the View grows to accomodate the content, the Nine-Patch image
-will also be scaled to match the size of the View. An example use of a Nine-Patch image is the
+is also scaled to match the size of the View. An example use of a Nine-Patch image is the
background used by Android's standard {@link android.widget.Button} widget, which must stretch to
accommodate the text (or image) inside the button.</p>
-<p>For a complete discussion about how to define a Nine-Patch file with stretchable regions,
+<p>Same as with a normal <a href="#Bitmap">bitmap</a>, you can reference a Nine-Patch file directly
+or from a resource defined by XML.</p>
+
+<p>For a complete discussion about how to create a Nine-Patch file with stretchable regions,
see the <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D Graphics</a>
document.</p>
+
+<h3 id="NinePatchFile">Nine-Patch File</h3>
+
<dl class="xml">
<dt>file location:</dt>
<dd><code>res/drawable/<em>filename</em>.9.png</code><br/>
-The filename will be used as the resource ID.</dd>
+The filename is used as the resource ID.</dd>
<dt>compiled resource datatype:</dt>
<dd>Resource pointer to a {@link android.graphics.drawable.NinePatchDrawable}.</dd>
<dt>resource reference:</dt>
+
<dd>
In Java: <code>R.drawable.<em>filename</em></code><br/>
In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
</dd>
<dt>example:</dt>
-<dd>With an image saved at <code>res/drawable/myninepatch.9.png</code>, this layout XML will
-apply the Nine-Patch to a View:
+
+<dd>With an image saved at <code>res/drawable/myninepatch.9.png</code>, this layout XML
+applies the Nine-Patch to a View:
<pre>
&lt;Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- <strong>android:background="@drawable/myninepatch"</strong> />
+ android:background="@drawable/myninepatch" />
</pre>
</dd>
<dt>see also:</dt>
+
<dd>
<ul>
<li><a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D Graphics</a></li>
@@ -153,6 +354,238 @@ apply the Nine-Patch to a View:
+<h3 id="NinePatchXml">XML Nine-Patch</h3>
+
+<p>An XML Nine-Patch is a resource defined in XML that points to a Nine-Patch file. The XML can
+specify dithering for the image.</p>
+
+<dl class="xml">
+
+<dt>file location:</dt>
+<dd><code>res/drawable/<em>filename</em>.xml</code><br/>
+The filename is used as the resource ID.</dd>
+
+<dt>compiled resource datatype:</dt>
+<dd>Resource pointer to a {@link android.graphics.drawable.NinePatchDrawable}.</dd>
+
+<dt>resource reference:</dt>
+
+<dd>
+In Java: <code>R.drawable.<em>filename</em></code><br/>
+In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
+</dd>
+
+
+<dt>syntax:</dt>
+
+<dd>
+<pre class="stx">
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;<a href="#bitmap-element">nine-patch</a>
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@[package:]drawable/<em>drawable_resource</em>"
+ android:dither=["true" | "false"] /&gt;
+</pre>
+</dd>
+
+
+<dt>elements:</dt>
+
+<dd>
+<dl class="tag-list">
+
+ <dt id="layerlist-element"><code>&lt;bitmap&gt;</code></dt>
+ <dd>Defines the bitmap source and its properties.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>xmlns:android</code></dt>
+ <dd><em>String</em>. <strong>Required.</strong> Defines the XML namespace, which must be
+ <code>"http://schemas.android.com/apk/res/android"</code>.
+ <dt><code>android:src</code></dt>
+ <dd><em>Drawable resource</em>. <strong>Required</strong>. Reference to a Nine-Patch
+file.</dd>
+ <dt><code>android:dither</code></dt>
+ <dd><em>Boolean</em>. Enables or disables dithering of the bitmap if the bitmap does not
+have the same pixel configuration as the screen (for instance: a ARGB 8888 bitmap with an RGB 565
+screen).</dd>
+ </dl>
+ </dd>
+</dl>
+</dd>
+
+
+<dt>example:</dt>
+
+<dd>
+<pre class="stx">
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/myninepatch"
+ android:dither="false" /&gt;
+</pre>
+</dd>
+</dl>
+
+
+
+
+
+
+<h2 id="LayerList">Layer List</h2>
+
+<p>A {@link android.graphics.drawable.LayerDrawable} is a drawable object
+that manages an array of other drawables. Each drawable in the list is drawn in the order of the
+list&mdash;the last drawable in the list is drawn on top.</p>
+
+<p>Each drawable is represented by an {@code &lt;item&gt;} element inside a single {@code
+&lt;layer-list&gt;} element.</p>
+
+<dl class="xml">
+
+<dt>file location:</dt>
+<dd><code>res/drawable/<em>filename</em>.xml</code><br/>
+The filename is used as the resource ID.</dd>
+
+<dt>compiled resource datatype:</dt>
+<dd>Resource pointer to a {@link android.graphics.drawable.LayerDrawable}.</dd>
+
+<dt>resource reference:</dt>
+
+<dd>
+In Java: <code>R.drawable.<em>filename</em></code><br/>
+In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
+</dd>
+
+<dt>syntax:</dt>
+
+<dd>
+<pre class="stx">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;<a href="#layerlist-element">layer-list</a>
+ xmlns:android="http://schemas.android.com/apk/res/android" &gt;
+ &lt;<a href="#layerlist-item-element">item</a>
+ android:drawable="@[package:]drawable/<em>drawable_resource</em>"
+ android:id="@[+][<em>package</em>:]id/<i>resource_name</i>"
+ android:top="<em>dimension</em>"
+ android:right="<em>dimension</em>"
+ android:bottom="<em>dimension</em>"
+ android:left="<em>dimension</em>" /&gt;
+&lt;/selector>
+</pre>
+</dd>
+
+<dt>elements:</dt>
+
+<dd>
+<dl class="tag-list">
+
+ <dt id="layerlist-element"><code>&lt;layer-list&gt;</code></dt>
+ <dd><strong>Required.</strong> This must be the root element. Contains one or more {@code
+&lt;item>} elements.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>xmlns:android</code></dt>
+ <dd><em>String</em>. <strong>Required.</strong> Defines the XML namespace, which must be
+ <code>"http://schemas.android.com/apk/res/android"</code>.
+ </dl>
+ </dd>
+ <dt id="layerlist-item-element"><code>&lt;item&gt;</code></dt>
+ <dd>Defines a drawable to place in the layer drawable, in a position defined by its attributes.
+Must be a child of a <code>&lt;selector&gt;</code> element. Accepts child {@code &lt;bitmap&gt;}
+elements.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>android:drawable</code></dt>
+ <dd><em>Drawable resource</em>. <strong>Required</strong>. Reference to a drawable
+resource.</dd>
+ <dt><code>android:id</code></dt>
+ <dd><em>Resource ID</em>. A unique resource ID for this drawable. To create a new resource
+ID for this item, use the form:
+<code>"@+id/<em>name</em>"</code>. The plus symbol indicates that this should be created as a new
+ID. You can use this identifier to
+retrieve and modify the drawable with {@link android.view.View#findViewById(int)
+View.findViewById()} or {@link android.app.Activity#findViewById(int) Activity.findViewById()}.</dd>
+ <dt><code>android:top</code></dt>
+ <dd><em>Integer</em>. The top offset in pixels.</dd>
+ <dt><code>android:right</code></dt>
+ <dd><em>Integer</em>. The right offset in pixels.</dd>
+ <dt><code>android:bottom</code></dt>
+ <dd><em>Integer</em>. The bottom offset in pixels.</dd>
+ <dt><code>android:left</code></dt>
+ <dd><em>Integer</em>. The left offset in pixels.</dd>
+ </dl>
+ <p>All drawable items are scaled to fit the size of the containing View, by default. Thus,
+placing your images in a layer list at different positions might increase the size of the View and
+some images scale as appropriate. To avoid
+scaling items in the list, use a {@code &lt;bitmap&gt;} element inside the {@code
+&lt;item&gt;} element to specify the drawable and define the gravity to something that does not
+scale, such as {@code "center"}. For example, the following {@code &lt;item&gt;} defines an item
+that scales to fit its container View:</p>
+<pre>
+&lt;item android:drawable="@drawable/image" /&gt;
+</pre>
+
+<p>To avoid scaling, the following example uses a {@code &lt;bitmap&gt;} element with centered
+gravity:</p>
+<pre>
+&lt;item&gt;
+ &lt;bitmap android:src="<b>@drawable/image</b>"
+ android:gravity="center" /&gt;
+&lt;/item&gt;
+</pre>
+ </dd>
+
+</dl>
+</dd> <!-- end elements and attributes -->
+
+<dt>example:</dt>
+
+<dd>XML file saved at <code>res/drawable/layers.xml</code>:
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;layer-list xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item&gt;
+ &lt;bitmap android:src="@drawable/android_red"
+ android:gravity="center" /&gt;
+ &lt;/item&gt;
+ &lt;item android:top="10dp" android:left="10dp"&gt;
+ &lt;bitmap android:src="@drawable/android_green"
+ android:gravity="center" /&gt;
+ &lt;/item&gt;
+ &lt;item android:top="20dp" android:left="20dp"&gt;
+ &lt;bitmap android:src="@drawable/android_blue"
+ android:gravity="center" /&gt;
+ &lt;/item&gt;
+&lt;/layer-list&gt;
+</pre>
+<p>Notice that this example uses a nested {@code &lt;bitmap&gt;} element to define the drawable
+resource for each item with a "center" gravity. This ensures that none of the images are scaled to
+fit the size of the container, due to resizing caused by the offset images.</p>
+
+<p>This layout XML applies the drawable to a View:</p>
+<pre>
+&lt;ImageView
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:src="@drawable/layers" /&gt;
+</pre>
+
+<p>The result is a stack of increasingly offset images:</p>
+<img src="{@docRoot}images/resources/layers.png" alt="" />
+</dd> <!-- end example -->
+
+<dt>see also:</dt>
+<dd>
+<ul>
+ <li>{@link android.graphics.drawable.LayerDrawable}</li>
+</ul>
+</dd>
+
+</dl>
+
+
+
+
@@ -163,33 +596,36 @@ apply the Nine-Patch to a View:
that uses a several different images to represent the same graphic, depending on the state of
the object. For example, a {@link
android.widget.Button} widget can exist in one of several different states (pressed, focused,
-or niether) and, using a state list drawable, you can provide a different button image for each
+or niether) and, using a state list drawable, you can provide a different background image for each
state.</p>
<p>You can describe the state list in an XML file. Each graphic is represented by an {@code
&lt;item>} element inside a single {@code &lt;selector>} element. Each {@code &lt;item>}
uses various attributes to describe the state in which it should be used as the graphic for the
drawable.</p>
+
<p>During each state change, the state list is traversed top to bottom and the first item that
-matches the current state will be used&mdash;the selection is <em>not</em> based on the "best
+matches the current state is used&mdash;the selection is <em>not</em> based on the "best
match," but simply the first item that meets the minimum criteria of the state.</p>
<dl class="xml">
<dt>file location:</dt>
<dd><code>res/drawable/<em>filename</em>.xml</code><br/>
-The filename will be used as the resource ID.</dd>
+The filename is used as the resource ID.</dd>
<dt>compiled resource datatype:</dt>
<dd>Resource pointer to a {@link android.graphics.drawable.StateListDrawable}.</dd>
<dt>resource reference:</dt>
+
<dd>
In Java: <code>R.drawable.<em>filename</em></code><br/>
In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
</dd>
<dt>syntax:</dt>
+
<dd>
<pre class="stx">
&lt;?xml version="1.0" encoding="utf-8"?>
@@ -202,16 +638,16 @@ In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_selected=["true" | "false"]
- android:state_active=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
- android:state_window_focused=["true" | "false"] />
+ android:state_window_focused=["true" | "false"] />
&lt;/selector>
</pre>
</dd>
<dt>elements:</dt>
+
<dd>
<dl class="tag-list">
@@ -224,8 +660,8 @@ In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
<dd><em>String</em>. <strong>Required.</strong> Defines the XML namespace, which must be
<code>"http://schemas.android.com/apk/res/android"</code>.
<dt><code>android:constantSize</code></dt>
- <dd><em>Boolean</em>. "true" if the drawable's reported internal size will remain constant as the state
-changes (the size will be the maximum of all of the states); "false" if the size will vary based on
+ <dd><em>Boolean</em>. "true" if the drawable's reported internal size remains constant as the state
+changes (the size is the maximum of all of the states); "false" if the size varies based on
the current state. Default is false.</dd>
<dt><code>android:dither</code></dt>
<dd><em>Boolean</em>. "true" to enable dithering of the bitmap if the bitmap does not have the same pixel
@@ -270,9 +706,9 @@ receiving touch/click events); "false" if it should be used when the object is d
application is in the foreground), "false" if this item should be used when the application
window does not have focus (for example, if the notification shade is pulled down or a dialog appears).</dd>
</dl>
- <p class="note"><strong>Note:</strong>Remember that the first item in the state list that
-matches the current state of the object will be applied. So if the first item in the list contains
-none of the state attributes above, then it will be applied every time, which is why your
+ <p class="note"><strong>Note:</strong> Remember that Android applies the first item in the state list that
+matches the current state of the object. So, if the first item in the list contains
+none of the state attributes above, then it is applied every time, which is why your
default value should always be last (as demonstrated in the following example).</p>
</dd>
@@ -280,6 +716,7 @@ default value should always be last (as demonstrated in the following example).<
</dd> <!-- end elements and attributes -->
<dt>example:</dt>
+
<dd>XML file saved at <code>res/drawable/button.xml</code>:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
@@ -292,12 +729,12 @@ default value should always be last (as demonstrated in the following example).<
&lt;/selector>
</pre>
-<p>This layout XML will apply the drawable to a View:</p>
+<p>This layout XML applies the state list drawable to a Button:</p>
<pre>
-&lt;ImageView
+&lt;Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- <strong>android:src="@drawable/button"</strong> />
+ android:background="@drawable/button" />
</pre>
</dd> <!-- end example -->
@@ -317,106 +754,513 @@ default value should always be last (as demonstrated in the following example).<
+<h2 id="LevelList">Level List</h2>
+<p>A Drawable that manages a number of alternate Drawables, each assigned a maximum numerical
+value. Setting the level value of the drawable with {@link
+android.graphics.drawable.Drawable#setLevel(int) setLevel()} loads the drawable resource in the
+level list that has a {@code android:maxLevel} value greater than or equal to the value
+passed to the method.</p>
+<dl class="xml">
+<dt>file location:</dt>
+<dd><code>res/drawable/<em>filename</em>.xml</code><br/>
+The filename is used as the resource ID.</dd>
+<dt>compiled resource datatype:</dt>
+<dd>Resource pointer to a {@link android.graphics.drawable.LevelListDrawable}.</dd>
+<dt>resource reference:</dt>
-<h2 id="Color">Color</h2>
+<dd>
+In Java: <code>R.drawable.<em>filename</em></code><br/>
+In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
+</dd>
+
+<dt>syntax:</dt>
+
+<dd>
+<pre class="stx">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;<a href="#levellist-element">level-list</a>
+ xmlns:android="http://schemas.android.com/apk/res/android" &gt;
+ &lt;<a href="#levellist-item-element">item</a>
+ android:drawable="@drawable/<i>drawable_resource</i>"
+ android:maxLevel="<i>integer</i>"
+ android:minLevel="<i>integer</i>" /&gt;
+&lt;/level-list&gt;
+</pre>
+</dd>
+
+<dt>elements:</dt>
+
+<dd>
+<dl class="tag-list">
+
+ <dt id="levellist-element"><code>&lt;level-list&gt;</code></dt>
+ <dd>This must be the root element. Contains one or more {@code &lt;item&gt;} elements.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>xmlns:android</code></dt>
+ <dd><em>String</em>. <strong>Required.</strong> Defines the XML namespace, which must be
+ <code>"http://schemas.android.com/apk/res/android"</code>.
+ </dl>
+ </dd>
+
+ <dt id="levellist-item-element"><code>&lt;item&gt;</code></dt>
+ <dd>Defines a drawable to use at a certain level.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>android:drawable</code></dt>
+ <dd><em>Drawable resource</em>. <strong>Required</strong>. Reference to a drawable
+resource to be inset.</dd>
+ <dt><code>android:maxLevel</code></dt>
+ <dd><em>Integer</em>. The maximum level allowed for this item.</dd>
+ <dt><code>android:minLevel</code></dt>
+ <dd><em>Integer</em>. The minimum level allowed for this item.</dd>
+ </dl>
+ </dd>
+</dl>
+
+</dd>
+
+<dt>example:</dt>
+
+<dd>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;level-list xmlns:android="http://schemas.android.com/apk/res/android" &gt;
+ &lt;item
+ android:drawable="@drawable/status_off"
+ android:maxLevel="0" /&gt;
+ &lt;item
+ android:drawable="@drawable/status_on"
+ android:maxLevel="1" /&gt;
+&lt;/level-list&gt;
+</pre>
+<p>Once this is applied to a {@link android.view.View}, the level can be changed with {@link
+android.graphics.drawable.Drawable#setLevel(int) setLevel()} or {@link
+android.widget.ImageView#setImageLevel(int) setImageLevel()}.</p>
+
+</dd>
+
+<dt>see also:</dt>
+
+<dd>
+<ul>
+ <li>{@link android.graphics.drawable.LevelListDrawable}</li>
+</ul>
+</dd>
+
+</dl>
-<p>This is a color defined in XML that's used as a drawable to fill a rectangular space,
-with optionally rounded corners. This kind of drawable behaves like a color fill.</p>
-<p class="note"><strong>Note:</strong> A color drawable is a simple resource that is referenced
-using the value provided in the {@code name} attribute (not the name of the XML file). As
-such, you can combine a color drawable resources with other simple resources in the one XML file,
-under one {@code &lt;resources>} element.</p>
+
+
+<h2 id="Transition">Transition Drawable</h2>
+
+<p>A {@link android.graphics.drawable.TransitionDrawable} is a drawable object
+that can cross-fade between the two drawable resources.</p>
+
+<p>Each drawable is represented by an {@code &lt;item&gt;} element inside a single {@code
+&lt;transition&gt;} element. No more than two items are supported. To transition forward, call
+{@link android.graphics.drawable.TransitionDrawable#startTransition(int) startTransition()}. To
+transition backward, call {@link android.graphics.drawable.TransitionDrawable#reverseTransition(int)
+reverseTransition()}.</p>
+
<dl class="xml">
<dt>file location:</dt>
-<dd><code>res/drawable/<em>filename</em>.png</code><br/>
-The filename is arbitrary. The element's {@code name} will be used as the resource ID.</dd>
+<dd><code>res/drawable/<em>filename</em>.xml</code><br/>
+The filename is used as the resource ID.</dd>
<dt>compiled resource datatype:</dt>
-<dd>Resource pointer to a {@link android.graphics.drawable.PaintDrawable}.</dd>
+<dd>Resource pointer to a {@link android.graphics.drawable.TransitionDrawable}.</dd>
<dt>resource reference:</dt>
+
<dd>
-In Java: <code>R.drawable.<em>color_name</em></code><br/>
-In XML: <code>@[<em>package</em>:]drawable/<em>color_name</em></code>
+In Java: <code>R.drawable.<em>filename</em></code><br/>
+In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
</dd>
<dt>syntax:</dt>
+
<dd>
<pre class="stx">
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;<a href="#color-resources-element">resources</a>>
- &lt;<a href="#drawable-element">drawable</a>
- name="<em>color_name</em>"
- &gt;<em>color</em>&lt;/drawable&gt;
-&lt;/resources&gt;
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;<a href="#transition-element">layer-list</a>
+xmlns:android="http://schemas.android.com/apk/res/android" &gt;
+ &lt;<a href="#transition-item-element">item</a>
+ android:drawable="@[package:]drawable/<em>drawable_resource</em>"
+ android:id="@[+][<em>package</em>:]id/<i>resource_name</i>"
+ android:top="<em>dimension</em>"
+ android:right="<em>dimension</em>"
+ android:bottom="<em>dimension</em>"
+ android:left="<em>dimension</em>" /&gt;
+&lt;/selector>
</pre>
</dd>
<dt>elements:</dt>
+
<dd>
<dl class="tag-list">
- <dt id="color-resources-element"><code>&lt;resources&gt;</code></dt>
- <dd><strong>Required.</strong> This must be the root node.
- <p>No attributes.</p>
+ <dt id="transition-element"><code>&lt;transition&gt;</code></dt>
+ <dd><strong>Required.</strong> This must be the root element. Contains one or more {@code
+&lt;item>} elements.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>xmlns:android</code></dt>
+ <dd><em>String</em>. <strong>Required.</strong> Defines the XML namespace, which must be
+ <code>"http://schemas.android.com/apk/res/android"</code>.
+ </dl>
</dd>
- <dt id="drawable-element"><code>&lt;drawable&gt;</code></dt>
- <dd>A color to use as a drawable rectangle. The value can be
- any valid hexadecimal color value or a <a href="more-resources.html#Color">color
- resource</a>. A color value always begins with a pound (#) character, followed
- by the Alpha-Red-Green-Blue information in one of the following formats:
- #<em>RGB</em>, #<em>RRGGBB</em>, #<em>ARGB</em>, or #<em>AARRGGBB</em>.
+ <dt id="transition-item-element"><code>&lt;item&gt;</code></dt>
+ <dd>Defines a drawable to place in the layer drawable, in a position defined by its attributes.
+Must be a child of a <code>&lt;selector&gt;</code> element. Accepts child {@code &lt;bitmap&gt;}
+elements.
<p class="caps">attributes:</p>
<dl class="atn-list">
- <dt><code>name</code></dt>
- <dd><em>String</em>. <strong>Required</strong>.
- A name for the color. This name will be used as the resource ID.</dd>
+ <dt><code>android:drawable</code></dt>
+ <dd><em>Drawable resource</em>. <strong>Required</strong>. Reference to a drawable
+resource.</dd>
+ <dt><code>android:id</code></dt>
+ <dd><em>Resource ID</em>. A unique resource ID for this drawable. To create a new resource
+ID for this item, use the form:
+<code>"@+id/<em>name</em>"</code>. The plus symbol indicates that this should be created as a new
+ID. You can use this identifier to
+retrieve and modify the drawable with {@link android.view.View#findViewById(int)
+View.findViewById()} or {@link android.app.Activity#findViewById(int) Activity.findViewById()}.</dd>
+ <dt><code>android:top</code></dt>
+ <dd><em>Integer</em>. The top offset in pixels.</dd>
+ <dt><code>android:right</code></dt>
+ <dd><em>Integer</em>. The right offset in pixels.</dd>
+ <dt><code>android:bottom</code></dt>
+ <dd><em>Integer</em>. The bottom offset in pixels.</dd>
+ <dt><code>android:left</code></dt>
+ <dd><em>Integer</em>. The left offset in pixels.</dd>
</dl>
-
</dd>
</dl>
</dd> <!-- end elements and attributes -->
<dt>example:</dt>
-<dd>XML file saved at <code>res/drawable/colors.xml</code>:
+
+<dd>XML file saved at <code>res/drawable/transition.xml</code>:
<pre>
-&lt;?xml version="1.0" encoding="utf-8"?>
-&lt;resources>
- &lt;drawable name="solid_red">#f00&lt;/drawable>
- &lt;drawable name="solid_blue">#0000ff&lt;/drawable>
-&lt;/resources>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;transition xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:drawable="@drawable/on" /&gt;
+ &lt;item android:drawable="@drawable/off" /&gt;
+&lt;/layer-list&gt;
</pre>
- <p>This layout XML will apply a color drawable to a View:</p>
+
+<p>This layout XML applies the drawable to a View:</p>
<pre>
-&lt;TextView
- android:layout_width="fill_parent"
+&lt;ImageButton
+ android:id="@+id/button"
android:layout_height="wrap_content"
- <strong>android:background="@drawable/solid_blue"</strong> />
+ android:layout_width="wrap_content"
+ android:src="@drawable/transition" /&gt;
+</pre>
+
+<p>And the following code performs a 500ms transition from the first item to the second:</p>
+<pre>
+ImageButton button = (ImageButton) findViewById(R.id.button);
+TransitionDrawable drawable = (TransitionDrawable) button.getDrawable();
+drawable.startTransition(500);
</pre>
- <p>This application code will get a color drawable and apply it to a View:</p>
+
+</dd> <!-- end example -->
+
+<dt>see also:</dt>
+
+<dd>
+<ul>
+ <li>{@link android.graphics.drawable.TransitionDrawable}</li>
+</ul>
+</dd>
+
+</dl>
+
+
+
+
+
+
+
+
+<h2 id="Inset">Inset Drawable</h2>
+
+<p>A drawable defined in XML that insets another drawable by a specified distance. This is used when
+a View needs a background that is smaller than the View's actual bounds.</p>
+
+<dl class="xml">
+
+<dt>file location:</dt>
+<dd><code>res/drawable/<em>filename</em>.xml</code><br/>
+The filename is used as the resource ID.</dd>
+
+<dt>compiled resource datatype:</dt>
+<dd>Resource pointer to a {@link android.graphics.drawable.InsetDrawable}.</dd>
+
+<dt>resource reference:</dt>
+
+<dd>
+In Java: <code>R.drawable.<em>filename</em></code><br/>
+In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
+</dd>
+
+<dt>syntax:</dt>
+
+<dd>
+<pre class="stx">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;<a href="#inset-element">inset</a>
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/<i>drawable_resource</i>"
+ android:insetTop="<i>dimension</i>"
+ android:insetRight="<i>dimension</i>"
+ android:insetBottom="<i>dimension</i>"
+ android:insetLeft="<i>dimension</i>" /&gt;
+</pre>
+</dd>
+
+<dt>elements:</dt>
+
+<dd>
+<dl class="tag-list">
+
+ <dt id="inset-element"><code>&lt;inset&gt;</code></dt>
+ <dd>Defines the inset drawable. This must be the root element.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>xmlns:android</code></dt>
+ <dd><em>String</em>. <strong>Required.</strong> Defines the XML namespace, which must be
+ <code>"http://schemas.android.com/apk/res/android"</code>.
+ <dt><code>android:drawable</code></dt>
+ <dd><em>Drawable resource</em>. <strong>Required</strong>. Reference to a drawable
+resource to be inset.</dd>
+ <dt><code>android:insetTop</code></dt>
+ <dd><em>Dimension</em>. The top inset, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a></dd>
+ <dt><code>android:insetRight</code></dt>
+ <dd><em>Dimension</em>. The right inset, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a></dd>
+ <dt><code>android:insetBottom</code></dt>
+ <dd><em>Dimension</em>. The bottom inset, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a></dd>
+ <dt><code>android:insetLeft</code></dt>
+ <dd><em>Dimension</em>. The left inset, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a></dd>
+ </dl>
+ </dd>
+</dl>
+
+</dd>
+
+<dt>example:</dt>
+
+<dd>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/background"
+ android:insetTop="10dp"
+ android:insetLeft="10dp" /&gt;
+</pre>
+</dd>
+
+<dt>see also:</dt>
+
+<dd>
+<ul>
+ <li>{@link android.graphics.drawable.InsetDrawable}</li>
+</ul>
+</dd>
+
+</dl>
+
+
+
+
+
+
+
+
+<h2 id="Clip">Clip Drawable</h2>
+
+<p>A drawable defined in XML that clips another drawable based on this Drawable's current level. You
+can control how much the child drawable gets clipped in width and height based on the level, as well
+as a gravity to control where it is placed in its overall container. Most often used to implement
+things like progress bars.</p>
+
+<dl class="xml">
+
+<dt>file location:</dt>
+<dd><code>res/drawable/<em>filename</em>.xml</code><br/>
+The filename is used as the resource ID.</dd>
+
+<dt>compiled resource datatype:</dt>
+<dd>Resource pointer to a {@link android.graphics.drawable.ClipDrawable}.</dd>
+
+<dt>resource reference:</dt>
+
+<dd>
+In Java: <code>R.drawable.<em>filename</em></code><br/>
+In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
+</dd>
+
+<dt>syntax:</dt>
+
+<dd>
+<pre class="stx">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;<a href="#clip-element">clip</a>
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/<i>drawable_resource</i>"
+ android:clipOrientation=["horizontal" | "vertical"]
+ android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
+ "fill_vertical" | "center_horizontal" | "fill_horizontal" |
+ "center" | "fill" | "clip_vertical" | "clip_horizontal"] /&gt;
+</pre>
+</dd>
+
+<dt>elements:</dt>
+
+<dd>
+<dl class="tag-list">
+
+ <dt id="clip-element"><code>&lt;clip&gt;</code></dt>
+ <dd>Defines the clip drawable. This must be the root element.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>xmlns:android</code></dt>
+ <dd><em>String</em>. <strong>Required.</strong> Defines the XML namespace, which must be
+ <code>"http://schemas.android.com/apk/res/android"</code>.
+ <dt><code>android:drawable</code></dt>
+ <dd><em>Drawable resource</em>. <strong>Required</strong>. Reference to a drawable
+resource to be clipped.</dd>
+ <dt><code>android:clipOrientation</code></dt>
+ <dd><em>Keyword</em>. The orientation for the clip.
+ <p>Must be one of the following constant values:</p>
+<table>
+<tr><th>Value</th><th>Description</th></tr>
+<tr><td><code>horizontal</code></td>
+<td>Clip the drawable horizontally.</td></tr>
+<tr><td><code>vertical</code></td>
+<td>Clip the drawable vertically.</td></tr>
+</table>
+ </dd>
+ <dt><code>android:gravity</code></dt>
+ <dd><em>Keyword</em>. Specifies where to clip within the drawable.
+ <p>Must be one or more (separated by '|') of the following constant values:</p>
+<table>
+<tr><th>Value</th><th>Description</th></tr>
+<tr><td><code>top</code></td>
+<td>Put the object at the top of its container, not changing its size. When {@code
+clipOrientation} is {@code "vertical"}, clipping occurs at the bottom of the drawable.</td></tr>
+<tr><td><code>bottom</code></td>
+<td>Put the object at the bottom of its container, not changing its size. When {@code
+clipOrientation} is {@code "vertical"}, clipping occurs at the top of the drawable.</td></tr>
+<tr><td><code>left</code></td>
+<td>Put the object at the left edge of its container, not changing its size. This is the
+default. When {@code clipOrientation} is {@code "horizontal"}, clipping occurs at the right side of
+the drawable. This is the default.</td></tr>
+<tr><td><code>right</code></td>
+<td>Put the object at the right edge of its container, not changing its size. When {@code
+clipOrientation} is {@code "horizontal"}, clipping occurs at the left side of
+the drawable.</td></tr>
+<tr><td><code>center_vertical</code></td>
+<td>Place object in the vertical center of its container, not changing its size. Clipping behaves
+the same as when gravity is {@code "center"}.</td></tr>
+<tr><td><code>fill_vertical</code></td>
+<td>Grow the vertical size of the object if needed so it completely fills its container. When {@code
+clipOrientation} is {@code "vertical"}, no clipping occurs because the drawable fills the
+vertical space (unless the drawable level is 0, in which case it's not visible).</td></tr>
+<tr><td><code>center_horizontal</code></td>
+<td>Place object in the horizontal center of its container, not changing its size.
+Clipping behaves the same as when gravity is {@code "center"}.</td></tr>
+<tr><td><code>fill_horizontal</code></td>
+<td>Grow the horizontal size of the object if needed so it completely fills its container. When
+{@code clipOrientation} is {@code "horizontal"}, no clipping occurs because the drawable fills the
+horizontal space (unless the drawable level is 0, in which case it's not visible).
+</td></tr>
+<tr><td><code>center</code></td>
+<td>Place the object in the center of its container in both the vertical and horizontal axis, not
+changing its size. When {@code
+clipOrientation} is {@code "horizontal"}, clipping occurs on the left and right. When {@code
+clipOrientation} is {@code "vertical"}, clipping occurs on the top and bottom.</td></tr>
+<tr><td><code>fill</code></td>
+<td>Grow the horizontal and vertical size of the object if needed so it completely fills its
+container. No clipping occurs because the drawable fills the
+horizontal and vertical space (unless the drawable level is 0, in which case it's not
+visible).</td></tr>
+<tr><td><code>clip_vertical</code></td>
+<td>Additional option that can be set to have the top and/or bottom edges of the child clipped to
+its container's bounds. The clip is based on the vertical gravity: a top gravity clips the
+bottom edge, a bottom gravity clips the top edge, and neither clips both edges.
+</td></tr>
+<tr><td><code>clip_horizontal</code></td>
+<td>Additional option that can be set to have the left and/or right edges of the child clipped to
+its container's bounds. The clip is based on the horizontal gravity: a left gravity clips
+the right edge, a right gravity clips the left edge, and neither clips both edges.
+</td></tr>
+</table></dd>
+ </dl>
+ </dd>
+</dl>
+
+</dd> <!-- end elements and attributes -->
+
+<dt>example:</dt>
+
+<dd>XML file saved at <code>res/drawable/clip.xml</code>:
<pre>
-Resources res = {@link android.content.Context#getResources()};
-Drawable redDrawable = res.{@link android.content.res.Resources#getDrawable(int) getDrawable}(R.drawable.solid_red);
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/android"
+ android:clipOrientation="horizontal"
+ android:gravity="left" /&gt;
+&lt;/shape>
+</pre>
+ <p>The following layout XML applies the clip drawable to a View:</p>
+<pre>
+&lt;ImageView
+ android:id="@+id/image"
+ android:background="@drawable/clip"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
+</pre>
-TextView tv = (TextView) findViewByID(R.id.text);
-tv.setBackground(redDrawable);
+ <p>The following code gets the drawable and increases the amount of clipping in order to
+progressively reveal the image:</p>
+<pre>
+ImageView imageview = (ImageView) findViewById(R.id.image);
+ClipDrawable drawable = (ClipDrawable) imageview.getDrawable();
+drawable.setLevel(drawable.getLevel() + 1000);
</pre>
+
+<p>Increasing the level reduces the amount of clipping and slowly reveals the image. Here it is
+at a level of 7000:</p>
+<img src="{@docRoot}images/resources/clip.png" alt="" />
+
+<p class="note"><strong>Note:</strong> The default level is 0, which is fully clipped so the image
+is not visible. When the level is 10,000, the image is not clipped and completely visible.</p>
</dd> <!-- end example -->
<dt>see also:</dt>
+
<dd>
<ul>
- <li>{@link android.graphics.drawable.PaintDrawable}</li>
+ <li>{@link android.graphics.drawable.ClipDrawable}</li>
</ul>
</dd>
@@ -430,10 +1274,139 @@ tv.setBackground(redDrawable);
+<h2 id="Scale">Scale Drawable</h2>
+
+<p>A drawable defined in XML that changes the size of another drawable based on its current
+level.</p>
+
+<dl class="xml">
+
+<dt>file location:</dt>
+<dd><code>res/drawable/<em>filename</em>.xml</code><br/>
+The filename is used as the resource ID.</dd>
+
+<dt>compiled resource datatype:</dt>
+<dd>Resource pointer to a {@link android.graphics.drawable.ScaleDrawable}.</dd>
+
+<dt>resource reference:</dt>
+
+<dd>
+In Java: <code>R.drawable.<em>filename</em></code><br/>
+In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
+</dd>
+
+<dt>syntax:</dt>
+
+<dd>
+<pre class="stx">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;<a href="#scale-element">scale</a>
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/<i>drawable_resource</i>"
+ android:scaleGravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
+ "fill_vertical" | "center_horizontal" | "fill_horizontal" |
+ "center" | "fill" | "clip_vertical" | "clip_horizontal"]
+ android:scaleHeight="<i>percentage</i>"
+ android:scaleWidth="<i>percentage</i>" /&gt;
+</pre>
+</dd>
+
+<dt>elements:</dt>
+<dd>
+<dl class="tag-list">
+ <dt id="scale-element"><code>&lt;scale&gt;</code></dt>
+ <dd>Defines the scale drawable. This must be the root element.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>xmlns:android</code></dt>
+ <dd><em>String</em>. <strong>Required.</strong> Defines the XML namespace, which must be
+ <code>"http://schemas.android.com/apk/res/android"</code>.
+ <dt><code>android:drawable</code></dt>
+ <dd><em>Drawable resource</em>. <strong>Required</strong>. Reference to a drawable
+resource.</dd>
+ <dt><code>android:scaleGravity</code></dt>
+ <dd><em>Keyword</em>. Specifies the gravity position after scaling.
+ <p>Must be one or more (separated by '|') of the following constant values:</p>
+<table>
+<tr><th>Value</th><th>Description</th></tr>
+<tr><td><code>top</code></td>
+<td>Put the object at the top of its container, not changing its size.</td></tr>
+<tr><td><code>bottom</code></td>
+<td>Put the object at the bottom of its container, not changing its size. </td></tr>
+<tr><td><code>left</code></td>
+<td>Put the object at the left edge of its container, not changing its size. This is the
+default.</td></tr>
+<tr><td><code>right</code></td>
+<td>Put the object at the right edge of its container, not changing its size. </td></tr>
+<tr><td><code>center_vertical</code></td>
+<td>Place object in the vertical center of its container, not changing its size. </td></tr>
+<tr><td><code>fill_vertical</code></td>
+<td>Grow the vertical size of the object if needed so it completely fills its container. </td></tr>
+<tr><td><code>center_horizontal</code></td>
+<td>Place object in the horizontal center of its container, not changing its size. </td></tr>
+<tr><td><code>fill_horizontal</code></td>
+<td>Grow the horizontal size of the object if needed so it completely fills its container.
+</td></tr>
+<tr><td><code>center</code></td>
+<td>Place the object in the center of its container in both the vertical and horizontal axis, not
+changing its size. </td></tr>
+<tr><td><code>fill</code></td>
+<td>Grow the horizontal and vertical size of the object if needed so it completely fills its
+container. </td></tr>
+<tr><td><code>clip_vertical</code></td>
+<td>Additional option that can be set to have the top and/or bottom edges of the child clipped to
+its container's bounds. The clip is based on the vertical gravity: a top gravity clips the
+bottom edge, a bottom gravity clips the top edge, and neither clips both edges.
+</td></tr>
+<tr><td><code>clip_horizontal</code></td>
+<td>Additional option that can be set to have the left and/or right edges of the child clipped to
+its container's bounds. The clip is based on the horizontal gravity: a left gravity clips
+the right edge, a right gravity clips the left edge, and neither clips both edges.
+</td></tr>
+</table></dd>
+ <dt><code>android:scaleHeight</code></dt>
+ <dd><em>Percentage</em>. The scale height, expressed as a percentage of the drawable's
+bound. The value's format is XX%. For instance: 100%, 12.5%, etc.</dd>
+ <dt><code>android:scaleWidth</code></dt>
+ <dd><em>Percentage</em>. The scale width, expressed as a percentage of the drawable's
+bound. The value's format is XX%. For instance: 100%, 12.5%, etc.</dd>
+ </dl>
+ </dd>
+</dl>
-<h2 id="Shape">Shape</h2>
+</dd>
+
+<dt>example:</dt>
+
+<dd>
+<pre class="stx">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;scale xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/logo"
+ android:scaleGravity="center_vertical|center_horizontal"
+ android:scaleHeight="80%"
+ android:scaleWidth="80%" /&gt;
+</pre>
+</dd>
+
+<dt>see also:</dt>
+<dd>
+<ul>
+ <li>{@link android.graphics.drawable.ScaleDrawable}</li>
+</ul>
+</dd>
+
+</dl>
+
+
+
+
+
+
+
+<h2 id="Shape">Shape Drawable</h2>
<p>This is a generic shape defined in XML.</p>
@@ -441,23 +1414,32 @@ tv.setBackground(redDrawable);
<dt>file location:</dt>
<dd><code>res/drawable/<em>filename</em>.xml</code><br/>
-The filename will be used as the resource ID.</dd>
+The filename is used as the resource ID.</dd>
<dt>compiled resource datatype:</dt>
<dd>Resource pointer to a {@link android.graphics.drawable.ShapeDrawable}.</dd>
<dt>resource reference:</dt>
+
<dd>
In Java: <code>R.drawable.<em>filename</em></code><br/>
In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
</dd>
<dt>syntax:</dt>
+
<dd>
<pre class="stx">
&lt;?xml version="1.0" encoding="utf-8"?>
-&lt;<a href="#shape-element">shape</a> xmlns:android="http://schemas.android.com/apk/res/android"
+&lt;<a href="#shape-element">shape</a>
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:shape=["rectangle" | "oval" | "line" | "ring"] >
+ &lt;<a href="#corners-element">corners</a>
+ android:radius="<em>integer</em>"
+ android:topLeftRadius="<em>integer</em>"
+ android:topRightRadius="<em>integer</em>"
+ android:bottomLeftRadius="<em>integer</em>"
+ android:bottomRightRadius="<em>integer</em>" /&gt;
&lt;<a href="#gradient-element">gradient</a>
android:angle="<em>integer</em>"
android:centerX="<em>integer</em>"
@@ -467,37 +1449,40 @@ In XML: <code>@[<em>package</em>:]drawable/<em>filename</em></code>
android:gradientRadius="<em>integer</em>"
android:startColor="<em>color</em>"
android:type=["linear" | "radial" | "sweep"]
- android:usesLevel=["true" | "false"] />
+ android:usesLevel=["true" | "false"] /&gt;
+ &lt;<a href="#padding-element">padding</a>
+ android:left="<em>integer</em>"
+ android:top="<em>integer</em>"
+ android:right="<em>integer</em>"
+ android:bottom="<em>integer</em>" /&gt;
+ &lt;<a href="#size-element">size</a>
+ android:width="<em>integer</em>"
+ android:color="<em>color</em>"
+ android:dashWidth="<em>integer</em>"
+ android:dashGap="<em>integer</em>" /&gt;
&lt;<a href="#solid-element">solid</a>
- android:color="<em>color</em>" />
+ android:color="<em>color</em>" /&gt;
&lt;<a href="#stroke-element">stroke</a>
android:width="<em>integer</em>"
android:color="<em>color</em>"
android:dashWidth="<em>integer</em>"
- android:dashGap="<em>integer</em>" />
- &lt;<a href="#padding-element">padding</a>
- android:left="<em>integer</em>"
- android:top="<em>integer</em>"
- android:right="<em>integer</em>"
- android:bottom="<em>integer</em>" />
- &lt;<a href="#corners-element">corners</a>
- android:radius="<em>integer</em>"
- android:topLeftRadius="<em>integer</em>"
- android:topRightRadius="<em>integer</em>"
- android:bottomLeftRadius="<em>integer</em>"
- android:bottomRightRadius="<em>integer</em>" />
+ android:dashGap="<em>integer</em>" /&gt;
&lt;/shape>
</pre>
</dd>
<dt>elements:</dt>
+
<dd>
<dl class="tag-list">
<dt id="shape-element"><code>&lt;shape&gt;</code></dt>
- <dd><strong>Required.</strong> This must be the root element.
+ <dd>The shape drawable. This must be the root element.
<p class="caps">attributes:</p>
<dl class="atn-list">
+ <dt><code>xmlns:android</code></dt>
+ <dd><em>String</em>. <strong>Required.</strong> Defines the XML namespace, which must be
+ <code>"http://schemas.android.com/apk/res/android"</code>.
<dt><code>android:shape</code></dt>
<dd><em>Keyword</em>. Defines the type of shape. Valid values are:
<table>
@@ -525,7 +1510,7 @@ href="more-resources.html#Dimension">dimension resource</a>.</dd>
<dd><em>Float</em>. The radius for the inner
part of the ring, expressed as a ratio of the ring's width. For instance, if {@code
android:innerRadiusRatio="5"}, then the inner radius equals the ring's width divided by 5. This
-value will be overridden by {@code android:innerRadius}. Default value is 9.</dd>
+value is overridden by {@code android:innerRadius}. Default value is 9.</dd>
<dt><code>android:thickness</code></dt>
<dd><em>Dimension</em>. The thickness of the
ring, as a dimension value or <a
@@ -533,13 +1518,40 @@ href="more-resources.html#Dimension">dimension resource</a>.</dd>
<dt><code>android:thicknessRatio</code></dt>
<dd><em>Float</em>. The thickness of the ring,
expressed as a ratio of the ring's width. For instance, if {@code android:thicknessRatio="2"}, then
-the thickness equals the ring's width divided by 2. This value will be overridden by {@code
+the thickness equals the ring's width divided by 2. This value is overridden by {@code
android:innerRadius}. Default value is 3.</dd>
<dt><code>android:useLevel</code></dt>
<dd><em>Boolean</em>. "true" if this is used as
a {@link android.graphics.drawable.LevelListDrawable}. This should normally be "false"
or your shape may not appear.</dd>
</dl>
+ <dt id="corners-element"><code>&lt;corners&gt;</code></dt>
+ <dd>Creates rounded corners for the shape. Applies only when the shape is a rectangle.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>android:radius</code></dt>
+ <dd><em>Dimension</em>. The radius for all corners, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>. This is overridden for each
+corner by the following attributes.</dd>
+ <dt><code>android:topLeftRadius</code></dt>
+ <dd><em>Dimension</em>. The radius for the top-left corner, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>.</dd>
+ <dt><code>android:topRightRadius</code></dt>
+ <dd><em>Dimension</em>. The radius for the top-right corner, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>.</dd>
+ <dt><code>android:bottomLeftRadius</code></dt>
+ <dd><em>Dimension</em>. The radius for the bottom-left corner, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>.</dd>
+ <dt><code>android:bottomRightRadius</code></dt>
+ <dd><em>Dimension</em>. The radius for the bottom-right corner, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>.</dd>
+ </dl>
+ <p class="note"><strong>Note:</strong> Every corner must (initially) be provided a corner
+radius greater than 1, or else no corners are rounded. If you want specific corners
+to <em>not</em> be rounded, a work-around is to use {@code android:radius} to set a default corner
+radius greater than 1, but then override each and every corner with the values you really
+want, providing zero ("0dp") where you don't want rounded corners.</p>
+ </dd>
<dt id="gradient-element"><code>&lt;gradient&gt;</code></dt>
<dd>Specifies a gradient color for the shape.
<p class="caps">attributes:</p>
@@ -582,6 +1594,42 @@ value or <a href="more-resources.html#Color">color resource</a>.</dd>
android.graphics.drawable.LevelListDrawable}.</dd>
</dl>
</dd>
+ <dt id="padding-element"><code>&lt;padding&gt;</code></dt>
+ <dd>Padding to apply to the containing View element (this pads the position of the View
+content, not the shape).
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>android:left</code></dt>
+ <dd><em>Dimension</em>. Left padding, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>.</dd>
+ <dt><code>android:top</code></dt>
+ <dd><em>Dimension</em>. Top padding, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>.</dd>
+ <dt><code>android:right</code></dt>
+ <dd><em>Dimension</em>. Right padding, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>.</dd>
+ <dt><code>android:bottom</code></dt>
+ <dd><em>Dimension</em>. Bottom padding, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>.</dd>
+ </dl>
+ </dd>
+ <dt id="solid-element"><code>&lt;size&gt;</code></dt>
+ <dd>The size of the shape.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>android:height</code></dt>
+ <dd><em>Dimension</em>. The height of the shape, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>.</dd>
+ <dt><code>android:width</code></dt>
+ <dd><em>Dimension</em>. The width of the shape, as a dimension value or <a
+href="more-resources.html#Dimension">dimension resource</a>.</dd>
+ </dl>
+ <p class="note"><strong>Note:</strong> The shape scales to the size of the container
+View proportionate to the dimensions defined here, by default. When you use the shape in an {@link
+android.widget.ImageView}, you can restrict scaling by setting the <a
+href="{@docRoot}reference/android/widget/ImageView.html#attr_android:scaleType">{@code
+android:scaleType}</a> to {@code "center"}.</p>
+ </dd>
<dt id="solid-element"><code>&lt;solid&gt;</code></dt>
<dd>A solid color to fill the shape.
<p class="caps">attributes:</p>
@@ -611,81 +1659,38 @@ href="more-resources.html#Dimension">dimension resource</a>. Only valid if {@cod
android:dashGap} is set.</dd>
</dl>
</dd>
- <dt id="padding-element"><code>&lt;padding&gt;</code></dt>
- <dd>Padding to apply to the containing View element (this pads the position of the View
-content, not the shape).
- <p class="caps">attributes:</p>
- <dl class="atn-list">
- <dt><code>android:left</code></dt>
- <dd><em>Dimension</em>. Left padding, as a dimension value or <a
-href="more-resources.html#Dimension">dimension resource</a>.</dd>
- <dt><code>android:top</code></dt>
- <dd><em>Dimension</em>. Top padding, as a dimension value or <a
-href="more-resources.html#Dimension">dimension resource</a>.</dd>
- <dt><code>android:right</code></dt>
- <dd><em>Dimension</em>. Right padding, as a dimension value or <a
-href="more-resources.html#Dimension">dimension resource</a>.</dd>
- <dt><code>android:bottom</code></dt>
- <dd><em>Dimension</em>. Bottom padding, as a dimension value or <a
-href="more-resources.html#Dimension">dimension resource</a>.</dd>
- </dl>
- </dd>
- <dt id="corners-element"><code>&lt;corners&gt;</code></dt>
- <dd>Creates rounded corners for the shape. Applies only when the shape is a rectangle.
- <p class="caps">attributes:</p>
- <dl class="atn-list">
- <dt><code>android:radius</code></dt>
- <dd><em>Dimension</em>. The radius for all corners, as a dimension value or <a
-href="more-resources.html#Dimension">dimension resource</a>. This will be overridden for each
-corner by the following attributes.</dd>
- <dt><code>android:topLeftRadius</code></dt>
- <dd><em>Dimension</em>. The radius for the top-left corner, as a dimension value or <a
-href="more-resources.html#Dimension">dimension resource</a>.</dd>
- <dt><code>android:topRightRadius</code></dt>
- <dd><em>Dimension</em>. The radius for the top-right corner, as a dimension value or <a
-href="more-resources.html#Dimension">dimension resource</a>.</dd>
- <dt><code>android:bottomLeftRadius</code></dt>
- <dd><em>Dimension</em>. The radius for the bottom-left corner, as a dimension value or <a
-href="more-resources.html#Dimension">dimension resource</a>.</dd>
- <dt><code>android:bottomRightRadius</code></dt>
- <dd><em>Dimension</em>. The radius for the bottom-right corner, as a dimension value or <a
-href="more-resources.html#Dimension">dimension resource</a>.</dd>
- </dl>
- <p class="note"><strong>Note:</strong> Every corner must (initially) be provided a corner
-radius greater than zero, or else no corners will be rounded. If you want specific corners
-to <em>not</em> be rounded, a work-around is to use {@code android:radius} to set a default corner
-radius greater than zero, but then override each and every corner with the values you really
-want, providing zero ("0dp") where you don't want rounded corners.</p>
- </dd>
</dl>
</dd> <!-- end elements and attributes -->
<dt>example:</dt>
+
<dd>XML file saved at <code>res/drawable/gradient_box.xml</code>:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- &lt;gradient
- android:startColor="#FFFF0000"
+ &lt;gradient
+ android:startColor="#FFFF0000"
android:endColor="#80FF00FF"
android:angle="45"/>
- &lt;padding android:left="7dp"
+ &lt;padding android:left="7dp"
android:top="7dp"
- android:right="7dp"
+ android:right="7dp"
android:bottom="7dp" />
&lt;corners android:radius="8dp" />
&lt;/shape>
</pre>
- <p>This layout XML will apply the shape drawable to a View:</p>
+
+ <p>This layout XML applies the shape drawable to a View:</p>
<pre>
&lt;TextView
android:background="@drawable/gradient_box"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</pre>
- <p>This application code will get the shape drawable and apply it to a View:</p>
+
+ <p>This application code gets the shape drawable and applies it to a View:</p>
<pre>
Resources res = {@link android.content.Context#getResources()};
Drawable shape = res. {@link android.content.res.Resources#getDrawable(int) getDrawable}(R.drawable.gradient_box);
@@ -695,6 +1700,14 @@ tv.setBackground(shape);
</pre>
</dd> <!-- end example -->
+<dt>see also:</dt>
+
+<dd>
+<ul>
+ <li>{@link android.graphics.drawable.ShapeDrawable}</li>
+</ul>
+</dd>
+
</dl>
diff --git a/docs/html/guide/topics/resources/layout-resource.jd b/docs/html/guide/topics/resources/layout-resource.jd
index 0688a18..36369d3 100644
--- a/docs/html/guide/topics/resources/layout-resource.jd
+++ b/docs/html/guide/topics/resources/layout-resource.jd
@@ -35,12 +35,12 @@ In XML: <code>@[<em>package</em>:]layout/<em>filename</em></code>
<pre class="stx">
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;<a href="#viewgroup-element"><em>ViewGroup</em></a> xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/<em>name</em>"
+ android:id="@[+][<em>package</em>:]id/<em>resource_name</em>"
android:layout_height=["<em>dimension</em>" | "fill_parent" | "wrap_content"]
android:layout_width=["<em>dimension</em>" | "fill_parent" | "wrap_content"]
[<em>ViewGroup-specific attributes</em>] &gt;
&lt;<a href="#view-element"><em>View</em></a>
- android:id="@+id/<em>name</em>"
+ android:id="@[+][<em>package</em>:]id/<em>resource_name</em>"
android:layout_height=["<em>dimension</em>" | "fill_parent" | "wrap_content"]
android:layout_width=["<em>dimension</em>" | "fill_parent" | "wrap_content"]
[<em>View-specific attributes</em>] &gt;
@@ -49,10 +49,12 @@ In XML: <code>@[<em>package</em>:]layout/<em>filename</em></code>
&lt;<a href="#viewgroup-element"><em>ViewGroup</em></a> &gt;
&lt;<a href="#view-element"><em>View</em></a> /&gt;
&lt;/<em>ViewGroup</em>&gt;
+ &lt;<a href="#include-element">include</a> layout="@layout/<i>layout_resource</i>"/&gt;
&lt;/<em>ViewGroup</em>&gt;
</pre>
<p class="note"><strong>Note:</strong> The root element can be either a
-{@link android.view.ViewGroup} or a {@link android.view.View}, but there must be only
+{@link android.view.ViewGroup}, a {@link android.view.View}, or a <a
+href="#merge-element">{@code &lt;merge&gt;}</a> element, but there must be only
one root element and it must contain the {@code xmlns:android} attribute with the {@code android}
namespace as shown.</p>
</dd>
@@ -74,10 +76,9 @@ namespace as shown.</p>
<p class="caps">attributes:</p>
<dl class="atn-list">
<dt><code>android:id</code></dt>
- <dd><em>Resource name</em>. A unique resource name for the element, which you can
-use to obtain a reference to the {@link android.view.ViewGroup} from your application.
- The value takes the form: <code>"@+id/<em>name</em>"</code>. See more about the
- <a href="#idvalue">value for {@code android:id}</a> below.
+ <dd><em>Resource ID</em>. A unique resource name for the element, which you can
+use to obtain a reference to the {@link android.view.ViewGroup} from your application. See more
+about the <a href="#idvalue">value for {@code android:id}</a> below.
</dd>
<dt><code>android:layout_height</code></dt>
<dd><em>Dimension or keyword</em>. <strong>Required</strong>. The height for the group, as a
@@ -107,10 +108,9 @@ attributes</a>).</p>
<p class="caps">attributes:</p>
<dl class="atn-list">
<dt><code>android:id</code></dt>
- <dd><em>Resource name</em>. A unique resource name for the element, which you can use to
- obtain a reference to the {@link android.view.View} from your application.
- The value takes the form: <code>"@+id/<em>name</em>"</code>. See more about the
- <a href="#idvalue">value for {@code android:id}</a> below.
+ <dd><em>Resource ID</em>. A unique resource name for the element, which you can use to
+ obtain a reference to the {@link android.view.View} from your application. See more about
+the <a href="#idvalue">value for {@code android:id}</a> below.
</dd>
<dt><code>android:layout_height</code></dt>
<dd><em>Dimension or keyword</em>. <strong>Required</strong>. The height for the element, as
@@ -137,20 +137,77 @@ or {@code "wrap_content"}). See the <a href="#layoutvalues">valid values</a> bel
which gives it's parent initial focus on the screen. You can have only one of these
elements per file.</dd>
+ <dt id="include-element"><code>&lt;include&gt;</code></dt>
+ <dd>Includes a layout file into this layout.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>layout</code></dt>
+ <dd><em>Layout resource</em>. <strong>Required</strong>. Reference to a layout
+resource.</dd>
+ <dt><code>android:id</code></dt>
+ <dd><em>Resource ID</em>. Overrides the ID given to the root view in the included layout.
+ </dd>
+ <dt><code>android:layout_height</code></dt>
+ <dd><em>Dimension or keyword</em>. Overrides the height given to the root view in the
+included layout. Only effective if <code>android:layout_width</code> is also declared.
+ </dd>
+ <dt><code>android:layout_width</code></dt>
+ <dd><em>Dimension or keyword</em>. Overrides the width given to the root view in the
+included layout. Only effective if <code>android:layout_height</code> is also declared.
+ </dd>
+ </dl>
+ <p>You can include any other layout attributes in the <code>&lt;include&gt;</code> that are
+supported by the root element in the included layout and they will override those defined in the
+root element.</p>
+
+ <p class="caution"><strong>Caution:</strong> If you want to override the layout dimensions,
+you must override both <code>android:layout_height</code> and
+<code>android:layout_width</code>&mdash;you cannot override only the height or only the width.
+If you override only one, it will not take effect. (Other layout properties, such as weight,
+are still inherited from the source layout.)</p>
+
+ <p>Another way to include a layout is to use {@link android.view.ViewStub}. It is a lightweight
+View that consumes no layout space until you explicitly inflate it, at which point, it includes a
+layout file defined by its {@code android:layout} attribute. For more information about using {@link
+android.view.ViewStub}, read <a href="{@docRoot}resources/articles/layout-tricks-stubs.html">Layout
+Tricks: ViewStubs</a>.</p>
+ </dd>
+
+ <dt id="merge-element"><code>&lt;merge&gt;</code></dt>
+ <dd>An alternative root element that is not drawn in the layout hierarchy. Using this as the
+root element is useful when you know that this layout will be placed into a layout
+that already contains the appropriate parent View to contain the children of the
+<code>&lt;merge&gt;</code> element. This is particularly useful when you plan to include this layout
+in another layout file using <a href="#include-element"><code>&lt;include&gt;</code></a> and
+this layout doesn't require a different {@link android.view.ViewGroup} container. For more
+information about merging layouts, read <a
+href="{@docRoot}resources/articles/layout-tricks-merging.html">Layout
+Tricks: Merging</a>.</dd>
+
</dl>
+
+
<h4 id="idvalue">Value for <code>android:id</code></h4>
-<p>For the ID value, you should use this syntax form: <code>"@+id/<em>name</em>"</code>. The plus symbol,
-{@code +}, indicates that this is a new resource ID and the aapt tool will create
-a new resource number to the {@code R.java} class, if it doesn't already exist. For example:</p>
+<p>For the ID value, you should usually use this syntax form: <code>"@+id/<em>name</em>"</code>. The
+plus symbol, {@code +}, indicates that this is a new resource ID and the <code>aapt</code> tool will
+create a new resource integer in the {@code R.java} class, if it doesn't already exist. For
+example:</p>
<pre>
&lt;TextView android:id="@+id/nameTextbox"/>
</pre>
-<p>You can then refer to it this way in Java:</p>
+<p>The <code>nameTextbox</code> name is now a resource ID attached to this element. You can then
+refer to the {@link android.widget.TextView} to which the ID is associated in Java:</p>
<pre>
findViewById(R.id.nameTextbox);
</pre>
+<p>This code returns the {@link android.widget.TextView} object.</p>
+
+<p>However, if you have already defined an <a
+href="{@docRoot}guide/topics/resources/drawable-resource.html#Id">ID resource</a> (and it is not
+already used), then you can apply that ID to a {@link android.view.View} element by excluding the
+plus symbol in the <code>android:id</code> value.</p>
<h4 id="layoutvalues">Value for <code>android:layout_height</code> and
<code>android:layout_width</code>:</h4>
diff --git a/docs/html/guide/topics/resources/localization.jd b/docs/html/guide/topics/resources/localization.jd
index 3d630c9..36e12f6 100755
--- a/docs/html/guide/topics/resources/localization.jd
+++ b/docs/html/guide/topics/resources/localization.jd
@@ -433,12 +433,12 @@ Menu &gt; Settings &gt; Locale &amp; text &gt; Select locale). </p>
href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a>.</p>
<h4>Creating and using a custom locale</h4>
-<p>A &quot;custom&quot; locale is a language/region combination that the
-Android system image does not explicitly support. (For a list of supported
-locales, see the <a href="{@docRoot}sdk/android-{@sdkCurrentVersion}.html">Android
-Version Notes</a>.) You can test how your application will run in a custom
-locale by creating a custom locale in the emulator. There are two ways to do
-this:</p>
+<p>A &quot;custom&quot; locale is a language/region combination that the Android
+system image does not explicitly support. (For a list of supported locales in
+Android platforms see the Version Notes in the <a
+href="{@docRoot}sdk/index.html">SDK</a> tab). You can test
+how your application will run in a custom locale by creating a custom locale in
+the emulator. There are two ways to do this:</p>
<ul>
<li>Use the Custom Locale application, which is accessible from the
diff --git a/docs/html/guide/topics/resources/menu-resource.jd b/docs/html/guide/topics/resources/menu-resource.jd
index badc403..cde72bd 100644
--- a/docs/html/guide/topics/resources/menu-resource.jd
+++ b/docs/html/guide/topics/resources/menu-resource.jd
@@ -35,7 +35,7 @@ In XML: <code>@[<em>package</em>:]menu.<em>filename</em></code>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;<a href="#menu-element">menu</a> xmlns:android="http://schemas.android.com/apk/res/android">
- &lt;<a href="#item-element">item</a> android:id="@+id/<em>id_name</em>"
+ &lt;<a href="#item-element">item</a> android:id="@[+][<em>package</em>:]id/<em>resource_name</em>"
android:menuCategory=["container" | "system" | "secondary" | "alternative"]
android:orderInCategory="<em>integer</em>"
android:title="<em>string</em>"
@@ -46,7 +46,7 @@ In XML: <code>@[<em>package</em>:]menu.<em>filename</em></code>
android:checkable=["true" | "false"]
android:visible=["visible" | "invisible" | "gone"]
android:enabled=["enabled" | "disabled"] /&gt;
- &lt;<a href="#group-element">group</a> android:id="<em>resource ID</em>"
+ &lt;<a href="#group-element">group</a> android:id="@[+][<em>package</em>:]id/<em>resource name</em>"
android:menuCategory=["container" | "system" | "secondary" | "alternative"]
android:orderInCategory="<em>integer</em>"
android:checkableBehavior=["none" | "all" | "single"]
@@ -84,8 +84,8 @@ child of a <code>&lt;menu&gt;</code> element.
<p class="caps">attributes:</p>
<dl class="atn-list">
<dt><code>android:id</code></dt>
- <dd><em>Resource name</em>. A unique resource name. The value takes the form:
-<code>"@+id/<em>name</em>"</code>.</dd>
+ <dd><em>Resource ID</em>. A unique resource ID. To create a new resource ID for this item, use the form:
+<code>"@+id/<em>name</em>"</code>. The plus symbol indicates that this should be created as a new ID.</dd>
<dt><code>android:menuCategory</code></dt>
<dd><em>Keyword</em>. Value corresponding to {@link android.view.Menu} {@code CATEGORY_*}
constants, which define the group's priority. Valid values:
@@ -124,8 +124,8 @@ on the data that is currently displayed.</td></tr>
<p class="caps">attributes:</p>
<dl class="atn-list">
<dt><code>android:id</code></dt>
- <dd><em>Resource name</em>. A unique resource name. The value takes the form:
-<code>"@+id/<em>name</em>"</code>.</dd>
+ <dd><em>Resource ID</em>. A unique resource ID. To create a new resource ID for this item, use the form:
+<code>"@+id/<em>name</em>"</code>. The plus symbol indicates that this should be created as a new ID.</dd>
<dt><code>android:menuCategory</code></dt>
<dd><em>Keyword</em>. Value corresponding to {@link android.view.Menu} {@code CATEGORY_*}
constants, which define the item's priority. Valid values:
diff --git a/docs/html/guide/topics/resources/more-resources.jd b/docs/html/guide/topics/resources/more-resources.jd
index 0e2b30b..6cae1eb 100644
--- a/docs/html/guide/topics/resources/more-resources.jd
+++ b/docs/html/guide/topics/resources/more-resources.jd
@@ -12,6 +12,9 @@ parent.link=available-resources.html
<dd>XML resource that carries a color value (a hexadecimal color).</dd>
<dt><a href="#Dimension">Dimension</a></dt>
<dd>XML resource that carries a dimension value (with a unit of measure).</dd>
+ <dt><a href="#Id">ID</a></dt>
+ <dd>XML resource that provides a unique identifier for application resources and
+components.</dd>
<dt><a href="#Integer">Integer</a></dt>
<dd>XML resource that carries an integer value.</dd>
<dt><a href="#IntegerArray">Integer Array</a></dt>
@@ -111,8 +114,9 @@ boolean screenIsSmall = res.{@link android.content.res.Resources#getBoolean(int)
<h2 id="Color">Color</h2>
<p>A color value defined in XML.
-The color is specified with an RGB value and alpha channel. A color resource can be used
-any place that expects a hexadecimal color value.</p>
+The color is specified with an RGB value and alpha channel. You can use a color resource
+any place that accepts a hexadecimal color value. You can also use a color resource when a
+drawable resource is expected in XML (for example, {@code android:drawable="@color/green"}).</p>
<p>The value always begins with a pound (#) character and then followed by the
Alpha-Red-Green-Blue information in one of the following formats:</p>
@@ -212,10 +216,13 @@ is specified with a number followed by a unit of measure.
For example: 10px, 2in, 5sp. The following units of measure are supported by Android:</p>
<dl>
<dt>{@code dp}</dt>
- <dd>Density-independent Pixels - an abstract unit that is based on the physical density of the screen.
- These units are relative to a 160 dpi screen, so one dp is one pixel on a 160 dpi screen. The ratio of
- dp-to-pixel will change with the screen density, but not necessarily in direct proportion. The
- compiler accepts both "dip" and "dp", though "dp" is more consistent with "sp".</dd>
+ <dd>Density-independent Pixels - an abstract unit that is based on the physical density of the
+screen. These units are relative to a 160 dpi (dots per inch) screen, so <em>{@code 160dp} is
+always one inch</em> regardless of the screen density. The ratio of dp-to-pixel will change with the
+screen density, but not necessarily in direct proportion. You should use these units when specifying
+view dimensions in your layout, so the UI properly scales to render at the same actual size on
+different screens. (The compiler accepts both "dip" and "dp", though "dp" is more consistent with
+"sp".)</dd>
<dt>{@code sp}</dt>
<dd>Scale-independent Pixels - this is like the dp unit, but it is also scaled by the user's font
size preference. It is recommend you use this unit when specifying font sizes, so they will be adjusted
@@ -306,7 +313,7 @@ float fontSize = res.{@link android.content.res.Resources#getDimension(int) getD
&lt;TextView
android:layout_height="@dimen/textview_height"
android:layout_width="@dimen/textview_width"
- android:textSize="@dimen/sixteen_sp"/>
+ android:textSize="@dimen/font_size"/>
</pre>
</dl>
</dd> <!-- end example -->
@@ -318,6 +325,118 @@ float fontSize = res.{@link android.content.res.Resources#getDimension(int) getD
+<h2 id="Id">ID</h2>
+
+<p>A unique resource ID defined in XML. Using the name you provide in the {@code &lt;item&gt;}
+element, the Android developer tools create a unique integer in your project's {@code
+R.java} class, which you can use as an
+identifier for an application resources (for example, a {@link android.view.View} in your UI layout)
+or a unique integer for use in your application code (for example, as an ID for a dialog or a
+result code).</p>
+
+<p class="note"><strong>Note:</strong> An ID is a simple resource that is referenced
+using the value provided in the {@code name} attribute (not the name of the XML file). As
+such, you can combine ID resources with other simple resources in the one XML file,
+under one {@code &lt;resources&gt;} element. Also, remember that an ID resources does not reference
+an actual resource item; it is simply a unique ID that you can attach to other resources or use
+as a unique integer in your application.</p>
+
+<dl class="xml">
+
+<dt>file location:</dt>
+<dd><code>res/values/<em>filename.xml</em></code><br/>
+The filename is arbitrary.</dd>
+
+<dt>resource reference:</dt>
+<dd>
+In Java: <code>R.id.<em>name</em></code><br/>
+In XML: <code>@[<em>package</em>:]id/<em>name</em></code>
+</dd>
+
+<dt>syntax:</dt>
+<dd>
+<pre class="stx">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;<a href="#id-resources-element">resources</a>&gt;
+ &lt;<a href="#id-item-element">item</a>
+ type="id"
+ name="<em>id_name</em>" /&gt;
+&lt;/resources&gt;
+</pre>
+</dd>
+
+<dt>elements:</dt>
+<dd>
+<dl class="tag-list">
+
+ <dt id="integer-resources-element"><code>&lt;resources&gt;</code></dt>
+ <dd><strong>Required.</strong> This must be the root node.
+ <p>No attributes.</p>
+ </dd>
+ <dt id="integer-element"><code>&lt;integer&gt;</code></dt>
+ <dd>Defines a unique ID. Takes no value, only attributes.
+ <p class="caps">attributes:</p>
+ <dl class="atn-list">
+ <dt><code>type</code></dt>
+ <dd>Must be "id".</dd>
+ <dt><code>name</code></dt>
+ <dd><em>String</em>. A unique name for the ID.</dd>
+ </dl>
+ </dd>
+
+</dl>
+</dd> <!-- end elements and attributes -->
+
+<dt>example:</dt>
+<dd>
+ <p>XML file saved at <code>res/values/ids.xml</code>:</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;item type="id" name="button_ok" /&gt;
+ &lt;item type="id" name="dialog_exit" /&gt;
+&lt;/resources>
+</pre>
+
+ <p>Then, this layout snippet uses the "button_ok" ID for a Button widget:</p>
+<pre>
+&lt;Button android:id="<b>@id/button_ok</b>"
+ style="@style/button_style" /&gt;
+</pre>
+
+ <p>Notice that the {@code android:id} value does not include the plus sign in the ID reference,
+because the ID already exists, as defined in the {@code ids.xml} example above. (When you specify an
+ID to an XML resource using the plus sign&mdash;in the format {@code
+android:id="@+id/name"}&mdash;it means that the "name" ID does not exist and should be created.)</p>
+
+ <p>As another example, the following code snippet uses the "dialog_exit" ID as a unique identifier
+for a dialog:</p>
+<pre>
+{@link android.app.Activity#showDialog(int) showDialog}(<b>R.id.dialog_exit</b>);
+</pre>
+ <p>In the same application, the "dialog_exit" ID is compared when creating a dialog:</p>
+<pre>
+protected Dialog {@link android.app.Activity#onCreateDialog(int)}(int id) {
+ Dialog dialog;
+ switch(id) {
+ case <b>R.id.dialog_exit</b>:
+ ...
+ break;
+ default:
+ dialog = null;
+ }
+ return dialog;
+}
+</pre>
+</dd> <!-- end example -->
+
+
+</dl>
+
+
+
+
+
<h2 id="Integer">Integer</h2>
<p>An integer defined in XML.</p>
@@ -347,7 +466,7 @@ In XML: <code>@[<em>package</em>:]integer/<em>integer_name</em></code>
&lt;<a href="#integer-resources-element">resources</a>>
&lt;<a href="#integer-element">integer</a>
name="<em>integer_name</em>"
- &gt;<em>integer</em>&lt;/dimen&gt;
+ &gt;<em>integer</em>&lt;/integer&gt;
&lt;/resources&gt;
</pre>
</dd>
@@ -379,8 +498,8 @@ In XML: <code>@[<em>package</em>:]integer/<em>integer_name</em></code>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;resources>
- &lt;integer name="max_speed">75&lt;/dimen>
- &lt;integer name="min_speed">5&lt;/dimen>
+ &lt;integer name="max_speed">75&lt;/integer>
+ &lt;integer name="min_speed">5&lt;/integer>
&lt;/resources>
</pre>
<p>This application code retrieves an integer:</p>
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index cac85e8..4f3b0da 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -129,9 +129,8 @@ Menu. See <a href="menu-resource.html">Menu Resource</a>.</td>
<tr>
<td><code>raw/</code></td>
- <td><p>Arbitrary files to save in their raw form. Files in here are not compressed by the
-system. To open these resources with a raw {@link java.io.InputStream}, call {@link
-android.content.res.Resources#openRawResource(int)
+ <td><p>Arbitrary files to save in their raw form. To open these resources with a raw
+{@link java.io.InputStream}, call {@link android.content.res.Resources#openRawResource(int)
Resources.openRawResource()} with the resource ID, which is {@code R.raw.<em>filename</em>}.</p>
<p>However, if you need access to original file names and file hierarchy, you might consider
saving some resources in the {@code
@@ -330,7 +329,8 @@ indicates the current locale.</p>
<td>
<code>small</code><br/>
<code>normal</code><br/>
- <code>large</code>
+ <code>large</code><br/>
+ <code>xlarge</code>
</td>
<td>
<ul class="nolist">
@@ -348,6 +348,10 @@ indicates the current locale.</p>
medium-density VGA screen. Such a screen has significantly more
available space in both width and height than an HVGA display.
Examples are VGA and WVGA medium density screens.</li>
+ <li>{@code xlarge}: Screens that are considerably larger than the traditional
+ medium-density HVGA screen. In most cases, devices with extra large screens would be too
+large to carry in a pocket and would most likely be tablet-style devices. <em>Added in API Level
+9.</em></li>
</ul>
<p><em>Added in API Level 4.</em></p>
<p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
@@ -438,6 +442,7 @@ application during runtime.</p>
<code>ldpi</code><br/>
<code>mdpi</code><br/>
<code>hdpi</code><br/>
+ <code>xhdpi</code><br/>
<code>nodpi</code>
</td>
<td>
@@ -446,12 +451,14 @@ application during runtime.</p>
<li>{@code mdpi}: Medium-density (on traditional HVGA) screens; approximately
160dpi.</li>
<li>{@code hdpi}: High-density screens; approximately 240dpi.</li>
+ <li>{@code xhdpi}: Extra high-density screens; approximately 320dpi. <em>Added in API
+Level 8</em></li>
<li>{@code nodpi}: This can be used for bitmap resources that you do not want to be scaled
to match the device density.</li>
</ul>
<p><em>Added in API Level 4.</em></p>
- <p>There is thus a 4:3 scaling factor between each density, so a 9x9 bitmap
- in ldpi is 12x12 in mdpi and 16x16 in hdpi.</p>
+ <p>There is thus a 3:4:6 scaling ratio between the three densities, so a 9x9 bitmap
+ in ldpi is 12x12 in mdpi and 18x18 in hdpi.</p>
<p>When Android selects which resource files to use,
it handles screen density differently than the other qualifiers.
In step 1 of <a href="#BestMatch">How Android finds the best
@@ -761,7 +768,7 @@ Android runs your application, it will crash if you do not provide default resou
cannot use the resources named with the new qualifier. For example, if your <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
minSdkVersion}</a> is set to 4, and you qualify all of your drawable resources using <a
-href="NightQualifier">night mode</a> ({@code night} or {@code notnight}, which were added in API
+href="#NightQualifier">night mode</a> ({@code night} or {@code notnight}, which were added in API
Level 8), then an API Level 4 device cannot access your drawable resources and will crash. In this
case, you probably want {@code notnight} to be your default resources, so you should exclude that
qualifier so your drawable resources are in either {@code drawable/} or {@code drawable-night/}.</p>
@@ -895,7 +902,7 @@ drawable-port-ldpi/
drawable-port-notouch-12key/
</pre>
<p class="note"><strong>Exception:</strong> Screen pixel density is the one qualifier that is not
-eliminated due to a contradiction. Even though the screen density of the device is mdpi,
+eliminated due to a contradiction. Even though the screen density of the device is hdpi,
<code>drawable-port-ldpi/</code> is not eliminated because every screen density is
considered to be a match at this point. More information is available in the <a
href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
@@ -922,9 +929,8 @@ drawable-en-notouch-12key/
<strike>drawable-port-notouch-12key/</strike>
</pre>
<p class="note"><strong>Exception:</strong> If the qualifier in question is screen pixel density,
-Android
-selects the option that most closely matches the device, and the selection process is complete.
-In general, Android prefers scaling down a larger original image to scaling up a smaller
+Android selects the option that most closely matches the device screen density.
+In general, Android prefers scaling down a larger original image to scaling up a smaller
original image. See <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
Screens</a>.</p>
</li>
diff --git a/docs/html/guide/topics/search/adding-custom-suggestions.jd b/docs/html/guide/topics/search/adding-custom-suggestions.jd
index 9ea4c8b..c8f06b9 100644
--- a/docs/html/guide/topics/search/adding-custom-suggestions.jd
+++ b/docs/html/guide/topics/search/adding-custom-suggestions.jd
@@ -5,74 +5,88 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.app.SearchManager}</li>
-<li>{@link android.content.SearchRecentSuggestionsProvider}</li>
-<li>{@link android.content.ContentProvider}</li>
-</ol>
<h2>In this document</h2>
<ol>
<li><a href="#TheBasics">The Basics</a></li>
-<li><a href="#CustomSearchableConfiguration">Modifying the searchable configuration</a></li>
+<li><a href="#CustomSearchableConfiguration">Modifying the Searchable Configuration</a></li>
<li><a href="#CustomContentProvider">Creating a Content Provider</a>
<ol>
<li><a href="#HandlingSuggestionQuery">Handling a suggestion query</a></li>
<li><a href="#SuggestionTable">Building a suggestion table</a></li>
</ol>
</li>
-<li><a href="#IntentForSuggestions">Declaring an Intent for suggestions</a>
+<li><a href="#IntentForSuggestions">Declaring an Intent for Suggestions</a>
<ol>
<li><a href="#IntentAction">Declaring the Intent action</a></li>
<li><a href="#IntentData">Declaring the Intent data</a></li>
</ol>
</li>
<li><a href="#HandlingIntent">Handling the Intent</a></li>
-<li><a href="#RewritingQueryText">Rewriting the query text</a></li>
-<li><a href="#QSB">Exposing search suggestions to Quick Search Box</a></li>
+<li><a href="#RewritingQueryText">Rewriting the Query Text</a></li>
+<li><a href="#QSB">Exposing Search Suggestions to Quick Search Box</a></li>
+</ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.app.SearchManager}</li>
+<li>{@link android.content.SearchRecentSuggestionsProvider}</li>
+<li>{@link android.content.ContentProvider}</li>
+</ol>
+
+<h2>Related samples</h2>
+<ol>
+<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable
+Dictionary</a></li>
</ol>
+
<h2>See also</h2>
<ol>
<li><a href="searchable-config.html">Searchable Configuration</a></li>
<li><a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></li>
-<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable
-Dictionary sample app</a></li>
</ol>
</div>
</div>
-<p>The Android search framework provides the ability for your application to
-provide suggestions while the user types into the Android search dialog. In this guide, you'll learn
-how to create custom suggestions. These are suggestions based on custom data provided by your
-application. For example, if your application is a word dictionary, you can suggest words from the
-dictionary that match the text entered so far. These are the most valuable suggestions because you
-can effectively predict what the user wants and provide instant access to it. Once you provide
-custom suggestions, you then make them available to the system-wide Quick Search Box, providing
-access to your content from outside your application.</p>
-
-<p>Before you begin, you need to have implemented the Android search dialog for searches in your
-application. If you haven't done this, see <a href="search-dialog.html">Using the Android Search
+<p>When using the Android search dialog, you can provide custom search suggestions that are
+created from data in your application. For example, if your application is a word
+dictionary, you can suggest words from the
+dictionary that match the text entered so far. These are the most valuable suggestions, because you
+can effectively predict what the user wants and provide instant access to it. Figure 1 shows
+an example of a search dialog with custom suggestions.</p>
+
+<p>Once you provide custom suggestions, you can also make them available to the system-wide Quick
+Search Box, providing access to your content from outside your application.</p>
+
+<p>Before you begin with this guide to add custom suggestions, you need to have implemented the
+Android search dialog for searches in your
+application. If you haven't, see <a href="search-dialog.html">Using the Android Search
Dialog</a>.</p>
<h2 id="TheBasics">The Basics</h2>
-<img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417"
-style="float:right;clear:right;" />
+<div class="figure" style="width:250px">
+<img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417" />
+<p class="img-caption"><strong>Figure 1.</strong> Screenshot of a search dialog with custom
+search suggestions.</p>
+</div>
-<p>When the user selects a custom suggestions, the Search Manager will send a customized Intent to
-your searchable Activity. Whereas a normal search query will send an Intent with the {@link
+<p>When the user selects a custom suggestion, the Search Manager sends an {@link
+android.content.Intent} to
+your searchable Activity. Whereas a normal search query sends an Intent with the {@link
android.content.Intent#ACTION_SEARCH} action, you can instead define your custom suggestions to use
-{@link android.content.Intent#ACTION_VIEW} (or any other action), and also include additional data
+{@link android.content.Intent#ACTION_VIEW} (or any other Intent action), and also include data
that's relevant to the selected suggestion. Continuing
the dictionary example, when the user selects a suggestion, your application can immediately
open the definition for that word, instead of searching the dictionary for matches.</p>
-<p>To provide custom suggestions, you need to do the following:</p>
+<p>To provide custom suggestions, do the following:</p>
<ul>
<li>Implement a basic searchable Activity, as described in <a
href="search-dialog.html">Using the Android Search Dialog</a>.</li>
+ <li>Modify the searchable configuration with information about the content provider that
+provides custom suggestions.</li>
<li>Build a table (such as in an {@link android.database.sqlite.SQLiteDatabase}) for your
suggestions and format the table with required columns.</li>
<li>Create a <a href="{@docRoot}guide/topics/providers/content-providers.html">Content
@@ -80,36 +94,32 @@ Provider</a> that has access to your suggestions table and declare the provider
in your manifest.</li>
<li>Declare the type of {@link android.content.Intent} to be sent when the user selects a
suggestion (including a custom action and custom data). </li>
- <li>Modify the searchable configuration with information about the content provider.</li>
</ul>
-<p>Just like the Search Manager handles the rendering of the search dialog, it will also do the work
-to display all search suggestions below the search dialog. All you need to do is provide a source
-from which the suggestions can be retrieved.</p>
-
-<p class="note"><strong>Note:</strong> If you're not familiar with creating Content
-Providers, please read the <a href="{@docRoot}guide/topics/providers/content-providers.html">Content
+<p>Just like the Search Manager displays the search dialog, it also displays your search
+suggestions. All you need is a content provider from which the Search Manager can retrieve your
+suggestions. If you're not familiar with creating content
+providers, read the <a href="{@docRoot}guide/topics/providers/content-providers.html">Content
Providers</a> developer guide before you continue.</p>
-<p>When the Search Manager identifies that your Activity is searchable and also provides search
-suggestions, the following procedure will take place as soon as the user types into the Android
-search box:</p>
+<p>When the Search Manager identifies that your Activity is searchable and provides search
+suggestions, the following procedure takes place as soon as the user enters text into the
+search dialog:</p>
-<ul>
- <li>The Search Manager takes the search query text (whatever has been typed so far) and performs a
-query to the content provider that manages your suggestions.</li>
- <li>Your content provider then returns a {@link android.database.Cursor} that points to all
+<ol>
+ <li>Search Manager takes the search query text (whatever has been typed so far) and performs a
+query to your content provider that manages your suggestions.</li>
+ <li>Your content provider returns a {@link android.database.Cursor} that points to all
suggestions that are relevant to the search query text.</li>
- <li>The Search Manager then displays the list of suggestions provided by the Cursor (as
-demonstrated in the screenshot to the right).</li>
-</ul>
+ <li>Search Manager displays the list of suggestions provided by the Cursor.</li>
+</ol>
-<p>At this point, the following may happen:</p>
+<p>Once the custom suggestions are displayed, the following might happen:</p>
<ul>
<li>If the user types another key, or changes the query in any way, the above steps are repeated
and the suggestion list is updated as appropriate. </li>
- <li>If the user executes the search, the suggestions are ignored and the search is delivered
+ <li>If the user executes the search, the suggestions are ignored and the search is delivered
to your searchable Activity using the normal {@link android.content.Intent#ACTION_SEARCH}
Intent.</li>
<li>If the user selects a suggestion, an Intent is sent to your searchable Activity, carrying a
@@ -124,56 +134,64 @@ custom action and custom data so that your application can open the suggested co
to the {@code &lt;searchable&gt;} element in your searchable configuration file. For example:</p>
<pre>
-&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_label"
android:hint="@string/search_hint"
- android:searchSuggestAuthority="my.package.MyCustomSuggestionProvider" >
-&lt;/searchable>
+ <b>android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"</b>&gt;
+&lt;/searchable&gt;
</pre>
-<p>You may require some additional attributes, depending on the type of Intent you attach
+<p>You might need some additional attributes, depending on the type of Intent you attach
to each suggestion and how you want to format queries to your content provider. The other optional
-attributes are discussed in the relevant sections below.</p>
+attributes are discussed in the following sections.</p>
+
<h2 id="CustomContentProvider">Creating a Content Provider</h2>
-<p>Creating a content provider for custom suggestions requires previous knowledge about Content
-Providers that's covered in the <a
+<p>Creating a content provider for custom suggestions requires previous knowledge about content
+providers that's covered in the <a
href="{@docRoot}guide/topics/providers/content-providers.html">Content Provider</a> developer
guide. For the most part, a content provider for custom suggestions is the
same as any other content provider. However, for each suggestion you provide, the respective row in
the {@link android.database.Cursor} must include specific columns that the Search Manager
-understands.</p>
+understands and uses to format the suggestions.</p>
-<p>When the user starts typing into the search dialog, the Search Manager will query your Content
-Provider for suggestions by calling {@link
+<p>When the user starts typing into the search dialog, the Search Manager queries your content
+provider for suggestions by calling {@link
android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} each time
a letter is typed. In your implementation of {@link
android.content.ContentProvider#query(Uri,String[],String,String[],String) query()}, your
content provider must search your suggestion data and return a {@link
-android.database.Cursor} that points to the rows you determine to be good suggestions.</p>
+android.database.Cursor} that points to the rows you have determined to be good suggestions.</p>
-<p>The following two sections describe how the Search Manager will send requests to your Content
-Provider and how you can handle them, and define the columns that the Search Manager understands and
-expects to be provided in the {@link android.database.Cursor} returned with each query.</p>
+<p>Details about creating a content provider for custom suggestions are discussed in the following
+two sections:</p>
+<dl>
+ <dt><a href="#HandlingSuggestionQuery">Handling the suggestion query</a></dt>
+ <dd>How the Search Manager sends requests to your content provider and how to handle them</dd>
+ <dt><a href="#SuggestionTable">Building a suggestion table</a></dt>
+ <dd>How to define the columns that the Search Manager expects in the {@link
+android.database.Cursor} returned with each query</dd>
+</dl>
<h3 id="HandlingSuggestionQuery">Handling the suggestion query</h3>
-<p>When the Search Manager makes a request for suggestions from your content provider, it will call
-{@link android.content.ContentProvider#query(Uri,String[],String,String[],String)}. You must
-implement this method in your content provider so that it will search your suggestions and return a
-Cursor that contains the suggestions you deem relevant.</p>
+<p>When the Search Manager requests suggestions from your content provider, it calls your content
+provider's {@link android.content.ContentProvider#query(Uri,String[],String,String[],String)
+query()} method. You must
+implement this method to search your suggestion data and return a
+{@link android.database.Cursor} pointing to the suggestions you deem relevant.</p>
-<p>Here's a summary of the parameters that the Search Manager will pass to your {@link
+<p>Here's a summary of the parameters that the Search Manager passes to your {@link
android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} method
(listed in order):</p>
<dl>
<dt><code>uri</code></dt>
- <dd>This will always be a content {@link android.net.Uri}, formatted as:
+ <dd>Always a content {@link android.net.Uri}, formatted as:
<pre class="no-pretty-print">
content://<em>your.authority</em>/<em>optional.suggest.path</em>/<em>{@link
android.app.SearchManager#SUGGEST_URI_PATH_QUERY}</em>
@@ -184,46 +202,48 @@ For example:</p>
content://<em>your.authority</em>/<em>optional.suggest.path</em>/<em>{@link
android.app.SearchManager#SUGGEST_URI_PATH_QUERY}</em>/puppies
</pre>
-<p>The query text on the end will be encoded using URI encoding rules, so you may need to decode
-it.</p>
+<p>The query text on the end is encoded using URI encoding rules, so you might need to decode
+it before performing a search.</p>
<p>The <em>{@code optional.suggest.path}</em> portion is only included in the URI if you have set
such a path in your searchable configuration file with the {@code android:searchSuggestPath}
attribute. This is only needed if you use the same content provider for multiple searchable
-activities, in which case you need to disambiguate the source of the suggestion query.</p>
-<p>Note that {@link android.app.SearchManager#SUGGEST_URI_PATH_QUERY} is not the literal
+activities, in which case, you need to disambiguate the source of the suggestion query.</p>
+<p class="note"><strong>Note:</strong> {@link
+android.app.SearchManager#SUGGEST_URI_PATH_QUERY} is not the literal
string provided in the URI, but a constant that you should use if you need to refer to this
path.</p>
</dd>
<dt><code>projection</code></dt>
- <dd>This is always null</dd>
+ <dd>Always null</dd>
<dt><code>selection</code></dt>
- <dd>This is the value provided in the {@code android:searchSuggestSelection} attribute of
+ <dd>The value provided in the {@code android:searchSuggestSelection} attribute of
your searchable configuration file, or null if you have not declared the {@code
-android:searchSuggestSelection} attribute. More about this below.</dd>
+android:searchSuggestSelection} attribute. More about using this to <a href="#GetTheQuery">get the
+query</a> below.</dd>
<dt><code>selectionArgs</code></dt>
- <dd>This contains the search query as the first (and only) element of the array if you have
+ <dd>Contains the search query as the first (and only) element of the array if you have
declared the {@code android:searchSuggestSelection} attribute in your searchable configuration. If
you have not declared {@code android:searchSuggestSelection}, then this parameter is null. More
-about this below.</dd>
+about using this to <a href="#GetTheQuery">get the query</a> below.</dd>
<dt><code>sortOrder</code></dt>
- <dd>This is always null</dd>
+ <dd>Always null</dd>
</dl>
-<p>As you may have realized, there are two ways by which the Search Manager can send you the search
-query text. The default manner is for the query text to be included as the last path of the content
-URI that is passed in the {@code uri} parameter. However, if you include a selection value in your
+<p>The Search Manager can send you the search query text in two ways. The
+default manner is for the query text to be included as the last path of the content
+URI passed in the {@code uri} parameter. However, if you include a selection value in your
searchable configuration's {@code
-android:searchSuggestSelection} attribute, then the query text will instead be passed as the first
-element of the {@code selectionArgs} string array. Both options are summarized below.</p>
+android:searchSuggestSelection} attribute, then the query text is instead passed as the first
+element of the {@code selectionArgs} string array. Both options are summarized next.</p>
-<h4>Get the query in the Uri</h4>
+<h4 id="GetTheQueryUri">Get the query in the Uri</h4>
-<p>By default, the query will be appended as the last segment of the {@code uri}
+<p>By default, the query is appended as the last segment of the {@code uri}
parameter (a {@link android.net.Uri} object). To retrieve the query text in this case, simply use
{@link android.net.Uri#getLastPathSegment()}. For example:</p>
@@ -231,52 +251,59 @@ parameter (a {@link android.net.Uri} object). To retrieve the query text in this
String query = uri.getLastPathSegment().toLowerCase();
</pre>
-<p>This will return the last segment of the Uri, which is the query text entered in the search
-dialog.</p>
+<p>This returns the last segment of the {@link android.net.Uri}, which is the query text entered in
+the search dialog.</p>
-<h4>Get the query in the selection arguments</h4>
+<h4 id="GetTheQuery">Get the query in the selection arguments</h4>
-<p>Instead of using the URI, you may decide it makes more sense for your {@link
+<p>Instead of using the URI, you might decide it makes more sense for your {@link
android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} method to
receive everything it needs to perform the look-up and you want the
-{@code selection} and {@code selectionArgs} parameters to carry values. In this case, you can
-add the {@code android:searchSuggestSelection} attribute to your searchable configuration with your
-SQLite selection string. In this selection string, you can include a question mark ("?") as
-a placeholder for the actual search query. This selection string will be delivered as the
-{@code selection} string parameter, and the query entered into the search dialog will be delivered
-as the first element in the {@code selectionArgs} string array parameter.</p>
+{@code selection} and {@code selectionArgs} parameters to carry the appropriate values. In such a
+case, add the {@code android:searchSuggestSelection} attribute to your searchable configuration with
+your SQLite selection string. In the selection string, include a question mark ("?") as
+a placeholder for the actual search query. The Search Manager calls {@link
+android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} with the
+selection string as the {@code selection} parameter and the search query as the first
+element in the {@code selectionArgs} array.</p>
<p>For example, here's how you might form the {@code android:searchSuggestSelection} attribute to
create a full-text search statement:</p>
<pre>
-&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_label"
android:hint="@string/search_hint"
- android:searchSuggestAuthority="my.package.MyCustomSuggestionProvider"
+ android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"
android:searchSuggestIntentAction="android.Intent.action.VIEW"
- android:searchSuggestSelection="word MATCH ?">
-&lt;/searchable>
+ <b>android:searchSuggestSelection="word MATCH ?"</b>&gt;
+&lt;/searchable&gt;
</pre>
-<p>When you then receive the {@code selection} and {@code selectionArgs} parameters in your {@link
-android.content.ContentProvider#query(Uri,String[],String,String[],String) ContentProvider.query()}
-method, they will carry the selection ("word MATCH ?") and the query text, respectively. When
-these are passed to an SQLite {@link
-android.database.sqlite.SQLiteDatabase#query(String,String[],String,String[],String,String,
-String) query} method, they will be synthesized together (replacing the question mark with the query
-text, wrapped in single-quotes). Note that if you chose this method and need to add any wildcards to
-your query text, you must do so by appending (and/or prefixing) them to the {@code selectionArgs}
-parameter, because this is the value that will be wrapped in quotes and inserted in place of the
+<p>With this configuration, your {@link
+android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} method
+delivers the {@code selection} parameter as "word MATCH ?" and the {@code selectionArgs}
+parameter as whatever the user entered in the search dialog. When you pass these to an SQLite
+{@link android.database.sqlite.SQLiteDatabase#query(String,String[],String,String[],String,String,
+String) query()} method, as their respective arguments, they are synthesized together (the
+question mark is replaced with the query
+text). If you chose to receive suggestion queries this way and need to add wildcards to
+the query text, append (and/or prefix) them to the {@code selectionArgs}
+parameter, because this value is wrapped in quotes and inserted in place of the
question mark.</p>
+<p>Another new attribute in the example above is {@code android:searchSuggestIntentAction}, which
+defines the Intent action sent with each Intent when the user selects a suggestion. It is
+discussed further in the section about <a href="#IntentForSuggestions">Declaring an Intent for
+suggestions</a>.</p>
+
<p class="note"><strong>Tip:</strong> If you don't want to define a selection clause in
the {@code android:searchSuggestSelection} attribute, but would still like to receive the query
text in the {@code selectionArgs} parameter, simply provide a non-null value for the {@code
-android:searchSuggestSelection} attribute. This will trigger the query to be passed in {@code
+android:searchSuggestSelection} attribute. This triggers the query to be passed in {@code
selectionArgs} and you can ignore the {@code selection} parameter. In this way, you can instead
define the actual selection clause at a lower level so that your content provider doesn't have to
handle it.</p>
@@ -287,11 +314,12 @@ handle it.</p>
<div class="sidebox-wrapper">
<div class="sidebox">
-<h2>Creating a Cursor on the fly</h2>
-<p>If your search suggestions are not stored in a table format using the columns required by the
+<h2>Creating a Cursor without a table</h2>
+<p>If your search suggestions are not stored in a table format (such as an SQLite table) using the
+columns required by the
Search Manager, then you can search your suggestion data for matches and then format them
-into the necessary table on the fly. To do so, create a {@link android.database.MatrixCursor} using
-the required column names and then add a row for each suggestion using {@link
+into the necessary table on each request. To do so, create a {@link android.database.MatrixCursor}
+using the required column names and then add a row for each suggestion using {@link
android.database.MatrixCursor#addRow(Object[])}. Return the final product from your Content
Provider's {@link
android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} method.</p>
@@ -299,97 +327,94 @@ android.content.ContentProvider#query(Uri,String[],String,String[],String) query
</div>
<p>When you return suggestions to the Search Manager with a {@link android.database.Cursor}, the
-Search Manager expects there to be specific columns in each row. So, regardless of whether you
+Search Manager expects specific columns in each row. So, regardless of whether you
decide to store
your suggestion data in an SQLite database on the device, a database on a web server, or another
format on the device or web, you must format the suggestions as rows in a table and
-present them with a {@link android.database.Cursor}. There are several columns that the Search
-Manager will understand, but only two are required:</p>
+present them with a {@link android.database.Cursor}. The Search
+Manager understands several columns, but only two are required:</p>
<dl>
<dt>{@link android.provider.BaseColumns#_ID}</dt>
- <dd>This is the unique row ID for each suggestion. The search dialog requires this in order
-to present the suggestions in a ListView.</dd>
+ <dd>A unique integer row ID for each suggestion. The search dialog requires this in order
+to present suggestions in a ListView.</dd>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_TEXT_1}</dt>
- <dd>This is the line of text that will be presented to the user as a suggestion.</dd>
+ <dd>The string that is presented as a suggestion.</dd>
</dl>
-<p>The following columns are all optional (and most will be discussed further in the following
-sections, so you may want to skip this list for now):</p>
+<p>The following columns are all optional (and most are discussed further in the following
+sections):</p>
<dl>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_TEXT_2}</dt>
- <dd>If your Cursor includes this column, then all suggestions will be provided in a two-line
-format. The data in this column will be displayed as a second, smaller line of text below the
+ <dd>A string. If your Cursor includes this column, then all suggestions are provided in a
+two-line format. The string in this column is displayed as a second, smaller line of text below the
primary suggestion text. It can be null or empty to indicate no secondary text.</dd>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_ICON_1}</dt>
- <dd>If your Cursor includes this column, then all suggestions will be provided in an
-icon-plus-text format with the icon on the left side. This value should be a reference to the
-icon. It can be null or zero to indicate no icon in this row.</dd>
+ <dd>A drawable resource, content, or file URI string. If your Cursor includes this column, then
+all suggestions are provided in an icon-plus-text format with the drawable icon on the left side.
+This can be null or zero to indicate no icon in this row.</dd>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_ICON_2}</dt>
- <dd>If your Cursor includes this column, then all suggestions will be provided in an
-icon-plus-text format with the icon on the right side. This value should be a reference to the
-icon. It can be null or zero to indicate no icon in this row.</dd>
+ <dd>A drawable resource, content, or file URI string. If your Cursor includes this column, then
+all suggestions are provided in an icon-plus-text format with the icon on the right side. This can
+be null or zero to indicate no icon in this row.</dd>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION}</dt>
- <dd>If this column exists and this element exists at the given row, this is the action that will
-be used when forming the suggestion's Intent . If the element is not provided, the action will be
-taken from the {@code android:searchSuggestIntentAction} field in your searchable configuration. At
-least one of these
-must be present for the suggestion to generate an Intent. Note: If your action is the same for all
+ <dd>An Intent action string. If this column exists and contains a value at the given row, the
+action defined here is used when forming the suggestion's Intent. If the element is not
+provided, the action is taken from the {@code android:searchSuggestIntentAction} field in your
+searchable configuration. If your action is the same for all
suggestions, it is more efficient to specify the action using {@code
-android:searchSuggestIntentAction} and omit this column from the Cursor .</dd>
+android:searchSuggestIntentAction} and omit this column.</dd>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA}</dt>
- <dd>If this column exists and this element exists at the given row, this is the data that will be
-used when forming the suggestion's Intent. If the element is not provided, the data will be taken
-from the {@code android:searchSuggestIntentData} field in your searchable configuration. If neither
-source is provided,
-the Intent's data field will be null. Note: If your data is the same for all suggestions, or can be
+ <dd>A data URI string. If this column exists and contains a value at the given row, this is the
+data that is used when forming the suggestion's Intent. If the element is not provided, the data is
+taken from the {@code android:searchSuggestIntentData} field in your searchable configuration. If
+neither source is provided,
+the Intent's data field is null. If your data is the same for all suggestions, or can be
described using a constant part and a specific ID, it is more efficient to specify it using {@code
-android:searchSuggestIntentData} and omit this column from the Cursor .
+android:searchSuggestIntentData} and omit this column.
</dd>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID}</dt>
- <dd>If this column exists and this element exists at the given row, then "/" and this value will
-be appended to the data field in the Intent. This should only be used if the data field specified
+ <dd>A URI path string. If this column exists and contains a value at the given row, then "/" and
+this value is appended to the data field in the Intent. This should only be used if the data field
+specified
by the {@code android:searchSuggestIntentData} attribute in the searchable configuration has already
been set to an appropriate base string.</dd>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_EXTRA_DATA}</dt>
- <dd>If this column exists and this element exists at a given row, this is the <em>extra</em> data
-that will be used when forming the suggestion's Intent. If not provided, the Intent's extra data
-field will be
-null. This column allows suggestions to provide additional arbitrary data which will be
+ <dd>Arbitrary data. If this column exists and contains a value at a given row, this is the
+<em>extra</em> data used when forming the suggestion's Intent. If not provided, the
+Intent's extra data field is null. This column allows suggestions to provide additional data that is
included as an extra in the Intent's {@link android.app.SearchManager#EXTRA_DATA_KEY} key.</dd>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_QUERY}</dt>
- <dd>If this column exists and this element exists at the given row, this is the data that will be
+ <dd>If this column exists and this element exists at the given row, this is the data that is
used when forming the suggestion's query, included as an extra in the Intent's {@link
android.app.SearchManager#QUERY} key. Required if suggestion's action is {@link
android.content.Intent#ACTION_SEARCH}, optional otherwise.</dd>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID}</dt>
- <dd>Only used when providing suggestions for Quick Search Box. This column is used to indicate
+ <dd>Only used when providing suggestions for Quick Search Box. This column indicates
whether a search suggestion should be stored as a
-shortcut, and whether it should be validated. Shortcuts are usually formed when the user clicks a
-suggestion from Quick Search Box. If missing, the result will be stored as a shortcut and never
-refreshed. If set to {@link android.app.SearchManager#SUGGEST_NEVER_MAKE_SHORTCUT}, the result will
-not be stored as a shortcut.
-Otherwise, the shortcut id will be used to check back for for an up to date suggestion using
+shortcut and whether it should be validated. Shortcuts are usually formed when the user clicks a
+suggestion from Quick Search Box. If missing, the result is stored as a shortcut and never
+refreshed. If set to {@link android.app.SearchManager#SUGGEST_NEVER_MAKE_SHORTCUT}, the result is
+not stored as a shortcut.
+Otherwise, the shortcut ID is used to check back for an up to date suggestion using
{@link android.app.SearchManager#SUGGEST_URI_PATH_SHORTCUT}.</dd>
<dt>{@link android.app.SearchManager#SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING}</dt>
- <dd>Only used when providing suggestions for Quick Search Box. This column is used to specify that
+ <dd>Only used when providing suggestions for Quick Search Box. This column specifies that
a spinner should be shown instead of an icon from {@link
android.app.SearchManager#SUGGEST_COLUMN_ICON_2}
while the shortcut of this suggestion is being refreshed in Quick Search Box.</dd>
</dl>
-<p>Again, most of these columns will be discussed in the relevant sections below, so don't worry if
-they don't make sense to you now.</p>
+<p>Some of these columns are discussed more in the following sections.</p>
<h2 id="IntentForSuggestions">Declaring an Intent for suggestions</h2>
-<p>When the user selects a suggestion from the list that appears below the search
-dialog (instead of performing a search), the Search Manager will send
-a custom {@link android.content.Intent} to your searchable Activity. You must define both the
-<em>action</em> and <em>data</em> for the Intent.</p>
+<p>When the user selects a suggestion from the list that appears below the search dialog, the Search
+Manager sends a custom {@link android.content.Intent} to your searchable Activity. You must define
+the action and data for the Intent.</p>
<h3 id="IntentAction">Declaring the Intent action</h3>
@@ -397,34 +422,42 @@ a custom {@link android.content.Intent} to your searchable Activity. You must de
<p>The most common Intent action for a custom suggestion is {@link
android.content.Intent#ACTION_VIEW}, which is appropriate when
you want to open something, like the definition for a word, a person's contact information, or a web
-page. However, the Intent action can be whatever you want and can even be different for each
+page. However, the Intent action can be any other action and can even be different for each
suggestion.</p>
-<p>To declare an Intent action that will be the same for all suggestions, define the action in
-the {@code android:searchSuggestIntentAction} attribute of your searchable configuration file. For
-example:</p>
+<p>Depending on whether you want all suggestions to use the same Intent action, you
+can define the action in two ways:</p>
+
+<ol type="a">
+ <li>Use the {@code android:searchSuggestIntentAction} attribute of your searchable configuration
+file to define the action for all suggestions. <p>For example:</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_label"
android:hint="@string/search_hint"
- android:searchSuggestAuthority="my.package.MySuggestionProvider"
- android:searchSuggestIntentAction="android.Intent.action.VIEW" >
+ android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"
+ <b>android:searchSuggestIntentAction="android.Intent.action.VIEW"</b> >
&lt;/searchable>
</pre>
-<p>If you want to declare an Intent action that's unique for each suggestion, add the {@link
-android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column to
+ </li>
+ <li>Use the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column to define the
+action for individual suggestions.
+ <p>Add the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column to
your suggestions table and, for each suggestion, place in it the action to use (such as
-{@code "android.Intent.action.VIEW"}). </p>
+{@code "android.Intent.action.VIEW"}).</p>
+
+ </li>
+</ol>
<p>You can also combine these two techniques. For instance, you can include the {@code
android:searchSuggestIntentAction} attribute with an action to be used with all suggestions by
default, then override this action for some suggestions by declaring a different action in the
{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column. If you do not include
a value in the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column, then the
-Intent provided in the {@code android:searchSuggestIntentAction} attribute will be used.</p>
+Intent provided in the {@code android:searchSuggestIntentAction} attribute is used.</p>
<p class="note"><strong>Note</strong>: If you do not include the
{@code android:searchSuggestIntentAction} attribute in your searchable configuration, then you
@@ -432,45 +465,45 @@ Intent provided in the {@code android:searchSuggestIntentAction} attribute will
column for every suggestion, or the Intent will fail.</p>
+
<h3 id="IntentData">Declaring Intent data</h3>
-<p>When the user selects a suggestion, your searchable Activity will receive the Intent with the
+<p>When the user selects a suggestion, your searchable Activity receives the Intent with the
action you've defined (as discussed in the previous section), but the Intent must also carry
-data in order for your Activity to identify which suggestions was selected. Specifically,
+data in order for your Activity to identify which suggestion was selected. Specifically,
the data should be something unique for each suggestion, such as the row ID for the suggestion in
-your suggestions table. When the Intent is received,
+your SQLite table. When the Intent is received,
you can retrieve the attached data with {@link android.content.Intent#getData()} or {@link
android.content.Intent#getDataString()}.</p>
-<p>There are two ways to define the data that is included with the Intent:</p>
+<p>You can define the data included with the Intent in two ways:</p>
<ol type="a">
<li>Define the data for each suggestion inside the {@link
-android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column of your suggestions table.</li>
- <li>Fragment a data URI into two pieces: the portion common to all suggestions and the portion
-unique to each suggestion. Place these parts into the {@code android:searchSuggestIntentData}
-attribute of the searchable configuration and the {@link
-android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} column of your
-suggestions table, respectively.</li>
-</ol>
+android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column of your suggestions table.
-<p>The first option is straight-forward. Simply provide all necessary data information for each
-Intent in the suggestions table by including the {@link
-android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column and then populating it with unique
-data for each row. The data from this column will be attached to the Intent exactly as it
-is found in this column. You can then retrieve it with with {@link android.content.Intent#getData()}
-or {@link android.content.Intent#getDataString()}.</p>
+<p>Provide all necessary data information for each Intent in the suggestions table by including the
+{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column and then populating it with
+unique data for each row. The data from this column is attached to the Intent exactly as you
+define it in this column. You can then retrieve it with with {@link
+android.content.Intent#getData()} or {@link android.content.Intent#getDataString()}.</p>
<p class="note"><strong>Tip</strong>: It's usually easiest to use the table's row ID as the
-Intent data because it's always unique. And the easiest way to do that is by using the
+Intent data, because it's always unique. And the easiest way to do that is by using the
{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column name as an alias for the row ID
column. See the <a
href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary sample
-app</a> for an example in which {@link android.database.sqlite.SQLiteQueryBuilder} is used to
-create a projection map of column names to aliases.</p>
+app</a> for an example in which {@link android.database.sqlite.SQLiteQueryBuilder} creates a
+projection map of column names to aliases.</p>
+ </li>
+
+ <li>Fragment a data URI into two pieces: the portion common to all suggestions and the portion
+unique to each suggestion. Place these parts into the {@code android:searchSuggestIntentData}
+attribute of the searchable configuration and the {@link
+android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} column of your
+suggestions table, respectively.
-<p>The second option is to fragment your data URI into the common piece and the unique piece.
-Declare the piece of the URI that is common to all suggestions in the {@code
+<p>Declare the piece of the URI that is common to all suggestions in the {@code
android:searchSuggestIntentData} attribute of your searchable configuration. For example:</p>
<pre>
@@ -478,35 +511,40 @@ android:searchSuggestIntentData} attribute of your searchable configuration. For
&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_label"
android:hint="@string/search_hint"
- android:searchSuggestAuthority="my.package.MySuggestionProvider"
+ android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"
android:searchSuggestIntentAction="android.Intent.action.VIEW"
- android:searchSuggestIntentData="content://my.package/datatable" >
+ <b>android:searchSuggestIntentData="content://com.example/datatable"</b> >
&lt;/searchable>
</pre>
-<p>Now include the final path for each suggestion (the unique part) in the {@link
+<p>Then include the final path for each suggestion (the unique part) in the {@link
android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID}
-column of your suggestions table. When the user selects a suggestion, the Search Manager will take
-the string from {@code android:searchSuggestIntentData}, append a slash ("/") and then add the
+column of your suggestions table. When the user selects a suggestion, the Search Manager takes
+the string from {@code android:searchSuggestIntentData}, appends a slash ("/") and then adds the
respective value from the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} column to
form a complete content URI. You can then retrieve the {@link android.net.Uri} with with {@link
android.content.Intent#getData()}.</p>
+ </li>
+</ol>
+
<h4>Add more data</h4>
<p>If you need to express even more information with your Intent, you can add another table column,
{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_EXTRA_DATA}, which can store additional
-information about the suggestion. The data saved in this column will be placed in {@link
+information about the suggestion. The data saved in this column is placed in {@link
android.app.SearchManager#EXTRA_DATA_KEY} of the Intent's extra Bundle.</p>
+
<h2 id="HandlingIntent">Handling the Intent</h2>
-<p>Now that your search dialog provides custom search suggestions with custom formatted Intents, you
-need your searchable Activity to handle these Intents as they are delivered once the user selects a
-suggestion. (This is, of course, in addition to handling the {@link
-android.content.Intent#ACTION_SEARCH} Intent, which your searchable Activity already does.)
-Accepting the new Intent is rather self-explanatory, so we'll skip straight to an example:</p>
+<p>Now that your search dialog provides custom search suggestions with custom Intents, you
+need your searchable Activity to handle these Intents when the user selects a
+suggestion. This is in addition to handling the {@link
+android.content.Intent#ACTION_SEARCH} Intent, which your searchable Activity already does.
+Here's an example of how you can handle the Intents during your Activity {@link
+android.app.Activity#onCreate(Bundle) onCreate()} callback:</p>
<pre>
Intent intent = getIntent();
@@ -515,26 +553,32 @@ if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
doSearch(query);
} else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
- // Handle a suggestions click (because my suggestions all use ACTION_VIEW)
- Uri data = intent.getData());
- showResult(rowId);
+ // Handle a suggestions click (because the suggestions all use ACTION_VIEW)
+ Uri data = intent.getData();
+ showResult(data);
}
</pre>
<p>In this example, the Intent action is {@link
android.content.Intent#ACTION_VIEW} and the data carries a complete URI pointing to the suggested
item, as synthesized by the {@code android:searchSuggestIntentData} string and {@link
-android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} column. The URI is then passed to a local
-method that will query the content provider for the item specified by the URI and show it.</p>
+android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} column. The URI is then passed to the local
+{@code showResult()} method that queries the content provider for the item specified by the URI.</p>
+<p class="note"><strong>Note:</strong> You do <em>not</em> need to add an Intent filter to your
+Android manifest file for the Intent action you defined with the {@code
+android:searchSuggestIntentAction} attribute or {@link
+android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column. The Search Manager opens your
+searchable Activity by name to deliver the suggestion's Intent, so the Activity does not need to
+declare the accepted action.</p>
<h2 id="RewritingQueryText">Rewriting the query text</h2>
-<p>If the user navigates through the suggestions list using the device directional controls, the
-text in the search dialog won't change, by default. However, you can temporarily rewrite the
-user's query text as it appears in the text box with
-a query that matches the currently selected suggestion. This enables the user to see what query is
+<p>If the user navigates through the suggestions list using the directional controls (trackball or
+d-pad), the text in the search dialog won't change, by default. However, you can temporarily rewrite
+the user's query text as it appears in the text box with
+a query that matches the suggestion currently in focus. This enables the user to see what query is
being suggested (if appropriate) and then select the search box and edit the query before
dispatching it as a search.</p>
@@ -544,39 +588,40 @@ dispatching it as a search.</p>
<li>Add the {@code android:searchMode} attribute to your searchable configuration with the
"queryRewriteFromText" value. In this case, the content from the suggestion's {@link
android.app.SearchManager#SUGGEST_COLUMN_TEXT_1}
-column will be used to rewrite the query text.</li>
+column is used to rewrite the query text.</li>
<li>Add the {@code android:searchMode} attribute to your searchable configuration with the
"queryRewriteFromData" value. In this case, the content from the suggestion's
-{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column will be used to rewrite the
-query text. Note that this should only
-be used with Uri's or other data formats that are intended to be user-visible, such as HTTP URLs.
-Internal Uri schemes should not be used to rewrite the query in this way.</li>
+{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column is used to rewrite the
+query text. This should only
+be used with URI's or other data formats that are intended to be user-visible, such as HTTP URLs.
+Internal URI schemes should not be used to rewrite the query in this way.</li>
<li>Provide a unique query text string in the {@link
android.app.SearchManager#SUGGEST_COLUMN_QUERY} column of your suggestions table. If this column is
-present and contains a value for the current suggestion, it will be used to rewrite the query text
+present and contains a value for the current suggestion, it is used to rewrite the query text
(and override either of the previous implementations).</li>
</ol>
+
<h2 id="QSB">Exposing search suggestions to Quick Search Box</h2>
-<p>Once your application is configured to provide custom search suggestions, making them available
-to the globally-accessible Quick Search Box is as easy as modifying your searchable configuration to
+<p>Once you configure your application to provide custom search suggestions, making them available
+to the globally accessible Quick Search Box is as easy as modifying your searchable configuration to
include {@code android:includeInGlobalSearch} as "true".</p>
-<p>The only scenario in which additional work will be required is if your content provider for
-custom suggestions requires a permission for read access. In which case, you need to add a special
-{@code &lt;path-permission>} element for the provider to grant Quick Search Box read access to your
-content provider. For example:</p>
+<p>The only scenario in which additional work is necessary is when your content provider demands a
+read permission. In which case, you need to add a special
+{@code &lt;path-permission&gt;} element for the provider to grant Quick Search Box read access to
+your content provider. For example:</p>
<pre>
&lt;provider android:name="MySuggestionProvider"
- android:authorities="my.package.authority"
+ android:authorities="com.example.MyCustomSuggestionProvider"
android:readPermission="com.example.provider.READ_MY_DATA"
- android:writePermission="com.example.provider.WRITE_MY_DATA">
+ android:writePermission="com.example.provider.WRITE_MY_DATA"&gt;
&lt;path-permission android:pathPrefix="/search_suggest_query"
- android:readPermission="android.permission.GLOBAL_SEARCH" />
-&lt;/provider>
+ android:readPermission="android.permission.GLOBAL_SEARCH" /&gt;
+&lt;/provider&gt;
</pre>
<p>In this example, the provider restricts read and write access to the content. The
@@ -585,8 +630,8 @@ inside the {@code "/search_suggest_query"} path prefix when the {@code
"android.permission.GLOBAL_SEARCH"} permission exists. This grants access to Quick Search Box
so that it may query your content provider for suggestions.</p>
-<p>Content providers that enforce no permissions are already available to the search
-infrastructure.</p>
+<p>If your content provider does not enforce read permissions, then Quick Search Box can read
+it by default.</p>
<h3 id="EnablingSuggestions">Enabling suggestions on a device</h3>
@@ -608,89 +653,93 @@ android:searchSettingsDescription} attribute to your searchable configuration. F
&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_label"
android:hint="@string/search_hint"
- android:searchSuggestAuthority="my.package.MySuggestionProvider"
+ android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"
android:searchSuggestIntentAction="android.Intent.action.VIEW"
android:includeInGlobalSearch="true"
- android:searchSettingsDescription="@string/search_description" >
+ <b>android:searchSettingsDescription="@string/search_description"</b> >
&lt;/searchable>
</pre>
<p>The string for {@code android:searchSettingsDescription} should be as concise as possible and
state the content that is searchable. For example, "Artists, albums, and tracks" for a music
application, or "Saved notes" for a notepad application. Providing this description is important so
-the user knows what kind of suggestions will be provided. This attribute should always be included
+the user knows what kind of suggestions are provided. You should always include this attribute
when {@code android:includeInGlobalSearch} is "true".</p>
-<p>Remember that the user must visit this settings menu to enable search suggestions for your
-application before your search suggestions will appear in Quick Search Box. As such, if search is an
-important aspect of your application, then you may want to consider a way to message this to your
-users &mdash; perhaps with a note the first time they launch the app about how to enable search
-suggestions for Quick Search Box.</p>
+<p>Remember that the user must visit the settings menu to enable search suggestions for your
+application before your search suggestions appear in Quick Search Box. As such, if search is an
+important aspect of your application, then you might want to consider a way to convey that to
+your users &mdash; you might provide a note the first time they launch the app that instructs
+them how to enable search suggestions for Quick Search Box.</p>
<h3 id="ManagingShortcuts">Managing Quick Search Box suggestion shortcuts</h3>
-<p>Suggestions that the user selects from Quick Search Box may be automatically made into shortcuts.
+<p>Suggestions that the user selects from Quick Search Box can be automatically made into shortcuts.
These are suggestions that the Search Manager has copied from your content provider so it can
quickly access the suggestion without the need to re-query your content provider. </p>
<p>By default, this is enabled for all suggestions retrieved by Quick Search Box, but if your
-suggestion data may change over time, then you can request that the shortcuts be refreshed. For
+suggestion data changes over time, then you can request that the shortcuts be refreshed. For
instance, if your suggestions refer to dynamic data, such as a contact's presence status, then you
should request that the suggestion shortcuts be refreshed when shown to the user. To do so,
include the {@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} in your suggestions table.
Using this column, you can
-configure the shortcut behavior for each suggestion in the following ways:</p>
+configure the shortcut behavior for each suggestion in one of the following ways:</p>
<ol type="a">
- <li>Have Quick Search Box re-query your content provider for a fresh version of the shortcutted
-suggestion.
+ <li>Have Quick Search Box re-query your content provider for a fresh version of the suggestion
+shortcut.
<p>Provide a value in the {@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} column
-and the suggestion will be
-re-queried for a fresh version of the suggestion each time the shortcut is displayed. The shortcut
-will be quickly displayed with whatever data was most recently available until the refresh query
-returns, after which the suggestion will be dynamically refreshed with the new information. The
-refresh query will be sent to your content provider with a URI path of {@link
+and the suggestion is
+re-queried for a fresh version each time the shortcut is displayed. The shortcut
+is quickly displayed with whatever data was most recently available until the refresh query
+returns, at which point the suggestion is refreshed with the new information. The
+refresh query is sent to your content provider with a URI path of {@link
android.app.SearchManager#SUGGEST_URI_PATH_SHORTCUT}
-(instead of {@link android.app.SearchManager#SUGGEST_URI_PATH_QUERY}). The Cursor you return should
-contain one suggestion using the
+(instead of {@link android.app.SearchManager#SUGGEST_URI_PATH_QUERY}).</p>
+ <p>The {@link android.database.Cursor} you return should contain one suggestion using the
same columns as the original suggestion, or be empty, indicating that the shortcut is no
-longer valid (in which case, the suggestion will disappear and the shortcut will be removed).</p>
- <p>If a suggestion refers to data that could take longer to refresh, such as a network based
-refresh, you may also add the {@link
+longer valid (in which case, the suggestion disappears and the shortcut is removed).</p>
+ <p>If a suggestion refers to data that could take longer to refresh, such as a network-based
+refresh, you can also add the {@link
android.app.SearchManager#SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING} column to your suggestions
table with a value
of "true" in order to show a progress spinner for the right hand icon until the refresh is complete.
-(Any value other than "true" will not show the progress spinner.)</p></li>
+Any value other than "true" does not show the progress spinner.</p>
+ </li>
+
<li>Prevent the suggestion from being copied into a shortcut at all.
<p>Provide a value of {@link android.app.SearchManager#SUGGEST_NEVER_MAKE_SHORTCUT} in the
{@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} column. In
-this case, the suggestion will never be copied into a shortcut. This should only be necessary if you
-absolutely do not want the previously copied suggestion to appear at all. (Recall that if you
-provide a normal value for the column then the suggestion shortcut will appear only until the
+this case, the suggestion is never copied into a shortcut. This should only be necessary if you
+absolutely do not want the previously copied suggestion to appear. (Recall that if you
+provide a normal value for the column, then the suggestion shortcut appears only until the
refresh query returns.)</p></li>
<li>Allow the default shortcut behavior to apply.
- <p>Simply leave the {@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} empty for each
+ <p>Leave the {@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} empty for each
suggestion that will not change and can be saved as a shortcut.</p></li>
</ol>
-<p>Of course, if none of your suggestions will ever change, then you do not need the
+<p>If none of your suggestions ever change, then you do not need the
{@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} column at all.</p>
-<p class="note"><strong>Note</strong>: Quick Search Box will ultimately decide whether to shortcut
-your app's suggestions, considering these values as a strong request from your application.</p>
+<p class="note"><strong>Note</strong>: Quick Search Box ultimately decides whether or not to create
+a shortcut for a suggestion, considering these values as a strong request from your
+application&mdash;there is no guarantee that the behavior you have requested for your suggestion
+shortcuts will be honored.</p>
<h3 id="AboutRanking">About Quick Search Box suggestion ranking</h3>
-<p>Once your application's search results are made available to Quick Search Box, how they surface
-to the user for a particular query will be determined as appropriate by Quick Search Box ranking.
-This may depend on how many other apps have results for that query, and how often the user has
-selected on your results compared to those of the other apps. There is no guarantee about how
-ranking will occur, or whether your app's suggestions will show at all for a given query. In
-general, you can expect that providing quality results will increase the likelihood that your app's
-suggestions are provided in a prominent position, and apps that provide lower quality suggestions
-will be more likely to be ranked lower and/or not displayed.</p>
+<p>Once you make your application's search suggestions available to Quick Search Box, the Quick
+Search Box ranking determines how the suggestions are surfaced to the user for a particular query.
+This might depend on how many other apps have results for that query, and how often the user has
+selected your results compared to those from other apps. There is no guarantee about how your
+suggestions are ranked, or whether your app's suggestions show at all for a given query. In
+general, you can expect that providing quality results increases the likelihood that your app's
+suggestions are provided in a prominent position and apps that provide low quality suggestions
+are more likely to be ranked lower or not displayed.</p>
<div class="special">
<p>See the <a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable
diff --git a/docs/html/guide/topics/search/adding-recent-query-suggestions.jd b/docs/html/guide/topics/search/adding-recent-query-suggestions.jd
index 37e0e82..cb063a1 100644
--- a/docs/html/guide/topics/search/adding-recent-query-suggestions.jd
+++ b/docs/html/guide/topics/search/adding-recent-query-suggestions.jd
@@ -5,20 +5,22 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.provider.SearchRecentSuggestions}</li>
-<li>{@link android.content.SearchRecentSuggestionsProvider}</li>
-</ol>
<h2>In this document</h2>
<ol>
<li><a href="#TheBasics">The Basics</a></li>
-<li><a href="#RecentQuerySearchableConfiguration">Modifying the searchable
-configuration</a></li>
<li><a href="#RecentQueryContentProvider">Creating a Content Provider</a></li>
-<li><a href="#SavingQueries">Saving queries</a></li>
-<li><a href="#ClearingSuggestionData">Clearing the suggestion data</a></li>
+<li><a href="#RecentQuerySearchableConfiguration">Modifying the Searchable
+Configuration</a></li>
+<li><a href="#SavingQueries">Saving Queries</a></li>
+<li><a href="#ClearingSuggestionData">Clearing the Suggestion Data</a></li>
</ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.provider.SearchRecentSuggestions}</li>
+<li>{@link android.content.SearchRecentSuggestionsProvider}</li>
+</ol>
+
<h2>See also</h2>
<ol>
<li><a href="searchable-config.html">Searchable Configuration</a></li>
@@ -26,99 +28,76 @@ configuration</a></li>
</div>
</div>
-<p>The Android search framework provides the ability for your application to
-provide suggestions while the user types into the Android search dialog. In this guide, you'll learn
-how to create recent query suggestions. These are suggestions based
-on queries previously entered by the user. So, if the user previously searched for "puppies" then it
-will appear as a suggestion as they begin typing the same string of text. The screenshot below
-shows an example of recent query suggestions.</p>
+<p>When using the Android search dialog, you can provide search suggestions based on recent search
+queries. For example, if a user previously searched for "puppies," then that query appears as a
+suggestion once he or she begins typing the same query. Figure 1 shows an example of a search dialog
+with recent query suggestions.</p>
+
+<p>Before you begin, you need to implement the search dialog for basic searches in your application.
+If you haven't, see <a href="search-dialog.html">Using the Android Search Dialog</a>.</p>
-<p>Before you begin, you need to have implemented the Android search dialog for searches in your
-application. If you haven't done this, see <a href="search-dialog.html">Using the Android Search
-Dialog</a>.</p>
<h2 id="TheBasics">The Basics</h2>
-<img src="{@docRoot}images/search/search-suggest-recent-queries.png" alt="" height="417"
-style="float:right;clear:right;" />
+<div class="figure" style="width:250px">
+<img src="{@docRoot}images/search/search-suggest-recent-queries.png" alt="" height="417" />
+<p class="img-caption"><strong>Figure 1.</strong> Screenshot of a search dialog with recent query
+suggestions.</p>
+</div>
<p>Recent query suggestions are simply saved searches. When the user selects one of
-the suggestions, your searchable Activity will receive a normal {@link
+the suggestions, your searchable Activity receives a {@link
android.content.Intent#ACTION_SEARCH} Intent with the suggestion as the search query, which your
-searchable Activity will already handle.</p>
+searchable Activity already handles (as described in <a href="search-dialog.html">Using the Android
+Search Dialog</a>).</p>
<p>To provide recent queries suggestions, you need to:</p>
<ul>
- <li>Implement a basic searchable Activity, as documented in <a
-href="{@docRoot}guide/topics/search/search-dialog.html">Using the Android Search Dialog</a>.</li>
+ <li>Implement a searchable Activity, <a
+href="{@docRoot}guide/topics/search/search-dialog.html">using the Android Search Dialog</a>.</li>
<li>Create a content provider that extends {@link
android.content.SearchRecentSuggestionsProvider} and declare it in your application manifest.</li>
- <li>Modify the searchable configuration with information about the content provider.</li>
- <li>Save queries to your content provider each time a search is made.</li>
+ <li>Modify the searchable configuration with information about the content provider that
+provides search suggestions.</li>
+ <li>Save queries to your content provider each time a search is executed.</li>
</ul>
-<p>Just like the Search Manager handles the rendering of the search dialog, it will also do the work
-to display all search suggestions below the search dialog. All you need to do is provide a source
-from which the suggestions can be retrieved.</p>
+<p>Just as the Search Manager displays the search dialog, it also displays the
+search suggestions. All you need to do is provide a source from which the suggestions can be
+retrieved.</p>
-<p>When the Search Manager identifies that your Activity is searchable and also provides search
-suggestions, the following procedure will take place as soon as the user types into the Android
-search box:</p>
+<p>When the Search Manager identifies that your Activity is searchable and provides search
+suggestions, the following procedure takes place as soon as the user types into the search
+dialog:</p>
-<ul>
- <li>The Search Manager takes the search query text (whatever has been typed so far) and performs a
-query to the content provider that manages your suggestions.</li>
- <li>Your content provider then returns a {@link android.database.Cursor} that points to all
-suggestions that are relevant to the search query text.</li>
- <li>The Search Manager then displays the list of suggestions provided by the Cursor (as
-demonstrated in the screenshot to the right).</li>
-</ul>
+<ol>
+ <li>Search Manager takes the search query text (whatever has been typed so far) and performs a
+query to the content provider that contains your suggestions.</li>
+ <li>Your content provider returns a {@link android.database.Cursor} that points to all
+suggestions that match the search query text.</li>
+ <li>Search Manager displays the list of suggestions provided by the Cursor.</li>
+</ol>
-<p>At this point, the following may happen:</p>
+<p>Once the recent query suggestions are displayed, the following might happen:</p>
<ul>
- <li>If the user types another key, or changes the query in any way, the above steps are repeated
-and the suggestion list is updated as appropriate.</li>
+ <li>If the user types another key, or changes the query in any way, the aforementioned steps are
+repeated and the suggestion list is updated.</li>
<li>If the user executes the search, the suggestions are ignored and the search is delivered
to your searchable Activity using the normal {@link android.content.Intent#ACTION_SEARCH}
Intent.</li>
- <li>If the user selects a suggestion, a normal
-{@link android.content.Intent#ACTION_SEARCH} Intent is triggered, using the suggested text as the
-query.</li>
+ <li>If the user selects a suggestion, an
+{@link android.content.Intent#ACTION_SEARCH} Intent is delivered to your searchable Activity using
+the suggested text as the query.</li>
</ul>
-<p>As you'll soon discover, the {@link android.content.SearchRecentSuggestionsProvider} class that
-you'll extend for your content provider will automatically do the work described above, so there's
+<p>The {@link android.content.SearchRecentSuggestionsProvider} class that
+you extend for your content provider automatically does the work described above, so there's
actually very little code to write.</p>
-<h2 id="RecentQuerySearchableConfiguration">Modifying the searchable configuration</h2>
-
-<p>First, you need to add the {@code android:searchSuggestAuthority} and
-{@code android:searchSuggestSelection} attributes to the {@code &lt;searchable&gt;} element in your
-searchable configuration file. For example:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?>
-&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
- android:label="@string/app_label"
- android:hint="@string/search_hint"
- android:searchSuggestAuthority="my.package.MySuggestionProvider"
- android:searchSuggestSelection=" ?" >
-&lt;/searchable>
-</pre>
-
-<p>The value for {@code android:searchSuggestAuthority} should be a fully-qualified name for
-your content provider: your application package name followed by the name of your content provider.
-This string must match the authority used in the content provider (discussed in the next section).
-</p>
-
-<p>The value for {@code android:searchSuggestSelection} must be a single question-mark, preceded by
-a space (" ?"), which is simply a placeholder for the SQLite selection argument (which will be
-automatically replaced by the query text entered by the user).</p>
-
<h2 id="RecentQueryContentProvider">Creating a Content Provider</h2>
@@ -131,7 +110,7 @@ suggestions:</p>
<pre>
public class MySuggestionProvider extends SearchRecentSuggestionsProvider {
- public final static String AUTHORITY = "my.package.MySuggestionProvider";
+ public final static String AUTHORITY = "com.example.MySuggestionProvider";
public final static int MODE = DATABASE_MODE_QUERIES;
public MySuggestionProvider() {
@@ -140,41 +119,72 @@ public class MySuggestionProvider extends SearchRecentSuggestionsProvider {
}
</pre>
-<p>The call to {@link android.content.SearchRecentSuggestionsProvider#setupSuggestions(String,int)}
-passes the name of the search authority (matching the one in the searchable configuration) and a
-database mode. The database mode must include {@link
+<p>The call to {@link android.content.SearchRecentSuggestionsProvider#setupSuggestions(String,int)
+setupSuggestions()} passes the name of the search authority and a
+database mode. The search authority can be any unique string, but the best practice is to use a
+fully qualified name for your content provider
+(package name followed by the provider's class name; for example,
+"com.example.MySuggestionProvider"). The database mode must include {@link
android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_QUERIES} and can optionally include
{@link
-android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES}, which will add another column
+android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES}, which adds another column
to the suggestions table that allows you to provide a second line of text with each suggestion. For
-example:</p>
+example, if you want to provide two lines in each suggestion:</p>
+
<pre>
public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;
</pre>
-<p>In the following section, you'll see how to save both lines of text.</p>
-
-<p>Now simply declare the content provider in your application manifest with the same authority
-string used in the class (and in the searchable configuration). For example:</p>
+<p>Now declare the content provider in your application manifest with the same authority
+string used in your {@link android.content.SearchRecentSuggestionsProvider} class (and in the
+searchable configuration). For example:</p>
<pre>
&lt;application>
&lt;provider android:name=".MySuggestionProvider"
- android:authorities="my.package.authority" />
+ android:authorities="com.example.MySuggestionProvider" />
...
&lt;/application>
</pre>
-<h2 id="SavingQueries">Saving queries</h2>
-<p>In order to populate your collection of recent queries, you need to add each query
-received by your searchable Activity to the content provider you've just built. To do this, create
-an instance of {@link
+<h2 id="RecentQuerySearchableConfiguration">Modifying the Searchable Configuration</h2>
+
+<p>To configure your search dialog to use your suggestions provider, you need to add
+the {@code android:searchSuggestAuthority} and {@code android:searchSuggestSelection} attributes to
+the {@code &lt;searchable&gt;} element in your searchable configuration file. For example:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
+ android:label="@string/app_label"
+ android:hint="@string/search_hint"
+ <b>android:searchSuggestAuthority="com.example.MySuggestionProvider"
+ android:searchSuggestSelection=" ?"</b> >
+&lt;/searchable>
+</pre>
+
+<p>The value for {@code android:searchSuggestAuthority} should be a fully qualified name for
+your content provider that exactly matches the authority used in the content provider (the {@code
+AUTHORITY} string in the above example).
+</p>
+
+<p>The value for {@code android:searchSuggestSelection} must be a single question mark, preceded by
+a space ({@code " ?"}), which is simply a placeholder for the SQLite selection argument (which is
+automatically replaced by the query text entered by the user).</p>
+
+
+
+<h2 id="SavingQueries">Saving Queries</h2>
+
+<p>To populate your collection of recent queries, add each query
+received by your searchable Activity to your {@link
+android.content.SearchRecentSuggestionsProvider}. To do this, create an instance of {@link
android.provider.SearchRecentSuggestions} and call {@link
-android.provider.SearchRecentSuggestions#saveRecentQuery(String,String)} each time your searchable
-Activity receives a query. For example, here's how you can save the query during your
-Activity's {@link android.app.Activity#onCreate(Bundle) onCreate()} method:</p>
+android.provider.SearchRecentSuggestions#saveRecentQuery(String,String) saveRecentQuery()} each time
+your searchable Activity receives a query. For example, here's how you can save the query during
+your Activity's {@link android.app.Activity#onCreate(Bundle) onCreate()} method:</p>
<pre>
&#64;Override
@@ -193,24 +203,24 @@ public void onCreate(Bundle savedInstanceState) {
}
</pre>
-<p>Notice that the {@link android.content.SearchRecentSuggestionsProvider} constructor requires the
+<p>The {@link android.content.SearchRecentSuggestionsProvider} constructor requires the
same authority and database mode declared by your content provider.</p>
-<p>The {@link android.provider.SearchRecentSuggestions#saveRecentQuery(String,String)} method takes
+<p>The {@link android.provider.SearchRecentSuggestions#saveRecentQuery(String,String)
+saveRecentQuery()} method takes
the search query string as the first parameter and, optionally, a second string to include as the
-second line of the suggestion. The second parameter is only used if you've enabled two-line mode
-for the search suggestions with {@link
+second line of the suggestion (or null). The second parameter is only used if you've enabled
+two-line mode for the search suggestions with {@link
android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES}. If you have enabled
-two-line mode, then the query text will be matched against this second line as well.</p>
+two-line mode, then the query text is also matched against this second line when the Search Manager
+looks for matching suggestions.</p>
-<p>That's all that's needed to build a recent queries suggestion provider. However, there's one
-other important thing to do: provide the ability for the user to clear this search history.</p>
-<h2 id="ClearingSuggestionData">Clearing the suggestion data</h2>
+<h2 id="ClearingSuggestionData">Clearing the Suggestion Data</h2>
<p>To protect the user's privacy, you should always provide a way for the user to clear the recent
-query suggestions. To clear the recent queries, simply call {@link
+query suggestions. To clear the query history, call {@link
android.provider.SearchRecentSuggestions#clearHistory()}. For example:</p>
<pre>
@@ -219,7 +229,7 @@ SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
suggestions.clearHistory();
</pre>
-<p>Simply execute this from your choice of a "Clear Search History" menu item,
-preference item, or button. You should also provide a confirmation dialog when this is pressed, to
+<p>Execute this from your choice of a "Clear Search History" menu item,
+preference item, or button. You should also provide a confirmation dialog to
verify that the user wants to delete their search history.</p>
diff --git a/docs/html/guide/topics/search/index.jd b/docs/html/guide/topics/search/index.jd
index b2252bb..f563715 100644
--- a/docs/html/guide/topics/search/index.jd
+++ b/docs/html/guide/topics/search/index.jd
@@ -13,98 +13,96 @@ page.title=Search
<ol>
<li><a href="searchable-config.html">Searchable Configuration</a></li>
</ol>
-<h2>See also</h2>
+<h2>Related samples</h2>
<ol>
<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable
-Dictionary sample app</a></li>
+Dictionary</a></li>
</ol>
</div>
</div>
-<p>The ability to search is considered to be a core user feature on Android. The user should be able
-to search any data that is available to them, whether the content is located on the device or the
-Internet. This experience should be seamless and consistent across the entire
-system, which is why Android provides a simple search framework to help you provide users with
+<p>Search is a core user feature on Android. Users should be able
+to search any data that is available to them, whether the content is located on the device or
+the Internet. The search experience should be seamless and consistent across the entire
+system, which is why Android provides a search framework to help you provide users with
a familiar search dialog and a great search experience.</p>
-<img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417"
-style="float:right;clear:right;" />
+<div class="figure" style="width:250px">
+<img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417" />
+<p class="img-caption"><strong>Figure 1.</strong> Screenshot of a search dialog with custom
+search suggestions.</p>
+</div>
+
+<p>Android's search framework provides a user interface in which users can perform a search and
+an interaction layer that communicates with your application, so you don't have to build
+your own search Activity. Instead, a search dialog appears at the top of the screen at the user's
+command without interrupting the current Activity.</p>
-<p>Android's search framework provides a user interface in which the user can perform a search and
-an interaction layer that communicates with your application. This way, you don't have to build
-a search box that the user must find in order to begin a search. Instead,
-a custom search dialog will appear at the top of the screen at the user's command.
-The search framework will manage the search dialog and when the user executes their search, the
-search framework will pass the query text to your application so that your application can begin a
-search. The screenshot to the right shows an example of the search dialog (using
-search suggestions).</p>
+<p>The search framework manages the life of the search dialog. When users execute a search, the
+search framework passes the query text to your application so your application can perform a
+search. Figure 1 shows an example of the search dialog with optional search suggestions.</p>
<p>Once your application is set up to use the search dialog, you can:</p>
<ul>
-<li>Customize some of the search dialog characteristics</li>
<li>Enable voice search</li>
<li>Provide search suggestions based on recent user queries</li>
-<li>Provide search suggestions that match actual results in your application data</li>
+<li>Provide custom search suggestions that match actual results in your application data</li>
<li>Offer your application's search suggestions in the system-wide Quick Search Box</li>
</ul>
-<p>The following documents will teach you how to use the search dialog in
-your application:</p>
+<p class="note"><strong>Note</strong>: The search framework does <em>not</em> provide APIs to
+search your data. To perform a search, you need to use APIs appropriate for your data. For example,
+if your data is stored in an SQLite database, you should use the {@link android.database.sqlite}
+APIs to perform searches.</p>
+
+<p>The following documents show you how to use the search dialog in your application:</p>
<dl>
<dt><strong><a href="search-dialog.html">Using the Android Search Dialog</a></strong></dt>
- <dd>How to set up your application to use the search dialog for searches. </dd>
+ <dd>How to set up your application to use the search dialog. </dd>
<dt><strong><a href="adding-recent-query-suggestions.html">Adding Recent Query
Suggestions</a></strong></dt>
<dd>How to show suggestions based on queries previously used in the search dialog.</dd>
<dt><strong><a href="adding-custom-suggestions.html">Adding Custom Suggestions</a></strong></dt>
<dd>How to show suggestions based on custom data from your application and offer your suggestions
in the system-wide Quick Search Box.</dd>
+ <dt><strong><a href="searchable-config.html">Searchable Configuration</a></strong></dt>
+ <dd>A reference for the searchable configuration file (though the other
+documents also discuss the configuration file in terms of specific behaviors).</dd>
</dl>
-<p>Also, the <strong><a href="searchable-config.html">Searchable Configuration</a></strong> document
-provides a reference for the searchable configuration file (though the above
-documents also discuss the configuration file in terms of specific behaviors).</p>
-
-<p class="note"><strong>Note</strong>: The search framework does <em>not</em> provide APIs to
-perform searches on your data. Performing actual searches is a task that you must accomplish
-using APIs appropriate for your data, such as those in {@link android.database.sqlite}
-if your data is in an SQLite database.</p>
-
<h2>Protecting User Privacy</h2>
-<p>When you implement search in your application, you should take steps to protect the user's
-privacy whenever possible. Many users consider their activities on the phone, including searches, to
-be private information. To protect the user's privacy, you should abide by the following
+<p>When you implement search in your application, take steps to protect the user's
+privacy. Many users consider their activities on the phone&mdash;including searches&mdash;to
+be private information. To protect each user's privacy, you should abide by the following
principles:</p>
<ul>
-<li><strong>Don't send personal information to servers, and if you do, don't log it.</strong>
-<p>"Personal information" is information that can personally identify your users, such as their
-name, email address, billing information, or other data which can be reasonably linked to such
-information. If
-your application implements search with the assistance of a server, try to avoid sending personal
-information along with the search queries. For example, if you are searching for businesses near a
-zip code,
-you don't need to send the user ID as well &mdash; send only the zip code to the server. If you must
-send the personal information, you should take steps to avoid logging it. If you must log it, you
-should protect that data very carefully and erase it as soon as possible.</p>
+<li><strong>Don't send personal information to servers, but if you must, do not log it.</strong>
+<p>Personal information is any information that can personally identify your users, such as their
+names, email addresses, billing information, or other data that can be reasonably linked to such
+information. If your application implements search with the assistance of a server, avoid sending
+personal information along with the search queries. For example, if you are searching for businesses
+near a zip code,
+you don't need to send the user ID as well; send only the zip code to the server. If you must
+send the personal information, you should not log it. If you must log it, protect that data
+very carefully and erase it as soon as possible.</p>
</li>
<li><strong>Provide the user with a way to clear their search history.</strong>
-<p>The search framework helps your application provide context-specific suggestions while they type.
-Sometimes these
-suggestions are based on previous searches, or other actions taken by the user in an earlier
-session. A user may not wish for previous searches to be revealed to other users, for instance if
-they share their phone with a friend. If your application provides suggestions that can reveal
-previous activities, you should implement a "Clear History" menu item, preference, or button. If you
-are
-using {@link android.provider.SearchRecentSuggestions}, you can simply call its {@link
-android.provider.SearchRecentSuggestions#clearHistory()} method. If you are implementing custom
-suggestions, you'll need to provide a
-similar "clear history" method in your provider that can be invoked by the user.</p>
+<p>The search framework helps your application provide context-specific suggestions while the user
+types. Sometimes these
+suggestions are based on previous searches or other actions taken by the user in an earlier
+session. A user might not wish for previous searches to be revealed to other device users, for
+instance, if they share their phone with a friend. If your application provides suggestions that can
+reveal previous activities, you should implement the ability for the user to clear the search
+history. If you are using {@link android.provider.SearchRecentSuggestions}, you can simply call the
+{@link android.provider.SearchRecentSuggestions#clearHistory()} method. If you are implementing
+custom suggestions, you'll need to provide a similar "clear history" method in your provider that
+the user can execute.</p>
</li>
</ul>
diff --git a/docs/html/guide/topics/search/search-dialog.jd b/docs/html/guide/topics/search/search-dialog.jd
index a5f99c7..49938b4 100644
--- a/docs/html/guide/topics/search/search-dialog.jd
+++ b/docs/html/guide/topics/search/search-dialog.jd
@@ -5,10 +5,6 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.app.SearchManager}</li>
-</ol>
<h2>In this document</h2>
<ol>
<li><a href="#TheBasics">The Basics</a></li>
@@ -27,64 +23,81 @@ parent.link=index.html
<li><a href="#SearchContextData">Passing Search Context Data</a></li>
<li><a href="#VoiceSearch">Adding Voice Search</a></li>
</ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.app.SearchManager}</li>
+</ol>
+
+<h2>Related samples</h2>
+<ol>
+<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable
+Dictionary</a></li>
+</ol>
+
+<h2>Downloads</h2>
+<ol>
+<li><a href="{@docRoot}shareables/search_icons.zip">search_icons.zip</a></li>
+</ol>
+
<h2>See also</h2>
<ol>
<li><a href="adding-recent-query-suggestions.html">Adding Recent Query Suggestions</a></li>
<li><a href="adding-custom-suggestions.html">Adding Custom Suggestions</a></li>
<li><a href="searchable-config.html">Searchable Configuration</a></li>
-<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable
-Dictionary App</a></li>
</ol>
+
</div>
</div>
-<p>When you want to provide search in your application, the last thing you should have to worry
-about is where to put your search box. By using the Android search framework, your application will
-reveal a custom search dialog whenever the user requests it. At the
-press of a dedicated search key or an API call from your application, the search dialog will
-appear at the top of the screen and will automatically show your application icon. An example is
-shown in the screenshot below.</p>
+<p>When you want to implement search in your application, the last thing you should have to worry
+about is where to put the search box. When you implement search with the Android search framework,
+you don't have to. When the user invokes search, a search dialog appears at the top of the screen
+with your application icon to the left of the search box. When the user executes the search, your
+application receives the query so it can search your application's data. An example of the search
+dialog is shown in figure 1.</p>
-<p>This guide will teach you how to set up your application to provide search in a custom search
-dialog. In doing so, you will provide a standardized search experience and be able to add
-features like voice search and search suggestions.</p>
+<p>This guide shows you how to set up your application to provide search in the search
+dialog. When you use the search dialog, you provide a standardized search
+experience and can add features such as voice search and search suggestions.</p>
<h2 id="TheBasics">The Basics</h2>
-<img src="{@docRoot}images/search/search-ui.png" alt="" height="417"
-style="float:right;clear:right;" />
+<div class="figure" style="width:250px">
+<img src="{@docRoot}images/search/search-ui.png" alt="" height="417" />
+<p class="img-caption"><strong>Figure 1.</strong> Screenshot of an application's search dialog.</p>
+</div>
-<p>The Android search framework will manage the search dialog on your behalf; you never need
-to draw it or worry about where it is, and your current Activity will not be
-interrupted. The {@link android.app.SearchManager} is the component that does this work for
-you (hereafter, referred to as "the Search Manager"). It manages the life of the Android search
-dialog and will send your application the search query when executed by the user.</p>
+<p>The Android search framework manages the search dialog for your application. You never need
+to draw it or worry about where it is, and your Activity is not interrupted when the search dialog
+appears. The Search Manager ({@link android.app.SearchManager}) is the component that does this work
+for you. It manages the life of the search dialog and sends your application the user's search
+query.</p>
-<p>When the user executes a search, the Search Manager will use a specially-formed Intent to pass
-the search query to the Activity that you've declared to handle searches. Essentially, all you
-need is an Activity that receives this Intent, performs the search, and presents the results.
-Specifically, what you need is the following:</p>
+<p>When the user executes a search, the Search Manager creates an {@link android.content.Intent} to
+pass the search query to the Activity that you've declared to handle searches. Basically, all you
+need is an Activity that receives the search Intent, performs the search, and presents the results.
+Specifically, you need the following:</p>
<dl>
<dt>A searchable configuration</dt>
- <dd>This is an XML file that configures the search dialog and includes settings for
-features such as the hint text shown in text box and settings voice search and search
-suggestion.</dd>
+ <dd>An XML file that configures the search dialog and includes settings for features such as voice
+search, search suggestion, and the hint text.</dd>
<dt>A searchable Activity</dt>
- <dd>This is the {@link android.app.Activity} that receives the search query then
-searches your data and displays the search results.</dd>
+ <dd>The {@link android.app.Activity} that receives the search query, then searches your data and
+displays the search results.</dd>
<dt>A mechanism by which the user can invoke search</dt>
- <dd>By default, the device search key (if available) will invoke the search dialog once
-you've configured a searchable Activity. However, you should always provide another means by
-which the user can invoke a search, such as with a search button in the Options Menu or elsewhere in
-the Activity UI, because not all devices provide a dedicated search key.</dd>
+ <dd>The device search key invokes the search dialog, by default. However, a dedicated search key
+is not guaranteed on all devices, so provide another means by which the user can invoke a search,
+such as a search button in the Options Menu or elsewhere in the Activity UI.</dd>
</dl>
+
<h2 id="SearchableConfiguration">Creating a Searchable Configuration</h2>
-<p>The searchable configuration is an XML file that defines several settings for the Android search
+<p>The searchable configuration is an XML file that defines several settings for the search
dialog in your application. This file is traditionally named {@code searchable.xml} and must be
saved in the {@code res/xml/} project directory.</p>
@@ -94,45 +107,61 @@ or more attributes that configure your search dialog. For example:</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
- android:label="@string/app_label" >
+ android:label="@string/app_label"
+ android:hint="@string/search_hint" >
&lt;/searchable>
</pre>
-<p>This is the minimum configuration required in order to provide the search dialog. The {@code
-android:label} attribute is the only required attribute and points to a string resource, which
-should normally be the same as the application. (Although it's required, this
-label isn't actually shown to the user until you enable suggestions for Quick Search Box.)</p>
+<p>The {@code android:label} attribute is the only required attribute and points to a string
+resource, which should be the same as the application name. This label isn't actually visible to the
+user until you enable suggestions for Quick Search Box, at which point, this label is visible in the
+list of Searchable items in the system Settings.</p>
-<p>There are several other attributes accepted by the {@code &lt;searchable&gt;} element. Most of
-which apply only when configuring features such as search suggestions and voice
-search. However, we recommend that you always include the {@code android:hint} attribute, which
-specifies a string resource for the text to display in the search dialog's text box before the user
-enters their query&mdash;it provides important clues to the user about what they can search. </p>
+<p>Though it's not required, we recommend that you always include the {@code android:hint}
+attribute, which provides a hint string in the search dialog's text box before the user
+enters their query. The hint is important because it provides important clues to users about what
+they can search.</p>
<p class="note"><strong>Tip:</strong> For consistency among other
Android applications, you should format the string for {@code android:hint} as "Search
<em>&lt;content-or-product&gt;</em>". For example, "Search songs and artists" or "Search
YouTube".</p>
-<p>Next, you'll hook this configuration into your application.</p>
+<p>The {@code &lt;searchable&gt;} element accepts several other attributes. Most attributes apply
+only when configuring features such as search suggestions and voice search.</p>
+
+<p>For more details about the searchable configuration file, see the <a
+href="{@docRoot}guide/topics/search/searchable-config.html">Searchable Configuration</a>
+reference.</p>
+
<h2 id="SearchableActivity">Creating a Searchable Activity</h2>
-<p>When the user executes a search from the search dialog, the Search Manager will send
-your searchable {@link android.app.Activity} the search query with the {@link
-android.content.Intent#ACTION_SEARCH} {@link android.content.Intent}. Your searchable Activity will
-then search your data and present the results.</p>
+<p>When the user executes a search from the search dialog, the Search Manager takes the query
+and sends it to your searchable {@link android.app.Activity} in the {@link
+android.content.Intent#ACTION_SEARCH} {@link android.content.Intent}. Your searchable Activity
+then searches your data using the query and presents the results to the user.</p>
+
+<p>In order for the Search Manager to know where to deliver the search query, you must declare your
+searchable Activity in the Android manifest file.</p>
<h3 id="DeclaringSearchableActivity">Declaring a searchable Activity</h3>
-<p>If you don't have one already, create an {@link android.app.Activity} that will be used to
-perform searches, then declare it to
-accept the {@link android.content.Intent#ACTION_SEARCH} {@link android.content.Intent} and apply the
-searchable configuration. To do so, you need to add an {@code
-&lt;intent-filter&gt;} element and a {@code &lt;meta-data&gt;} element to the
-appropriate {@code &lt;activity&gt;} element in your manifest file. For example:</p>
+<p>If you don't have one already, create an {@link android.app.Activity} that performs
+searches and present search results. To set up this Activity as your searchable Activity:</p>
+<ol>
+ <li>Declare the Activity to accept the {@link android.content.Intent#ACTION_SEARCH} {@link
+android.content.Intent}, in an <a
+href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>
+element.</li>
+ <li>Apply the searchable configuration, in a <a
+href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
+element.</li>
+</ol>
+
+<p>For example:</p>
<pre>
&lt;application ... >
@@ -147,29 +176,27 @@ appropriate {@code &lt;activity&gt;} element in your manifest file. For example:
&lt;/application>
</pre>
-<p>The {@code android:name} attribute in the {@code &lt;meta-data&gt;} element must be defined with
-{@code "android.app.searchable"} and the {@code android:resource} attribute value must be a
-reference to the searchable configuration file saved in {@code res/xml} (in this example, it
+<p>The {@code &lt;meta-data&gt;} element must include the {@code android:name} attribute with a
+value of {@code "android.app.searchable"} and the {@code android:resource} attribute with a
+reference to the searchable configuration file (in this example, it
refers to the {@code res/xml/searchable.xml} file).</p>
-<p class="note">If you're wondering why the {@code
-&lt;intent-filter&gt;} does not include a {@code &lt;category&gt;} with the {@code DEFAULT}
-value, it's because the Intent that is delivered to this Activity when a search is executed will
-explicitly define this Activity as the component for the Intent (which the Search Manager knows
-from the searcahble meta-data declared for the Activity).</p>
+<p class="note"><strong>Note:</strong> The {@code &lt;intent-filter&gt;} does not need a <a
+href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a> with the
+{@code DEFAULT} value, because the Search Manager delivers the {@link
+android.content.Intent#ACTION_SEARCH} Intent explicitly to your searchable Activity by name.</p>
-<p>Be aware that the search dialog will not be available from within every
-Activity of your application, by default. Rather, the search dialog will be presented to
-users only when they
+<p>The search dialog is not, by default, available from every Activity of your
+application. Rather, the search dialog is presented to users only when they
invoke search from a searchable context of your application. A searchable context is any Activity
for which you have
declared searchable meta-data in the manifest file. For example, the searchable Activity itself
(declared in the manifest snippet above) is
-a searchable context because it contains searchable meta-data that defines the
+a searchable context because it includes meta-data that defines the
searchable configuration. Any other Activity in your application is not a searchable context, by
-default, and thus, will not reveal the search dialog. You probably do want the
-search dialog to be available from every Activity in your application, so this can be easily
-fixed.</p>
+default, and thus, does not reveal the search dialog. However, you probably do want the search
+dialog available from your other activities (and to launch the searchable Activity when the user
+executes a search). You can do exactly that.</p>
<p>If you want all of your activities to provide the search dialog, add another {@code
&lt;meta-data&gt;} element inside the {@code
@@ -187,9 +214,9 @@ default searchable Activity. For example:</p>
&lt;/activity>
&lt;activity android:name=".AnotherActivity" ... >
&lt;/activity>
- &lt;!-- this one declares the searchable Activity for the whole app --&gt;
- &lt;meta-data android:name="android.app.default_searchable"
- android:value=".MySearchableActivity" />
+ &lt;!-- declare the default searchable Activity for the whole app --&gt;
+ <b>&lt;meta-data android:name="android.app.default_searchable"
+ android:value=".MySearchableActivity" /&gt;</b>
...
&lt;/application>
</pre>
@@ -199,28 +226,34 @@ default searchable Activity. For example:</p>
which it is placed (which, in this case, is the entire application). The searchable Activity to
use is specified with the {@code android:value} attribute. All other activities in the
application, such as {@code AnotherActivity}, are now considered a searchable context and can invoke
-the search dialog. When a search is executed, {@code MySearchableActivity} will
-be launched to handle the search query.</p>
+the search dialog. When a search is executed, {@code MySearchableActivity} is launched to handle
+the search query.</p>
-<p>Notice that this allows you to control which activities provide search at a more granular level.
-To specify only an individual Activity as a searchable context, simply place the {@code
+<p>You can also control which activities provide search at a more granular level.
+To specify only an individual Activity as a searchable context, place the {@code
&lt;meta-data&gt;} with the {@code
"android.app.default_searchable"} name inside the respective {@code &lt;activity&gt;}
-element (rather than inside the {@code &lt;application&gt;}). And, while it is uncommon, you can
-even create more than one searchable Activity and provide each one in different contexts of your
+element (rather than inside the {@code &lt;application&gt;} element). While uncommon, you
+can also create more than one searchable Activity and provide each one in different contexts of your
application, either by declaring a different searchable Activity in each {@code &lt;activity&gt;}
-element, or declaring a default searchable Activity for the entire application and then overriding
-it with a different {@code &lt;meta-data&gt;} element inside certain activities.</p>
+element, or by declaring a default searchable Activity for the entire application and then
+overriding it with a {@code &lt;meta-data&gt;} element inside certain activities. (You might do
+this if you want to search different sets of data that cannot be handled by the same
+searchable Activity, depending on the currently open Activity.)</p>
<h3 id="PerformingSearch">Performing a search</h3>
-<p>Once your Activity is declared searchable, performing the actual search involves three steps:
-receiving the query, searching your data, and presenting the results.</p>
+<p>Once you have declared your searchable Activity, performing a search for the user involves
+three steps:</p>
+<ol>
+ <li><a href="#ReceivingTheQuery">Receiving the query</a></li>
+ <li><a href="#SearchingYourData">Searching your data</a></li>
+ <li><a href="#PresentingTheResults">Presenting the results</a></li>
+</ol>
-<p>Traditionally, your search results should be presented in a {@link android.widget.ListView}
-(assuming that our results are text-based), so
-you may want your searchable Activity to extend {@link android.app.ListActivity}, which
+<p>Traditionally, your search results should be presented in a {@link android.widget.ListView}, so
+you might want your searchable Activity to extend {@link android.app.ListActivity}, which
provides easy access to {@link android.widget.ListView} APIs. (See the <a
href="{@docRoot}resources/tutorials/views/hello-listview.html">List View Tutorial</a> for a simple
{@link android.app.ListActivity} sample.)</p>
@@ -228,12 +261,12 @@ href="{@docRoot}resources/tutorials/views/hello-listview.html">List View Tutoria
<h4 id="ReceivingTheQuery">Receiving the query</h4>
-<p>When a search is executed from the search dialog, your searchable Activity will be opened
-with the {@link android.content.Intent#ACTION_SEARCH} {@link android.content.Intent}, which carries
-the search query in the
-{@link android.app.SearchManager#QUERY QUERY} extra. All you need to do is check for
-this Intent and extract the string. For example, here's how you can get the query when your
-Activity launches:</p>
+<p>When a user executes a search from the search dialog, the Search Manager sends the {@link
+android.content.Intent#ACTION_SEARCH} {@link android.content.Intent} to your searchable Activity.
+This Intent carries the search query in the
+{@link android.app.SearchManager#QUERY QUERY} string extra. You must check for
+this Intent when the Activity starts and extract the string. For example, here's how you can get the
+query when your Activity starts:</p>
<pre>
&#64;Override
@@ -258,22 +291,21 @@ is done.</p>
<h4 id="SearchingYourData">Searching your data</h4>
-<p>The process of storing and searching your data is a process that's unique to your application.
-There are many ways that you might do this and discussing all options is beyond the scope of
-this document. This guide will not teach you how to store your data and search it; this
-is something you must carefully consider in terms of your needs and your data. However, here are
-some tips you may be able to apply:</p>
+<p>The process of storing and searching your data is unique to your application.
+You can store and search your data in many ways, but this guide does not show you how to store your
+data and search it. Storing and searching your data is something you should carefully consider in
+terms of your needs and your data. However, here are some tips you might be able to apply:</p>
<ul>
<li>If your data is stored in a SQLite database on the device, performing a full-text search
(using FTS3, rather than a LIKE query) can provide a more robust search across text data and can
-produce results many, many times faster. See <a href="http://sqlite.org/fts3.html">sqlite.org</a>
+produce results significantly faster. See <a href="http://sqlite.org/fts3.html">sqlite.org</a>
for information about FTS3 and the {@link android.database.sqlite.SQLiteDatabase} class for
information about SQLite on Android. Also look at the <a
href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample
application to see a complete SQLite implementation that performs searches with FTS3.</li>
- <li>If your data is stored online, then the perceived search performance may be
-inhibited by the user's data connection. You may want to display a spinning progress wheel until
+ <li>If your data is stored online, then the perceived search performance might be
+inhibited by the user's data connection. You might want to display a spinning progress wheel until
your search returns. See {@link android.net} for a reference of network APIs and <a
href="{@docRoot}guide/topics/ui/dialogs.html#ProgressDialog">Creating a Progress Dialog</a> to see
how you can display a progress wheel.</li>
@@ -283,32 +315,32 @@ how you can display a progress wheel.</li>
<div class="sidebox-wrapper">
<div class="sidebox">
<h2>About Adapters</h2>
-<p>An Adapter will bind individual items from a set of data into individual {@link
+<p>An Adapter binds individual items from a set of data into individual {@link
android.view.View} objects. When the Adapter
is applied to a {@link android.widget.ListView}, the Views are injected as individual items of the
list. {@link
android.widget.Adapter} is simply an interface, so implementations such as {@link
android.widget.CursorAdapter} (for binding data from a {@link android.database.Cursor}) are needed.
If none of the existing implementations work for your data, then you should implement your own from
-{@link android.widget.BaseAdapter}. Install the SDK Samples package for API Level 4 to see a
-version of the Searchable Dictionary that creates a custom BaseAdapter.</p>
+{@link android.widget.BaseAdapter}. Install the SDK Samples package for API Level 4 to see the
+original version of the Searchable Dictionary, which creates a custom BaseAdapter.</p>
</div>
</div>
<p>Regardless of where your data lives and how you search it, we recommend that you return search
results to your searchable Activity with an {@link android.widget.Adapter}. This way, you can easily
present all the search results in a {@link android.widget.ListView}. If your data comes from a
-SQLite database query, then you can easily apply your results to a {@link android.widget.ListView}
+SQLite database query, then you can apply your results to a {@link android.widget.ListView}
using a {@link android.widget.CursorAdapter}. If your data comes in some other type of format, then
you can create an extension of the {@link android.widget.BaseAdapter}.</p>
<h4 id="PresentingTheResults">Presenting the results</h4>
-<p>Presenting your search results is mostly a UI detail and not something covered by the search
-framework APIs. However, a simple solution is to create your searchable Activity to extend {@link
-android.app.ListActivity} and then call {@link
+<p>Presenting your search results is mostly a UI detail that is not handled by the search APIs.
+However, one option is to create your searchable Activity to extend {@link
+android.app.ListActivity} and call {@link
android.app.ListActivity#setListAdapter(ListAdapter)}, passing it an {@link
-android.widget.Adapter} that is bound to your data. This will automatically project all the
+android.widget.Adapter} that is bound to your data. This injects all the
results into the Activity {@link android.widget.ListView}.</p>
<p>For more help presenting your results, see the {@link android.app.ListActivity}
@@ -316,29 +348,27 @@ documentation.</p>
<p>Also see the <a
href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample
-application for an a complete demonstration of how to search an SQLite database and use an
-{@link android.widget.Adapter} to provide resuls in a {@link android.widget.ListView}.</p>
+for an a complete demonstration of how to search an SQLite database and use an
+{@link android.widget.Adapter} to provide results in a {@link android.widget.ListView}.</p>
+
<h2 id="InvokingTheSearchDialog">Invoking the Search Dialog</h2>
-<p>Once you have a searchable Activity in place, invoking the search dialog so the user can
-submit a
-query is easy. Many Android devices provide a dedicated search key and when it is pressed while the
-user is within a searchable context of your application, the search dialog will be revealed.
-However,
-you should never assume that a search key is available on the user's device and should always
-provide a search button in your UI that will invoke search.</p>
+<p>Once you have a searchable Activity, invoking the search dialog is easy. Many Android
+devices provide a dedicated SEARCH key, which reveals the search dialog when the user presses it
+from a searchable context of your application. However, you should not assume that a SEARCH
+key is available on the user's device and should always provide a search button in your UI that
+invokes search.</p>
-<p>To invoke search from your Activity, simply call {@link
-android.app.Activity#onSearchRequested()}.</p>
+<p>To invoke search from your Activity, call {@link android.app.Activity#onSearchRequested()}.</p>
-<p>For example, you should provide a menu item in your <a
+<p>For instance, you should provide a menu item in your <a
href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a> or a button in your UI to
-invoke search with this method. For your convenience, this <a
+invoke search with this method. The <a
href="{@docRoot}shareables/search_icons.zip">search_icons.zip</a> file includes icons for
-medium and high density screens, which you can use for your menu item or button (low density
-screens will automatically scale-down the hdpi image by one half). </p>
+medium and high density screens, which you can use for your search menu item or button (low density
+screens automatically scale-down the hdpi image by one half). </p>
<!-- ... maybe this should go into the Creating Menus document ....
<p>If you chose to provide a shortcut key for the menu item, using {@link
@@ -346,28 +376,29 @@ android.view.MenuItem#setAlphabeticShortcut(char)}, then SearchManager.MENU_KEY
key character, representing the default search key.</p>
-->
-<p>You can also enable "type-to-search" functionality in your Activity by calling {@link
-android.app.Activity#setDefaultKeyMode(int) setDefaultKeyMode}({@link
-android.app.Activity#DEFAULT_KEYS_SEARCH_LOCAL}). When this is enabled and the user begins typing on
-the keyboard, search will automatically be
-invoked and the keystrokes will be inserted in the search dialog. Be sure to enable this mode
-during your Activity {@link android.app.Activity#onCreate(Bundle) onCreate()} method.</p>
+<p>You can also enable "type-to-search" functionality, which reveals the search dialog when the
+user starts typing on the keyboard and the keystrokes are inserted into the search dialog. You can
+enable type-to-search in your Activity by calling
+{@link android.app.Activity#setDefaultKeyMode(int) setDefaultKeyMode}({@link
+android.app.Activity#DEFAULT_KEYS_SEARCH_LOCAL}) during your Activity's
+{@link android.app.Activity#onCreate(Bundle) onCreate()} method.</p>
-<h3 id="LifeCycle">The impact of the search dialog on your Activity life-cycle</h3>
+<h3 id="LifeCycle">The impact of the search dialog on your Activity lifecycle</h3>
-<p>The search dialog behaves like a {@link android.app.Dialog} that floats at the top of the
-screen. It
-does not cause any change in the Activity stack, so no life-cycle methods (such as {@link
-android.app.Activity#onPause()}) will
-be called. All that happens is your Activity loses input focus as it is given to the search dialog.
+<p>The search dialog is a {@link android.app.Dialog} that floats at the top of the
+screen. It does not cause any change in the Activity stack, so when the search dialog appears, no
+lifecycle methods for the currently open Activity (such as {@link
+android.app.Activity#onPause()}) are called. Your Activity just loses input focus as it is given to
+the search dialog.
</p>
-<p>If you want to be notified when search is invoked, simply override the {@link
-android.app.Activity#onSearchRequested()} method. When this is called, you can do any work you may
-want to do when your Activity looses input focus (such as pause animations). But unless you are
-<a href="#SearchContextData">Passing Search Context Data</a> (discussed above), you should always
-call the super class implementation. For example:</p>
+<p>If you want to be notified when search is invoked, override the {@link
+android.app.Activity#onSearchRequested()} method. When the system calls this method, you can do any
+work you want to when your Activity looses input focus to the search dialog (such as pause
+animations). Unless you are <a href="#SearchContextData">passing search context data</a>
+(discussed below), you should end the method by calling the super class implementation. For
+example:</p>
<pre>
&#64;Override
@@ -377,35 +408,37 @@ public boolean onSearchRequested() {
}
</pre>
-<p>If the user cancels search by pressing the device Back key, the Activity in which search was
-invoked will re-gain input focus. You can register to be notified when the search dialog is
-closed with {@link android.app.SearchManager#setOnDismissListener(SearchManager.OnDismissListener)}
-and/or {@link android.app.SearchManager#setOnCancelListener(SearchManager.OnCancelListener)}. You
-should normally only need to register the {@link android.app.SearchManager.OnDismissListener
-OnDismissListener}, because this is called every time that the search dialog is closed. The {@link
+<p>If the user cancels search by pressing the BACK key, the Activity in which search was
+invoked re-gains input focus. You can register to be notified when the search dialog is
+closed with {@link android.app.SearchManager#setOnDismissListener(SearchManager.OnDismissListener)
+setOnDismissListener()}
+and/or {@link android.app.SearchManager#setOnCancelListener(SearchManager.OnCancelListener)
+setOnCancelListener()}. You
+should need to register only the {@link android.app.SearchManager.OnDismissListener
+OnDismissListener}, because it is called every time the search dialog closes. The {@link
android.app.SearchManager.OnCancelListener OnCancelListener} only pertains to events in which the
-user explicitly left the search dialog, so it is not called when a search is executed (in which
+user explicitly exited the search dialog, so it is not called when a search is executed (in which
case, the search dialog naturally disappears).</p>
-<p>If the current Activity is not the searchable Activity, then the normal Activity life-cycle
-events will be triggered once the user executes a search (the current Activity will receive {@link
+<p>If the current Activity is not the searchable Activity, then the normal Activity lifecycle
+events are triggered once the user executes a search (the current Activity receives {@link
android.app.Activity#onPause()} and so forth, as
described in <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application
Fundamentals</a>). If, however, the current Activity is the searchable Activity, then one of two
-things will happen:</p>
+things happens:</p>
-<ul>
- <li>By default, the searchable Activity will receive the {@link
+<ol type="a">
+ <li>By default, the searchable Activity receives the {@link
android.content.Intent#ACTION_SEARCH} Intent with a call to {@link
android.app.Activity#onCreate(Bundle) onCreate()} and a new instance of the
-Activity will be brought to the top of the stack. You'll now have two instances of your searchable
-Activity in the Activity stack (so pressing the Back key will go back to the previous instance of
-the searchable Activity, rather than exiting the searchable Activity).</li>
- <li>On the other hand, if the Activity has set {@code android:launchMode} to "singleTop" then the
-searchable Activity will receive the {@link android.content.Intent#ACTION_SEARCH} Intent with a call
+Activity is brought to the top of the Activity stack. There are now two instances of your
+searchable Activity in the Activity stack (so pressing the BACK key goes back to the previous
+instance of the searchable Activity, rather than exiting the searchable Activity).</li>
+ <li>If you set {@code android:launchMode} to "singleTop", then the
+searchable Activity receives the {@link android.content.Intent#ACTION_SEARCH} Intent with a call
to {@link android.app.Activity#onNewIntent(Intent)}, passing the new {@link
-android.content.Intent#ACTION_SEARCH} Intent here. For example, here's how you might want to handle
-this case:
+android.content.Intent#ACTION_SEARCH} Intent here. For example, here's how you might handle
+this case, in which the searchable Activity's launch mode is "singleTop":
<pre>
&#64;Override
public void onCreate(Bundle savedInstanceState) {
@@ -430,28 +463,30 @@ private void handleIntent(Intent intent) {
<p>Compared to the example code in the section about <a href="#PerfomingSearch">Performing a
Search</a>, all the code to handle the
-search Intent has been moved outside the {@link android.app.Activity#onCreate(Bundle)
-onCreate()} method so it can also be executed from {@link android.app.Activity#onNewIntent(Intent)
-onNewIntent()}.
-It's important to note that when {@link android.app.Activity#onNewIntent(Intent)} is
-called, the Activity has not been restarted, so the {@link android.app.Activity#getIntent()} method
-will still return the Intent that was first received with {@link
-android.app.Activity#onCreate(Bundle) onCreate()}. This is why {@link
-android.app.Activity#setIntent(Intent)} is called inside {@link
-android.app.Activity#onNewIntent(Intent)} (just in case you call {@link
-android.app.Activity#getIntent()} at a later time).</p>
+search Intent is now in the {@code handleIntent()} method, so that both {@link
+android.app.Activity#onCreate(Bundle)
+onCreate()} and {@link android.app.Activity#onNewIntent(Intent) onNewIntent()} can execute it.</p>
+
+<p>When the system calls {@link android.app.Activity#onNewIntent(Intent)}, the Activity has
+not been restarted, so the {@link android.app.Activity#getIntent()} method
+returns the same Intent that was received with {@link
+android.app.Activity#onCreate(Bundle) onCreate()}. This is why you should call {@link
+android.app.Activity#setIntent(Intent)} inside {@link
+android.app.Activity#onNewIntent(Intent)} (so that the Intent saved by the Activity is updated in
+case you call {@link android.app.Activity#getIntent()} in the future).</p>
</li>
-</ul>
+</ol>
-<p>This second scenario is normally ideal, because the chances are good that once a search is
-completed, the user will perform additional searches and it's a bad experience if your application
-piles multiple instances of the searchable Activity on the stack. So we recommend that you set your
-searchable Activity to "singleTop" launch mode in the application manifest. For example:</p>
+<p>The second scenario using "singleTop" launch mode is usually ideal, because chances are good that
+once a search is done, the user will perform additional searches and it's a bad experience if your
+application creates multiple instances of the searchable Activity. So, we recommend that you set
+your searchable Activity to "singleTop" launch mode in the application
+manifest. For example:</p>
<pre>
&lt;activity android:name=".MySearchableActivity"
- android:launchMode="singleTop" >
+ <b>android:launchMode="singleTop"</b> >
&lt;intent-filter>
&lt;action android:name="android.intent.action.SEARCH" />
&lt;/intent-filter>
@@ -461,19 +496,20 @@ searchable Activity to "singleTop" launch mode in the application manifest. For
</pre>
+
<h2 id="SearchContextData">Passing Search Context Data</h2>
-<p>In order to refine your search criteria, you may want to provide some additional
-data to your searchable Activity when a search is executed. For instance, when you search your data,
-you may want to filter results based on more than just the search query text. In a simple
-case, you could just make your refinements inside the searchable Activity, for every search made.
-If, however, your
-search criteria may vary from one searchable context to another, then you can pass whatever data is
-necessary to refine your search in the {@link android.app.SearchManager#APP_DATA} Bundle, which is
-included in the {@link android.content.Intent#ACTION_SEARCH} Intent.</p>
-
-<p>To pass this kind of data to your searchable Activity, you need to override {@link
-android.app.Activity#onSearchRequested()} method for the Activity in which search will be invoked.
+<p>To refine your search criteria from the current Activity instead of depending only on the user's
+search query, you can provide additional data in the Intent that the Search Manager sends to your
+searchable Activity. In a simple case, you can make your refinements inside the searchable
+Activity, for every search made, but if your
+search criteria varies from one searchable context to another, then you can pass whatever data
+is necessary to refine your search in the {@link android.app.SearchManager#APP_DATA} {@link
+android.os.Bundle}, which is included in the {@link android.content.Intent#ACTION_SEARCH}
+Intent.</p>
+
+<p>To pass this kind of data to your searchable Activity, override {@link
+android.app.Activity#onSearchRequested()} method for the Activity in which search can be invoked.
For example:</p>
<pre>
@@ -487,56 +523,54 @@ public boolean onSearchRequested() {
</pre>
<p>Returning "true" indicates that you have successfully handled this callback event. Then in your
-searchable Activity, you can extract this data from the {@link
+searchable Activity, you can extract the data placed inside {@code appdata} from the {@link
android.app.SearchManager#APP_DATA} {@link android.os.Bundle} to refine the search. For example:</p>
<pre>
- Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
- if (appData != null) {
- boolean jargon = appData.getBoolean(MySearchableActivity.JARGON);
- }
+Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
+if (appData != null) {
+ boolean jargon = appData.getBoolean(MySearchableActivity.JARGON);
+}
</pre>
-<p class="caution"><strong>Note:</strong> You should never call the {@link
+<p class="caution"><strong>Caution:</strong> Never call the {@link
android.app.Activity#startSearch(String,boolean,Bundle,boolean) startSearch()} method from outside
-the {@link android.app.Activity#onSearchRequested()} callback method. When you want to invoke the
-search dialog, always call {@link android.app.Activity#onSearchRequested()} so that custom
-implementations (such as the addition of {@code appData}, in the above example) can be accounted
-for.</p>
+the {@link android.app.Activity#onSearchRequested()} callback method. To invoke the search dialog
+in your Activity, always call {@link android.app.Activity#onSearchRequested()}. Otherwise, {@link
+android.app.Activity#onSearchRequested()} is not called and customizations (such as the addition of
+{@code appData} in the above example) are missed.</p>
<h2 id="VoiceSearch">Adding Voice Search</h2>
-<p>You can easily add voice search functionality to your search dialog by adding the {@code
-android:voiceSearchMode} attribute to your searchable configuration. This will add a voice search
-button in the search dialog that, when clicked, will launch a voice prompt. When the user
-has finished speaking, the transcribed search query will be sent to your searchable
+<p>You can add voice search functionality to your search dialog by adding the {@code
+android:voiceSearchMode} attribute to your searchable configuration. This adds a voice search
+button in the search dialog that launches a voice prompt. When the user
+has finished speaking, the transcribed search query is sent to your searchable
Activity.</p>
-<p>To enable voice search for your activity, add the {@code android:voiceSearchMode}
-attribute to your searchable configuration. For example:</p>
+<p>For example:</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/search_label"
android:hint="@string/search_hint"
- android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" >
+ <b>android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"</b> >
&lt;/searchable>
</pre>
<p>The value {@code showVoiceSearchButton} is required to enable voice
search, while the second value, {@code launchRecognizer}, specifies that the voice search button
-should launch a recognizer that returns the transcribed text to the searchable Activity. This is
-how most applications should declare this attribute.</p>
+should launch a recognizer that returns the transcribed text to the searchable Activity.</p>
-<p>There are some additional attributes you can provide to specify the voice search behavior, such
+<p>You can provide additional attributes to specify the voice search behavior, such
as the language to be expected and the maximum number of results to return. See the <a
-href="searchable-config.html">Searchable Configuration</a> for more information about the
+href="searchable-config.html">Searchable Configuration</a> reference for more information about the
available attributes.</p>
<p class="note"><strong>Note:</strong> Carefully consider whether voice search is appropriate for
-your application. All searches performed with the voice search button will be immediately sent to
-your searchable Activity without a chance for the user to review the transcribed query. Be sure to
-sufficiently test the voice recognition and ensure that it understands the types of queries that
-the user will submit inside your application.</p>
+your application. All searches performed with the voice search button are immediately sent to
+your searchable Activity without a chance for the user to review the transcribed query. Sufficiently
+test the voice recognition and ensure that it understands the types of queries that
+the user might submit inside your application.</p>
diff --git a/docs/html/guide/topics/search/searchable-config.jd b/docs/html/guide/topics/search/searchable-config.jd
index 71566de..2aa2db6 100644
--- a/docs/html/guide/topics/search/searchable-config.jd
+++ b/docs/html/guide/topics/search/searchable-config.jd
@@ -14,18 +14,18 @@ parent.link=index.html
</div>
</div>
-<p>In order to utilize the Android search framework and provide a custom search dialog, your
+<p>To utilize the Android search framework and provide a custom search dialog, your
application must provide a search
configuration in the form of an XML resource. This document describes the search configuration XML
-in terms of its syntax and usage. For a more complete discussion about how to implement search
-features for your application, see the companion documents about <a
+in terms of its syntax and usage. For more information about how to implement search
+features for your application, see the developer guide about <a
href="index.html">Search</a>.</p>
<dl class="xml">
<dt>file location:</dt>
<dd><code>res/xml/<em>filename</em>.xml</code><br/>
-The filename will be used as the resource ID.</dd>
+Android uses the filename as the resource ID.</dd>
<dt>syntax:</dt>
<dd>
@@ -70,174 +70,187 @@ The filename will be used as the resource ID.</dd>
<p class="caps">attributes:</p>
<dl class="atn-list">
<dt><code>android:label</code></dt>
- <dd><em>String resource</em>. <strong>Required</strong>. This is the name of your application.
-It should normally be the same as the name applied to the {@code android:label} attribute of your <a
+ <dd><em>String resource</em>. (Required.) The name of your application.
+It should be the same as the name applied to the {@code android:label} attribute of your <a
href="{@docRoot}guide/topics/manifest/activity-element.html#label">{@code &lt;activity&gt;}</a> or
<a href="{@docRoot}guide/topics/manifest/application-element.html#label">{@code
-&lt;application&gt;}</a> manifest element. This is only visible to the user when you set
-<code>android:includeInGlobalSearch</code> "true", in which case, this label is used to identify
+&lt;application&gt;}</a> manifest element. This label is only visible to the user when you set
+<code>android:includeInGlobalSearch</code> to "true", in which case, this label is used to identify
your application as a searchable item in the system's search settings.</dd>
+
<dt><code>android:hint</code></dt>
- <dd><em>String resource</em>. The text to display in the search text field when no text has
- been entered. This is recommended in order to provide a hint to the user about what
-content is searchable. For consistency among other Android applications, you should format the
+ <dd><em>String resource</em>. (Recommended.) The text to display in the search text field when
+no text has been entered. It provides a hint to the user about what
+content is searchable. For consistency with other Android applications, you should format the
string for {@code android:hint} as "Search <em>&lt;content-or-product&gt;</em>". For example,
"Search songs and artists" or "Search YouTube".</dd>
+
<dt><code>android:searchMode</code></dt>
- <dd><em>Keyword</em>. Sets additional modes that control the search presentation.
-Specifically, the available modes define how the query text in the search dialog's text box
-should be rewritten when a suggestion is focused. The following mode values are accepted:
+ <dd><em>Keyword</em>. Sets additional modes that control the search dialog presentation.
+Currently available modes define how the query text that appears in the search dialog
+should be rewritten when a custom suggestion receives focus. The following mode values are accepted:
<table>
<tr><th>Value</th><th>Description</th></tr>
<tr>
- <td><code>"queryRewriteFromData"</code></td>
- <td>If set, this causes the suggestion column
- {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} to be considered as the
-text for suggestion query
- rewriting. This should only be used when the values in
- {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} are suitable for user
-inspection and editing -
- typically, HTTP/HTTPS Uri's.</td>
+ <td><code>"queryRewriteFromText"</code></td>
+ <td>Use the value from the {@link android.app.SearchManager#SUGGEST_COLUMN_TEXT_1}
+colum to rewrite the query text in the search dialog.</td>
</tr>
<tr>
- <td><code>"queryRewriteFromText"</code></td>
- <td>If set, this causes the suggestion
- column {@link android.app.SearchManager#SUGGEST_COLUMN_TEXT_1} to be considered as the
-text for suggestion query
- rewriting. This should be used for suggestions in which no query
- text is provided and the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA}
-values are not suitable
- for user inspection and editing.</td>
+ <td><code>"queryRewriteFromData"</code></td>
+ <td>Use the value from the
+ {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column to rewrite the
+query text in the search dialog. This should only be used when the values in
+ {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} are suitable for user
+inspection and editing, typically HTTP URI's.</td>
</tr>
</table>
<p>For more information, see the discussion about rewriting the query text in <a
href="adding-custom-suggestions.html#RewritingQueryText">Adding Custom Suggestions</a>.</p>
</dd>
+
<dt><code>android:searchButtonText</code></dt>
- <dd><em>String resource</em>. The text to display in the button that executes the search. By
+ <dd><em>String resource</em>. The text to display in the button that executes search. By
default, the button shows a search icon (a magnifying glass), which is ideal for
-internationalization.</dd>
+internationalization, so you should not use this attribute to change the button unless the
+behavior is something other than a search (such as a URL request in a web browser).</dd>
+
<dt><code>android:inputType</code></dt>
- <dd><em>Keyword</em>. Defines the type of input method (soft-keyboard) to use with the search
-dialog. For most searches, in which free form text is expected, this attribute is not needed and
-the default input method should be used. See {@link android.R.attr#inputType} for a list of suitable
-values for this attribute.</dd>
+ <dd><em>Keyword</em>. Defines the type of input method (such as the type of soft keyboard)
+to use with the search dialog. For most searches, in which free-form text is expected, you don't
+need this attribute. See {@link android.R.attr#inputType} for a list of suitable values for this
+attribute.</dd>
+
<dt><code>android:imeOptions</code></dt>
<dd><em>Keyword</em>. Supplies additional options for the input method.
- For most searches, in which free form text is expected, this attribute is not needed,
- and will default to "actionSearch" (provides the "search" button instead of a carriage
-return). See {@link android.R.attr#imeOptions} for a list of suitable values for this attribute.
+ For most searches, in which free-form text is expected, you don't need this attribute. The
+default IME is "actionSearch" (provides the "search" button instead of a carriage
+return in the soft keyboard). See {@link android.R.attr#imeOptions} for a list of suitable values
+for this attribute.
</dd>
</dl>
+
+ <h4>Search suggestion attributes</h4>
+
<p>If you have defined a content provider to generate search suggestions, you need to
- define additional attributes in order to configure communications with the Content
- Provider. When providing search suggestions, you'll need some of the following
+ define additional attributes that configure communications with the content
+ provider. When providing search suggestions, you need some of the following
{@code &lt;searchable>} attributes:</p><br/>
<dl class="atn-list">
<dt><code>android:searchSuggestAuthority</code></dt>
- <dd><em>String</em>. <strong>Required to provide search suggestions</strong>.
+ <dd><em>String</em>. (Required to provide search suggestions.)
This value must match the authority string provided in the {@code android:authorities}
-attribute of the {@code &lt;provider>} element.</dd>
+attribute of the Android manifest {@code &lt;provider>} element.</dd>
+
<dt><code>android:searchSuggestPath</code></dt>
- <dd><em>String</em>. This path will be used as a portion of the suggestions
+ <dd><em>String</em>. This path is used as a portion of the suggestions
query {@link android.net.Uri}, after the prefix and authority, but before
the standard suggestions path.
This is only required if you have a single content provider issuing different types
- of suggestions (e.g. for different data types) and you need
- a way to disambiguate the suggestions queries when they are received.</dd>
+ of suggestions (such as for different data types) and you need
+ a way to disambiguate the suggestions queries when you receive them.</dd>
+
<dt><code>android:searchSuggestSelection</code></dt>
- <dd><em>String</em>. This value will be passed into your
- query function as the {@code selection} parameter. Typically this will be a WHERE clause
-for your database, and should contain a single question mark, which is a place-holder for the
-actual query string that has been typed by the user. However, you can also use any non-null
-value to simply trigger the delivery of the query text via the {@code
+ <dd><em>String</em>. This value is passed into your
+ query function as the {@code selection} parameter. Typically this is a WHERE clause
+for your database, and should contain a single question mark, which is a placeholder for the
+actual query string that has been typed by the user (for example, {@code "query=?"}). However, you
+can also use any non-null value to trigger the delivery of the query text via the {@code
selectionArgs} parameter (and then ignore the {@code selection} parameter).</dd>
+
<dt><code>android:searchSuggestIntentAction</code></dt>
<dd><em>String</em>. The default Intent action to be used when a user
- clicks on a search suggestion (such as {@code "android.intent.action.VIEW"}).
- If not overridden by the selected suggestion (via the {@link
-android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column), this value will
- be placed in the action field of the {@link android.content.Intent} when the
- user clicks a suggestion.</dd>
+ clicks on a custom search suggestion (such as {@code "android.intent.action.VIEW"}).
+ If this is not overridden by the selected suggestion (via the {@link
+android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column), this value is placed in the action
+field of the {@link android.content.Intent} when the user clicks a suggestion.</dd>
+
<dt><code>android:searchSuggestIntentData</code></dt>
<dd><em>String</em>. The default Intent data to be used when a user
- clicks on a search suggestion.
+ clicks on a custom search suggestion.
If not overridden by the selected suggestion (via the {@link
-android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column), this value will be
+android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column), this value is
placed in the data field of the {@link android.content.Intent} when the user clicks
a suggestion.</dd>
+
<dt><code>android:searchSuggestThreshold</code></dt>
<dd><em>Integer</em>. The minimum number of characters needed to
- trigger a suggestion look-up. Only guarantees that a source will not be
- queried for anything shorter than the threshold. The default value is 0.</dd>
+ trigger a suggestion look-up. Only guarantees that the Search Manager will not query your
+ content provider for anything shorter than the threshold. The default value is 0.</dd>
</dl>
<p>For more information about the above attributes for search suggestions, see the guides for
<a href="adding-recent-query-suggestions.html">Adding Recent Query Suggestions</a> and
<a href="adding-custom-suggestions.html">Adding Custom Suggestions</a>.</p>
- <p>Beyond providing search suggestions while using your application's search dialog, you
- can also configure your search suggestions to be made available to Quick Search Box,
- which will allow users so receive search suggestions from your application content from outside
- your application. When providing search suggestions to Quick Search Box, you'll need some of the
+
+ <h4>Quick Search Box attributes</h4>
+
+ <p>To make your custom search suggestions available to Quick Search Box, you need some of the
following {@code &lt;searchable>} attributes:</p><br/>
<dl class="atn-list">
<dt><code>android:includeInGlobalSearch</code></dt>
- <dd><em>Boolean</em>. <strong>Required to provide search suggestions in
- Quick Search Box</strong>. "true" if you want your suggestions to be
- included in the globally accessible Quick Search Box. Note that the user must
- still enable your application as a searchable item in the system search settings in order
- for your suggestions to appear in Quick Search Box.</dd>
+ <dd><em>Boolean</em>. (Required to provide search suggestions in
+ Quick Search Box.) Set to "true" if you want your suggestions to be
+ included in the globally accessible Quick Search Box. The user must
+ still enable your application as a searchable item in the system search settings before
+ your suggestions will appear in Quick Search Box.</dd>
+
<dt><code>android:searchSettingsDescription</code></dt>
<dd><em>String</em>. Provides a brief description of the search suggestions that you provide
-to Quick Search Box, which will be displayed in the searchable items entry for your application.
+to Quick Search Box, which is displayed in the searchable items entry for your application.
Your description should concisely describe the content that is searchable. For example, "Artists,
albums, and tracks" for a music application, or "Saved notes" for a notepad application.</dd>
+
<dt><code>android:queryAfterZeroResults</code></dt>
- <dd><em>Boolean</em>. "true" if you want your content provider to be invoked for
- supersets of queries that have returned zero results for in the past. For example, if a
- source returned zero results for "bo", it would be ignored for "bob". If "false",
- this source will only be ignored for a single session; the next time the search dialog
- is invoked, all sources will be queried. The default value is false.</dd>
+ <dd><em>Boolean</em>. Set to "true" if you want your content provider to be invoked for
+ supersets of queries that have returned zero results in the past. For example, if
+your content provider returned zero results for "bo", it should be requiried for "bob". If set to
+"false", supersets are ignored for a single session ("bob" does not invoke a requery). This lasts
+only for the life of the search dialog (when the search dialog is reopened, "bo" queries your
+content provider again). The default value is false.</dd>
</dl>
+
+ <h4>Voice search attributes</h4>
+
<p>To enable voice search for your search dialog, you'll need some of the
following {@code &lt;searchable>} attributes:</p><br/>
<dl class="atn-list">
<dt><code>android:voiceSearchMode</code></dt>
- <dd><em>Keyword</em>. <strong>Required to provide voice search capabilities</strong>.
+ <dd><em>Keyword</em>. (Required to provide voice search capabilities.)
Enables voice search for the search dialog, with a specific mode for voice search.
- (Voice search may not be provided by the device, in which case these flags will
+ (Voice search may not be provided by the device, in which case these flags
have no effect.) The following mode values are accepted:
<table>
<tr><th>Value</th><th>Description</th></tr>
<tr>
<td><code>"showVoiceSearchButton"</code></td>
- <td>Display a voice search button. This only
- takes effect if voice search is available on the device. If set, then either
- {@code "launchWebSearch"} or {@code "launchRecognizer"} must also be set
+ <td>Display a voice search button, if voice search is available on the device. If set,
+then either {@code "launchWebSearch"} or {@code "launchRecognizer"} must also be set
(separated by the pipe | character).</td>
</tr>
<tr>
<td><code>"launchWebSearch"</code></td>
- <td>The voice search button will take the user directly
- to a built-in voice web search activity. Most applications will not use this flag, as
- it will take the user away from the Activity in which search was invoked.</td>
+ <td>The voice search button takes the user directly
+ to a built-in voice web search activity. Most applications don't need this flag, as
+ it takes the user away from the Activity in which search was invoked.</td>
</tr>
<tr>
<td><code>"launchRecognizer"</code></td>
- <td>The voice search button will take
+ <td>The voice search button takes
the user directly to a built-in voice recording activity. This Activity
- will prompt the user to speak, transcribe the spoken text, and forward the resulting
- query text to the searchable Activity, just as if the user had typed it into the
+ prompts the user to speak, transcribes the spoken text, and forwards the resulting
+ query text to the searchable Activity, just as if the user typed it into the
search UI and clicked the search button.</td>
</tr>
</table>
</dd>
+
<dt><code>android:voiceLanguageModel</code></dt>
<dd><em>Keyword</em>. The language model that
should be used by the voice recognition system. The following values are accepted:
@@ -245,92 +258,99 @@ albums, and tracks" for a music application, or "Saved notes" for a notepad appl
<tr><th>Value</th><th>Description</th></tr>
<tr>
<td><code>"free_form"</code></td>
- <td>Use a language model based on free-form speech recognition. This is the
-default.</td>
+ <td>Use free-form speech recognition for dictating queries. This is primarily
+optimized for English. This is the default.</td>
</tr>
<tr>
<td><code>"web_search"</code></td>
- <td>Use a language model based on web search terms.</td>
+ <td>Use web-search-term recognition for shorter, search-like phrases. This is
+available in more languages than "free_form".</td>
</tr>
</table>
<p>Also see
{@link android.speech.RecognizerIntent#EXTRA_LANGUAGE_MODEL} for more
information.</p></dd>
+
<dt><code>android:voicePromptText</code></dt>
<dd><em>String</em>. An additional message to display in the voice input dialog.</dd>
+
<dt><code>android:voiceLanguage</code></dt>
<dd><em>String</em>. The spoken language to be expected, expressed as the string value of
-a constants in {@link java.util.Locale} (for example, {@code "de"} for German or {@code "fr"} for
-French). This is only needed if it is different from the current value of {@link
+a constants in {@link java.util.Locale} (such as {@code "de"} for German or {@code "fr"} for
+French). This is needed only if it is different from the current value of {@link
java.util.Locale#getDefault() Locale.getDefault()}.</dd>
+
<dt><code>android:voiceMaxResults</code></dt>
<dd><em>Integer</em>. Forces the maximum number of results to return,
- including the "best" result which will always be provided as the {@link
+ including the "best" result which is always provided as the {@link
android.content.Intent#ACTION_SEARCH} Intent's primary
query. Must be 1 or greater. Use {@link android.speech.RecognizerIntent#EXTRA_RESULTS} to
get the results from the Intent.
- If not provided, the recognizer will choose how many results to return.</dd>
+ If not provided, the recognizer chooses how many results to return.</dd>
</dl>
</dd> <!-- end searchable element -->
+
<dt id="actionkey-element"><code>&lt;actionkey&gt;</code></dt>
- <dd>Defines a shortcut key for a search action, in order to provide special behaviors at the touch
-of a button, based on the current query or focused suggestion. ​For example, the Contacts
-application enables the device call key for suggestions. So, when
-the user focuses on a search suggestion using the directional controls and then presses the call
-key, the application will immediately initiate a phone call to the suggested contact.
+ <dd>Defines a device key and behavior for a search action. A search action provides a
+special behavior at the touch of a button on the device, based on the current query or focused
+suggestion. For example, the Contacts application provides a search action to initiate a phone call
+to the currenly focused contact suggestion at the press of the CALL button.
<p>Not all action keys are available on every device, and not
all keys are allowed to be overriden in this way. For example, the "Home" key cannot be used and
must always return to the home screen. Also be sure not to define an action
key for a key that's needed for typing a search query. This essentially limits the
available and reasonable action keys to the call button and menu button. Also note that action
keys are not generally discoverable, so you should not provide them as a core user feature.</p>
+ <p>You must define the <code>android:keycode</code> to define the key and at least one of the
+other three attributes in order to define the search action.</p>
<p class="caps">attributes:</p>
<dl class="atn-list">
<dt><code>android:keycode</code></dt>
- <dd><em>String</em>. <strong>Required</strong>. A key code from {@link
+ <dd><em>String</em>. (Required.) A key code from {@link
android.view.KeyEvent} that represents the action key
- you wish to respond to (for example {@code "KEYCODE_CALL"}). This will be added to the
- {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent that is passed to your
- searchable Activity. To examine the key code, use
- {@link android.content.Intent#getIntExtra getIntExtra(SearchManager.ACTION_KEY)}.
- In addition to the key code, you must also provide one or more of
- the action specifier attributes below. Not all action keys
-are actually supported using this mechanism, as many of them are used for typing,
- navigation, or system functions. Note that although each of the action message elements are
-optional, at least one must be present for the action key to have any effect.</dd>
+ you wish to respond to (for example {@code "KEYCODE_CALL"}). This is added to the
+ {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent that is passed to your
+ searchable Activity. To examine the key code, use
+ {@link android.content.Intent#getIntExtra getIntExtra(SearchManager.ACTION_KEY)}. Not all
+keys are supported for a search action, as many of them are used for typing, navigation, or system
+functions.</dd>
+
<dt><code>android:queryActionMsg</code></dt>
<dd><em>String</em>. An action message to be sent if the action key is pressed while the
-user is simply entering query text. This will be added to the
- {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent that is
- passed to your searchable Activity. To examine the string, use
+user is entering query text. This is added to the
+ {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent that the Search Manager
+ passes to your searchable Activity. To examine the string, use
{@link android.content.Intent#getStringExtra
getStringExtra(SearchManager.ACTION_MSG)}.</dd>
+
<dt><code>android:suggestActionMsg</code></dt>
<dd><em>String</em>. An action message to be sent if the action key is pressed while a
- suggestion is focused. This will be added to the
- Intent that is passed to your searchable Activity (using the action you've defined for
- the suggestion). To examine the string,
+ suggestion is in focus. This is added to the
+ Intent that that the Search Manager passes to your searchable Activity (using the action
+you've defined for the suggestion). To examine the string,
use {@link android.content.Intent#getStringExtra
- getStringExtra(SearchManager.ACTION_MSG)}. Note that this should only be used if all your
+ getStringExtra(SearchManager.ACTION_MSG)}. This should only be used if all your
suggestions support this action key. If not all suggestions can handle the same action key, then
you must instead use the following {@code android:suggestActionMsgColumn} attribute.</dd>
+
<dt><code>android:suggestActionMsgColumn</code></dt>
<dd><em>String</em>. The name of the column in your content provider that defines the
-action message for this action key, which is to be sent if the action key is pressed while a
- suggestion is focused. This attribute lets you control the
+action message for this action key, which is to be sent if the user presses the action key while a
+ suggestion is in focus. This attribute lets you control the
action key on a suggestion-by-suggestion basis, because, instead of using the {@code
android:suggestActionMsg} attribute to define the action message for all suggestions, each entry in
-your content provider provides its own action message. First, you must define a column in your
+your content provider provides its own action message.
+ <p>First, you must define a column in your
content provider for each suggestion to provide an action message, then provide the name of that
-column in this attribute. The search manager will look at your suggestion cursor,
- using the string provided here in order to select your action message column, and
- then select the action message string from the cursor. That string will be added to the
- Intent that is passed to your searchable Activity (using the action you've defined for
- suggestions). To examine the string, use {@link
+column in this attribute. The Search Manager looks at your suggestion cursor,
+ using the string provided here to select your action message column, and
+ then select the action message string from the Cursor. That string is added to the
+ Intent that the Search Manager passes to your searchable Activity (using the action you've
+defined for suggestions). To examine the string, use {@link
android.content.Intent#getStringExtra getStringExtra(SearchManager.ACTION_MSG)}. If the data
-does not exist for the selected suggestion, the action key will be ignored.</dd>
+does not exist for the selected suggestion, the action key is ignored.</dd>
</dl>
</dd><!-- end action key -->
</dl>
diff --git a/docs/html/guide/topics/security/security.jd b/docs/html/guide/topics/security/security.jd
index dbc9866..de0c6e5 100644
--- a/docs/html/guide/topics/security/security.jd
+++ b/docs/html/guide/topics/security/security.jd
@@ -21,14 +21,15 @@ page.title=Security and Permissions
</div>
</div>
-<p>Android is a multi-process system, in which each application (and parts of the
-system) runs in its own process. Most security between applications and
-the system is enforced at the process level through standard Linux facilities,
-such as user and group IDs that are assigned to applications.
-Additional finer-grained security features are provided
-through a "permission" mechanism that enforces restrictions on the specific
-operations that a particular process can perform, and per-URI permissions
-for granting ad-hoc access to specific pieces of data.</p>
+<p>Android is a privilege-separated operating system, in which each
+application runs with a distinct system identity (Linux user ID and group
+ID). Parts of the system are also separated into distinct identities.
+Linux thereby isolates applications from each other and from the system.</p>
+
+<p>Additional finer-grained security features are provided through a
+"permission" mechanism that enforces restrictions on the specific operations
+that a particular process can perform, and per-URI permissions for granting
+ad-hoc access to specific pieces of data.</p>
<a name="arch"></a>
<h2>Security Architecture</h2>
@@ -38,39 +39,46 @@ application, by default, has permission to perform any operations that would
adversely impact other applications, the operating system, or the user. This
includes reading or writing the user's private data (such as contacts or
e-mails), reading or writing another application's files, performing
-network access, keeping the device awake, etc.<p>
-
-<p>An application's process runs in a security sandbox. The sandbox is designed
-to prevent applications from disrupting each other, except by explicitly
-declaring the <em>permissions</em> they need for additional capabilities not
-provided by the basic sandbox. The system handles requests for permissions
-in various ways, typically by automatically allowing or disallowing based on
-certificates or by prompting the user. The permissions required by an
-application are declared statically in that application, so they can be known
-up-front at install time and will not change after that.</p>
+network access, keeping the device awake, etc.</p>
+
+<p>Because the kernel sandboxes applications from each other, applications
+must explicitly share resources and data. They do this by declaring the
+<em>permissions</em> they need for additional capabilities not provided by
+the basic sandbox. Applications statically declare the permissions they
+require, and the Android system prompts the user for consent at the time the
+application is installed. Android has no mechanism for granting permissions
+dynamically (at run-time) because it complicates the user experience to the
+detriment of security.</p>
+
+<p>The kernel is solely responsible for sandboxing applications from each
+other. In particular the Dalvik VM is not a security boundary, and any app
+can run native code (see <a href="/sdk/ndk/index.html">the Android NDK</a>).
+All types of applications &mdash; Java, native, and hybrid &mdash; are
+sandboxed in the same way and have the same degree of security from each
+other.</p>
<a name="signing"></a>
<h2>Application Signing</h2>
-<p>All Android applications (.apk files) must be signed with a certificate whose
-private key is held by their developer. This certificate identifies the author
-of the application. The certificate does <em>not</em> need to be signed by
-a certificate authority: it is perfectly allowable, and typical, for Android
-applications to use self-signed certificates. The certificate is used only
-to establish trust relationships between applications, not for wholesale
-control over whether an application can be installed. The most significant
-ways that signatures impact security is by determining who can access
-signature-based permissions and who can share user IDs.</p>
-
+<p>All Android applications (.apk files) must be signed with a certificate
+whose private key is held by their developer. This certificate identifies
+the author of the application. The certificate does <em>not</em> need to be
+signed by a certificate authority: it is perfectly allowable, and typical,
+for Android applications to use self-signed certificates. The purpose of
+certificates in Android is to distinguish application authors. This allows
+the system to grant or deny applications access to <a
+href="/guide/topics/manifest/permission-element.html#plevel">signature-level
+permissions</a> and to grant or deny an application's <a
+href="/guide/topics/manifest/manifest-element.html#uid">request to be given
+the same Linux identity</a> as another application.</p>
<a name="userid"></a>
<h2>User IDs and File Access</h2>
-<p>Each Android package (.apk) file installed on the device is given its
-own unique Linux user ID, creating a sandbox for it and preventing it from touching
-other applications (or other applications from touching it). This user ID is
-assigned to it when the application is installed on the device, and
-remains constant for the duration of its life on that device.</p>
+<p>At install time, Android gives each package a distinct Linux user ID. The
+identity remains constant for the duration of the package's life on that
+device. On a different device, the same package may have a different UID;
+what matters is that each package has a distinct UID on a given device.</p>
<p>Because security enforcement happens at the
process level, the code of any two packages can not normally
@@ -150,7 +158,7 @@ activities of other applications.</li>
<li>Both sending and receiving broadcasts, to control who can receive
your broadcast or who can send a broadcast to you.</li>
<li>When accessing and operating on a content provider.</li>
-<li>Binding or starting a service.</li>
+<li>Binding to or starting a service.</li>
</ul>
diff --git a/docs/html/guide/topics/testing/activity_testing.jd b/docs/html/guide/topics/testing/activity_testing.jd
new file mode 100644
index 0000000..6392ad7
--- /dev/null
+++ b/docs/html/guide/topics/testing/activity_testing.jd
@@ -0,0 +1,392 @@
+page.title=Activity Testing
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li>
+ <a href="#ActivityTestAPI">The Activity Testing API</a>
+ <ol>
+ <li>
+ <a href="#ActivityInstrumentationTestCase2">ActivityInstrumentationTestCase2</a>
+ </li>
+ <li>
+ <a href="#ActivityUnitTestCase">ActivityUnitTestCase</a>
+ </li>
+ <li>
+ <a href="#SingleLaunchActivityTestCase">SingleLaunchActivityTestCase</a>
+ </li>
+ <li>
+ <a href="#MockObjectNotes">Mock objects and activity testing</a>
+ </li>
+ <li>
+ <a href="#AssertionNotes">Assertions for activity testing</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#WhatToTest">What to Test</a>
+ </li>
+ <li>
+ <a href="#NextSteps">Next Steps</a>
+ </li>
+ <li>
+ <a href="#UITesting">Appendix: UI Testing Notes</a>
+ <ol>
+ <li>
+ <a href="#RunOnUIThread">Testing on the UI thread</a>
+ </li>
+ <li>
+ <a href="#NotouchMode">Turning off touch mode</a>
+ </li>
+ <li>
+ <a href="#UnlockDevice">Unlocking the Emulator or Device</a>
+ </li>
+ <li>
+ <a href="#UITestTroubleshooting">Troubleshooting UI tests</a>
+ </li>
+ </ol>
+ </li>
+ </ol>
+<h2>Key Classes</h2>
+ <ol>
+ <li>{@link android.test.InstrumentationTestRunner}</li>
+ <li>{@link android.test.ActivityInstrumentationTestCase2}</li>
+ <li>{@link android.test.ActivityUnitTestCase}</li>
+ </ol>
+<h2>Related Tutorials</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">
+ Hello, Testing</a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
+ </li>
+ </ol>
+<h2>See Also</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">
+ Testing in Eclipse, with ADT</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/developing/testing/testing_otheride.html">
+ Testing in Other IDEs</a>
+ </li>
+ </ol>
+ </div>
+</div>
+<p>
+ Activity testing is particularly dependent on the the Android instrumentation framework.
+ Unlike other components, activities have a complex lifecycle based on callback methods; these
+ can't be invoked directly except by instrumentation. Also, the only way to send events to the
+ user interface from a program is through instrumentation.
+</p>
+<p>
+ This document describes how to test activities using instrumentation and other test
+ facilities. The document assumes you have already read
+ <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Fundamentals</a>,
+ the introduction to the Android testing and instrumentation framework.
+</p>
+<h2 id="ActivityTestAPI">The Activity Testing API</h2>
+<p>
+ The activity testing API base class is {@link android.test.InstrumentationTestCase},
+ which provides instrumentation to the test case subclasses you use for Activities.
+</p>
+<p>
+ For activity testing, this base class provides these functions:
+</p>
+<ul>
+ <li>
+ Lifecycle control: With instrumentation, you can start the activity under test, pause it,
+ and destroy it, using methods provided by the test case classes.
+ </li>
+ <li>
+ Dependency injection: Instrumentation allows you to create mock system objects such as
+ Contexts or Applications and use them to run the activity under test. This
+ helps you control the test environment and isolate it from production systems. You can
+ also set up customized Intents and start an activity with them.
+ </li>
+ <li>
+ User interface interaction: You use instrumentation to send keystrokes or touch events
+ directly to the UI of the activity under test.
+ </li>
+</ul>
+<p>
+ The activity testing classes also provide the JUnit framework by extending
+ {@link junit.framework.TestCase} and {@link junit.framework.Assert}.
+</p>
+<p>
+ The two main testing subclasses are {@link android.test.ActivityInstrumentationTestCase2} and
+ {@link android.test.ActivityUnitTestCase}. To test an Activity that is launched in a mode
+ other than <code>standard</code>, you use {@link android.test.SingleLaunchActivityTestCase}.
+</p>
+<h3 id="ActivityInstrumentationTestCase2">ActivityInstrumentationTestCase2</h3>
+<p>
+ The {@link android.test.ActivityInstrumentationTestCase2} test case class is designed to do
+ functional testing of one or more Activities in an application, using a normal system
+ infrastructure. It runs the Activities in a normal instance of the application under test,
+ using a standard system Context. It allows you to send mock Intents to the activity under
+ test, so you can use it to test an activity that responds to multiple types of intents, or
+ an activity that expects a certain type of data in the intent, or both. Notice, though, that it
+ does not allow mock Contexts or Applications, so you can not isolate the test from the rest of
+ a production system.
+</p>
+<h3 id="ActivityUnitTestCase">ActivityUnitTestCase</h3>
+<p>
+ The {@link android.test.ActivityUnitTestCase} test case class tests a single activity in
+ isolation. Before you start the activity, you can inject a mock Context or Application, or both.
+ You use it to run activity tests in isolation, and to do unit testing of methods
+ that do not interact with Android. You can not send mock Intents to the activity under test,
+ although you can call
+ {@link android.app.Activity#startActivity(Intent) Activity.startActivity(Intent)} and then
+ look at arguments that were received.
+</p>
+<h3 id="SingleLaunchActivityTestCase">SingleLaunchActivityTestCase</h3>
+<p>
+ The {@link android.test.SingleLaunchActivityTestCase} class is a convenience class for
+ testing a single activity in an environment that doesn't change from test to test.
+ It invokes {@link junit.framework.TestCase#setUp() setUp()} and
+ {@link junit.framework.TestCase#tearDown() tearDown()} only once, instead of once per
+ method call. It does not allow you to inject any mock objects.
+</p>
+<p>
+ This test case is useful for testing an activity that runs in a mode other than
+ <code>standard</code>. It ensures that the test fixture is not reset between tests. You
+ can then test that the activity handles multiple calls correctly.
+</p>
+<h3 id="MockObjectNotes">Mock objects and activity testing</h3>
+<p>
+ This section contains notes about the use of the mock objects defined in
+ {@link android.test.mock} with activity tests.
+</p>
+<p>
+ The mock object {@link android.test.mock.MockApplication} is only available for activity
+ testing if you use the {@link android.test.ActivityUnitTestCase} test case class.
+ By default, <code>ActivityUnitTestCase</code>, creates a hidden <code>MockApplication</code>
+ object that is used as the application under test. You can inject your own object using
+ {@link android.test.ActivityUnitTestCase#setApplication(Application) setApplication()}.
+</p>
+<h3 id="AssertionNotes">Assertions for activity testing</h3>
+<p>
+ {@link android.test.ViewAsserts} defines assertions for Views. You use it to verify the
+ alignment and position of View objects, and to look at the state of ViewGroup objects.
+</p>
+<h2 id="WhatToTest">What To Test</h2>
+<ul>
+ <li>
+ Input validation: Test that an activity responds correctly to input values in an
+ EditText View. Set up a keystroke sequence, send it to the activity, and then
+ use {@link android.view.View#findViewById(int)} to examine the state of the View. You can
+ verify that a valid keystroke sequence enables an OK button, while an invalid one leaves the
+ button disabled. You can also verify that the Activity responds to invalid input by
+ setting error messages in the View.
+ </li>
+ <li>
+ Lifecycle events: Test that each of your application's activities handles lifecycle events
+ correctly. In general, lifecycle events are actions, either from the system or from the
+ user, that trigger a callback method such as <code>onCreate()</code> or
+ <code>onClick()</code>. For example, an activity should respond to pause or destroy events
+ by saving its state. Remember that even a change in screen orientation causes the current
+ activity to be destroyed, so you should test that accidental device movements don't
+ accidentally lose the application state.
+ </li>
+ <li>
+ Intents: Test that each activity correctly handles the intents listed in the intent
+ filter specified in its manifest. You can use
+ {@link android.test.ActivityInstrumentationTestCase2} to send mock Intents to the
+ activity under test.
+ </li>
+ <li>
+ Runtime configuration changes: Test that each activity responds correctly to the
+ possible changes in the device's configuration while your application is running. These
+ include a change to the device's orientation, a change to the current language, and so
+ forth. Handling these changes is described in detail in the topic
+ <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime
+ Changes</a>.
+ </li>
+ <li>
+ Screen sizes and resolutions: Before you publish your application, make sure to test it on
+ all of the screen sizes and densities on which you want it to run. You can test the
+ application on multiple sizes and densities using AVDs, or you can test your application
+ directly on the devices that you are targeting. For more information, see the topic
+ <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.
+ </li>
+</ul>
+<h2 id="NextSteps">Next Steps</h2>
+<p>
+ To learn how to set up and run tests in Eclipse, please refer to <a
+ href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in
+ Eclipse, with ADT</a>. If you're not working in Eclipse, refer to <a
+ href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other
+ IDEs</a>.
+</p>
+<p>
+ If you want a step-by-step introduction to testing activities, try one of the
+ testing tutorials:
+</p>
+<ul>
+ <li>
+ The <a
+ href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello,
+ Testing</a> tutorial introduces basic testing concepts and procedures in the
+ context of the Hello, World application.
+ </li>
+ <li>
+ The <a
+ href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity
+ Testing</a> tutorial is an excellent follow-up to the Hello, Testing tutorial.
+ It guides you through a more complex testing scenario that you develop against a
+ more realistic activity-oriented application.
+ </li>
+</ul>
+<h2 id="UITesting">Appendix: UI Testing Notes</h2>
+<p>
+ The following sections have tips for testing the UI of your Android application, specifically
+ to help you handle actions that run in the UI thread, touch screen and keyboard events, and home
+ screen unlock during testing.
+</p>
+<h3 id="RunOnUIThread">Testing on the UI thread</h3>
+<p>
+ An application's activities run on the application's <strong>UI thread</strong>. Once the
+ UI is instantiated, for example in the activity's <code>onCreate()</code> method, then all
+ interactions with the UI must run in the UI thread. When you run the application normally, it
+ has access to the thread and does not have to do anything special.
+</p>
+<p>
+ This changes when you run tests against the application. With instrumentation-based classes,
+ you can invoke methods against the UI of the application under test. The other test classes
+ don't allow this. To run an entire test method on the UI thread, you can annotate the thread
+ with <code>@UIThreadTest</code>. Notice that this will run <em>all</em> of the method statements
+ on the UI thread. Methods that do not interact with the UI are not allowed; for example, you
+ can't invoke <code>Instrumentation.waitForIdleSync()</code>.
+</p>
+<p>
+ To run a subset of a test method on the UI thread, create an anonymous class of type
+ <code>Runnable</code>, put the statements you want in the <code>run()</code> method, and
+ instantiate a new instance of the class as a parameter to the method
+ <code><em>appActivity</em>.runOnUiThread()</code>, where <code><em>appActivity</em></code> is
+ the instance of the application you are testing.
+</p>
+<p>
+ For example, this code instantiates an activity to test, requests focus (a UI action) for the
+ Spinner displayed by the activity, and then sends a key to it. Notice that the calls to
+ <code>waitForIdleSync</code> and <code>sendKeys</code> aren't allowed to run on the UI thread:
+</p>
+<pre>
+ private MyActivity mActivity; // MyActivity is the class name of the app under test
+ private Spinner mSpinner;
+
+ ...
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mInstrumentation = getInstrumentation();
+
+ mActivity = getActivity(); // get a references to the app under test
+
+ /*
+ * Get a reference to the main widget of the app under test, a Spinner
+ */
+ mSpinner = (Spinner) mActivity.findViewById(com.android.demo.myactivity.R.id.Spinner01);
+
+ ...
+
+ public void aTest() {
+ /*
+ * request focus for the Spinner, so that the test can send key events to it
+ * This request must be run on the UI thread. To do this, use the runOnUiThread method
+ * and pass it a Runnable that contains a call to requestFocus on the Spinner.
+ */
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mSpinner.requestFocus();
+ }
+ });
+
+ mInstrumentation.waitForIdleSync();
+
+ this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+</pre>
+
+<h3 id="NotouchMode">Turning off touch mode</h3>
+<p>
+ To control the emulator or a device with key events you send from your tests, you must turn off
+ touch mode. If you do not do this, the key events are ignored.
+</p>
+<p>
+ To turn off touch mode, you invoke
+ <code>ActivityInstrumentationTestCase2.setActivityTouchMode(false)</code>
+ <em>before</em> you call <code>getActivity()</code> to start the activity. You must invoke the
+ method in a test method that is <em>not</em> running on the UI thread. For this reason, you
+ can't invoke the touch mode method from a test method that is annotated with
+ <code>@UIThread</code>. Instead, invoke the touch mode method from <code>setUp()</code>.
+</p>
+<h3 id="UnlockDevice">Unlocking the emulator or device</h3>
+<p>
+ You may find that UI tests don't work if the emulator's or device's home screen is disabled with
+ the keyguard pattern. This is because the application under test can't receive key events sent
+ by <code>sendKeys()</code>. The best way to avoid this is to start your emulator or device
+ first and then disable the keyguard for the home screen.
+</p>
+<p>
+ You can also explicitly disable the keyguard. To do this,
+ you need to add a permission in the manifest file (<code>AndroidManifest.xml</code>) and
+ then disable the keyguard in your application under test. Note, though, that you either have to
+ remove this before you publish your application, or you have to disable it with code in
+ the published application.
+</p>
+<p>
+ To add the the permission, add the element
+ <code>&lt;uses-permission android:name="android.permission.DISABLE_KEYGUARD"/&gt;</code>
+ as a child of the <code>&lt;manifest&gt;</code> element. To disable the KeyGuard, add the
+ following code to the <code>onCreate()</code> method of activities you intend to test:
+</p>
+<pre>
+ mKeyGuardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
+ mLock = mKeyGuardManager.newKeyguardLock("<em>activity_classname</em>");
+ mLock.disableKeyguard();
+</pre>
+<p>where <code><em>activity_classname</em></code> is the class name of the activity.</p>
+<h3 id="UITestTroubleshooting">Troubleshooting UI tests</h3>
+<p>
+ This section lists some of the common test failures you may encounter in UI testing, and their
+ causes:
+</p>
+<dl>
+ <dt><code>WrongThreadException</code></dt>
+ <dd>
+ <p><strong>Problem:</strong></p>
+ For a failed test, the Failure Trace contains the following error message:
+ <code>
+ android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created
+ a view hierarchy can touch its views.
+ </code>
+ <p><strong>Probable Cause:</strong></p>
+ This error is common if you tried to send UI events to the UI thread from outside the UI
+ thread. This commonly happens if you send UI events from the test application, but you don't
+ use the <code>@UIThread</code> annotation or the <code>runOnUiThread()</code> method. The
+ test method tried to interact with the UI outside the UI thread.
+ <p><strong>Suggested Resolution:</strong></p>
+ Run the interaction on the UI thread. Use a test class that provides instrumentation. See
+ the previous section <a href="#RunOnUIThread">Testing on the UI Thread</a>
+ for more details.
+ </dd>
+ <dt><code>java.lang.RuntimeException</code></dt>
+ <dd>
+ <p><strong>Problem:</strong></p>
+ For a failed test, the Failure Trace contains the following error message:
+ <code>
+ java.lang.RuntimeException: This method can not be called from the main application thread
+ </code>
+ <p><strong>Probable Cause:</strong></p>
+ This error is common if your test method is annotated with <code>@UiThreadTest</code> but
+ then tries to do something outside the UI thread or tries to invoke
+ <code>runOnUiThread()</code>.
+ <p><strong>Suggested Resolution:</strong></p>
+ Remove the <code>@UiThreadTest</code> annotation, remove the <code>runOnUiThread()</code>
+ call, or re-factor your tests.
+ </dd>
+</dl>
diff --git a/docs/html/guide/topics/testing/contentprovider_testing.jd b/docs/html/guide/topics/testing/contentprovider_testing.jd
new file mode 100644
index 0000000..279e347
--- /dev/null
+++ b/docs/html/guide/topics/testing/contentprovider_testing.jd
@@ -0,0 +1,222 @@
+page.title=Content Provider Testing
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li>
+ <a href="#DesignAndTest">Content Provider Design and Testing</a>
+ </li>
+ <li>
+ <a href="#ContentProviderTestAPI">The Content Provider Testing API</a>
+ <ol>
+ <li>
+ <a href="#ProviderTestCase2">ProviderTestCase2 </a>
+ </li>
+ <li>
+ <a href="#MockObjects">Mock object classes</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#WhatToTest">What To Test</a>
+ </li>
+ <li>
+ <a href="#NextSteps">Next Steps</a>
+ </li>
+ </ol>
+ <h2>Key Classes</h2>
+ <ol>
+ <li>{@link android.test.InstrumentationTestRunner}</li>
+ <li>{@link android.test.ProviderTestCase2}</li>
+ <li>{@link android.test.IsolatedContext}</li>
+ <li>{@link android.test.mock.MockContentResolver}</li>
+ </ol>
+ <h2>See Also</h2>
+ <ol>
+ <li>
+ <a
+ href="{@docRoot}guide/topics/testing/topics/testing_android.html">
+ Testing Fundamentals</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">
+ Testing in Eclipse, with ADT</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/developing/testing/testing_otheride.html">
+ Testing in Other IDEs</a>
+ </li>
+ </ol>
+ </div>
+</div>
+<p>
+ Content providers, which store and retrieve data and make it accessible across applications,
+ are a key part of the Android API. As an application developer you're allowed to provide your
+ own public providers for use by other applications. If you do, then you should test them
+ using the API you publish.
+</p>
+<p>
+ This document describes how to test public content providers, although the information is
+ also applicable to providers that you keep private to your own application. If you aren't
+ familiar with content providers or the Android testing framework, please read
+ <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>,
+ the guide to developing content providers, and
+ <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Fundamentals</a>,
+ the introduction to the Android testing and instrumentation framework.
+</p>
+<h2 id="DesignAndTest">Content Provider Design and Testing</h2>
+<p>
+ In Android, content providers are viewed externally as data APIs that provide
+ tables of data, with their internals hidden from view. A content provider may have many
+ public constants, but it usually has few if any public methods and no public variables.
+ This suggests that you should write your tests based only on the provider's public members.
+ A content provider that is designed like this is offering a contract between itself and its
+ users.
+</p>
+<p>
+ The base test case class for content providers,
+ {@link android.test.ProviderTestCase2}, allows you to test your content provider in an
+ isolated environment. Android mock objects such as {@link android.test.IsolatedContext} and
+ {@link android.test.mock.MockContentResolver} also help provide an isolated test environment.
+</p>
+<p>
+ As with other Android tests, provider test packages are run under the control of the test
+ runner {@link android.test.InstrumentationTestRunner}. The section
+ <a href="{@docRoot}guide/topics/testing/testing_android.html#InstrumentationTestRunner">
+ Running Tests With InstrumentationTestRunner</a> describes the test runner in
+ more detail. The topic <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">
+ Testing in Eclipse, with ADT</a> shows you how to run a test package in Eclipse, and the
+ topic <a href="{@docRoot}guide/developing/testing/testing_otheride.html">
+ Testing in Other IDEs</a>
+ shows you how to run a test package from the command line.
+</p>
+<h2 id="ContentProviderTestAPI">Content Provider Testing API</h2>
+<p>
+ The main focus of the provider testing API is to provide an isolated testing environment. This
+ ensures that tests always run against data dependencies set explicitly in the test case. It
+ also prevents tests from modifying actual user data. For example, you want to avoid writing
+ a test that fails because there was data left over from a previous test, and you want to
+ avoid adding or deleting contact information in a actual provider.
+</p>
+<p>
+ The test case class and mock object classes for provider testing set up this isolated testing
+ environment for you.
+</p>
+<h3 id="ProviderTestCase2">ProviderTestCase2</h3>
+<p>
+ You test a provider with a subclass of {@link android.test.ProviderTestCase2}. This base class
+ extends {@link android.test.AndroidTestCase}, so it provides the JUnit testing framework as well
+ as Android-specific methods for testing application permissions. The most important
+ feature of this class is its initialization, which creates the isolated test environment.
+</p>
+<p>
+ The initialization is done in the constructor for {@link android.test.ProviderTestCase2}, which
+ subclasses call in their own constructors. The {@link android.test.ProviderTestCase2}
+ constructor creates an {@link android.test.IsolatedContext} object that allows file and
+ database operations but stubs out other interactions with the Android system.
+ The file and database operations themselves take place in a directory that is local to the
+ device or emulator and has a special prefix.
+</p>
+<p>
+ The constructor then creates a {@link android.test.mock.MockContentResolver} to use as the
+ resolver for the test. The {@link android.test.mock.MockContentResolver} class is described in
+ detail in the section
+ <a href="{@docRoot}guide/topics/testing/test_android#MockObjectClasses">Mock object classes</a>.
+</p>
+<p>
+ Lastly, the constructor creates an instance of the provider under test. This is a normal
+ {@link android.content.ContentProvider} object, but it takes all of its environment information
+ from the {@link android.test.IsolatedContext}, so it is restricted to
+ working in the isolated test environment. All of the tests done in the test case class run
+ against this isolated object.
+</p>
+<h3 id="MockObjects">Mock object classes</h3>
+<p>
+ {@link android.test.ProviderTestCase2} uses {@link android.test.IsolatedContext} and
+ {@link android.test.mock.MockContentResolver}, which are standard mock object classes. To
+ learn more about them, please read
+ <a href="{@docRoot}guide/topics/testing/test_android#MockObjectClasses">
+ Testing Fundamentals</a>.
+</p>
+<h2 id="WhatToTest">What To Test</h2>
+<p>
+ The topic <a href="{@docRoot}guide/topics/testing/what_to_test.html">What To Test</a>
+ lists general considerations for testing Android components.
+ Here are some specific guidelines for testing content providers.
+</p>
+<ul>
+ <li>
+ Test with resolver methods: Even though you can instantiate a provider object in
+ {@link android.test.ProviderTestCase2}, you should always test with a resolver object
+ using the appropriate URI. This ensures that you are testing the provider using the same
+ interaction that a regular application would use.
+ </li>
+ <li>
+ Test a public provider as a contract: If you intent your provider to be public and
+ available to other applications, you should test it as a contract. This includes
+ the following ideas:
+ <ul>
+ <li>
+ Test with constants that your provider publicly exposes. For
+ example, look for constants that refer to column names in one of the provider's
+ data tables. These should always be constants publicly defined by the provider.
+ </li>
+ <li>
+ Test all the URIs offered by your provider. Your provider may offer several URIs,
+ each one referring to a different aspect of the data. The
+ <a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> sample,
+ for example, features a provider that offers one URI for retrieving a list of notes,
+ another for retrieving an individual note by it's database ID, and a third for
+ displaying notes in a live folder.
+ </li>
+ <li>
+ Test invalid URIs: Your unit tests should deliberately call the provider with an
+ invalid URI, and look for errors. Good provider design is to throw an
+ IllegalArgumentException for invalid URIs.
+
+ </li>
+ </ul>
+ </li>
+ <li>
+ Test the standard provider interactions: Most providers offer six access methods:
+ query, insert, delete, update, getType, and onCreate(). Your tests should verify that all
+ of these methods work. These are described in more detail in the topic
+ <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.
+ </li>
+ <li>
+ Test business logic: Don't forget to test the business logic that your provider should
+ enforce. Business logic includes handling of invalid values, financial or arithmetic
+ calculations, elimination or combining of duplicates, and so forth. A content provider
+ does not have to have business logic, because it may be implemented by activities that
+ modify the data. If the provider does implement business logic, you should test it.
+ </li>
+</ul>
+<h2 id="NextSteps">Next Steps</h2>
+<p>
+ To learn how to set up and run tests in Eclipse, please refer to <a
+ href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in
+ Eclipse, with ADT</a>. If you're not working in Eclipse, refer to <a
+ href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other
+ IDEs</a>.
+</p>
+<p>
+ If you want a step-by-step introduction to testing activities, try one of the
+ testing tutorials:
+</p>
+<ul>
+ <li>
+ The <a
+ href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello,
+ Testing</a> tutorial introduces basic testing concepts and procedures in the
+ context of the Hello, World application.
+ </li>
+ <li>
+ The <a
+ href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity
+ Testing</a> tutorial is an excellent follow-up to the Hello, Testing tutorial.
+ It guides you through a more complex testing scenario that you develop against a
+ more realistic activity-oriented application.
+ </li>
+</ul>
diff --git a/docs/html/guide/topics/testing/index.jd b/docs/html/guide/topics/testing/index.jd
new file mode 100644
index 0000000..762a897
--- /dev/null
+++ b/docs/html/guide/topics/testing/index.jd
@@ -0,0 +1,84 @@
+page.title=Testing
+@jd:body
+<p>
+ The Android development environment includes an integrated testing framework that helps you
+ test all aspects of your application.
+</p>
+<h4>Fundamentals</h4>
+<p>
+ To start learning how to use the framework to create tests for your applications, please
+ read the topic <a href="{@docRoot}guide/topics/testing/testing_android.html">
+ Testing Fundamentals</a>.
+</p>
+<h4>Concepts</h4>
+<ul>
+ <li>
+ <a href="{@docRoot}guide/topics/testing/activity_testing.html">
+ Activity Testing</a> focuses on testing activities. It describes how instrumentation allows
+ you to control activities outside the normal application lifecycle. It also lists
+ activity-specific features you should test, and it provides tips for testing Android
+ user interfaces.
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/testing/contentprovider_testing.html">
+ Content Provider Testing</a> focuses on testing content providers. It describes the
+ mock system objects you can use, provides tips for designing providers so that they
+ can be tested, and lists provider-specific features you should test.
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/testing/service_testing.html">
+ Service Testing</a> focuses on testing services. It also lists service-specific features
+ you should test.
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/testing/what_to_test.html">What to Test</a>
+ is an overview of the types of testing you should do. It focuses on testing
+ system-wide aspects of Android that can affect every component in your application.
+ </li>
+</ul>
+<h4>Procedures</h4>
+<ul>
+ <li>
+ The topic <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">
+ Testing in Eclipse, with ADT</a> describes how to create and run tests in Eclipse with ADT.
+ </li>
+ <li>
+ The topic <a href="{@docRoot}guide/developing/testing/testing_otheride.html">
+ Testing in other IDEs</a> describes how to create and run tests with command-line tools.
+ </li>
+</ul>
+<h4>Tutorials</h4>
+<ul>
+ <li>
+ The <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">
+ Hello, Testing</a> tutorial introduces basic testing concepts and procedures.
+ </li>
+ <li>
+ For a more advanced tutorial, try
+ <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>,
+ which guides you through a more complex testing scenario.
+ </li>
+</ul>
+<h4>Tools</h4>
+<ul>
+ <li>
+ The
+ <a href="{@docRoot}guide/developing/tools/monkey.html">UI/Application Exerciser Monkey</a>,
+ usually called Monkey, is a command-line tool that sends pseudo-random
+ streams of keystrokes, touches, and gestures to a device.
+ </li>
+ <li>
+ The <a href="{@docRoot}guide/developing/tools/monkeyrunner_concepts.html">monkeyrunner</a> tool
+ is an API and execution environment. You use monkeyrunner with Python programs
+ to test applications and devices.
+ </li>
+</ul>
+<h4>Samples</h4>
+<ul>
+ <li>
+ The <a href="{@docRoot}resources/samples/AlarmServiceTest.html">Alarm Service Test</a>
+ is a test package for the <a href="{@docRoot}resources/samples/Alarm.html">Alarm</a>
+ sample application. It provides a simple example of unit
+ testing a {@link android.app.Service}.
+ </li>
+</ul>
diff --git a/docs/html/guide/topics/testing/service_testing.jd b/docs/html/guide/topics/testing/service_testing.jd
new file mode 100644
index 0000000..3979f3c
--- /dev/null
+++ b/docs/html/guide/topics/testing/service_testing.jd
@@ -0,0 +1,178 @@
+page.title=Service Testing
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li>
+ <a href="#DesignAndTest">Service Design and Testing</a>
+ </li>
+ <li>
+ <a href="#ServiceTestCase">ServiceTestCase</a>
+ </li>
+ <li>
+ <a href="#MockObjects">Mock object classes</a>
+ </li>
+ <li>
+ <a href="#TestAreas">What to Test</a>
+ </li>
+ </ol>
+ <h2>Key Classes</h2>
+ <ol>
+ <li>{@link android.test.InstrumentationTestRunner}</li>
+ <li>{@link android.test.ServiceTestCase}</li>
+ <li>{@link android.test.mock.MockApplication}</li>
+ <li>{@link android.test.RenamingDelegatingContext}</li>
+ </ol>
+ <h2>Related Tutorials</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">
+ Hello, Testing</a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
+ </li>
+ </ol>
+ <h2>See Also</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">
+ Testing in Eclipse, with ADT</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/developing/testing/testing_otheride.html">
+ Testing in Other IDEs</a>
+ </li>
+ </ol>
+ </div>
+</div>
+<p>
+ Android provides a testing framework for Service objects that can run them in
+ isolation and provides mock objects. The test case class for Service objects is
+ {@link android.test.ServiceTestCase}. Since the Service class assumes that it is separate
+ from its clients, you can test a Service object without using instrumentation.
+</p>
+<p>
+ This document describes techniques for testing Service objects. If you aren't familiar with the
+ Service class, please read <a href="{@docRoot}guide/topics/fundamentals.html">
+ Application Fundamentals</a>. If you aren't familiar with Android testing, please read
+ <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Fundamentals</a>,
+ the introduction to the Android testing and instrumentation framework.
+</p>
+<h2 id="DesignAndTest">Service Design and Testing</h2>
+<p>
+ When you design a Service, you should consider how your tests can examine the various states
+ of the Service lifecycle. If the lifecycle methods that start up your Service, such as
+ {@link android.app.Service#onCreate() onCreate()} or
+ {@link android.app.Service#onStartCommand(Intent, int, int) onStartCommand()} do not normally
+ set a global variable to indicate that they were successful, you may want to provide such a
+ variable for testing purposes.
+</p>
+<p>
+ Most other testing is facilitated by the methods in the {@link android.test.ServiceTestCase}
+ test case class. For example, the {@link android.test.ServiceTestCase#getService()} method
+ returns a handle to the Service under test, which you can test to confirm that the Service is
+ running even at the end of your tests.
+</p>
+<h2 id="ServiceTestCase">ServiceTestCase</h2>
+<p>
+ {@link android.test.ServiceTestCase} extends the JUnit {@link junit.framework.TestCase} class
+ with with methods for testing application permissions and for controlling the application and
+ Service under test. It also provides mock application and Context objects that isolate your
+ test from the rest of the system.
+</p>
+<p>
+ {@link android.test.ServiceTestCase} defers initialization of the test environment until you
+ call {@link android.test.ServiceTestCase#startService(Intent) ServiceTestCase.startService()} or
+ {@link android.test.ServiceTestCase#bindService(Intent) ServiceTestCase.bindService()}. This
+ allows you to set up your test environment, particularly your mock objects, before the Service
+ is started.
+</p>
+<p>
+ Notice that the parameters to <code>ServiceTestCase.bindService()</code>are different from
+ those for <code>Service.bindService()</code>. For the <code>ServiceTestCase</code> version,
+ you only provide an Intent. Instead of returning a boolean,
+ <code>ServiceTestCase.bindService()</code> returns an object that subclasses
+ {@link android.os.IBinder}.
+</p>
+<p>
+ The {@link android.test.ServiceTestCase#setUp()} method for {@link android.test.ServiceTestCase}
+ is called before each test. It sets up the test fixture by making a copy of the current system
+ Context before any test methods touch it. You can retrieve this Context by calling
+ {@link android.test.ServiceTestCase#getSystemContext()}. If you override this method, you must
+ call <code>super.setUp()</code> as the first statement in the override.
+</p>
+<p>
+ The methods {@link android.test.ServiceTestCase#setApplication(Application) setApplication()}
+ and {@link android.test.AndroidTestCase#setContext(Context)} setContext()} allow you to set
+ a mock Context or mock Application (or both) for the Service, before you start it. These mock
+ objects are described in <a href="#MockObjects">Mock object classes</a>.
+</p>
+<p>
+ By default, {@link android.test.ServiceTestCase} runs the test method
+ {@link android.test.AndroidTestCase#testAndroidTestCaseSetupProperly()}, which asserts that
+ the base test case class successfully set up a Context before running.
+</p>
+<h2 id="MockObjects">Mock object classes</h2>
+<p>
+ <code>ServiceTestCase</code> assumes that you will use a mock Context or mock Application
+ (or both) for the test environment. These objects isolate the test environment from the
+ rest of the system. If you don't provide your own instances of these objects before you
+ start the Service, then {@link android.test.ServiceTestCase} will create its own internal
+ instances and inject them into the Service. You can override this behavior by creating and
+ injecting your own instances before starting the Service
+</p>
+<p>
+ To inject a mock Application object into the Service under test, first create a subclass of
+ {@link android.test.mock.MockApplication}. <code>MockApplication</code> is a subclass of
+ {@link android.app.Application} in which all the methods throw an Exception, so to use it
+ effectively you subclass it and override the methods you need. You then inject it into the
+ Service with the
+ {@link android.test.ServiceTestCase#setApplication(Application) setApplication()} method.
+ This mock object allows you to control the application values that the Service sees, and
+ isolates it from the real system. In addition, any hidden dependencies your Service has on
+ its application reveal themselves as exceptions when you run the test.
+</p>
+<p>
+ You inject a mock Context into the Service under test with the
+ {@link android.test.AndroidTestCase#setContext(Context) setContext()} method. The mock
+ Context classes you can use are described in more detail in
+ <a href="{@docRoot}guide/topics/testing/testing_android.html#MockObjectClasses">
+ Testing Fundamentals</a>.
+</p>
+<h2 id="TestAreas">What to Test</h2>
+<p>
+ The topic <a href="{@docRoot}guide/topics/testing/what_to_test.html">What To Test</a>
+ lists general considerations for testing Android components.
+ Here are some specific guidelines for testing a Service:
+</p>
+<ul>
+ <li>
+ Ensure that the {@link android.app.Service#onCreate()} is called in response to
+ {@link android.content.Context#startService(Intent) Context.startService()} or
+ {@link android.content.Context#bindService(Intent,ServiceConnection,int) Context.bindService()}.
+ Similarly, you should ensure that {@link android.app.Service#onDestroy()} is called in
+ response to {@link android.content.Context#stopService(Intent) Context.stopService()},
+ {@link android.content.Context#unbindService(ServiceConnection) Context.unbindService()},
+ {@link android.app.Service#stopSelf()}, or
+ {@link android.app.Service#stopSelfResult(int) stopSelfResult()}.
+ </li>
+ <li>
+ Test that your Service correctly handles multiple calls from
+ <code>Context.startService()</code>. Only the first call triggers
+ <code>Service.onCreate()</code>, but all calls trigger a call to
+ <code>Service.onStartCommand()</code>.
+ <p>
+ In addition, remember that <code>startService()</code> calls don't
+ nest, so a single call to <code>Context.stopService()</code> or
+ <code>Service.stopSelf()</code> (but not <code>stopSelf(int)</code>)
+ will stop the Service. You should test that your Service stops at the correct point.
+ </p>
+ </li>
+ <li>
+ Test any business logic that your Service implements. Business logic includes checking for
+ invalid values, financial and arithmetic calculations, and so forth.
+ </li>
+</ul>
diff --git a/docs/html/guide/topics/testing/testing_android.jd b/docs/html/guide/topics/testing/testing_android.jd
index 46ba769..d4b0dcc 100755
--- a/docs/html/guide/topics/testing/testing_android.jd
+++ b/docs/html/guide/topics/testing/testing_android.jd
@@ -1,4 +1,4 @@
-page.title=Testing and Instrumentation
+page.title=Testing Fundamentals
@jd:body
<div id="qv-wrapper">
@@ -6,512 +6,658 @@ page.title=Testing and Instrumentation
<h2>In this document</h2>
<ol>
<li>
- <a href="#Overview">Overview</a>
+ <a href="#TestStructure">Test Structure</a>
+ </li>
+ <li>
+ <a href="#TestProjects">Test Projects</a>
</li>
<li>
<a href="#TestAPI">The Testing API</a>
<ol>
<li>
- <a href="#Extensions">JUnit test case classes</a>
+ <a href="#JUnit">JUnit</a>
+ </li>
+ <li>
+ <a href="#Instrumentation">Instrumentation</a>
</li>
<li>
- <a href="#Instrumentation">Instrumentation test case classes</a>
+ <a href="#TestCaseClasses">Test case classes</a>
</li>
<li>
- <a href="#Assert">Assert classes</a>
+ <a href="#AssertionClasses">Assertion classes</a>
</li>
<li>
- <a href="#MockObjects">Mock object classes</a>
+ <a href="#MockObjectClasses">Mock object classes</a>
</li>
- <li>
- <a href="#InstrumentationTestRunner">Instrumentation Test Runner</a>
- </li>
</ol>
</li>
<li>
- <a href="#TestEnviroment">Working in the Test Environment</a>
+ <a href="#InstrumentationTestRunner">Running Tests</a>
</li>
<li>
- <a href="#TestAreas">What to Test</a>
+ <a href="#TestResults">Seeing Test Results</a>
</li>
<li>
- <a href="#UITesting">Appendix: UI Testing Notes</a>
- <ol>
- <li>
- <a href="#RunOnUIThread">Testing on the UI thread</a>
- </li>
- <li>
- <a href="#NotouchMode">Turning off touch mode</a>
- </li>
- <li>
- <a href="#UnlockDevice">Unlocking the Emulator or Device</a>
- </li>
- <li>
- <a href="#UITestTroubleshooting">Troubleshooting UI tests</a>
- </li>
- </ol>
+ <a href="#Monkeys">monkey and monkeyrunner</a>
+ </li>
+ <li>
+ <a href="#PackageNames">Working With Package Names</a>
+ </li>
+ <li>
+ <a href="#WhatToTest">What To Test</a>
+ </li>
+ <li>
+ <a href="#NextSteps">Next Steps</a>
</li>
</ol>
- <h2>Key Classes</h2>
+ <h2>Key classes</h2>
<ol>
<li>{@link android.test.InstrumentationTestRunner}</li>
- <li>{@link android.test.ActivityInstrumentationTestCase2}</li>
- <li>{@link android.test.ActivityUnitTestCase}</li>
- <li>{@link android.test.ApplicationTestCase}</li>
- <li>{@link android.test.ProviderTestCase2}</li>
- <li>{@link android.test.ServiceTestCase}</li>
+ <li>{@link android.test}</li>
+ <li>{@link android.test.mock}</li>
+ <li>{@link junit.framework}</li>
</ol>
- <h2>Related Tutorials</h2>
+ <h2>Related tutorials</h2>
<ol>
<li>
- <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello, Testing</a>
+ <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">
+ Hello, Testing</a>
</li>
<li>
<a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
</li>
</ol>
- <h2>See Also</h2>
+ <h2>See also</h2>
<ol>
<li>
- <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in Eclipse, with ADT</a>
+ <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">
+ Testing in Eclipse, with ADT</a>
</li>
<li>
- <a href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other IDEs</a>
+ <a href="{@docRoot}guide/developing/testing/testing_otheride.html">
+ Testing in Other IDEs</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/developing/tools/monkeyrunner_concepts.html">
+ monkeyrunner</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/developing/tools/monkey.html">UI/Application Exerciser Monkey</a>
</li>
</ol>
</div>
</div>
-
-<p>Android includes a powerful set of testing tools that extend the
-industry-standard JUnit test framework with features specific to the Android
-environment. Although you can test an Android application with JUnit, the
-Android tools allow you to write much more sophisticated tests for every aspect
-of your application, both at the unit and framework levels.</p>
-
-<p>Key features of the Android testing environment include:</p>
-
+<p>
+ The Android testing framework, an integral part of the development environment,
+ provides an architecture and powerful tools that help you test every aspect of your application
+ at every level from unit to framework.
+</p>
+<p>
+ The testing framework has these key features:
+</p>
<ul>
- <li>Android extensions to the JUnit framework that provide access to Android
-system objects.</li>
- <li>An instrumentation framework that lets tests control and examine the
-application.</li>
- <li>Mock versions of commonly-used Android system objects.</li>
- <li>Tools for running single tests or test suites, with or without
-instrumentation.</li>
- <li>Support for managing tests and test projects in the ADT Plugin for Eclipse
-and at the command line.</li>
+ <li>
+ Android test suites are based on JUnit. You can use plain JUnit to test a class that doesn't
+ call the Android API, or Android's JUnit extensions to test Android components. If you're
+ new to Android testing, you can start with general-purpose test case classes such as {@link
+ android.test.AndroidTestCase} and then go on to use more sophisticated classes.
+ </li>
+ <li>
+ The Android JUnit extensions provide component-specific test case classes. These classes
+ provide helper methods for creating mock objects and methods that help you control the
+ lifecycle of a component.
+ </li>
+ <li>
+ Test suites are contained in test packages that are similar to main application packages, so
+ you don't need to learn a new set of tools or techniques for designing and building tests.
+ </li>
+ <li>
+ The SDK tools for building and tests are available in Eclipse with ADT, and also in
+ command-line form for use with other IDES. These tools get information from the project of
+ the application under test and use this information to automatically create the build files,
+ manifest file, and directory structure for the test package.
+ </li>
+ <li>
+ The SDK also provides
+ <a href="{@docRoot}guide/developing/tools/monkeyrunner_concepts.html">monkeyrunner</a>, an API
+ testing devices with Python programs, and <a
+ href="{@docRoot}guide/developing/tools/monkey.html">UI/Application Exerciser Monkey</a>,
+ a command-line tool for stress-testing UIs by sending pseudo-random events to a device.
+ </li>
</ul>
+<p>
+ This document describes the fundamentals of the Android testing framework, including the
+ structure of tests, the APIs that you use to develop tests, and the tools that you use to run
+ tests and view results. The document assumes you have a basic knowledge of Android application
+ programming and JUnit testing methodology.
+</p>
+<p>
+ The following diagram summarizes the testing framework:
+</p>
+<div style="width: 70%; margin-left:auto; margin-right:auto;">
+<a href="{@docRoot}images/testing/test_framework.png">
+ <img src="{@docRoot}images/testing/test_framework.png"
+ alt="The Android testing framework"/>
+</a>
+</div>
+<h2 id="TestStructure">Test Structure</h2>
+<p>
+ Android's build and test tools assume that test projects are organized into a standard
+ structure of tests, test case classes, test packages, and test projects.
+</p>
+<p>
+ Android testing is based on JUnit. In general, a JUnit test is a method whose
+ statements test a part of the application under test. You organize test methods into classes
+ called test cases (or test suites). Each test is an isolated test of an individual module in
+ the application under test. Each class is a container for related test methods, although it
+ often provides helper methods as well.
+</p>
+<p>
+ In JUnit, you build one or more test source files into a class file. Similarly, in Android you
+ use the SDK's build tools to build one or more test source files into class files in an
+ Android test package. In JUnit, you use a test runner to execute test classes. In Android, you
+ use test tools to load the test package and the application under test, and the tools then
+ execute an Android-specific test runner.
+</p>
+<h2 id="TestProjects">Test Projects</h2>
+<p>
+ Tests, like Android applications, are organized into projects.
+</p>
+<p>
+ A test project is a directory or Eclipse project in which you create the source code, manifest
+ file, and other files for a test package. The Android SDK contains tools for Eclipse with ADT
+ and for the command line that create and update test projects for you. The tools create the
+ directories you use for source code and resources and the manifest file for the test package.
+ The command-line tools also create the Ant build files you need.
+</p>
+<p>
+ You should always use Android tools to create a test project. Among other benefits,
+ the tools:
+</p>
+ <ul>
+ <li>
+ Automatically set up your test package to use
+ {@link android.test.InstrumentationTestRunner} as the test case runner. You must use
+ <code>InstrumentationTestRunner</code> (or a subclass) to run JUnit tests.
+ </li>
+ <li>
+ Create an appropriate name for the test package. If the application
+ under test has a package name of <code>com.mydomain.myapp</code>, then the
+ Android tools set the test package name to <code>com.mydomain.myapp.test</code>. This
+ helps you identify their relationship, while preventing conflicts within the system.
+ </li>
+ <li>
+ Automatically create the proper build files, manifest file, and directory
+ structure for the test project. This helps you to build the test package without
+ having to modify build files and sets up the linkage between your test package and
+ the application under test.
+ The
+ </li>
+ </ul>
+<p>
+ You can create a test project anywhere in your file system, but the best approach is to
+ add the test project so that its root directory <code>tests/</code> is at the same level
+ as the <code>src/</code> directory of the main application's project. This helps you find the
+ tests associated with an application. For example, if your application project's root directory
+ is <code>MyProject</code>, then you should use the following directory structure:
+</p>
+<pre class="classic no-pretty-print">
+ MyProject/
+ AndroidManifest.xml
+ res/
+ ... (resources for main application)
+ src/
+ ... (source code for main application) ...
+ tests/
+ AndroidManifest.xml
+ res/
+ ... (resources for tests)
+ src/
+ ... (source code for tests)
+</pre>
+<h2 id="TestAPI">The Testing API</h2>
+<p>
+ The Android testing API is based on the JUnit API and extended with a instrumentation
+ framework and Android-specific testing classes.
+</p>
+<h3 id="JUnit">JUnit</h3>
+<p>
+ You can use the JUnit {@link junit.framework.TestCase TestCase} class to do unit testing on
+ a plain Java object. <code>TestCase</code> is also the base class for
+ {@link android.test.AndroidTestCase}, which you can use to test Android-dependent objects.
+ Besides providing the JUnit framework, AndroidTestCase offers Android-specific setup,
+ teardown, and helper methods.
+</p>
+<p>
+ You use the JUnit {@link junit.framework.Assert} class to display test results.
+ The assert methods compare values you expect from a test to the actual results and
+ throw an exception if the comparison fails. Android also provides a class of assertions that
+ extend the possible types of comparisons, and another class of assertions for testing the UI.
+ These are described in more detail in the section <a href="#AssertionClasses">
+ Assertion classes</a>
+</p>
+<p>
+ To learn more about JUnit, you can read the documentation on the
+ <a href="http://www.junit.org">junit.org</a> home page.
+ Note that the Android testing API supports JUnit 3 code style, but not JUnit 4. Also, you must
+ use Android's instrumented test runner {@link android.test.InstrumentationTestRunner} to run
+ your test case classes. This test runner is described in the
+ section <a href="#InstrumentationTestRunner">Running Tests</a>.
+</p>
+<h3 id="Instrumentation">Instrumentation</h3>
+<p>
+ Android instrumentation is a set of control methods or "hooks" in the Android system. These hooks
+ control an Android component independently of its normal lifecycle. They also control how
+ Android loads applications.
+</p>
+<p>
+ Normally, an Android component runs in a lifecycle determined by the system. For example, an
+ Activity object's lifecycle starts when the Activity is activated by an Intent. The object's
+ <code>onCreate()</code> method is called, followed by <code>onResume()</code>. When the user
+ starts another application, the <code>onPause()</code> method is called. If the Activity
+ code calls the <code>finish()</code> method, the <code>onDestroy()</code> method is called.
+ The Android framework API does not provide a way for your code to invoke these callback
+ methods directly, but you can do so using instrumentation.
+</p>
+<p>
+ Also, the system runs all the components of an application into the same
+ process. You can allow some components, such as content providers, to run in a separate process,
+ but you can't force an application to run in the same process as another application that is
+ already running.
+</p>
+<p>
+ With Android instrumentation, though, you can invoke callback methods in your test code.
+ This allows you to run through the lifecycle of a component step by step, as if you were
+ debugging the component. The following test code snippet demonstrates how to use this to
+ test that an Activity saves and restores its state:
+</p>
+<a name="ActivitySnippet"></a>
+<pre>
+ // Start the main activity of the application under test
+ mActivity = getActivity();
-<p>This document is an overview of the Android testing environment and the way
-you use it. The document assumes you have a basic knowledge of Android
-application programming and JUnit testing methodology.</p>
-
-<h2 id="Overview">Overview</h2>
-
-<p> At the heart of the Android testing environment is an instrumentation
-framework that your test application uses to precisely control the application
-under test. With instrumentation, you can set up mock system objects such as
-Contexts before the main application starts, control your application at various
-points of its lifecycle, send UI events to the application, and examine the
-application's state during its execution. The instrumentation framework
-accomplishes this by running both the main application and the test application
-in the same process. </p>
-
-<p>Your test application is linked to the application under test by means of an
-<a
-href="{@docRoot}guide/topics/manifest/instrumentation-element.html"><code>&lt;instrumentation&gt;</code></a>
-element in the test application's manifest file. The attributes of the element
-specify the package name of the application under test and also tell Android how
-to run the test application. Instrumentation is described in more detail in the
-section <a href="#InstrumentationTestRunner">Instrumentation Test
-Runner</a>.</p>
-
-<p>The following diagram summarizes the Android testing environment:</p>
-
-<img src="{@docRoot}images/testing/android_test_framework.png"/>
+ // Get a handle to the Activity object's main UI widget, a Spinner
+ mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01);
-<p>In Android, test applications are themselves Android applications, so you
-write them in much the same way as the application you are testing. The SDK
-tools help you create a main application project and its test project at the same
-time. You can run Android tests within Eclipse with ADT or from the command
-line. Eclipse with ADT provides an extensive set of tools for creating tests,
-running them, and viewing their results. You can also use the <code>adb</code>
-tool to run tests, or use a built-in Ant target.</p>
+ // Set the Spinner to a known position
+ mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);
-<p>To learn how to set up and run tests in Eclipse, please refer to <a
-href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in
-Eclipse, with ADT</a>. If you're not working in Eclipse, refer to <a
-href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other
-IDEs</a>.</p>
+ // Stop the activity - The onDestroy() method should save the state of the Spinner
+ mActivity.finish();
-<p>If you want a step-by-step introduction to Android testing, try one of the
-testing tutorials:</p>
+ // Re-start the Activity - the onResume() method should restore the state of the Spinner
+ mActivity = getActivity();
-<ul>
- <li>The <a
-href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello,
-Testing</a> tutorial introduces basic testing concepts and procedures in the
-context of the Hello, World application.</li>
- <li>The <a
-href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity
-Testing</a> tutorial is an excellent follow-up to the Hello, Testing tutorial.
-It guides you through a more complex testing scenario that you develop against a
-more realistic application.</li>
-</ul>
+ // Get the Spinner's current position
+ int currentPosition = mActivity.getSpinnerPosition();
-<h2 id="TestAPI">The Testing API</h2>
+ // Assert that the current position is the same as the starting position
+ assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);
+</pre>
<p>
- For writing tests and test applications in the Java programming language, Android provides a
- testing API that is based in part on the JUnit test framework. Adding to that, Android includes
- a powerful instrumentation framework that lets your tests access the state and runtime objects
- of the application under tests.
+ The key method used here is
+ {@link android.test.ActivityInstrumentationTestCase2#getActivity()}, which is a
+ part of the instrumentation API. The Activity under test is not started until you call this
+ method. You can set up the test fixture in advance, and then call this method to start the
+ Activity.
</p>
-<p>The sections below describe the major components of the testing API available in Android.</p>
-<h3 id="Extensions">JUnit test case classes</h3>
<p>
- Some of the classes in the testing API extend the JUnit {@link junit.framework.TestCase TestCase} but do not use the instrumentation framework. These classes
- contain methods for accessing system objects such as the Context of the application under test. With this Context, you can look at its resources, files, databases,
- and so forth. The base class is {@link android.test.AndroidTestCase}, but you usually use a subclass associated with a particular component.
+ Also, instrumentation can load both a test package and the application under test into the
+ same process. Since the application components and their tests are in the same process, the
+ tests can invoke methods in the components, and modify and examine fields in the components.
+</p>
+<h3 id="TestCaseClasses">Test case classes</h3>
<p>
- The subclasses are:
+ Android provides several test case classes that extend {@link junit.framework.TestCase} and
+ {@link junit.framework.Assert} with Android-specific setup, teardown, and helper methods.
</p>
- <ul>
- <li>
- {@link android.test.ApplicationTestCase} - A class for testing an entire application. It allows you to inject a mock Context into the application,
- set up initial test parameters before the application starts, and examine the application after it finishes but before it is destroyed.
- </li>
- <li>
- {@link android.test.ProviderTestCase2} - A class for isolated testing of a single {@link android.content.ContentProvider}. Since it is restricted to using a
- {@link android.test.mock.MockContentResolver} for the provider, and it injects an {@link android.test.IsolatedContext}, your provider testing is isolated
- from the rest of the OS.
- </li>
- <li>
- {@link android.test.ServiceTestCase} - a class for isolated testing of a single {@link android.app.Service}. You can inject a mock Context or
- mock Application (or both), or let Android provide you a full Context and a {@link android.test.mock.MockApplication}.
- </li>
- </ul>
-<h3 id="Instrumentation">Instrumentation test case classes</h3>
+<h4 id="AndroidTestCase">AndroidTestCase</h4>
<p>
- The API for testing activities extends the JUnit {@link junit.framework.TestCase TestCase} class and also uses the instrumentation framework. With instrumentation,
- Android can automate UI testing by sending events to the application under test, precisely control the start of an activity, and monitor the state of the
- activity during its life cycle.
+ A useful general test case class, especially if you are
+ just starting out with Android testing, is {@link android.test.AndroidTestCase}. It extends
+ both {@link junit.framework.TestCase} and {@link junit.framework.Assert}. It provides the
+ JUnit-standard <code>setUp()</code> and <code>tearDown()</code> methods, as well as well as
+ all of JUnit's Assert methods. In addition, it provides methods for testing permissions, and a
+ method that guards against memory leaks by clearing out certain class references.
</p>
+<h4 id="ComponentTestCase">Component-specific test cases</h4>
<p>
- The base class is {@link android.test.InstrumentationTestCase}. All of its subclasses have the ability to send a keystroke or touch event to the UI of the application
- under test. The subclasses can also inject a mock Intent.
- The subclasses are:
+ A key feature of the Android testing framework is its component-specific test case classes.
+ These address specific component testing needs with methods for fixture setup and
+ teardown and component lifecycle control. They also provide methods for setting up mock objects.
+ These classes are described in the component-specific testing topics:
</p>
- <ul>
+<ul>
<li>
- {@link android.test.ActivityTestCase} - A base class for activity test classes.
+ <a href="{@docRoot}guide/topics/testing/activity_testing.html">Activity Testing</a>
</li>
<li>
- {@link android.test.SingleLaunchActivityTestCase} - A convenience class for testing a single activity.
- It invokes {@link junit.framework.TestCase#setUp() setUp()} and {@link junit.framework.TestCase#tearDown() tearDown()} only
- once, instead of once per method call. Use it when all of your test methods run against the same activity.
+ <a href="{@docRoot}guide/topics/testing/contentprovider_testing.html">
+ Content Provider Testing</a>
</li>
<li>
- {@link android.test.SyncBaseInstrumentation} - A class that tests synchronization of a content provider. It uses instrumentation to cancel and disable
- existing synchronizations before starting the test synchronization.
+ <a href="{@docRoot}guide/topics/testing/service_testing.html">Service Testing</a>
</li>
+</ul>
+<p>
+ Android does not provide a separate test case class for BroadcastReceiver. Instead, test a
+ BroadcastReceiver by testing the component that sends it Intent objects, to verify that the
+ BroadcastReceiver responds correctly.
+</p>
+<h4 id="ApplicationTestCase">ApplicationTestCase</h4>
+<p>
+ You use the {@link android.test.ApplicationTestCase} test case class to test the setup and
+ teardown of {@link android.app.Application} objects. These objects maintain the global state of
+ information that applies to all the components in an application package. The test case can
+ be useful in verifying that the &lt;application&gt; element in the manifest file is correctly
+ set up. Note, however, that this test case does not allow you to control testing of the
+ components within your application package.
+</p>
+<h4 id="InstrumentationTestCase">InstrumentationTestCase</h4>
+<p>
+ If you want to use instrumentation methods in a test case class, you must use
+ {@link android.test.InstrumentationTestCase} or one of its subclasses. The
+ {@link android.app.Activity} test cases extend this base class with other functionality that
+ assists in Activity testing.
+</p>
+
+<h3 id="AssertionClasses">Assertion classes</h3>
+<p>
+ Because Android test case classes extend JUnit, you can use assertion methods to display the
+ results of tests. An assertion method compares an actual value returned by a test to an
+ expected value, and throws an AssertionException if the comparison test fails. Using assertions
+ is more convenient than doing logging, and provides better test performance.
+</p>
+<p>
+ Besides the JUnit {@link junit.framework.Assert} class methods, the testing API also provides
+ the {@link android.test.MoreAsserts} and {@link android.test.ViewAsserts} classes:
+</p>
+<ul>
<li>
- {@link android.test.ActivityUnitTestCase} - This class does an isolated test of a single activity. With it, you can inject a mock context or application, or both.
- It is intended for doing unit tests of an activity, and is the activity equivalent of the test classes described in <a href="#Extensions">JUnit test case classes</a>.
- <p> Unlike the other instrumentation classes, this test class cannot inject a mock Intent.</p>
+ {@link android.test.MoreAsserts} contains more powerful assertions such as
+ {@link android.test.MoreAsserts#assertContainsRegex}, which does regular expression
+ matching.
</li>
<li>
- {@link android.test.ActivityInstrumentationTestCase2} - This class tests a single activity within the normal system environment.
- You cannot inject a mock Context, but you can inject mock Intents. Also, you can run a test method on the UI thread (the main thread of the application under test),
- which allows you to send key and touch events to the application UI.
+ {@link android.test.ViewAsserts} contains useful assertions about Views. For example
+ it contains {@link android.test.ViewAsserts#assertHasScreenCoordinates} that tests if a View
+ has a particular X and Y position on the visible screen. These asserts simplify testing of
+ geometry and alignment in the UI.
</li>
- </ul>
-<h3 id="Assert">Assert classes</h3>
-<p>
- Android also extends the JUnit {@link junit.framework.Assert} class that is the basis of <code>assert()</code> calls in tests.
- There are two extensions to this class, {@link android.test.MoreAsserts} and {@link android.test.ViewAsserts}:
-</p>
-<ul>
- <li>
- The <code>MoreAsserts</code> class contains more powerful assertions such as {@link android.test.MoreAsserts#assertContainsRegex} that does regular expression matching.
- </li>
- <li>
- The {@link android.test.ViewAsserts} class contains useful assertions about Android Views, such as {@link android.test.ViewAsserts#assertHasScreenCoordinates} that tests if a View has a particular X and Y
- position on the visible screen. These asserts simplify testing of geometry and alignment in the UI.
- </li>
</ul>
-<h3 id="MockObjects">Mock object classes</h3>
- <p>
- Android has convenience classes for creating mock system objects such as applications, contexts, content resolvers, and resources. Android also provides
- methods in some test classes for creating mock Intents. Use these mocks to facilitate dependency injection, since they are easier to use than creating their
- real counterparts. These convenience classes are found in {@link android.test} and {@link android.test.mock}. They are:
- </p>
- <ul>
- <li>
- {@link android.test.IsolatedContext} - Mocks a Context so that the application using it runs in isolation.
- At the same time, it has enough stub code to satisfy OS code that tries to communicate with contexts. This class is useful in unit testing.
- </li>
- <li>
- {@link android.test.RenamingDelegatingContext} - Delegates most context functions to an existing, normal context while changing the default file and database
- names in the context. Use this to test file and database operations with a normal system context, using test names.
- </li>
- <li>
- {@link android.test.mock.MockApplication}, {@link android.test.mock.MockContentResolver}, {@link android.test.mock.MockContext},
- {@link android.test.mock.MockDialogInterface}, {@link android.test.mock.MockPackageManager},
- {@link android.test.mock.MockResources} - Classes that create mock Android system objects for use in testing. They expose only those methods that are
- useful in managing the object. The default implementations of these methods simply throw an Exception. You are expected to extend the classes and
- override any methods that are called by the application under test.
- </li>
- </ul>
-<h3 id="InstrumentationTestRunner">Instrumentation Test Runner</h3>
+<h3 id="MockObjectClasses">Mock object classes</h3>
<p>
- Android provides a custom class for running tests with instrumentation called called
- {@link android.test.InstrumentationTestRunner}. This class
- controls of the application under test, runs the test application and the main application in the same process, and routes
- test output to the appropriate place. Using instrumentation is key to the ability of <code>InstrumentationTestRunner</code> to control the entire test
- environment at runtime. Notice that you use this test runner even if your test class does not itself use instrumentation.
+ To facilitate dependency injection in testing, Android provides classes that create mock system
+ objects such as {@link android.content.Context} objects,
+ {@link android.content.ContentProvider} objects, {@link android.content.ContentResolver}
+ objects, and {@link android.app.Service} objects. Some test cases also provide mock
+ {@link android.content.Intent} objects. You use these mocks both to isolate tests
+ from the rest of the system and to facilitate dependency injection for testing. These classes
+ are found in the Java packages {@link android.test} and {@link android.test.mock}.
</p>
<p>
- When you run a test application, you first run a system utility called Activity Manager. Activity Manager uses the instrumentation framework to start and control the test runner, which in turn uses instrumentation to shut down any running instances
- of the main application, starts the test application, and then starts the main application in the same process. This allows various aspects of the test application to work directly with the main application.
+ Mock objects isolate tests from a running system by stubbing out or overriding
+ normal operations. For example, a {@link android.test.mock.MockContentResolver}
+ replaces the normal resolver framework with its own local framework, which is isolated
+ from the rest of the system. MockContentResolver also also stubs out the
+ {@link android.content.ContentResolver#notifyChange(Uri, ContentObserver, boolean)} method
+ so that observer objects outside the test environment are not accidentally triggered.
</p>
<p>
- If you are developing in Eclipse, the ADT plugin assists you in the setup of <code>InstrumentationTestRunner</code> or other test runners.
- The plugin UI prompts you to specify the test runner class to use, as well as the package name of the application under test.
- The plugin then adds an <code>&lt;instrumentation&gt;</code> element with appropriate attributes to the manifest file of the test application.
- Eclipse with ADT automatically starts a test application under the control of Activity Manager using instrumentation,
- and redirects the test output to the Eclipse window's JUnit view.
+ Mock object classes also facilitate dependency injection by providing a subclass of the
+ normal object that is non-functional except for overrides you define. For example, the
+ {@link android.test.mock.MockResources} object provides a subclass of
+ {@link android.content.res.Resources} in which all the methods throw Exceptions when called.
+ To use it, you override only those methods that must provide information.
</p>
<p>
- If you prefer working from the command line, you can use Ant and the <code>android</code>
- tool to help you set up your test projects. To run tests with instrumentation, you can access the
- Activity Manager through the <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug
- Bridge</a> (<code>adb</code>) tool and the output is directed to <code>STDOUT</code>.
+ These are the mock object classes available in Android:
</p>
-<h2 id="TestEnviroment">Working in the Test Environment</h2>
+<h4 id="SimpleMocks">Simple mock object classes</h4>
<p>
- The tests for an Android application are contained in a test application, which itself is an Android application. A test application resides in a separate Android project that has the
- same files and directories as a regular Android application. The test project is linked to the project of the application it tests
- (known as the application under test) by its manifest file.
+ {@link android.test.mock.MockApplication}, {@link android.test.mock.MockContext},
+ {@link android.test.mock.MockContentProvider}, {@link android.test.mock.MockCursor},
+ {@link android.test.mock.MockDialogInterface}, {@link android.test.mock.MockPackageManager}, and
+ {@link android.test.mock.MockResources} provide a simple and useful mock strategy. They are
+ stubbed-out versions of the corresponding system object class, and all of their methods throw an
+ {@link java.lang.UnsupportedOperationException} exception if called. To use them, you override
+ the methods you need in order to provide mock dependencies.
</p>
+<p class="Note"><strong>Note:</strong>
+ {@link android.test.mock.MockContentProvider}
+ and {@link android.test.mock.MockCursor} are new as of API level 8.
+</p>
+<h4 id="ResolverMocks">Resolver mock objects</h4>
<p>
- Each test application contains one or more test case classes based on an Android class for a
- particular type of component. The test case class contains methods that define tests on some part of the application under test. When you run the test application, Android
- starts it, loads the application under test into the same process, and then invokes each method in the test case class.
+ {@link android.test.mock.MockContentResolver} provides isolated testing of content providers by
+ masking out the normal system resolver framework. Instead of looking in the system to find a
+ content provider given an authority string, MockContentResolver uses its own internal table. You
+ must explicitly add providers to this table using
+ {@link android.test.mock.MockContentResolver#addProvider(String,ContentProvider)}.
</p>
<p>
- The tools and procedures you use with testing depend on the development environment you are using. If you use Eclipse, then the ADT plug in for Eclipse provides tools that
- allow you to develop and run tests entirely within Eclipse. This is documented in the topic <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in Eclipse, with ADT</a>.
- If you use another development environment, then you use Android's command-line tools, as documented in the topic <a href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other IDEs</a>.
+ With this feature, you can associate a mock content provider with an authority. You can create
+ an instance of a real provider but use test data in it. You can even set the provider for an
+ authority to <code>null</code>. In effect, a MockContentResolver object isolates your test
+ from providers that contain real data. You can control the
+ function of the provider, and you can prevent your test from affecting real data.
</p>
-<h3 id="TestProjects">Working with test projects</h3>
+<h3 id="ContextMocks">Contexts for testing</h3>
<p>
- To start testing an Android application, you create a test project for it using Android tools. The tools create the project directory and the files and subdirectories needed.
- The tools also create a manifest file that links the application in the test project to the application under test. The procedure for creating a test project in Eclipse with
- ADT is documented in <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in Eclipse, with ADT</a>. The procedure for creating a test project for use with development
- tools other than Eclipse is documented in <a href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other IDEs</a>.
+ Android provides two Context classes that are useful for testing:
</p>
-<h3 id="TestClasses">Working with test case classes</h3>
+<ul>
+ <li>
+ {@link android.test.IsolatedContext} provides an isolated {@link android.content.Context},
+ File, directory, and database operations that use this Context take place in a test area.
+ Though its functionality is limited, this Context has enough stub code to respond to
+ system calls.
+ <p>
+ This class allows you to test an application's data operations without affecting real
+ data that may be present on the device.
+ </p>
+ </li>
+ <li>
+ {@link android.test.RenamingDelegatingContext} provides a Context in which
+ most functions are handled by an existing {@link android.content.Context}, but
+ file and database operations are handled by a {@link android.test.IsolatedContext}.
+ The isolated part uses a test directory and creates special file and directory names.
+ You can control the naming yourself, or let the constructor determine it automatically.
+ <p>
+ This object provides a quick way to set up an isolated area for data operations,
+ while keeping normal functionality for all other Context operations.
+ </p>
+ </li>
+</ul>
+<h2 id="InstrumentationTestRunner">Running Tests</h2>
<p>
- A test application contains one or more test case classes that extend an Android test case class. You choose a test case class based on the type of Android component you are testing and the
- tests you are doing. A test application can test different components, but each test case class is designed to test a single type of component.
- The Android test case classes are described in the section <a href="#TestAPI">The Testing API</a>.
+ Test cases are run by a test runner class that loads the test case class, set ups,
+ runs, and tears down each test. An Android test runner must also be instrumented, so that
+ the system utility for starting applications can control how the test package
+ loads test cases and the application under test. You tell the Android platform
+ which instrumented test runner to use by setting a value in the test package's manifest file.
</p>
<p>
- Some Android components have more than one associated test case class. In this case, you choose among the available classes based on the type of tests you want to do. For activities,
- for example, you have the choice of either {@link android.test.ActivityInstrumentationTestCase2} or {@link android.test.ActivityUnitTestCase}.
+ {@link android.test.InstrumentationTestRunner} is the primary Android test runner class. It
+ extends the JUnit test runner framework and is also instrumented. It can run any of the test
+ case classes provided by Android and supports all possible types of testing.
+</p>
<p>
- <code>ActivityInstrumentationTestCase2</code> is designed to do functional testing, so it tests activities in a normal system infrastructure. You can inject mocked Intents, but not
- mocked Contexts. In general, you can't mock dependencies for the activity under test.
+ You specify <code>InstrumentationTestRunner</code> or a subclass in your test package's
+ manifest file, in the <a href="{@docRoot}guide/topics/manifest/instrumentation-element.html">
+ instrumentation</a> element. Also, <code>InstrumentationTestRunner</code> code resides
+ in the shared library <code>android.test.runner</code>, which is not normally linked to
+ Android code. To include it, you must specify it in a
+ <a href="{@docRoot}guide/topics/manifest/uses-library-element.html">uses-library</a> element.
+ You do not have to set up these elements yourself. Both Eclipse with ADT and the
+ <code>android</code> command-line tool construct them automatically and add them to your
+ test package's manifest file.
+</p>
+<p class="Note">
+ <strong>Note:</strong> If you use a test runner other than
+ <code>InstrumentationTestRunner</code>, you must change the &lt;instrumentation&gt;
+ element to point to the class you want to use.
</p>
<p>
- In comparison, <code>ActivityUnitTestCase</code> is designed for unit testing, so it tests activities in an isolated system infrastructure. You can inject mocked or wrappered dependencies for
- the activity under test, particularly mocked Contexts. On the other hand, when you use this test case class the activity under test runs in isolation and can't interact with other activities.
+ To run {@link android.test.InstrumentationTestRunner}, you use internal system classes called by
+ Android tools. When you run a test in Eclipse with ADT, the classes are called automatically.
+ When you run a test from the command line, you run these classes with
+ <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug Bridge (adb)</a>.
</p>
<p>
- As a rule of thumb, if you wanted to test an activity's interaction with the rest of Android, you would use <code>ActivityInstrumentationTestCase2</code>. If you wanted to do regression testing
- on an activity, you would use <code>ActivityUnitTestCase</code>.
+ The system classes load and start the test package, kill any processes that
+ are running an instance of the application under test, and then load a new instance of the
+ application under test. They then pass control to
+ {@link android.test.InstrumentationTestRunner}, which runs
+ each test case class in the test package. You can also control which test cases and
+ methods are run using settings in Eclipse with ADT, or using flags with the command-line tools.
</p>
-<h3 id="Tests">Working with test methods</h3>
<p>
- Each test case class provides methods that you use to set up the test environment and control the application under test. For example, all test case classes provide the JUnit {@link junit.framework.TestCase#setUp() setUp()}
- method that you can override to set up fixtures. In addition, you add methods to the class to define individual tests. Each method you add is run once each time you run the test application. If you override the <code>setUp()</code>
- method, it runs before each of your methods. Similarly, the JUnit {@link junit.framework.TestCase#tearDown() tearDown()} method is run once after each of your methods.
+ Neither the system classes nor {@link android.test.InstrumentationTestRunner} run
+ the application under test. Instead, the test case does this directly. It either calls methods
+ in the application under test, or it calls its own methods that trigger lifecycle events in
+ the application under test. The application is under the complete control of the test case,
+ which allows it to set up the test environment (the test fixture) before running a test. This
+ is demonstrated in the previous <a href="#ActivitySnippet">code snippet</a> that tests an
+ Activity that displays a Spinner widget.
</p>
<p>
- The test case classes give you substantial control over starting and stopping components. For this reason, you have to specifically tell Android to start a component before you run tests against it. For example, you use the
- {@link android.test.ActivityInstrumentationTestCase2#getActivity()} method to start the activity under test. You can call this method once during the entire test case, or once for each test method. You can even destroy the
- activity under test by calling its {@link android.app.Activity#finish()} method and then restart it with <code>getActivity()</code> within a single test method.
+ To learn more about running tests, please read the topics
+ <a href="{@docRoot}guide/developing/testing/testing_eclipse.html"">
+ Testing in Eclipse, with ADT</a> or
+ <a href="{@docRoot}guide/developing/testing/testing_otheride.html">
+ Testing in Other IDes</a>.
</p>
-<h3 id="RunTests">Running tests and seeing the results</h3>
+<h2 id="TestResults">Seeing Test Results</h2>
<p>
- To run your tests, you build your test project and then run the test application using the system utility Activity Manager with instrumentation. You provide to Activity Manager the name of the test runner (usually
- {@link android.test.InstrumentationTestRunner}) you specified for your application; the name includes both your test application's package name and the test runner class name. Activity Manager loads and starts your
- test application, kills any instances of the application under test, loads an instance of the application under test into the same process as the test application, and then passes control to the first test case
- class in your test application. The test runner then takes control of the tests, running each of your test methods against the application under test until all the methods in all the classes have been run.
+ The Android testing framework returns test results back to the tool that started the test.
+ If you run a test in Eclipse with ADT, the results are displayed in a new JUnit view pane. If
+ you run a test from the command line, the results are displayed in <code>STDOUT</code>. In
+ both cases, you see a test summary that displays the name of each test case and method that
+ was run. You also see all the assertion failures that occurred. These include pointers to the
+ line in the test code where the failure occurred. Assertion failures also list the expected
+ value and actual value.
</p>
<p>
- If you run a test within Eclipse with ADT, the output appears in a new JUnit view pane. If you run a test from the command line, the output goes to STDOUT.
+ The test results have a format that is specific to the IDE that you are using. The test
+ results format for Eclipse with ADT is described in
+ <a href="{@docRoot}guide/developing/testing/testing_eclipse.html#RunTestEclipse">
+ Testing in Eclipse, with ADT</a>. The test results format for tests run from the
+ command line is described in
+ <a href="{@docRoot}guide/developing/testing/testing_otheride.html#RunTestsCommand">
+ Testing in Other IDEs</a>.
</p>
-<h2 id="TestAreas">What to Test</h2>
+<h2 id="Monkeys">monkey and monkeyrunner</h2>
<p>
- In addition to the functional areas you would normally test, here are some areas
- of Android application testing that you should consider:
+ The SDK provides two tools for functional-level application testing:
</p>
- <ul>
- <li>
- Activity lifecycle events: You should test that your activities handle lifecycle events correctly. For example
- an activity should respond to pause or destroy events by saving its state. Remember that even a change in screen orientation
- causes the current activity to be destroyed, so you should test that accidental device movements don't accidentally lose the
- application state.
- </li>
- <li>
- Database operations: You should ensure that database operations correctly handle changes to the application's state.
- To do this, use mock objects from the package {@link android.test.mock android.test.mock}.
- </li>
- <li>
- Screen sizes and resolutions: Before you publish your application, make sure to test it on all of the
- screen sizes and densities on which you want it to run. You can test the application on multiple sizes and densities using
- AVDs, or you can test your application directly on the devices that you are targeting. For more information, see
- the topic <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.
- </li>
- </ul>
+ <ul>
+ <li>
+The <a href="{@docRoot}guide/developing/tools/monkey.html">UI/Application Exerciser Monkey</a>,
+ usually called "monkey", is a command-line tool that sends pseudo-random streams of
+ keystrokes, touches, and gestures to a device. You run it with the
+ <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug Bridge</a> (adb) tool.
+ You use it to stress-test your application and report back errors that are encountered.
+ You can repeat a stream of events by running the tool each time with the same random
+ number seed.
+ </li>
+ <li>
+ The <a href="{@docRoot}guide/developing/tools/monkeyrunner_concepts.html">monkeyrunner</a> tool
+ is an API and execution environment for test programs written in Python. The API
+ includes functions for connecting to a device, installing and uninstalling packages,
+ taking screenshots, comparing two images, and running a test package against an
+ application. Using the API, you can write a wide range of large, powerful, and complex
+ tests. You run programs that use the API with the <code>monkeyrunner</code> command-line
+ tool.
+ </li>
+ </ul>
+<h2 id="PackageNames">Working With Package names</h2>
<p>
- When possible, you should run these tests on an actual device. If this is not possible, you can
- use the <a href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a> with
- <a href="{@docRoot}guide/developing/tools/avd.html">Android Virtual Devices</a> configured for
- the hardware, screens, and versions you want to test.
+ In the test environment, you work with both Android application package names and
+ Java package identifiers. Both use the same naming format, but they represent substantially
+ different entities. You need to know the difference to set up your tests correctly.
</p>
-<h2 id="UITesting">Appendix: UI Testing Notes</h2>
<p>
- The following sections have tips for testing the UI of your Android application, specifically
- to help you handle actions that run in the UI thread, touch screen and keyboard events, and home
- screen unlock during testing.
+ An Android package name is a unique system name for a <code>.apk</code> file, set by the
+ &quot;android:package&quot; attribute of the &lt;manifest&gt; element in the package's
+ manifest. The Android package name of your test package must be different from the
+ Android package name of the application under test. By default, Android tools create the
+ test package name by appending ".test" to the package name of the application under test.
</p>
-<h3 id="RunOnUIThread">Testing on the UI thread</h3>
<p>
- An application's activities run on the application's <strong>UI thread</strong>. Once the
- UI is instantiated, for example in the activity's <code>onCreate()</code> method, then all
- interactions with the UI must run in the UI thread. When you run the application normally, it
- has access to the thread and does not have to do anything special.
+ The test package also uses an Android package name to target the application package it
+ tests. This is set in the &quot;android:targetPackage&quot; attribute of the
+ &lt;instrumentation&gt; element in the test package's manifest.
</p>
<p>
- This changes when you run tests against the application. With instrumentation-based classes,
- you can invoke methods against the UI of the application under test. The other test classes don't allow this.
- To run an entire test method on the UI thread, you can annotate the thread with <code>@UIThreadTest</code>.
- Notice that this will run <em>all</em> of the method statements on the UI thread. Methods that do not interact with the UI
- are not allowed; for example, you can't invoke <code>Instrumentation.waitForIdleSync()</code>.
+ A Java package identifier applies to a source file. This package name reflects the directory
+ path of the source file. It also affects the visibility of classes and members to each other.
</p>
<p>
- To run a subset of a test method on the UI thread, create an anonymous class of type
- <code>Runnable</code>, put the statements you want in the <code>run()</code> method, and instantiate a new
- instance of the class as a parameter to the method <code><em>appActivity</em>.runOnUiThread()</code>, where
- <code><em>appActivity</em></code> is the instance of the app you are testing.
+ Android tools that create test projects set up an Android test package name for you.
+ From your input, the tools set up the test package name and the target package name for the
+ application under test. For these tools to work, the application project must already exist.
</p>
<p>
- For example, this code instantiates an activity to test, requests focus (a UI action) for the Spinner displayed
- by the activity, and then sends a key to it. Notice that the calls to <code>waitForIdleSync</code> and <code>sendKeys</code>
- aren't allowed to run on the UI thread:</p>
-<pre>
- private MyActivity mActivity; // MyActivity is the class name of the app under test
- private Spinner mSpinner;
-
- ...
-
- protected void setUp() throws Exception {
- super.setUp();
- mInstrumentation = getInstrumentation();
-
- mActivity = getActivity(); // get a references to the app under test
-
- /*
- * Get a reference to the main widget of the app under test, a Spinner
- */
- mSpinner = (Spinner) mActivity.findViewById(com.android.demo.myactivity.R.id.Spinner01);
-
- ...
-
- public void aTest() {
- /*
- * request focus for the Spinner, so that the test can send key events to it
- * This request must be run on the UI thread. To do this, use the runOnUiThread method
- * and pass it a Runnable that contains a call to requestFocus on the Spinner.
- */
- mActivity.runOnUiThread(new Runnable() {
- public void run() {
- mSpinner.requestFocus();
- }
- });
-
- mInstrumentation.waitForIdleSync();
-
- this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-</pre>
-
-<h3 id="NotouchMode">Turning off touch mode</h3>
+ By default, these tools set the Java package identifier for the test class to be the same
+ as the Android package identifier. You may want to change this if you want to expose
+ members in the application under test by giving them package visibility. If you do this,
+ change only the Java package identifier, not the Android package names, and change only the
+ test case source files. Do not change the Java package name of the generated
+ <code>R.java</code> class in your test package, because it will then conflict with the
+ <code>R.java</code> class in the application under test. Do not change the Android package name
+ of your test package to be the same as the application it tests, because then their names
+ will no longer be unique in the system.
+</p>
+<h2 id="WhatToTest">What to Test</h2>
<p>
- To control the emulator or a device with key events you send from your tests, you must turn off
- touch mode. If you do not do this, the key events are ignored.
+ The topic <a href="{@docRoot}guide/topics/testing/what_to_test.html">What To Test</a>
+ describes the key functionality you should test in an Android application, and the key
+ situations that might affect that functionality.
</p>
<p>
- To turn off touch mode, you invoke <code>ActivityInstrumentationTestCase2.setActivityTouchMode(false)</code>
- <em>before</em> you call <code>getActivity()</code> to start the activity. You must invoke the method in a test method
- that is <em>not</em> running on the UI thread. For this reason, you can't invoke the touch mode method
- from a test method that is annotated with <code>@UIThread</code>. Instead, invoke the touch mode method from <code>setUp()</code>.
+ Most unit testing is specific to the Android component you are testing.
+ The topics <a href="{@docRoot}guide/topics/testing/activity_testing.html">Activity Testing</a>,
+ <a href="{@docRoot}guide/topics/testing/contentprovider_testing.html">
+ Content Provider Testing</a>, and <a href="{@docRoot}guide/topics/testing/service_testing.html">
+ Service Testing</a> each have a section entitled "What To Test" that lists possible testing
+ areas.
</p>
-<h3 id="UnlockDevice">Unlocking the emulator or device</h3>
<p>
- You may find that UI tests don't work if the emulator's or device's home screen is disabled with the keyguard pattern.
- This is because the application under test can't receive key events sent by <code>sendKeys()</code>. The best
- way to avoid this is to start your emulator or device first and then disable the keyguard for the home screen.
+ When possible, you should run these tests on an actual device. If this is not possible, you can
+ use the <a href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a> with
+ <a href="{@docRoot}guide/developing/tools/avd.html">Android Virtual Devices</a> configured for
+ the hardware, screens, and versions you want to test.
</p>
+<h2 id="NextSteps">Next Steps</h2>
<p>
- You can also explicitly disable the keyguard. To do this,
- you need to add a permission in the manifest file (<code>AndroidManifest.xml</code>) and
- then disable the keyguard in your application under test. Note, though, that you either have to remove this before
- you publish your application, or you have to disable it programmatically in the published app.
+ To learn how to set up and run tests in Eclipse, please refer to <a
+ href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in
+ Eclipse, with ADT</a>. If you're not working in Eclipse, refer to <a
+ href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other
+ IDEs</a>.
</p>
<p>
- To add the the permission, add the element <code>&lt;uses-permission android:name="android.permission.DISABLE_KEYGUARD"/&gt;</code>
- as a child of the <code>&lt;manifest&gt;</code> element. To disable the KeyGuard, add the following code
- to the <code>onCreate()</code> method of activities you intend to test:
+ If you want a step-by-step introduction to Android testing, try one of the
+ testing tutorials or sample test packages:
</p>
-<pre>
- mKeyGuardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
- mLock = mKeyGuardManager.newKeyguardLock("<em>activity_classname</em>");
- mLock.disableKeyguard();
-</pre>
-<p>where <code><em>activity_classname</em></code> is the class name of the activity.</p>
-<h3 id="UITestTroubleshooting">Troubleshooting UI tests</h3>
-<p>
- This section lists some of the common test failures you may encounter in UI testing, and their causes:
-</p>
-<dl>
- <dt><code>WrongThreadException</code></dt>
- <dd>
- <p><strong>Problem:</strong></p>
- For a failed test, the Failure Trace contains the following error message:
- <code>
- android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
- </code>
- <p><strong>Probable Cause:</strong></p>
- This error is common if you tried to send UI events to the UI thread from outside the UI thread. This commonly happens if you send UI events
- from the test application, but you don't use the <code>@UIThread</code> annotation or the <code>runOnUiThread()</code> method. The test method tried to interact with the UI outside the UI thread.
- <p><strong>Suggested Resolution:</strong></p>
- Run the interaction on the UI thread. Use a test class that provides instrumentation. See the previous section <a href="#RunOnUIThread">Testing on the UI Thread</a>
- for more details.
- </dd>
- <dt><code>java.lang.RuntimeException</code></dt>
- <dd>
- <p><strong>Problem:</strong></p>
- For a failed test, the Failure Trace contains the following error message:
- <code>
- java.lang.RuntimeException: This method can not be called from the main application thread
- </code>
- <p><strong>Probable Cause:</strong></p>
- This error is common if your test method is annotated with <code>@UiThreadTest</code> but then tries to
- do something outside the UI thread or tries to invoke <code>runOnUiThread()</code>.
- <p><strong>Suggested Resolution:</strong></p>
- Remove the <code>@UiThreadTest</code> annotation, remove the <code>runOnUiThread()</code> call, or re-factor your tests.
- </dd>
-</dl>
+<ul>
+ <li>
+ The <a
+ href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello,
+ Testing</a> tutorial introduces basic testing concepts and procedures in the
+ context of the Hello, World application.
+ </li>
+ <li>
+ The <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity
+ Testing</a> tutorial is an excellent follow-up to the Hello, Testing tutorial.
+ It guides you through a more complex testing scenario that you develop against a
+ more realistic application.
+ </li>
+ <li>
+ The sample test package <a href="{@docRoot}resources/samples/AlarmServiceTest"}>
+ Alarm Service Test</a> is an example of testing a {@link android.app.Service}. It contains
+ a set of unit tests for the Alarm Service sample application's {@link android.app.Service}.
+ </li>
+</ul>
diff --git a/docs/html/guide/topics/testing/what_to_test.jd b/docs/html/guide/topics/testing/what_to_test.jd
new file mode 100644
index 0000000..e13538a
--- /dev/null
+++ b/docs/html/guide/topics/testing/what_to_test.jd
@@ -0,0 +1,84 @@
+page.title=What To Test
+@jd:body
+<p>
+ As you develop Android applications, knowing what to test is as important as knowing how to
+ test. This document lists some most common Android-related situations that you should consider
+ when you test, even at the unit test level. This is not an exhaustive list, and you consult the
+ documentation for the features that you use for more ideas. The
+ <a href="http://groups.google.com/group/android-developers">android-developers</a> Google Groups
+ site is another resource for information about testing.
+</p>
+<h2 id="Tests">Ideas for Testing</h2>
+<p>
+ The following sections are organized by behaviors or situations that you should test. Each
+ section contains a scenario that further illustrates the situation and the test or tests you
+ should do.
+</p>
+<h4>Change in orientation</h4>
+<p>
+ For devices that support multiple orientations, Android detects a change in orientation when
+ the user turns the device so that the display is "landscape" (long edge is horizontal) instead
+ of "portrait" (long edge is vertical).
+</p>
+<p>
+ When Android detects a change in orientation, its default behavior is to destroy and then
+ re-start the foreground Activity. You should consider testing the following:
+</p>
+<ul>
+ <li>
+ Is the screen re-drawn correctly? Any custom UI code you have should handle changes in the
+ orientation.
+ </li>
+ <li>
+ Does the application maintain its state? The Activity should not lose anything that the
+ user has already entered into the UI. The application should not "forget" its place in the
+ current transaction.
+ </li>
+</ul>
+<h4>Change in configuration</h4>
+<p>
+ A situation that is more general than a change in orientation is a change in the device's
+ configuration, such as a change in the availability of a keyboard or a change in system
+ language.
+</p>
+<p>
+ A change in configuration also triggers the default behavior of destroying and then restarting
+ the foreground Activity. Besides testing that the application maintains the UI and its
+ transaction state, you should also test that the application updates itself to respond
+ correctly to the new configuration.
+</p>
+<h4>Battery life</h4>
+<p>
+ Mobile devices primarily run on battery power. A device has finite "battery budget", and when it
+ is gone, the device is useless until it is recharged. You need to write your application to
+ minimize battery usage, you need to test its battery performance, and you need to test the
+ methods that manage battery usage.
+</p>
+<p>
+ Techniques for minimizing battery usage were presented at the 2010 Google I/O conference in the
+ presentation
+ <a href="http://code.google.com/events/io/2009/sessions/CodingLifeBatteryLife.html">
+ Coding for Life -- Battery Life, That Is</a>. This presentation describes the impact on battery
+ life of various operations, and the ways you can design your application to minimize these
+ impacts. When you code your application to reduce battery usage, you also write the
+ appropriate unit tests.
+</p>
+<h4>Dependence on external resources</h4>
+<p>
+ If your application depends on network access, SMS, Bluetooth, or GPS, then you should
+ test what happens when the resource or resources are not available.
+</p>
+<p>
+ For example, if your application uses the network,it can notify the user if access is
+ unavailable, or disable network-related features, or do both. For GPS, it can switch to
+ IP-based location awareness. It can also wait for WiFi access before doing large data transfers,
+ since WiFi transfers maximize battery usage compared to transfers over 3G or EDGE.
+</p>
+<p>
+ You can use the emulator to test network access and bandwidth. To learn more, please see
+ <a href="{@docRoot}guide/developing/tools/emulator.html#netspeed">Network Speed Emulation</a>.
+ To test GPS, you can use the emulator console and {@link android.location.LocationManager}. To
+ learn more about the emulator console, please see
+ <a href="{@docRoot}/guide/developing/tools/emulator.html#console">
+ Using the Emulator Console</a>.
+</p>
diff --git a/docs/html/guide/topics/ui/binding.jd b/docs/html/guide/topics/ui/binding.jd
index 6ac0bb0..26364ee 100644
--- a/docs/html/guide/topics/ui/binding.jd
+++ b/docs/html/guide/topics/ui/binding.jd
@@ -11,11 +11,11 @@ parent.link=index.html
<li><a href="#HandlingUserSelections">Handling User Selections</a></li>
</ol>
- <h2>See also</h2>
+ <h2>Related tutorials</h2>
<ol>
- <li><a href="{@docRoot}resources/tutorials/views/hello-spinner.html">Hello Spinner tutorial</a></li>
- <li><a href="{@docRoot}resources/tutorials/views/hello-listview.html">Hello ListView tutorial</a></li>
- <li><a href="{@docRoot}resources/tutorials/views/hello-gridview.html">Hello GridView tutorial</a></li>
+ <li><a href="{@docRoot}resources/tutorials/views/hello-spinner.html">Spinner</a></li>
+ <li><a href="{@docRoot}resources/tutorials/views/hello-listview.html">List View</a></li>
+ <li><a href="{@docRoot}resources/tutorials/views/hello-gridview.html">Grid View</a></li>
</ol>
</div>
</div>
diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd
index 5c12db9..fe641a2 100644
--- a/docs/html/guide/topics/ui/declaring-layout.jd
+++ b/docs/html/guide/topics/ui/declaring-layout.jd
@@ -5,12 +5,6 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
- <h2>Key classes</h2>
- <ol>
- <li>{@link android.view.View}</li>
- <li>{@link android.view.ViewGroup}</li>
- <li>{@link android.view.ViewGroup.LayoutParams}</li>
- </ol>
<h2>In this document</h2>
<ol>
<li><a href="#write">Write the XML</a></li>
@@ -26,6 +20,12 @@ parent.link=index.html
<li><a href="#example">Example Layout</a></li>
</ol>
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.view.View}</li>
+ <li>{@link android.view.ViewGroup}</li>
+ <li>{@link android.view.ViewGroup.LayoutParams}</li>
+ </ol>
</div>
</div>
diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd
index 74b544b..1a997f9 100644
--- a/docs/html/guide/topics/ui/dialogs.jd
+++ b/docs/html/guide/topics/ui/dialogs.jd
@@ -5,10 +5,6 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
- <h2>Key classes</h2>
- <ol>
- <li>{@link android.app.Dialog}</li>
- </ol>
<h2>In this document</h2>
<ol>
<li><a href="#ShowingADialog">Showing a Dialog</a></li>
@@ -26,6 +22,11 @@ parent.link=index.html
</li>
<li><a href="#CustomDialog">Creating a Custom Dialog</a></li>
</ol>
+
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.app.Dialog}</li>
+ </ol>
</div>
</div>
diff --git a/docs/html/guide/topics/ui/index.jd b/docs/html/guide/topics/ui/index.jd
index abcf6be..375c9fe 100644
--- a/docs/html/guide/topics/ui/index.jd
+++ b/docs/html/guide/topics/ui/index.jd
@@ -4,13 +4,6 @@ page.title=User Interface
<div id="qv-wrapper">
<div id="qv">
- <h2>Key classes</h2>
- <ol>
- <li>{@link android.view.View}</li>
- <li>{@link android.view.ViewGroup}</li>
- <li>{@link android.widget Widget classes}</li>
- </ol>
-
<h2>In this document</h2>
<ol>
<li><a href="#ViewHierarchy">View Hierarchy</a></li>
@@ -25,6 +18,13 @@ page.title=User Interface
</ol>
</li>
</ol>
+
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.view.View}</li>
+ <li>{@link android.view.ViewGroup}</li>
+ <li>{@link android.widget Widget classes}</li>
+ </ol>
</div>
</div>
diff --git a/docs/html/guide/topics/ui/menus.jd b/docs/html/guide/topics/ui/menus.jd
index cf3c7de..b4e467c 100644
--- a/docs/html/guide/topics/ui/menus.jd
+++ b/docs/html/guide/topics/ui/menus.jd
@@ -5,198 +5,324 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
- <h2>Key classes</h2>
- <ol>
- <li>{@link android.view.Menu}</li>
- <li>{@link android.view.ContextMenu}</li>
- <li>{@link android.view.SubMenu}</li>
- </ol>
<h2>In this document</h2>
<ol>
- <li><a href="#options-menu">Options Menu</a></li>
- <li><a href="#context-menu">Context Menu</a></li>
- <li><a href="#submenu">Submenu</a></li>
- <li><a href="#xml">Define Menus in XML</a></li>
- <li><a href="#features">Menu Features</a>
+ <li><a href="#xml">Defining Menus</a></li>
+ <li><a href="#Inflating">Inflating a Menu Resource</a>
+ <li><a href="#options-menu">Creating an Options Menu</a>
+ <ol>
+ <li><a href="#ChangingTheMenu">Changing the menu when it opens</a></li>
+ </ol>
+ </li>
+ <li><a href="#context-menu">Creating a Context Menu</a></li>
+ <li><a href="#submenu">Creating a Submenu</a></li>
+ <li><a href="#features">Other Menu Features</a>
<ol>
<li><a href="#groups">Menu groups</a></li>
<li><a href="#checkable">Checkable menu items</a></li>
<li><a href="#shortcuts">Shortcut keys</a></li>
- <li><a href="#intents">Menu item intents</a></li>
+ <li><a href="#intents">Intents for menu items</a></li>
</ol>
</li>
</ol>
+
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.view.Menu}</li>
+ <li>{@link android.view.MenuItem}</li>
+ <li>{@link android.view.ContextMenu}</li>
+ <li>{@link android.view.SubMenu}</li>
+ </ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/topics/resources/menu-resource.html">Menu Resource</a></li>
+ </ol>
</div>
</div>
-<p>Menus are an important part of any application. They provide familiar interfaces
-that reveal application functions and settings. Android offers an easy programming interface
-for developers to provide standardized application menus for various situations.</p>
+<p>Menus are an important part of an application that provide a familiar interface for the user
+to access application functions and settings. Android offers an easy programming interface
+for you to provide application menus in your application.</p>
-<p>Android offers three fundamental types of application menus:</p>
+<p>Android provides three types of application menus:</p>
<dl>
<dt><strong>Options Menu</strong></dt>
- <dd>This is the primary set of menu items for an Activity. It is revealed by pressing
- the device MENU key. Within the Options Menu are two groups of menu items:
+ <dd>The primary menu for an Activity, which appears when the user presses
+ the device MENU key. Within the Options Menu are two groups:
<dl style="margin-top:1em">
<dt><em>Icon Menu</em></dt>
- <dd>This is the collection of items initially visible at the bottom of the screen
+ <dd>The menu items visible at the bottom of the screen
at the press of the MENU key. It supports a maximum of six menu items.
These are the only menu items that support icons and the only menu items that <em>do not</em> support
checkboxes or radio buttons.</dd>
<dt><em>Expanded Menu</em></dt>
- <dd>This is a vertical list of items exposed by the "More" menu item from the Icon Menu.
- It exists only when the Icon Menu becomes over-loaded and is comprised of the sixth
- Option Menu item and the rest.</dd>
+ <dd>The vertical list of menu items exposed by the "More" menu item in the Icon Menu.
+ When the Icon Menu is full, the expanded menu is comprised of the sixth
+ menu item and the rest.</dd>
</dl>
</dd>
<dt><strong>Context Menu</strong></dt>
- <dd>This is a floating list of menu items that may appear when you perform a long-press on a View
- (such as a list item). </dd>
+ <dd>A floating list of menu items that appears when the user performs a long-press on a View.
+</dd>
<dt><strong>Submenu</strong></dt>
- <dd>This is a floating list of menu items that is revealed by an item in the Options Menu
- or a Context Menu. A Submenu item cannot support nested Submenus. </dd>
+ <dd>A floating list of menu items that the user opens by pressing a menu item in the Options
+Menu or a context menu. A submenu item cannot support a nested submenu. </dd>
</dl>
-<h2 id="options-menu">Options Menu</h2>
-<img align="right" src="{@docRoot}images/options_menu.png" />
-<p>The Options Menu is opened by pressing the device MENU key.
-When opened, the Icon Menu is displayed, which holds the first six menu items.
-If more than six items are added to the Options Menu, then those that can't fit
-in the Icon Menu are revealed in the Expanded Menu, via the "More" menu item. The Expanded Menu
-is automatically added when there are more than six items.</p>
-<p>The Options Menu is where you should include basic application functions
-and any necessary navigation items (e.g., to a home screen or application settings).
-You can also add <a href="#submenu">Submenus</a> for organizing topics
-and including extra menu functionality.</p>
-
-<p>When this menu is opened for the first time,
-the Android system will call the Activity <code>{@link android.app.Activity#onCreateOptionsMenu(Menu)
-onCreateOptionsMenu()}</code> callback method. Override this method in your Activity
-and populate the {@link android.view.Menu} object given to you. You can populate the menu by
-inflating a menu resource that was <a href="#xml">defined in XML</a>, or by calling
-<code>{@link android.view.Menu#add(CharSequence) add()}</code>
-for each item you'd like in the menu. This method adds a {@link android.view.MenuItem}, and returns the
-newly created object to you. You can use the returned MenuItem to set additional properties like
-an icon, a keyboard shortcut, an intent, and other settings for the item.</p>
-
-<p>There are multiple <code>{@link android.view.Menu#add(CharSequence) add()}</code> methods.
-Usually, you'll want to use one that accepts an <var>itemId</var> argument.
-This is a unique integer that allows you to identify the item during a callback.</p>
-
-<p>When a menu item is selected from the Options Menu, you will receive a callback to the
-<code>{@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}</code>
-method of your Activity. This callback passes you the
-<code>MenuItem</code> that has been selected. You can identify the item by requesting the
-<var>itemId</var>, with <code>{@link android.view.MenuItem#getItemId() getItemId()}</code>,
-which returns the integer that was assigned with the <code>add()</code> method. Once you identify
-the menu item, you can take the appropriate action.</p>
-
-<p>Here's an example of this procedure, inside an Activity, wherein we create an
-Options Menu and handle item selections:</p>
+<h2 id="xml">Defining Menus</h2>
+
+<p>Instead of instantiating {@link android.view.Menu} objects in your application code, you should
+define a menu and all its items in an XML <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>, then inflate the menu
+resource (load it as a programmable object) in your application code. Defining your menus in XML is
+a good practice because it separates your interface design from your application code (the same as
+when you <a href="{@docRoot}guide/topics/ui/declaring-layout.html">define your Activity
+layout</a>).</p>
+
+<p>To define a menu, create an XML file inside your project's <code>res/menu/</code>
+directory and build the menu with the following elements:</p>
+<dl>
+ <dt><code>&lt;menu></code></dt>
+ <dd>Creates a {@link android.view.Menu}, which is a container for menu items. It must be
+the root node and holds one or more of the following elements. You can also nest this element
+in an {@code &lt;item&gt;} to create a submenu.</dd>
+ <dt><code>&lt;item></code></dt>
+ <dd>Creates a {@link android.view.MenuItem}, which represents a single item in a menu.</dd>
+ <dt><code>&lt;group></code></dt>
+ <dd>An optional, invisible container for {@code &lt;item&gt;} elements. It allows you to
+categorize menu items so they share properties such as active state and visibility. See <a
+href="#groups">Menu groups</a>.</dd>
+</dl>
+<p>For example, here is a file in <code>res/menu/</code> named <code>game_menu.xml</code>:</p>
<pre>
-/* Creates the menu items */
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:id="@+id/new_game"
+ android:icon="@drawable/ic_new_game"
+ android:title="@string/new_game" /&gt;
+ &lt;item android:id="@+id/quit"
+ android:icon="@drawable/ic_quit"
+ android:title="@string/quit" /&gt;
+&lt;/menu&gt;
+</pre>
+
+<p>This example defines a menu with two menu items. Each item includes the attributes:</p>
+<dl>
+ <dt>{@code android:id}</dt>
+ <dd>A resource ID that's unique to the item so that the application can recognize the item when
+the user selects it.</dd>
+ <dt>{@code android:icon}</dt>
+ <dd>A drawable resource that is the icon visible to the user.</dd>
+ <dt>{@code android:title}</dt>
+ <dd>A string resource that is the title visible to the user.</dd>
+</dl>
+
+<p>For more about the XML syntax and attributes for a menu resource, see the <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">Menu Resource</a> reference.</p>
+
+
+<h2 id="Inflating">Inflating a Menu Resource</h2>
+
+<p>You can inflate your menu resource (convert the XML resource into a programmable object) using
+{@link android.view.MenuInflater#inflate(int,Menu) MenuInflater.inflate()}. For
+example, the following code inflates the <code>game_menu.xml</code> file defined above during the
+{@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} callback method, to be
+used for the Options Menu:</p>
+
+<pre>
+&#64;Override
public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(0, MENU_NEW_GAME, 0, "New Game");
- menu.add(0, MENU_QUIT, 0, "Quit");
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.game_menu, menu);
return true;
}
+</pre>
+
+<p>The {@link android.app.Activity#getMenuInflater()} method returns a {@link
+android.view.MenuInflater} for the Activity. With this object, you can call {@link
+android.view.MenuInflater#inflate(int,Menu) inflate()}, which inflates a menu resource into a
+{@link android.view.Menu} object. In this example, the menu resource defined by
+<code>game_menu.xml</code>
+is inflated into the {@link android.view.Menu} that was passed into {@link
+android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}. (This callback method for
+creating an option menu is discussed more in the next section.)</p>
+
+
+
+<h2 id="options-menu">Creating an Options Menu</h2>
+
+<div class="figure" style="width:200px">
+ <img src="{@docRoot}images/options_menu.png" height="300" alt="" />
+ <p class="img-caption"><strong>Figure 1.</strong> Screenshot of an Options Menu.</p>
+</div>
+
+
+<p>The Options Menu is where you should include basic application functions
+and necessary navigation items (for example, a button
+to open application settings). The user
+can open the Options Menu with the device MENU key.
+Figure 1 shows a screenshot of an Options Menu.</p>
+
+<p>When opened, the first visible portion of the Options Menu is called the Icon Menu. It
+holds the first six menu items.
+If you add more than six items to the Options Menu, Android places the sixth item and those after it
+into the Expanded Menu, which the user can open with the "More" menu item.</p>
+
+<p>When the user opens the Options Menu for the first time, Android calls your Activity's
+{@link android.app.Activity#onCreateOptionsMenu(Menu)
+onCreateOptionsMenu()} method. Override this method in your Activity
+and populate the {@link android.view.Menu} that is passed into the method. Populate the
+{@link android.view.Menu} by inflating a menu resource as described in <a
+href="#Inflating">Inflating a Menu Resource</a>. (You can
+also populate the menu in code, using {@link android.view.Menu#add(int,int,int,int)
+add()} to add menu items.)</p>
+
+<p>When the user selects a menu item from the Options Menu, the system calls your Activity's
+{@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}
+method. This method passes the
+{@link android.view.MenuItem} that the user selected. You can identify the menu item by calling
+{@link android.view.MenuItem#getItemId()}, which returns the unique ID for the menu
+item (defined by the {@code android:id} attribute in the menu resource or with an integer passed
+to the {@link android.view.Menu#add(int,int,int,int) add()} method). You can match this ID
+against known menu items and perform the appropriate action.</p>
+
+<p>For example:</p>
-/* Handles item selections */
+<pre>
+&#64;Override
public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle item selection
switch (item.getItemId()) {
- case MENU_NEW_GAME:
+ case R.id.new_game:
newGame();
return true;
- case MENU_QUIT:
+ case R.id.quit:
quit();
return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
- return false;
}
</pre>
-<p>The <code>add()</code> method used in this sample takes four arguments:
-<var>groupId</var>, <var>itemId</var>, <var>order</var>, and <var>title</var>.
-The <var>groupId</var> allows you to associate this menu item with a group of other items
-(more about <a href="#groups">Menu groups</a>, below) &mdash; in
-this example, we ignore it. <var>itemId</var> is a unique integer that we give the
-MenuItem so that can identify it in the next callback. <var>order</var> allows us to
-define the display order of the item &mdash; by default, they are displayed by the
-order in which we add them. <var>title</var> is, of course, the name that goes on the
-menu item (this can also be a
-<a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">string resource</a>,
-and we recommend you do it that way for easier localization).</p>
-
-<p class="note"><strong>Tip:</strong>
-If you have several menu items that can be grouped together with a title,
-consider organizing them into a <a href="#submenu">Submenu</a>.</p>
-
-<h3>Adding icons</h3>
-<p>Icons can also be added to items that appears in the Icon Menu with
-<code>{@link android.view.MenuItem#setIcon(Drawable) setIcon()}</code>. For example:</p>
-<pre>
-menu.add(0, MENU_QUIT, 0, "Quit")
- .setIcon(R.drawable.menu_quit_icon);</pre>
-
-<h3>Modifying the menu</h3>
-<p>If you want to sometimes re-write the Options Menu as it is opened, override the
-<code>{@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}</code> method, which is
-called each time the menu is opened. This will pass you the Menu object, just like the
-<code>onCreateOptionsMenu()</code> callback. This is useful if you'd like to add or remove
-menu options depending on the current state of an application or game.</p>
+<p>In this example, {@link android.view.MenuItem#getItemId()} queries the ID for the selected menu
+item and the switch statement compares the ID against the resource IDs that were assigned to menu
+items in the XML resource. When a switch case successfully handles the item, it
+returns "true" to indicate that the item selection was handled. Otherwise, the default statement
+passes the menu item to the super class in
+case it can handle the item selected. (If you've directly extended the {@link android.app.Activity}
+class, then the super class returns "false", but it's a good practice to
+pass unhandled menu items to the super class instead of directly returning "false".)</p>
+
+<p class="note"><strong>Tip:</strong> If your application contains multiple activities and
+some of them provide the same Options Menu, consider creating
+an Activity that implements nothing except the {@link android.app.Activity#onCreateOptionsMenu(Menu)
+onCreateOptionsMenu()} and {@link android.app.Activity#onOptionsItemSelected(MenuItem)
+onOptionsItemSelected()} methods. Then extend this class for each Activity that should share the
+same Options Menu. This way, you have to manage only one set of code for handling menu
+actions and each decendent class inherits the menu behaviors.<br/><br/>
+If you want to add menu items to one of your decendent activities,
+override {@link android.app.Activity#onCreateOptionsMenu(Menu)
+onCreateOptionsMenu()} in that Activity. Call {@code super.onCreateOptionsMenu(menu)} so the
+original menu items are created, then add new menu items with {@link
+android.view.Menu#add(int,int,int,int) menu.add()}. You can also override the super class's
+behavior for individual menu items.</p>
+
+
+<h3 id="ChangingTheMenu">Changing the menu when it opens</h3>
+
+<p>The {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} method is
+called only the first time the Options Menu is opened. The system keeps and re-uses the {@link
+android.view.Menu} you define in this method until your Activity is destroyed. If you want to change
+the Options Menu each time it opens, you must override the
+{@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} method. This passes
+you the {@link android.view.Menu} object as it currently exists. This is useful if you'd like to
+remove, add, disable, or enable menu items depending on the current state of your application.</p>
<p class="note"><strong>Note:</strong>
-When changing items in the menu, it's bad practice to do so based on the currently selected item.
-Keep in mind that, when in touch mode, there will not be a selected (or focused) item. Instead, you
-should use a <a href="#context-menu">Context Menu</a> for such behaviors, when you want to provide
-functionality based on a particular item in the UI.</p>
-
-
-<h2 id="context-menu">Context Menu</h2>
-<p>The Android context menu is similar, in concept, to the menu revealed with a "right-click" on a PC.
-When a view is registered to a context menu,
-performing a "long-press" (press and hold for about two seconds) on the object
-will reveal a floating menu that provides functions relating to that item.
-Context menus can be registered to any View object,
-however, they are most often used for items in a
-{@link android.widget.ListView}, which helpfully indicates the presence of the context menu
-by transforming the background color of the ListView item when pressed.
-(The items in the phone's contact list offer an example of this feature.)
-</p>
-
-<p class="note"><strong>Note:</strong> Context menu items do not support icons or shortcut keys.</p>
-
-<p>To create a context menu, you must override the Activity's context menu callback methods:
-<code>{@link android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) onCreateContextMenu()}</code> and
-<code>{@link android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}</code>.
-Inside the <code>onCreateContextMenu()</code> callback method, you can add menu items using one of the
-<code>{@link android.view.Menu#add(CharSequence) add()}</code> methods, or by
-inflating a menu resource that was <a href="#xml">defined in XML</a>.
-Then, register a {@link android.view.ContextMenu} for the View, with
-<code>{@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()}</code>.</p>
-
-<p>For example, here is some code that can be used with the
-<a href="{@docRoot}resources/tutorials/notepad/index.html">Notepad application</a>
-to add a context menu for each note in the list:</p>
+You should never change items in the Options Menu based on the {@link android.view.View} currently
+in focus. When in touch mode (when the user is not using a trackball or d-pad), Views
+cannot take focus, so you should never use focus as the basis for modifying
+items in the Options Menu. If you want to provide menu items that are context-sensitive to a {@link
+android.view.View}, use a <a href="#context-menu">Context Menu</a>.</p>
+
+
+
+<h2 id="context-menu">Creating a Context Menu</h2>
+
+<p>A context menu is conceptually similar to the menu displayed when the user performs a
+"right-click" on a PC. You should use a context menu to provide the user access to
+actions that pertain to a specific item in the user interface. On Android, a context menu is
+displayed when the user performs a "long press" (press and hold) on an item.</p>
+
+<p>You can create a context menu for any View, though context menus are most often used for items in
+a {@link android.widget.ListView}. When the user performs a long-press on an item in a ListView and
+the list is registered to provide a context menu, the list item signals to the user that a context
+menu is available by animating its background color&mdash;it transitions from
+orange to white before opening the context menu. (The Contacts application demonstrates this
+feature.)</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h3>Register a ListView</h3>
+<p>If your Activity uses a {@link android.widget.ListView} and
+you want all list items to provide a context menu, register all items for a context
+menu by passing the {@link android.widget.ListView} to {@link
+android.app.Activity#registerForContextMenu(View) registerForContextMenu()}. For
+example, if you're using a {@link android.app.ListActivity}, register all list items like this:</p>
+<p><code>registerForContextMenu({@link android.app.ListActivity#getListView()});</code></p>
+</div>
+</div>
+
+<p>In order for a View to provide a context menu, you must "register" the view for a context
+menu. Call {@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()} and
+pass it the {@link android.view.View} you want to give a context menu. When this View then
+receives a long-press, it displays a context menu.</p>
+
+<p>To define the context menu's appearance and behavior, override your Activity's context menu
+callback methods, {@link android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo)
+onCreateContextMenu()} and
+{@link android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}.</p>
+
+<p>For example, here's an {@link
+android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo)
+onCreateContextMenu()} that uses the {@code context_menu.xml} menu resource:</p>
<pre>
+&#64;Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
- menu.add(0, EDIT_ID, 0, "Edit");
- menu.add(0, DELETE_ID, 0, "Delete");
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.context_menu, menu);
}
+</pre>
+
+<p>{@link android.view.MenuInflater} is used to inflate the context menu from a <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>. (You can also use
+{@link android.view.Menu#add(int,int,int,int) add()} to add menu items.) The callback method
+parameters include the {@link android.view.View}
+that the user selected and a {@link android.view.ContextMenu.ContextMenuInfo} object that provides
+additional information about the item selected. You might use these parameters to determine
+which context menu should be created, but in this example, all context menus for the Activity are
+the same.</p>
+
+<p>Then when the user selects an item from the context menu, the system calls {@link
+android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}. Here is an example
+of how you can handle selected items:</p>
+<pre>
+&#64;Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
- case EDIT_ID:
+ case R.id.edit:
editNote(info.id);
return true;
- case DELETE_ID:
+ case R.id.delete:
deleteNote(info.id);
return true;
default:
@@ -205,285 +331,276 @@ public boolean onContextItemSelected(MenuItem item) {
}
</pre>
-<p>In <code>onCreateContextMenu()</code>, we are given not only the ContextMenu to
-which we will add {@link android.view.MenuItem}s, but also the {@link android.view.View}
-that was selected and a {@link android.view.ContextMenu.ContextMenuInfo ContextMenuInfo} object,
-which provides additional information about the object that was selected.
-In this example, nothing special is done in <code>onCreateContextMenu()</code> &mdash; just
-a couple items are added as usual. In the <code>onContextItemSelected()</code>
-callback, we request the {@link android.widget.AdapterView.AdapterContextMenuInfo AdapterContextMenuInfo}
-from the {@code MenuItem}, which provides information about the currently selected item.
-All we need from
-this is the list ID for the selected item, so whether editing a note or deleting it,
-we find the ID with the {@code AdapterContextMenuInfo.info} field of the object. This ID
-is passed to the <code>editNote()</code> and <code>deleteNote()</code> methods to perform
-the respective action.</p>
-
-<p>Now, to register this context menu for all the items in a {@link android.widget.ListView},
-we pass the entire {@code ListView} to the
-<code>{@link android.app.Activity#registerForContextMenu(View)}</code> method:</p>
-
-<pre>registerForContextMenu(getListView());</pre>
-<p>Remember, you can pass any View object to register a context menu. Here,
-<code>{@link android.app.ListActivity#getListView()}</code> returns the ListView
-object used in the Notepad application's {@link android.app.ListActivity}. As such, each item
-in the list is registered to this context menu.</p>
-
-
-
-<h2 id="submenu">Submenus</h2>
-<p>A sub menu can be added within any menu, except another sub menu.
-These are very useful when your application has a lot of functions that may be
-organized in topics, like the items in a PC application's menu bar (File, Edit, View, etc.).</p>
-
-<p>A sub menu is created by adding it to an existing {@link android.view.Menu}
-with <code>{@link android.view.Menu#addSubMenu(CharSequence) addSubMenu()}</code>.
-This returns a {@link android.view.SubMenu} object (an extension of {@link android.view.Menu}).
-You can then add additional items to this menu, with the normal routine, using
-the <code>{@link android.view.Menu#add(CharSequence) add()}</code> methods. For example:</p>
+<p>The structure of this code is similar to the example for <a href="#options-menu">Creating an
+Options Menu</a>, in which {@link android.view.MenuItem#getItemId()} queries the ID for the selected
+menu item and a switch statement matches the item to the IDs that are defined in the menu resource.
+And like the options menu example, the default statement calls the super class in case it
+can handle menu items not handled here, if necessary.</p>
-<pre>
-public boolean onCreateOptionsMenu(Menu menu) {
- boolean result = super.onCreateOptionsMenu(menu);
+<p>In this example, the selected item is an item from a {@link android.widget.ListView}. To
+perform an action on the selected item, the application needs to know the list
+ID for the selected item (it's position in the ListView). To get the ID, the application calls
+{@link android.view.MenuItem#getMenuInfo()}, which returns a {@link
+android.widget.AdapterView.AdapterContextMenuInfo} object that includes the list ID for the
+selected item in the {@link android.widget.AdapterView.AdapterContextMenuInfo#id id} field. The
+local methods <code>editNote()</code> and <code>deleteNote()</code> methods accept this list ID to
+perform an action on the data specified by the list ID.</p>
- SubMenu fileMenu = menu.addSubMenu("File");
- SubMenu editMenu = menu.addSubMenu("Edit");
- fileMenu.add("new");
- fileMenu.add("open");
- fileMenu.add("save");
- editMenu.add("undo");
- editMenu.add("redo");
+<p class="note"><strong>Note:</strong> Items in a context menu do not support icons or shortcut
+keys.</p>
- return result;
-}
-</pre>
-<p>Callbacks for items selected in a sub menu are made to the parent menu's callback method.
-For the example above, selections in the sub menu will be handled by the
-<code>onOptionsItemSelected()</code> callback.</p>
-<p>You can also add Submenus when you <a href="#xml">define the parent menu in XML</a>.</p>
-<h2 id="xml">Define Menus in XML</h2>
-<p>Just like Android UI layouts, you can define application menus in XML, then inflate them
-in your menu's <code>onCreate...()</code> callback method. This makes your application code cleaner and
-separates more interface design into XML, which is easier to visualize.</p>
+<h2 id="submenu">Creating Submenus</h2>
-<p>To start, create a new folder in your project <code>res/</code> directory called <code>menu</code>.
-This is where you should keep all XML files that define your application menus.</p>
+<p>A submenu is a menu that the user can open by selecting an item in another menu. You can add a
+submenu to any menu (except a submenu). Submenus are useful when your application has a lot of
+functions that can be organized into topics, like items in a PC application's menu bar (File, Edit,
+View, etc.).</p>
-<p>In a menu XML layout, there are
-three valid elements: <code>&lt;menu></code>, <code>&lt;group></code> and <code>&lt;item></code>. The
-<code>item</code> and <code>group</code> elements must be children of a <code>menu</code>, but <code>item</code>
-elements may also be the children of a <code>group</code>, and another <code>menu</code> element may be the child
-of an <code>item</code> (to create a Submenu). Of course, the root node of any file
-must be a <code>menu</code> element.</p>
+<p>When creating your <a href="{@docRoot}guide/topics/resources/menu-resource.html">menu
+resource</a>, you can create a submenu by adding a {@code &lt;menu&gt;} element as the child of an
+{@code &lt;item&gt;}. For example:</p>
-<p>As an example, we'll define the same menu created in the <a href="#options-menu">Options Menu</a> section,
-above. We start with an XML file named <code>options_menu.xml</code> inside the <code>res/menu/</code> folder:</p>
<pre>
-&lt;menu xmlns:android="http://schemas.android.com/apk/res/android">
- &lt;item android:id="@+id/new_game"
- android:title="New Game" />
- &lt;item android:id="@+id/quit"
- android:title="Quit" />
-&lt;/menu>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:id="@+id/file"
+ android:icon="@drawable/file"
+ android:title="@string/file" &gt;
+ &lt;!-- "file" submenu --&gt;
+ &lt;menu"&gt;
+ &lt;item android:id="@+id/new"
+ android:title="@string/new" /&gt;
+ &lt;item android:id="@+id/open"
+ android:title="@string/open" /&gt;
+ &lt;/menu&gt;
+ &lt;/item&gt;
+&lt;/menu&gt;
</pre>
-<p>Then, in the <code>onCreateOptionsMenu()</code> method, we inflate this resource using
-<code>{@link android.view.MenuInflater#inflate(int,Menu) MenuInflater.inflate()}</code>:</p>
-<pre>
-public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.options_menu, menu);
- return true;
-}
-</pre>
+<p>When the user selects an item from a submenu, the parent menu's respective on-item-selected
+callback method receives the event. For instance, if the above menu is applied as an Options Menu,
+then the {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} method
+is called when a submenu item is selected.</p>
-<p>The <code>{@link android.app.Activity#getMenuInflater()}</code> method returns the {@link android.view.MenuInflater}
-for our activity's context. We then call <code>{@link android.view.MenuInflater#inflate(int,Menu) inflate()}</code>,
-passing it a pointer to our menu resource and the Menu object given by the callback.</code></p>
+<p>You can also use {@link android.view.Menu#addSubMenu(int,int,int,int) addSubMenu()} to
+dynamically add a {@link android.view.SubMenu} to an existing {@link android.view.Menu}. This
+returns the new {@link android.view.SubMenu} object, to which you can add
+submenu items, using {@link android.view.Menu#add(int,int,int,int) add()}</p>
-<p>While this small sample may seem like more effort, compared to creating the menu items in the
-<code>onCreateOptionsMenu()</code> method, this will save a lot of trouble when dealing with more items
-and it keeps your application code clean.</p>
-<p>You can define <a href="#groups">menu groups</a> by wrapping <code>item</code> elements in a <code>group</code>
-element, and create Submenus by nesting another <code>menu</code> inside an <code>item</code>.
-Each element also supports all the necessary attributes to control features like shortcut keys,
-checkboxes, icons, and more. To learn about these attributes and more about the XML syntax, see the Menus
-topic in the <a href="{@docRoot}guide/topics/resources/available-resources.html#menus">Available
-Resource Types</a> document.</p>
-<h2 id="features">Menu Features</h2>
-<p>Here are some other features that can be applied to most menu items.</p>
+<h2 id="features">Other Menu Features</h2>
+
+<p>Here are some other features that you can apply to most menu items.</p>
<h3 id="groups">Menu groups</h3>
-<p>When adding new items to a menu, you can optionally include each item in a group.
-A menu group is a collection of menu items that can share certain traits, like
-whether they are visible, enabled, or checkable.</p>
-
-<p>A group is defined by an integer (or a resource id, in XML). A menu item is added to the group when it is
-added to the menu, using one of the <code>add()</code> methods that accepts a <var>groupId</var>
-as an argument, such as <code>{@link android.view.Menu#add(int,int,int,int)}</code>.</p>
-
-<p>You can show or hide the entire group with
-<code>{@link android.view.Menu#setGroupVisible(int,boolean) setGroupVisible()}</code>;
-enable or disable the group with
-<code>{@link android.view.Menu#setGroupEnabled(int,boolean) setGroupEnabled()}</code>;
-and set whether the items can be checkable with
-<code>{@link android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()}</code>.
-</p>
+
+<p>A menu group is a collection of menu items that share certain traits. With a group, you
+can:</p>
+<ul>
+ <li>Show or hide all items with {@link android.view.Menu#setGroupVisible(int,boolean)
+setGroupVisible()}</li>
+ <li>Enable or disable all items with {@link android.view.Menu#setGroupEnabled(int,boolean)
+setGroupEnabled()}</li>
+ <li>Specify whether all items are checkable with {@link
+android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()}</li>
+</ul>
+
+<p>You can create a group by nesting {@code &lt;item&gt;} elements inside a {@code &lt;group&gt;}
+element in your menu resource or by specifying a group ID with the the {@link
+android.view.Menu#add(int,int,int,int) add()} method.</p>
+
+<p>Here's an example menu resource that includes a group:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:id="@+id/item1"
+ android:icon="@drawable/item1"
+ android:title="@string/item1" /&gt;
+ &lt;!-- menu group --&gt;
+ &lt;group android:id="@+id/group1"&gt;
+ &lt;item android:id="@+id/groupItem1"
+ android:title="@string/groupItem1" /&gt;
+ &lt;item android:id="@+id/groupItem2"
+ android:title="@string/groupItem2" /&gt;
+ &lt;/group&gt;
+&lt;/menu&gt;
+</pre>
+
+<p>The items that are in the group appear the same as the first item that is not in a
+group&mdash;all three items in the menu are siblings. However, you can modify the traits of the two
+items in the group by referencing the group ID and using the methods listed above.</p>
+
<h3 id="checkable">Checkable menu items</h3>
-<img align="right" src="{@docRoot}images/radio_buttons.png" alt="" />
-<p>Any menu item can be used as an interface for turning options on and off. This can
-be indicated with a checkbox for stand-alone options, or radio buttons for groups of
-mutually exclusive options (see the screenshot, to the right).</p>
-<p class="note"><strong>Note:</strong> Menu items in the Icon Menu cannot
+<div class="figure" style="width:200px">
+ <img src="{@docRoot}images/radio_buttons.png" height="300" alt="" />
+ <p class="img-caption"><strong>Figure 2.</strong> Screenshot of checkable menu items</p>
+</div>
+
+<p>A menu can be useful as an interface for turning options on and off, using a checkbox for
+stand-alone options, or radio buttons for groups of
+mutually exclusive options. Figure 2 shows a submenu with items that are checkable with radio
+buttons.</p>
+
+<p class="note"><strong>Note:</strong> Menu items in the Icon Menu (from the Options Menu) cannot
display a checkbox or radio button. If you choose to make items in the Icon Menu checkable,
-then you must personally indicate the state by swapping the icon and/or text
-each time the state changes between on and off.</p>
+you must manually indicate the checked state by swapping the icon and/or text
+each time the state changes.</p>
+
+<p>You can define the checkable behavior for individual menu items using the {@code
+android:checkable} attribute in the {@code &lt;item&gt;} element, or for an entire group with
+the {@code android:checkableBehavior} attribute in the {@code &lt;group&gt;} element. For
+example, all items in this menu group are checkable with a radio button:</p>
-<p>To make a single item checkable, use the <code>{@link android.view.MenuItem#setCheckable(boolean)
-setCheckable()}</code> method, like so:</p>
<pre>
-menu.add(0, VIBRATE_SETTING_ID, 0, "Vibrate")
- .setCheckable(true);
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;group android:checkableBehavior="single"&gt;
+ &lt;item android:id="@+id/red"
+ android:title="@string/red" /&gt;
+ &lt;item android:id="@+id/blue"
+ android:title="@string/blue" /&gt;
+ &lt;/group&gt;
+&lt;/menu&gt;
</pre>
-<p>This will display a checkbox with the menu item (unless it's in the Icon Menu). When the item
-is selected, the <code>onOptionsItemSelected()</code> callback is called as usual. It is here that
-you must set the state of the checkbox. You can query the current state of the item with
-<code>{@link android.view.MenuItem#isChecked()}</code> and set the checked state with
-<code>{@link android.view.MenuItem#setChecked(boolean) setChecked()}</code>.
-Here's what this looks like inside the
-<code>onOptionsItemSelected()</code> callback:</p>
+
+<p>The {@code android:checkableBehavior} attribute accepts either:
+<dl>
+ <dt>{@code single}</dt>
+ <dd>Only one item from the group can be checked (radio buttons)</dd>
+ <dt>{@code all}</dt>
+ <dd>All items can be checked (checkboxes)</dd>
+ <dt>{@code none}</dt>
+ <dd>No items are checkable</dd>
+</dl>
+
+<p>You can apply a default checked state to an item using the {@code android:checked} attribute in
+the {@code &lt;item&gt;} element and change it in code with the {@link
+android.view.MenuItem#setChecked(boolean) setChecked()} method.</p>
+
+<p>When a checkable item is selected, the system calls your respective item-selected callback method
+(such as {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}). It
+is here that you must set the state of the checkbox, because a checkbox or radio button does not
+change its state automatically. You can query the current state of the item (as it was before the
+user selected it) with {@link android.view.MenuItem#isChecked()} and then set the checked state with
+{@link android.view.MenuItem#setChecked(boolean) setChecked()}. For example:</p>
+
<pre>
-switch (item.getItemId()) {
-case VIBRATE_SETTING_ID:
- if (item.isChecked()) item.setChecked(false);
- else item.setChecked(true);
- return true;
-...
+&#64;Override
+public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.vibrate:
+ case R.id.dont_vibrate:
+ if (item.isChecked()) item.setChecked(false);
+ else item.setChecked(true);
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
}
</pre>
-<p>To make a group of mutually exclusive radio button items, simply
-assign the same group ID to each menu item
-and call <code>{@link android.view.Menu#setGroupCheckable(int,boolean,boolean)
-setGroupCheckable()}</code>. In this case, you don't need to call <code>setCheckable()</code>
-on each menu items, because the group as a whole is set checkable. Here's an example of
-two mutually exclusive options in a Submenu:</p>
-<pre>
-SubMenu subMenu = menu.addSubMenu("Color");
-subMenu.add(COLOR_MENU_GROUP, COLOR_RED_ID, 0, "Red");
-subMenu.add(COLOR_MENU_GROUP, COLOR_BLUE_ID, 0, "Blue");
-subMenu.setGroupCheckable(COLOR_MENU_GROUP, true, true);
-</pre>
-<p>In the <code>setGroupCheckable()</code> method, the first argument is the group ID
-that we want to set checkable. The second argument is whether we want the group items
-to be checkable. The last one is whether we want each item to be exclusively checkable
-(if we set this <em>false</em>, then all the items will be checkboxes instead of radio buttons).
-When the group is set to be exclusive (radio buttons), each time a new item is selected,
-all other are automatically de-selected.</p>
-<p>
+<p>If you don't set the checked state this way, then the visible state of the item (the checkbox or
+radio button) will not
+change when the user selects it. When you do set the state, the Activity preserves the checked state
+of the item so that when the user opens the menu later, the checked state that you
+set is visible.</p>
<p class="note"><strong>Note:</strong>
-Checkable menu items are intended to be used only on a per-session basis and not saved to the device
-(e.g., the <em>Map mode</em> setting in the Maps application is not saved &mdash; screenshot above).
-If there are application settings that you would like to save for the user,
-then you should store the data using <a href="#{@docRoot}guide/topics/data/data-storage.html#pref">Preferences</a>,
-and manage them with a {@link android.preference.PreferenceActivity}.</p>
+Checkable menu items are intended to be used only on a per-session basis and not saved after the
+application is destroyed. If you have application settings that you would like to save for the user,
+you should store the data using <a
+href="#{@docRoot}guide/topics/data/data-storage.html#pref">Shared Preferences</a>.</p>
<h3 id="shortcuts">Shortcut keys</h3>
-<p>Quick access shortcut keys using letters and/or numbers can be added to menu items with
-<code>setAlphabeticShortcut(char)</code> (to set char shortcut), <code>setNumericShortcut(int)</code>
-(to set numeric shortcut),
-or <code>setShortcut(char,int)</code> (to set both)</code>. Case is <em>not</em> sensitive.
-For example:</p>
-<pre>
-menu.add(0, MENU_QUIT, 0, "Quit")
- .setAlphabeticShortcut('q');
-</pre>
-<p>Now, when the menu is open (or while holding the MENU key), pressing the "q" key will
-select this item.</p>
-<p>This shortcut key will be displayed as a tip in the menu item, below the menu item name
-(except for items in the Icon Menu).</p>
-<p class="note"><strong>Note:</strong> Shortcuts cannot be added to items in a Context Menu.</p>
-
-
-<h3 id="intents">Menu item intents</h3>
-<p>If you've read the <a href="{@docRoot}guide/topics/fundamentals.html">Application
-Fundamentals</a>, then you're at least a little familiar
-with Android Intents. These allow applications to bind with each other, share information,
-and perform user tasks cooperatively. Just like your application might fire an Intent to launch a web browser,
-an email client, or another Activity in your application,
-you can perform such actions from within a menu.
-There are two ways to do this: define an Intent and assign it to a single menu item, or
-define an Intent and allow Android to search the device for activities and dynamically add a
-menu item for each one that meets the Intent criteria.</p>
-
-<p>For more information on creating Intents and providing your application's services to other applications,
-read the <a href="/guide/topics/intents/intents-filters.html">Intents
-and Intent Filters</a> document.</p>
-
-<h4>Set an intent for a single menu item</h4>
-<p>If you want to offer a specific menu item that launches a new Activity, then you
-can specifically define an Intent for the menu item with the
-<code>{@link android.view.MenuItem#setIntent(Intent)
-setIntent()}</code> method.</p>
-
-<p>For example, inside the <code>{@link android.app.Activity#onCreateOptionsMenu(Menu)
-onCreateOptionsMenu()}</code> method, you can define a new menu item with an Intent like this:</p>
-<pre>
-MenuItem menuItem = menu.add(0, PHOTO_PICKER_ID, 0, "Select Photo");
-menuItem.setIntent(new Intent(this, PhotoPicker.class));
-</pre>
-<p>Android will automatically launch the Activity when the item is selected.</p>
-
-<p class="note"><strong>Note:</strong> This will not return a result to your Activity.
-If you wish to be returned a result, then do not use <code>setIntent()</code>.
-Instead, handle the selection as usual in the <code>onOptionsMenuItemSelected()</code>
-or <code>onContextMenuItemSelected()</code> callback and call
-<code>{@link android.app.Activity#startActivityForResult(Intent,int) startActivityForResult()}</code>.
-</p>
-
-<h4>Dynamically add intents</h4>
-
-<p>If there are potentially multiple activities that are relevant to your current
-Activity or selected item, then the application can dynamically add menu items that execute other
-services.</p>
-<p>During menu creation, define an Intent with the category <var>Intent.ALTERNATIVE_CATEGORY</var> and/or
-<var>Intent.SELECTED_ALTERNATIVE</var>, the MIME type currently selected (if any), and any other
-requirements, the same way as you would satisfy an intent filter to open a new
-Activity. Then call
-<code>{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
-addIntentOptions()}</code> to have Android search for any services meeting those requirements
-and add them to the menu for you. If there are no applications installed
-that satisfy the Intent, then no additional menu items are added.</p>
+<p>You can add quick-access shortcut keys using letters and/or numbers to menu items with the
+{@code android:alphabeticShortcut} and {@code android:numericShortcut} attributes in the {@code
+&lt;item&gt;} element. You can also use the methods {@link
+android.view.MenuItem#setAlphabeticShortcut(char)} and {@link
+android.view.MenuItem#setNumericShortcut(char)}. Shortcut keys are <em>not</em>
+case sensitive.</p>
+
+<p>For example, if you apply the "s" character as an alphabetic shortcut to a "save" menu item, then
+when the menu is open (or while the user holds the MENU key) and the user presses the "s" key,
+the "save" menu item is selected.</p>
+
+<p>This shortcut key is displayed as a tip in the menu item, below the menu item name
+(except for items in the Icon Menu, which are displayed only if the user holds the MENU
+key).</p>
+
+<p class="note"><strong>Note:</strong> Shortcut keys for menu items only work on devices with a
+hardware keyboard. Shortcuts cannot be added to items in a Context Menu.</p>
+
+
+<h3 id="intents">Intents for menu items</h3>
+
+<p>Sometimes you'll want a menu item to launch an Activity using an Intent (whether it's an
+Actvitity in your application or another application). When you know the Intent you want to use and
+have a specific menu item that should initiate the Intent, you can execute the Intent with {@link
+android.app.Activity#startActivity(Intent) startActivity()} during the appropriate on-item-selected
+callback method (such as the {@link android.app.Activity#onOptionsItemSelected(MenuItem)
+onOptionsItemSelected()} callback).</p>
+
+<p>However, if you are not certain that the user's device
+contains an application that handles the Intent, then adding a menu item that executes the
+Intent can result in a non-functioning menu item, because the Intent might not resolve to an
+Activity that accepts it. To solve this, Android lets you dynamically add menu items to your menu
+when Android finds activities on the device that handle your Intent.</p>
+
+<p>If you're not familiar with creating Intents, read the <a
+href="/guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>.</p>
+
+
+<h4>Dynamically adding Intents</h4>
+
+<p>When you don't know if the user's device has an application that handles a specific Intent,
+you can define the Intent and let Android search the device for activities that accept the Intent.
+When it finds activies that handle the Intent, it adds a menu item for
+each one to your menu and attaches the appropriate Intent to open the Activity when the user
+selects it.</p>
+
+<p>To add menu items based on available activities that accept an Intent:</p>
+<ol>
+ <li>Define an
+Intent with the category {@link android.content.Intent#CATEGORY_ALTERNATIVE} and/or
+{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE}, plus any other requirements.</li>
+ <li>Call {@link
+android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
+Menu.addIntentOptions()}. Android then searches for any applications that can perform the Intent
+and adds them to your menu.</li>
+</ol>
+
+<p>If there are no applications installed
+that satisfy the Intent, then no menu items are added.</p>
<p class="note"><strong>Note:</strong>
-<var>SELECTED_ALTERNATIVE</var> is used to handle the currently selected element on the
-screen. So, it should only be used when creating a Menu in <code>onCreateContextMenu()</code> or
-<code>onPrepareOptionsMenu()</code>, which is called every time the Options Menu is opened.</p>
+{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} is used to handle the currently
+selected element on the screen. So, it should only be used when creating a Menu in {@link
+android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo)
+onCreateContextMenu()}.</p>
-<p>Here's an example demonstrating how an application would search for
-additional services to display on its menu.</p>
+<p>For example:</p>
<pre>
+&#64;Override
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
// Create an Intent that describes the requirements to fulfill, to be included
- // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
- Intent intent = new Intent(null, getIntent().getData());
+ // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
+ Intent intent = new Intent(null, dataUri);
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
-
- // Search for, and populate the menu with, acceptable offering applications.
+
+ // Search and populate the menu with acceptable offering applications.
menu.addIntentOptions(
- thisClass.INTENT_OPTIONS, // Menu group
+ R.id.intent_group, // Menu group to which new items will be added
0, // Unique item ID (none)
0, // Order for the items (none)
this.getComponentName(), // The current Activity name
@@ -495,17 +612,27 @@ public boolean onCreateOptionsMenu(Menu menu){
return true;
}</pre>
-<p>For each Activity found that provides an Intent Filter matching the Intent defined, a menu
-item will be added, using the <var>android:label</var> value of the intent filter as the text
-for the menu item.
-The <code>{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) addIntentOptions()}</code> method will also return the number of menu items added.</p>
-<p>Also be aware that, when <code>addIntentOptions()</code> is called, it will override any and all
-menu items in the menu group specified in the first argument.</p>
-
-<p>If you wish to offer the services of your Activity to other application menus, then you
-only need to define an intent filter as usual. Just be sure to include the <var>ALTERNATIVE</var> and/or
-<var>SELECTED_ALTERNATIVE</var> values in the <var>name</var> attribute of
-a <code>&lt;category></code> element in the intent filter. For example:</p>
+<p>For each Activity found that provides an Intent filter matching the Intent defined, a menu
+item is added, using the value in the Intent filter's <code>android:label</code> as the
+menu item title and the application icon as the menu item icon. The
+{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
+addIntentOptions()} method returns the number of menu items added.</p>
+
+<p class="note"><strong>Note:</strong> When you call {@link
+android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
+addIntentOptions()}, it overrides any and all menu items by the menu group specified in the first
+argument.</p>
+
+
+<h4>Allowing your Activity to be added to menus</h4>
+
+<p>You can also offer the services of your Activity to other applications, so your
+application can be included in the menu of others (reverse the roles described above).</p>
+
+<p>To be included in other application menus, you need to define an Intent
+filter as usual, but be sure to include the {@link android.content.Intent#CATEGORY_ALTERNATIVE}
+and/or {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} values for the Intent filter
+category. For example:</p>
<pre>
&lt;intent-filter label="Resize Image">
...
@@ -514,9 +641,10 @@ a <code>&lt;category></code> element in the intent filter. For example:</p>
...
&lt;/intent-filter>
</pre>
-<p>read more about writing intent filters in the
+
+<p>Read more about writing Intent filters in the
<a href="/guide/topics/intents/intents-filters.html">Intents and Intent Filters</a> document.</p>
<p>For a sample application using this technique, see the
-<a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a>
-sample code.</p>
+<a href="{@docRoot}resources/samples/NotePad/src/com/example/android/notepad/NoteEditor.html">Note
+Pad</a> sample code.</p>
diff --git a/docs/html/guide/topics/ui/notifiers/index.jd b/docs/html/guide/topics/ui/notifiers/index.jd
index f7ccce7..d29324c 100644
--- a/docs/html/guide/topics/ui/notifiers/index.jd
+++ b/docs/html/guide/topics/ui/notifiers/index.jd
@@ -3,13 +3,7 @@ page.title=Notifying the User
<div id="qv-wrapper">
<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#Toast">Toast Notification</a></li>
- <li><a href="#StatusBarNotification">Status Bar Notification</a></li>
- <li><a href="#Dialog">Dialog Notification</a></li>
- </ol>
- <h2>More about</h2>
+ <h2>Topics</h2>
<ol>
<li><a href="toasts.html">Creating Toast Notifications</a></li>
<li><a href="notifications.html">Creating Status Bar Notifications</a></li>
diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd
index a0dd9f1..abc945a 100644
--- a/docs/html/guide/topics/ui/notifiers/notifications.jd
+++ b/docs/html/guide/topics/ui/notifiers/notifications.jd
@@ -5,18 +5,21 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
- <h2>Key classes</h2>
- <ol>
- <li>{@link android.app.Notification}</li>
- <li>{@link android.app.NotificationManager}</li>
- </ol>
+ <h2>Quickview</h2>
+ <ul>
+ <li>A status bar notification allows your application to notify the user of an event
+without interupting their current activity</li>
+ <li>You can attach an intent to your notification that the system will initiate when the
+user clicks it</li>
+ </ul>
+
<h2>In this document</h2>
<ol>
<li><a href="#Basics">The Basics</a></li>
<li><a href="#ManageYourNotifications">Managing your Notifications</a></li>
<li><a href="#CreateANotification">Creating a Notification</a>
<ol>
- <li><a href="#Update">Updating the notification</a></li>
+ <li><a href="#Updating">Updating the notification</a></li>
<li><a href="#Sound">Adding a sound</a></li>
<li><a href="#Vibration">Adding vibration</a></li>
<li><a href="#Lights">Adding flashing lights</a></li>
@@ -25,6 +28,11 @@ parent.link=index.html
</li>
<li><a href="#CustomExpandedView">Creating a Custom Expanded View</a></li>
</ol>
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.app.Notification}</li>
+ <li>{@link android.app.NotificationManager}</li>
+ </ol>
</div>
</div>
diff --git a/docs/html/guide/topics/ui/notifiers/toasts.jd b/docs/html/guide/topics/ui/notifiers/toasts.jd
index 5b324d2..0d3e10c 100644
--- a/docs/html/guide/topics/ui/notifiers/toasts.jd
+++ b/docs/html/guide/topics/ui/notifiers/toasts.jd
@@ -5,16 +5,24 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
- <h2>Key classes</h2>
+ <h2>Quickview</h2>
<ol>
- <li>{@link android.widget.Toast}</li>
+ <li>A toast is a message that appears on the surface of the screen for a moment, but it
+does not take focus (or pause the current activity), so it cannot accept user input</li>
+ <li>You can customize the toast layout to include images</li>
</ol>
+
<h2>In this document</h2>
<ol>
<li><a href="#Basics">The Basics</a></li>
- <li><a href="#Position">Positioning your Toast</a></li>
+ <li><a href="#Positioning">Positioning your Toast</a></li>
<li><a href="#CustomToastView">Creating a Custom Toast View</a></li>
</ol>
+
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.widget.Toast}</li>
+ </ol>
</div>
</div>
diff --git a/docs/html/guide/topics/ui/ui-events.jd b/docs/html/guide/topics/ui/ui-events.jd
index ccef64f..7d7bfaf 100644
--- a/docs/html/guide/topics/ui/ui-events.jd
+++ b/docs/html/guide/topics/ui/ui-events.jd
@@ -13,9 +13,9 @@ parent.link=index.html
<li><a href="#HandlingFocus">Handling Focus</a></li>
</ol>
- <h2>See also</h2>
+ <h2>Related tutorials</h2>
<ol>
- <li><a href="{@docRoot}resources/tutorials/views/hello-formstuff.html">Hello Form Stuff tutorial</a></li>
+ <li><a href="{@docRoot}resources/tutorials/views/hello-formstuff.html">Form Stuff</a></li>
</ol>
</div>
</div>
diff --git a/docs/html/guide/topics/wireless/bluetooth.jd b/docs/html/guide/topics/wireless/bluetooth.jd
index a8ff007..98b6e7d 100644
--- a/docs/html/guide/topics/wireless/bluetooth.jd
+++ b/docs/html/guide/topics/wireless/bluetooth.jd
@@ -3,13 +3,12 @@ page.title=Bluetooth
<div id="qv-wrapper">
<div id="qv">
- <h2>Key Classes</h2>
- <ol>
- <li>{@link android.bluetooth.BluetoothAdapter}</li>
- <li>{@link android.bluetooth.BluetoothDevice}</li>
- <li>{@link android.bluetooth.BluetoothSocket}</li>
- <li>{@link android.bluetooth.BluetoothServerSocket}</li>
- </ol>
+
+ <h2>Quickview</h2>
+ <ul>
+ <li>Android's bluetooth APIs allow your application to perform wireless data transactions with
+other devices</li>
+ </ul>
<h2>In this document</h2>
<ol>
@@ -34,10 +33,17 @@ page.title=Bluetooth
<li><a href="#ManagingAConnection">Managing a Connection</a></li>
</ol>
- <h2>See also</h2>
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.bluetooth.BluetoothAdapter}</li>
+ <li>{@link android.bluetooth.BluetoothDevice}</li>
+ <li>{@link android.bluetooth.BluetoothSocket}</li>
+ <li>{@link android.bluetooth.BluetoothServerSocket}</li>
+ </ol>
+
+ <h2>Related samples</h2>
<ol>
- <li><a href="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat sample
- app</a></li>
+ <li><a href="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat</a></li>
</ol>
</div>
@@ -283,7 +289,7 @@ is discussed below.</p>
of paired devices to see if the desired device is already known. To do so,
call {@link android.bluetooth.BluetoothAdapter#getBondedDevices()}. This
will return a Set of {@link android.bluetooth.BluetoothDevice}s representing
-paired devices. For example, you can query all paired devices and then add then
+paired devices. For example, you can query all paired devices and then
show the name of each device to the user, using an ArrayAdapter:</p>
<pre>
Set&lt;BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
diff --git a/docs/html/guide/webapps/best-practices.jd b/docs/html/guide/webapps/best-practices.jd
new file mode 100644
index 0000000..4e9ae81
--- /dev/null
+++ b/docs/html/guide/webapps/best-practices.jd
@@ -0,0 +1,90 @@
+page.title=Best Practices for Web Apps
+@jd:body
+
+<style>
+.bold li {
+ font-weight:bold;
+}
+.bold li * {
+ font-weight:normal;
+}
+</style>
+
+<p>Developing web pages and web applications for mobile devices presents a different set of
+challenges compared to developing a web page for the typical
+desktop web browser. To help you get started, the following is a list of practices you should
+follow in order to provide the most effective web application for Android and other mobile
+devices.</p>
+
+<ol class="bold">
+
+<li>Redirect mobile devices to a dedicated mobile version of your web site
+ <p>There are several ways you can redirect requests to the mobile version of your web site, using
+server-side redirects. Most often, this is done by "sniffing" the User Agent
+string provided by the web browser. To determine whether to serve a mobile version of your site, you
+should simply look for the "mobile" string in the User Agent, which matches a wide variety of mobile
+devices. If necessary, you can also identify the specific operating system in the User Agent string
+(such as "Android 2.1").</p>
+</li>
+
+
+<li>Use a valid markup DOCTYPE that's appropriate for mobile devices
+ <p>The most common markup language used for mobile web sites is <a
+href="http://www.w3.org/TR/2008/REC-xhtml-basic-20080729/">XHTML Basic</a>. This standard
+ensures specific markup for your web site that works best on mobile devices. For instance, it does
+not allow HTML frames or nested tables, which perform poorly on mobile devices. Along with the
+DOCTYPE, be sure to declare the appropriate character encoding for the document (such as
+UTF-8).</p>
+ <p>For example:</p>
+<pre>
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
+ "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"&gt;
+</pre>
+
+ <p>Also be sure that your web page markup is valid against the declared DOCTYPE. Use a
+validator, such as the one available at
+<a href="http://validator.w3.org/">http://validator.w3.org</a>.</p>
+</li>
+
+
+<li>Use viewport meta data to properly resize your web page
+ <p>In your document {@code &lt;head&gt;}, you should provide meta data that specifies how you
+want the browser's viewport to render your web page. For example, your viewport meta data can
+specify the height and width for the browser's viewport, the initial web page scale and even the
+target screen density.</p>
+ <p>For example:</p>
+<pre>
+&lt;meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"&gt;
+</pre>
+ <p>For more information about how to use viewport meta data for Android-powered devices, read <a
+href="{@docRoot}guide/webapps/targeting.html">Targeting Screens from Web Apps</a>.</p>
+</li>
+
+
+<li>Avoid multiple file requests
+ <p>Because mobile devices typically have a connection speed far slower than a desktop
+computer, you should make your web pages load as fast as possible. One way to speed it up is to
+avoid loading extra files such as stylesheets and script files in the {@code
+&lt;head&gt;}. Instead, provide your CSS and JavaScript directly in the &lt;head&gt; (or
+at the end of the &lt;body&gt;, for scripts that you don't need until the page is loaded).
+Alternatively, you should optimize the size and speed of your files by compressing them with tools
+like <a href="http://code.google.com/p/minify/">Minify</a>.</p>
+</li>
+
+
+<li>Use a vertical linear layout
+ <p>Avoid the need for the user to scroll left and right while navigating your web
+page. Scrolling up and down is easier for the user and makes your web page simpler.</p>
+</li>
+
+</ol>
+
+<p>For a more thorough guide to creating great mobile web applications, see the W3C's <a
+href="http://www.w3.org/TR/mobile-bp/">Mobile Web Best Practices</a>. For other guidance on
+improving the speed of your web site (for mobile and desktop), see Yahoo!'s guide to <a
+href="http://developer.yahoo.com/performance/index.html#rules">Exceptional Performance</a> and
+Google's speed tutorials in <a href="http://code.google.com/speed/articles/">Let's make the web
+faster</a>.</p>
+
+
diff --git a/docs/html/guide/webapps/debugging.jd b/docs/html/guide/webapps/debugging.jd
new file mode 100644
index 0000000..ee4b723
--- /dev/null
+++ b/docs/html/guide/webapps/debugging.jd
@@ -0,0 +1,158 @@
+page.title=Debugging Web Apps
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>Quickview</h2>
+<ul>
+ <li>You can debug your web app using console methods in JavaScript</li>
+ <li>If debugging in a custom WebView, you need to implement a callback method to handle debug
+messages</li>
+</ul>
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#Browser">Using Console APIs in the Android Browser</a></li>
+ <li><a href="#WebView">Using Console APIs in WebView</a></li>
+</ol>
+
+<h2>See also</h2>
+<ol>
+ <li><a href="{@docRoot}guide/developing/debug-tasks.html">Debugging Tasks</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>If you're developing a web application for Android, you can debug your JavaScript
+using the {@code console} JavaScript APIs, which output messages to logcat. If you're familiar with
+debugging web pages with Firebug or Web Inspector, then you're probably familiar
+with using {@code console} (such as {@code console.log()}). Android's WebKit framework supports most
+of the same APIs, so you can receive logs from your web page when debugging in Android's Browser
+or in your own {@link android.webkit.WebView}.</p>
+
+
+
+<h2 id="Browser">Using Console APIs in the Android Browser</h2>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h2>Logcat</h2>
+ <p>Logcat is a tool that dumps a log of system messages. The messages include a stack trace when
+the device throws an error, as well as log messages written from your application and
+those written using JavaScript {@code console} APIs.</p>
+ <p>To run logcat and view messages, execute
+{@code adb logcat} from your Android SDK {@code tools/} directory, or, from DDMS, select
+<strong>Device > Run logcat</strong>. When using the <a href="{@docRoot}sdk/eclipse-adt.html">ADT
+plugin for Eclipse</a>, you can also view logcat messages by opening the Logcat view, available from
+<strong>Window > Show View > Other > Android > Logcat</strong>.</p>
+ <p>See <a href="{@docRoot}guide/developing/debug-tasks.html">Debugging
+Tasks</a> for more information about logcat.</p>
+</div>
+</div>
+
+<p>When you call a {@code console} function (in the DOM's {@code window.console} object),
+the output appears in logcat. For example, if your web page executes the following
+JavaScript:</p>
+<pre>
+console.log("Hello World");
+</pre>
+<p>Then the logcat message looks something like this:</p>
+<pre class="no-pretty-print">
+Console: Hello World http://www.example.com/hello.html :82
+</pre>
+
+<p>The format of the message might appear different depending on which version of Android you're
+using. On Android 2.1 and higher, console messages from the Android Browser
+are tagged with the name "browser". On Android 1.6 and lower, Android Browser
+messages are tagged with the name "WebCore".</p>
+
+<p>Android's WebKit does not implement all of the console APIs available in other desktop browsers.
+You can, however, use the basic text logging functions:</p>
+<ul>
+ <li>{@code console.log(String)}</li>
+ <li>{@code console.info(String)}</li>
+ <li>{@code console.warn(String)}</li>
+ <li>{@code console.error(String)}</li>
+</ul>
+
+<p>Other console functions don't raise errors, but might not behave the same as what you
+expect from other web browsers.</p>
+
+
+
+<h2 id="WebView">Using Console APIs in WebView</h2>
+
+<p>If you've implemented a custom {@link android.webkit.WebView} in your application, all the
+same console APIs are supported when debugging your web page in WebView. On Android
+1.6 and lower, console messages are automatically sent to logcat with the
+"WebCore" logging tag. If you're targeting Android 2.1 (API Level 7) or higher, then you must
+provide a {@link android.webkit.WebChromeClient}
+that implements the {@link android.webkit.WebChromeClient#onConsoleMessage(String,int,String)
+onConsoleMessage()} callback method, in order for console messages to appear in logcat.</p>
+
+<p>Additionally, the {@link
+android.webkit.WebChromeClient#onConsoleMessage(String,int,String)} method introduced in API
+Level 7 has been deprecated in favor of {@link
+android.webkit.WebChromeClient#onConsoleMessage(ConsoleMessage)} in API Level 8.</p>
+
+<p>Whether you're developing for Android 2.1 (API Level 7) or Android 2.2 (API Level 8 or
+greater), you must implement {@link android.webkit.WebChromeClient} and override the appropriate
+{@link
+android.webkit.WebChromeClient#onConsoleMessage(String,int,String) onConsoleMessage()} callback
+method. Then, apply the {@link android.webkit.WebChromeClient} to your {@link
+android.webkit.WebView} with {@link android.webkit.WebView#setWebChromeClient(WebChromeClient)
+setWebChromeClient()}.
+
+<p>Using API Level 7, this is how your code for {@link
+android.webkit.WebChromeClient#onConsoleMessage(String,int,String)} might look:</p>
+
+<pre>
+WebView myWebView = (WebView) findViewById(R.id.webview);
+myWebView.setWebChromeClient(new WebChromeClient() {
+ public void onConsoleMessage(String message, int lineNumber, String sourceID) {
+ Log.d("MyApplication", message + " -- From line "
+ + lineNumber + " of "
+ + sourceID);
+ }
+});
+</pre>
+
+<p>With API Level 8 or greater, your code for {@link
+android.webkit.WebChromeClient#onConsoleMessage(ConsoleMessage)} might look like this:</p>
+
+<pre>
+WebView myWebView = (WebView) findViewById(R.id.webview);
+myWebView.setWebChromeClient(new WebChromeClient() {
+ public boolean onConsoleMessage(ConsoleMessage cm) {
+ Log.d("MyApplication", cm.{@link android.webkit.ConsoleMessage#message()} + " -- From line "
+ + cm.{@link android.webkit.ConsoleMessage#lineNumber()} + " of "
+ + cm.{@link android.webkit.ConsoleMessage#sourceId()} );
+ return true;
+ }
+});
+</pre>
+
+<p>The {@link android.webkit.ConsoleMessage} also includes a {@link
+android.webkit.ConsoleMessage.MessageLevel MessageLevel} to indicate the type of console message
+being delivered. You can query the message level with {@link
+android.webkit.ConsoleMessage#messageLevel()} to determine the severity of the message, then
+use the appropriate {@link android.util.Log} method or take other appropriate actions.</p>
+
+<p>Whether you're using {@link
+android.webkit.WebChromeClient#onConsoleMessage(String,int,String)} or {@link
+android.webkit.WebChromeClient#onConsoleMessage(ConsoleMessage)}, when you execute a console method
+in your web page, Android calls the appropriate {@link
+android.webkit.WebChromeClient#onConsoleMessage(String,int,String)
+onConsoleMessage()} method so you can report the error. For example, with the example code above,
+a logcat message is printed that looks like this:</p>
+
+<pre class="no-pretty-print">
+Hello World -- From line 82 of http://www.example.com/hello.html
+</pre>
+
+
+
+
+
+
diff --git a/docs/html/guide/webapps/index.jd b/docs/html/guide/webapps/index.jd
new file mode 100644
index 0000000..280380f
--- /dev/null
+++ b/docs/html/guide/webapps/index.jd
@@ -0,0 +1,71 @@
+page.title=Web Apps Overview
+@jd:body
+
+<div class="figure" style="width:327px">
+ <img src="{@docRoot}images/webapps/webapps.png" alt="" />
+ <p class="img-caption"><strong>Figure 1.</strong> You can make your web content available to
+users in two ways: in a traditional web browser and in an Android application, by
+including a WebView in the layout.</p>
+</div>
+
+<p>There are essentially two ways to deliver an application on Android: as a
+client-side application (developed using the Android SDK and installed on user devices as an {@code
+.apk}) or as a web application (developed using web standards and accessed through a web
+browser&mdash;there's nothing to install on user devices).</p>
+
+<p>The approach you choose for your application could depend on several factors, but Android makes
+the decision to develop a web application easier by providing:</p>
+<ul>
+ <li>Support for viewport properties that allow you to properly size your web application
+based on the screen size</li>
+ <li>CSS and JavaScript features that allow you to provide different styles and images
+based on the screen's pixel density (screen resolution)</li>
+</ul>
+
+<p>Thus, your decision to develop a web application for Android can exclude consideration for
+screen support, because it's already easy to make your web pages look good on all types of screens
+powered by Android.</p>
+
+<p>Another great feature of Android is that you don't have to build your application purely on
+the client or purely on the web. You can mix the two together by developing a client-side Android
+application that embeds some web pages (using a {@link android.webkit.WebView} in your Android
+application layout). Figure 1 visualizes how you can provide access to your web pages from either
+a web browser or your Android application. However, you shouldn't develop an Android
+application simply as a means to launch your web site. Rather, the web pages you embed in your
+Android application should be designed especially for that environment. You can even define an
+interface between your Android application and your web pages that allows JavaScript in the web
+pages to call upon APIs in your Android application&mdash;providing Android APIs to your web-based
+application.</p>
+
+<p>Since Android 1.0, {@link android.webkit.WebView} has been available for Android
+applications to embed web content in their layout and bind JavaScript to Android APIs. After
+Android added support for more screen densities (adding support for high and low-density
+screens), Android 2.0 added features to the WebKit framework to allow web pages to specify
+viewport properties and query the screen density in order to modify styles
+and image assets, as mentioned above. Because these features are a part of Android's WebKit
+framework, both the Android Browser (the default web browser provided with the platform) and
+{@link android.webkit.WebView} support the same viewport and screen density features.</p>
+
+<p>To develop a web application for Android-powered devices, you should read the
+following documents:</p>
+
+<dl>
+ <dt><a href="{@docRoot}guide/webapps/targeting.html"><strong>Targeting Screens from Web
+Apps</strong></a></dt>
+ <dd>How to properly size your web app on Android-powered devices and support
+multiple screen densities. The information in this document is important if you're building a web
+application that you at least expect to be available on Android-powered devices (which you should
+assume for anything you publish on the web), but especially if you're targeting mobile devices
+or using {@link android.webkit.WebView}.</dd>
+ <dt><a href="{@docRoot}guide/webapps/webview.html"><strong>Building Web Apps in
+WebView</strong></a></dt>
+ <dd>How to embed web pages into your Android application using {@link android.webkit.WebView} and
+bind JavaScript to Android APIs.</dd>
+ <dt><a href="{@docRoot}guide/webapps/debugging.html"><strong>Debugging Web Apps</strong></a></dt>
+ <dd>How to debug web apps using JavaScript Console APIs.</dd>
+ <dt><a href="{@docRoot}guide/webapps/best-practices.html"><strong>Best Practices for Web</strong>
+Apps</a></dt>
+ <dd>A list of practices you should follow, in order to provide an effective web application on
+Android-powered devices.</dd>
+</dl>
+
diff --git a/docs/html/guide/webapps/targeting.jd b/docs/html/guide/webapps/targeting.jd
new file mode 100644
index 0000000..bdc2d5e
--- /dev/null
+++ b/docs/html/guide/webapps/targeting.jd
@@ -0,0 +1,439 @@
+page.title=Targeting Screens from Web Apps
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>Quickview</h2>
+<ul>
+ <li>You can target your web page for different screens using viewport metadata, CSS, and
+JavaScript</li>
+ <li>Techniques in this document work for Android 2.0 and greater, and for web pages rendered
+in the default Android Browser and in a {@link android.webkit.WebView}</li>
+</ul>
+
+<h2>In this document</h2>
+<ol>
+<li><a href="#Metadata">Using Viewport Metadata</a>
+ <ol>
+ <li><a href="#ViewportSize">Defining the viewport size</a></li>
+ <li><a href="#ViewportScale">Defining the viewport scale</a></li>
+ <li><a href="#ViewportDensity">Defining the viewport target density</a></li>
+ </ol>
+</li>
+<li><a href="#DensityCSS">Targeting Device Density with CSS</a></li>
+<li><a href="#DensityJS">targeting Device Density with JavaScript</a></li>
+</ol>
+
+</div>
+</div>
+
+
+<p>If you're developing a web application for Android or redesigning one for mobile devices, you
+should carefully consider how your web pages appear on different kinds of screens. Because
+Android is available on devices with different types of screens, you should account for some factors
+that affect the way your web pages appear on Android devices.</p>
+
+<p class="note"><strong>Note:</strong> The features described in this document are supported
+by the Android Browser application (provided with the default Android platform) and {@link
+android.webkit.WebView} (the framework view widget for displaying web pages), on Android 2.0 and
+greater. Third-party web browsers running on Android might not support these features for
+controlling the viewport size and screen densities.</p>
+
+<p>When targeting your web pages for Android devices, there are two fundamental factors that you
+should account for:</p>
+
+<dl>
+ <dt>The size of the viewport and scale of the web page</dt>
+ <dd>When the Android Browser loads a web page, the default behavior is to load the
+page in "overview mode," which provides a zoomed-out perspective of the web page. You can override
+this behavior for your web page by defining the default dimensions of the viewport or the initial
+scale of the viewport. You can also control how much the user can zoom in and out of your web
+page, if at all. The user can also disable overview mode in the
+Browser settings, so you should never assume that your page will load in overview mode. You
+should instead customize the viewport size and/or scale as appropriate for your page.</p>
+ <p>However, when your page is rendered in a {@link android.webkit.WebView}, the page loads at
+full zoom (not in "overview mode"). That is, it appears at the default size for the page,
+instead of zoomed out. (This is also how the page appears if the user disables overview
+mode.)</p></dd>
+
+ <dt>The device's screen density</dt>
+ <dd>The screen density (the number of pixels per inch) on an Android-powered device affects
+the resolution and size at which a web page is displayed. (There are three screen density
+categories: low, medium, and high.) The Android Browser and {@link android.webkit.WebView}
+compensate for variations in the screen
+density by scaling a web page so that all devices display the web page at the same perceivable size
+as a medium-density screen. If graphics are an important element of your web design, you
+should pay close attention to the scaling that occurs on different densities, because image scaling
+can produce artifacts (blurring and pixelation).
+ <p>To provide the best visual representation on all
+screen densities, you should control how scaling occurs by providing viewport metadata about
+your web page's target screen density and providing alternative graphics for different screen
+densities, which you can apply to different screens using CSS or JavaScript.</p></dd>
+</dl>
+
+<p>The rest of this document describes how you can account for these effects and provide a good
+design on multiple types of screens.</p>
+
+
+
+<h2 id="Metadata">Using Viewport Metadata</h2>
+
+<p>The viewport is the area in which your web page is drawn. Although the viewport's visible area
+matches the size of the screen,
+the viewport has its own dimensions that determine the number of pixels available to a web page.
+That is, the number of pixels available to a web page before it exceeds the screen area is
+defined by the dimensions of the viewport,
+not the dimensions of the device screen. For example, although a device screen might have a width of
+480 pixels, the viewport can have a width of 800 pixels, so that a web page designed to be 800
+pixels wide is completely visible on the screen.</p>
+
+<p>You can define properties of the viewport for your web page using the {@code "viewport"}
+property in an HTML {@code &lt;meta&gt;} tag (which must
+be placed in your document {@code &lt;head&gt;}). You can define multiple viewport properties in the
+{@code &lt;meta&gt;} tag's {@code content} attribute. For example, you can define the height and
+width of the viewport, the initial scale of the page, and the target screen density.
+Each viewport property in the {@code content} attribute must be separated by a comma.</p>
+
+<p>For example, the following snippet from an HTML document specifies that the viewport width
+should exactly match the device screen width and that the ability to zoom should be disabled:</p>
+
+<pre>
+&lt;head&gt;
+ &lt;title&gt;Example&lt;/title&gt;
+ &lt;meta name="viewport" content="width=device-width, user-scalable=no" /&gt;
+&lt;/head&gt;
+</pre>
+
+<p>That's an example of just two viewport properties. The following syntax shows all of the
+supported viewport properties and the general types of values accepted by each one:</p>
+
+<pre>
+&lt;meta name="viewport"
+ content="
+ <b>height</b> = [<em>pixel_value</em> | device-height] ,
+ <b>width</b> = [<em>pixel_value</em> | device-width ] ,
+ <b>initial-scale</b> = <em>float_value</em> ,
+ <b>minimum-scale</b> = <em>float_value</em> ,
+ <b>maximum-scale</b> = <em>float_value</em> ,
+ <b>user-scalable</b> = [yes | no] ,
+ <b>target-densitydpi</b> = [<em>dpi_value</em> | device-dpi |
+ high-dpi | medium-dpi | low-dpi]
+ " /&gt;
+</pre>
+
+<p>The following sections discuss how to use each of these viewport properties and exactly what the
+accepted values are.</p>
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/webapps/compare-default.png" alt="" height="300" />
+ <p class="img-caption"><strong>Figure 1.</strong> A web page with an image that's 320 pixels
+wide, in the Android Browser when there is no viewport metadata set (with "overview mode"
+enabled, the viewport is 800 pixels wide, by default).</p>
+</div>
+
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/webapps/compare-width400.png" alt="" height="300" />
+ <p class="img-caption"><strong>Figure 2.</strong> A web page with viewport {@code width=400} and
+"overview mode" enabled (the image in the web page is 320 pixels wide).</p>
+</div>
+
+
+<h3 id="ViewportSize">Defining the viewport size</h3>
+
+<p>Viewport's {@code height} and {@code width} properties allow you to specify the size of the
+viewport (the number of pixels available to the web page before it goes off screen).</p>
+
+<p>As mentioned in the introduction above, the Android Browser loads pages in "overview mode" by
+default (unless disable by the user), which sets the minimum viewport width to 800 pixels. So, if
+your web page specifies its size to be 320 pixels wide, then your page appears smaller than the
+visible screen (even if the physical screen is 320 pixels wide, because the viewport simulates a
+drawable area that's 800 pixels wide), as shown in figure 1. To avoid this effect, you should
+explicitly define the viewport {@code width} to match the width for which you have designed your web
+page.</p>
+
+<p>For example, if your web page is designed to be exactly 320 pixels wide, then you might
+want to specify that size for the viewport width:</p>
+
+<pre>
+&lt;meta name="viewport" content="width=320" /&gt;
+</pre>
+
+<p>In this case, your web page exactly fits the screen width, because the web page width and
+viewport width are the same.</p>
+
+<p class="note"><strong>Note:</strong> Width values that are greater than 10,000 are ignored and
+values less than (or equal to) 320 result in a value equal to the device-width (discussed below).
+Height values that are greater then 10,000 or less than 200 are also ignored.</p>
+
+<p>To demonstrate how this property affects the size of
+your web page, figure 2 shows a web page that contains an image that's 320 pixels
+wide, but with the viewport width set to 400.</p>
+
+
+<p class="note"><strong>Note:</strong> If you set the viewport width to match your web page width
+and the device's screen width does <em>not</em> match those dimensions, then the web page
+still fits the screen even if the device has a high or low-density screen, because the
+Android Browser and {@link android.webkit.WebView} scale web pages to match the perceived size on a
+medium-density screen, by default (as you can see in figure 2, when comparing the hdpi device to the
+mdpi device). Screen densities are discussed more in <a href="#ViewportDensity">Defining the
+viewport target density</a>.</p>
+
+
+<h4>Automatic sizing</h4>
+
+<p>As an alternative to specifying the viewport dimensions with exact pixels, you can set the
+viewport size to always match the dimensions of the device screen, by defining the
+viewport properties {@code height}
+and {@code width} with the values {@code device-height} and {@code device-width}, respectively. This
+is appropriate when you're developing a web application that has a fluid width (not fixed width),
+but you want it to appear as if it's fixed (to perfectly fit every screen as
+if the web page width is set to match each screen). For example:</p>
+
+<pre>
+&lt;meta name="viewport" content="width=device-width" /&gt;
+</pre>
+
+<p>This results in the viewport width matching whatever the current screen width is, as shown in
+figure 3. It's important to notice that, this results in images being scaled to fit the screen
+when the current device does not match the <a href="#ViewportDensity">target
+density</a>, which is medium-density if you don't specify otherwise. As a result, the image
+displayed on the high-density device in figure 3 is scaled up in order to match the width
+of a screen with a medium-density screen.</p>
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/webapps/compare-initialscale.png" alt="" height="300" />
+ <p class="img-caption"><strong>Figure 3.</strong> A web page with viewport {@code
+width=device-width} <em>or</em> {@code initial-scale=1.0}.</p>
+</div>
+
+<p class="note"><strong>Note:</strong> If you instead want {@code
+device-width} and {@code device-height} to match the physical screen pixels for every device,
+instead of scaling your web page to match the target density, then you must also include
+the {@code target-densitydpi} property with a value of {@code device-dpi}. This is discussed more in
+the section about <a href="#ViewportDensity">Defining the viewport density</a>. Otherwise, simply
+using {@code device-height} and {@code device-width} to define the viewport size makes your web page
+fit every device screen, but scaling occurs on your images in order to adjust for different screen
+densities.</p>
+
+
+
+<h3 id="ViewportScale">Defining the viewport scale</h3>
+
+<p>The scale of the viewport defines the level of zoom applied to the web page. Viewport
+properties allow you to specify the scale of your web page in the following ways:</p>
+<dl>
+ <dt>{@code initial-scale}</dt>
+ <dd>The initial scale of the page. The value is a float that indicates a multiplier for your web
+page size, relative to the screen size. For example, if you set the initial scale to "1.0" then the
+web page is displayed to match the resolution of the <a href="#ViewportDensity">target
+density</a> 1-to-1. If set to "2.0", then the page is enlarged (zoomed in) by a factor of 2.
+ <p>The default initial scale is calculated to fit the web page in the viewport size.
+Because the default viewport width is 800 pixels, if the device screen resolution is less than
+800 pixels wide, the initial scale is something less than 1.0, by default, in order to fit the
+800-pixel-wide page on the screen.</p></dd>
+
+ <dt>{@code minimum-scale}</dt>
+ <dd>The minimum scale to allow. The value is a float that indicates the minimum multiplier for
+your web page size, relative to the screen size. For example, if you set this to "1.0", then the
+page can't zoom out because the minimum size is 1-to-1 with the <a href="#ViewportDensity">target
+density</a>.</dd>
+
+ <dt>{@code maximum-scale}</dt>
+ <dd>The maximum scale to allow for the page. The value is a float that indicates the
+maximum multiplier for your web page size,
+relative to the screen size. For example, if you set this to "2.0", then the page can't
+zoom in more than 2 times the target size.</dd>
+
+ <dt>{@code user-scalable}</dt>
+ <dd>Whether the user can change the scale of the page at all (zoom in and out). Set to {@code yes}
+to allow scaling and {@code no} to disallow scaling. The default is {@code yes}. If you set
+this to {@code no}, then the {@code minimum-scale} and {@code maximum-scale} are ignored,
+because scaling is not possible.</dd>
+</dl>
+
+<p>All scale values must be within the range 0.01&ndash;10.</p>
+
+<p>For example:</p>
+
+<pre>
+&lt;meta name="viewport" content="initial-scale=1.0" /&gt;
+</pre>
+
+<p>This metadata sets the initial scale to be full sized, relative to the viewport's target
+density.</p>
+
+
+
+
+<h3 id="ViewportDensity">Defining the viewport target density</h3>
+
+<p>The density of a device's screen is based on the screen resolution, as defined by the number of
+dots per inch (dpi). There are three screen
+density categories supported by Android: low (ldpi), medium (mdpi), and high (mdpi). A screen
+with low density has fewer available pixels per inch, whereas a screen with high density has more
+pixels per inch (compared to a medium density screen). The Android Browser and {@link
+android.webkit.WebView} target a medium density screen by default.</p>
+
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/webapps/compare-initialscale-devicedpi.png" alt="" height="300" />
+ <p class="img-caption"><strong>Figure 4.</strong> A web page with viewport {@code
+width=device-width} and {@code target-densitydpi=device-dpi}.</p>
+</div>
+
+
+<p>Because the default target density is medium, when users have a device with a low or high density
+screen, the Android Browser and {@link android.webkit.WebView} scale web pages (effectively zoom
+the pages) so they display at a
+size that matches the perceived appearance on a medium density screen. More specifically, the
+Android Browser and {@link android.webkit.WebView} apply approximately 1.5x scaling to web pages
+on a high density screen (because its screen pixels are smaller) and approximately 0.75x scaling to
+pages on a low density screen (because its screen pixels are bigger).</p>
+
+<p>Due to this default scaling, figures 1, 2, and 3 show the example web page at the same physical
+size on both the high and medium density device (the high-density device shows the
+web page with a default scale factor that is 1.5 times larger than the actual pixel resolution, to
+match the target density). This can introduce some undesirable artifacts in your images.
+For example, although an image appears the same size on a medium and high-density device, the image
+on the high-density device appears more blurry, because the image is designed to be 320 pixels
+wide, but is drawn with 480 pixels.</p>
+
+<p>You can change the target screen density for your web page using the {@code target-densitydpi}
+viewport property. It accepts the following values:</p>
+
+<ul>
+<li><code>device-dpi</code> - Use the device's native dpi as the target dpi. Default scaling never
+occurs.</li>
+<li><code>high-dpi</code> - Use hdpi as the target dpi. Medium and low density screens scale down
+as appropriate.</li>
+<li><code>medium-dpi</code> - Use mdpi as the target dpi. High density screens scale up and low
+density screens scale down. This is the default target density.</li>
+<li><code>low-dpi</code> - Use ldpi as the target dpi. Medium and high density screens scale up
+as appropriate.</li>
+<li><em><code>&lt;value&gt;</code></em> - Specify a dpi value to use as the target dpi. Values must
+be within the range 70&ndash;400.</li>
+</ul></p>
+
+<p>For example, to prevent the Android Browser and {@link android.webkit.WebView} from scaling
+your web page for different screen densities, set
+the {@code target-densitydpi} viewport property to {@code device-dpi}. When you do, the page is
+not scaled. Instead, the page is displayed at a size that matches the current screen's
+density. In this case, you should also define the viewport width to match the device width, so your
+web page naturally fits the screen size. For example:</p>
+
+<pre>
+&lt;meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" /&gt;
+</pre>
+
+<p>Figure 4 shows a web page using these viewport settings&mdash;the high-density device
+now displays the page smaller because its physical pixels are smaller than those on the
+medium-density device, so no scaling occurs and the 320-pixel-wide image is drawn using exactly 320
+pixels on both screens. (This is how you should define your viewport if
+you want to customize your web page based on screen density and provide different image assets for
+different densities, <a href="#DensityCSS">with CSS</a> or
+<a href="#DensityJS">with JavaScript</a>.)</p>
+
+
+<h2 id="DensityCSS">Targeting Device Density with CSS</h2>
+
+<p>The Android Browser and {@link android.webkit.WebView} support a CSS media feature that allows
+you to create styles for specific
+screen densities&mdash;the <code>-webkit-device-pixel-ratio</code> CSS media feature. The
+value you apply to this feature should be either
+"0.75", "1", or "1.5", to indicate that the styles are for devices with low density, medium density,
+or high density screens, respectively.</p>
+
+<p>For example, you can create separate stylesheets for each density:</p>
+
+<pre>
+&lt;link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="hdpi.css" /&gt;
+&lt;link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.0)" href="mdpi.css" /&gt;
+&lt;link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 0.75)" href="ldpi.css" /&gt;
+</pre>
+
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/webapps/compare-width-devicedpi-css.png" alt="" height="300" />
+ <p class="img-caption"><strong>Figure 5.</strong> A web page with CSS that's targetted to
+specific screen densities using the {@code -webkit-device-pixel-ratio} media feature. Notice
+that the hdpi device shows a different image that's applied in CSS.</p>
+</div>
+
+<p>Or, specify the different styles in one stylesheet:</p>
+
+<pre class="no-pretty-print">
+#header {
+ background:url(medium-density-image.png);
+}
+
+&#64;media screen and (-webkit-device-pixel-ratio: 1.5) {
+ // CSS for high-density screens
+ #header {
+ background:url(high-density-image.png);
+ }
+}
+
+&#64;media screen and (-webkit-device-pixel-ratio: 0.75) {
+ // CSS for low-density screens
+ #header {
+ background:url(low-density-image.png);
+ }
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> The default style for {@code #header} applies the image
+designed for medium-density devices in order to support devices running a version of Android less
+than 2.0, which do not support the {@code -webkit-device-pixel-ratio} media feature.</p>
+
+<p>The types of styles you might want to adjust based on the screen density depend on how you've
+defined your viewport properties. To provide fully-customized styles that tailor your web page for
+each of the supported densities, you should set your viewport properties so the viewport width and
+density match the device. That is:</p>
+
+<pre>
+&lt;meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" /&gt;
+</pre>
+
+<p>This way, the Android Browser and {@link android.webkit.WebView} do not perform scaling on your
+web page and the viewport width
+matches the screen width exactly. On their own, these viewport properties create results shown in
+figure 4. However, by adding some custom CSS using the {@code -webkit-device-pixel-ratio} media
+feature, you can apply different styles. For example, figure 5 shows a web page with these viewport
+properties and also some CSS added that applies a high-resolution image for high-density
+screens.</p>
+
+
+
+<h2 id="DensityJS">Targeting Device Density with JavaScript</h2>
+
+<p>The Android Browser and {@link android.webkit.WebView} support a DOM property that allows you to
+query the density of the current
+device&mdash;the <code>window.devicePixelRatio</code> DOM property. The value of this property
+specifies the scaling factor used for the current device. For example, if the value
+of <code>window.devicePixelRatio</code> is "1.0", then the device is considered a medium density
+device and no scaling is applied by default; if the value is "1.5", then the device is
+considered a high density device and the page is scaled 1.5x by default; if the value
+is "0.75", then the device is considered a low density device and the page is scaled
+0.75x by default. Of course, the scaling that the Android Browser and {@link android.webkit.WebView}
+apply is based on the web page's
+target density&mdash;as described in the section about <a href="#ViewportDensity">Defining the
+viewport target density</a>, the default target is medium-density, but you can change the
+target to affect how your web page is scaled for different screen densities.</p>
+
+<p>For example, here's how you can query the device density with JavaScript:</p>
+
+<pre>
+if (window.devicePixelRatio == 1.5) {
+ alert("This is a high-density screen");
+} else if (window.devicePixelRation == 0.75) {
+ alert("This is a low-density screen");
+}
+</pre>
+
+
+
+
+
+
+
diff --git a/docs/html/guide/webapps/webview.jd b/docs/html/guide/webapps/webview.jd
new file mode 100644
index 0000000..ed28f21
--- /dev/null
+++ b/docs/html/guide/webapps/webview.jd
@@ -0,0 +1,328 @@
+page.title=Building Web Apps in WebView
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>Quickview</h2>
+<ul>
+ <li>Use {@link android.webkit.WebView} to display web pages in your Android application
+layout</li>
+ <li>You can create interfaces from your JavaScript to your client-side Android code</li>
+</ul>
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#AddingWebView">Adding a WebView to Your Application</a></li>
+ <li><a href="#UsingJavaScript">Using JavaScript in WebView</a>
+ <ol>
+ <li><a href="#EnablingJavaScript">Enabling JavaScript</a></li>
+ <li><a href="#BindingJavaScript">Binding JavaScript code to Android code</a></li>
+ </ol>
+ </li>
+ <li><a href="#HandlingNavigation">Handling Page Navigation</a>
+ <ol>
+ <li><a href="#NavigatingHistory">Navigating web page history</a></li>
+ </ol>
+ </li>
+</ol>
+
+<h2>Key classes</h2>
+<ol>
+ <li>{@link android.webkit.WebView}</li>
+ <li>{@link android.webkit.WebSettings}</li>
+ <li>{@link android.webkit.WebViewClient}</li>
+</ol>
+
+<h2>Related tutorials</h2>
+<ol>
+ <li><a href="{@docRoot}resources/tutorials/views/hello-webview.html">Web View</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>If you want to deliver a web application (or just a web page) as a part of a client application,
+you can do it using {@link android.webkit.WebView}. The {@link android.webkit.WebView} class is an
+extension of Android's {@link android.view.View} class that allows you to display web pages as a
+part of your activity layout. It does <em>not</em> include any features of a fully developed web
+browser, such as navigation controls or an address bar. All that {@link android.webkit.WebView}
+does, by default, is show a web page.</p>
+
+<p>A common scenario in which using {@link android.webkit.WebView} is helpful is when you want to
+provide information in your application that you might need to update, such as an end-user agreement
+or a user guide. Within your Android application, you can create an {@link android.app.Activity}
+that contains a {@link android.webkit.WebView}, then use that to display your document that's
+hosted online.</p>
+
+<p>Another scenario in which {@link android.webkit.WebView} can help is if your application provides
+data to the user that
+always requires an Internet connection to retrieve data, such as email. In this case, you might
+find that it's easier to build a {@link android.webkit.WebView} in your Android application that
+shows a web page with all
+the user data, rather than performing a network request, then parsing the data and rendering it in
+an Android layout. Instead, you can design a web page that's tailored for Android devices
+and then implement a {@link android.webkit.WebView} in your Android application that loads the web
+page.</p>
+
+<p>This document shows you how to get started with {@link android.webkit.WebView} and how to do some
+additional things, such as handle page navigation and bind JavaScript from your web page to
+client-side code in your Android application.</p>
+
+
+
+<h2 id="AddingWebView">Adding a WebView to Your Application</h2>
+
+<p>To add a {@link android.webkit.WebView} to your Application, simply include the {@code
+&lt;WebView&gt;} element in your activity layout. For example, here's a layout file in which the
+{@link android.webkit.WebView} fills the screen:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;WebView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/webview"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+/&gt;
+</pre>
+
+<p>To load a web page in the {@link android.webkit.WebView}, use {@link
+android.webkit.WebView#loadUrl(String) loadUrl()}. For example:</p>
+
+<pre>
+WebView myWebView = (WebView) findViewById(R.id.webview);
+myWebView.loadUrl("http://www.example.com");
+</pre>
+
+<p>Before this will work, however, your application must have access to the Internet. To get
+Internet access, request the {@link android.Manifest.permission#INTERNET} permission in your
+manifest file. For example:</p>
+
+<pre>
+&lt;manifest ... &gt;
+ &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
+ ...
+&lt;/manifest&gt;
+</pre>
+
+<p>That's all you need for a basic {@link android.webkit.WebView} that displays a web page.</p>
+
+
+
+
+<h2 id="UsingJavaScript">Using JavaScript in WebView</h2>
+
+<p>If the web page you plan to load in your {@link android.webkit.WebView} use JavaScript, you
+must enable JavaScript for your {@link android.webkit.WebView}. Once JavaScript is enabled, you can
+also create interfaces between your application code and your JavaScript code.</p>
+
+
+<h3 id="EnablingJavaScript">Enabling JavaScript</h3>
+
+<p>JavaScript is disabled in a {@link android.webkit.WebView} by default. You can enable it
+through the {@link
+android.webkit.WebSettings} attached to your {@link android.webkit.WebView}. You can retrieve {@link
+android.webkit.WebSettings} with {@link android.webkit.WebView#getSettings()}, then enable
+JavaScript with {@link android.webkit.WebSettings#setJavaScriptEnabled(boolean)
+setJavaScriptEnabled()}.</p>
+
+<p>For example:</p>
+
+<pre>
+WebView myWebView = (WebView) findViewById(R.id.webview);
+WebSettings webSettings = myWebView.getSettings();
+webSettings.setJavaScriptEnabled(true);
+</pre>
+
+<p>{@link android.webkit.WebSettings} provides access to a variety of other settings that you might
+find useful. For example, if you're developing a web application
+that's designed specifically for the {@link android.webkit.WebView} in your Android application,
+then you can define a
+custom user agent string with {@link android.webkit.WebSettings#setUserAgentString(String)
+setUserAgentString()}, then query the custom user agent in your web page to verify that the
+client requesting your web page is actually your Android application.</p>
+
+from your Android SDK {@code tools/} directory
+<h3 id="BindingJavaScript">Binding JavaScript code to Android code</h3>
+
+<p>When developing a web application that's designed specifically for the {@link
+android.webkit.WebView} in your Android
+application, you can create interfaces between your JavaScript code and client-side Android code.
+For example, your JavaScript code can call a method in your Android code to display a {@link
+android.app.Dialog}, instead of using JavaScript's {@code alert()} function.</p>
+
+<p>To bind a new interface between your JavaScript and Android code, call {@link
+android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()}, passing it
+a class instance to bind to your JavaScript and an interface name that your JavaScript can call to
+access the class.</p>
+
+<p>For example, you can include the following class in your Android application:</p>
+
+<pre>
+public class JavaScriptInterface {
+ Context mContext;
+
+ /** Instantiate the interface and set the context */
+ JavaScriptInterface(Context c) {
+ mContext = c;
+ }
+
+ /** Show a toast from the web page */
+ public void showToast(String toast) {
+ Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
+ }
+}
+</pre>
+
+<p>In this example, the {@code JavaScriptInterface} class allows the web page to create a {@link
+android.widget.Toast} message, using the {@code showToast()} method.</p>
+
+<p>You can bind this class to the JavaScript that runs in your {@link android.webkit.WebView} with
+{@link android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} and
+name the interface {@code Android}. For example:</p>
+
+<pre>
+WebView webView = (WebView) findViewById(R.id.webview);
+webView.addJavascriptInterface(new JavaScriptInterface(this), "Android");
+</pre>
+
+<p>This creates an interface called {@code Android} for JavaScript running in the {@link
+android.webkit.WebView}. At this point, your web application has access to the {@code
+JavaScriptInterface} class. For example, here's some HTML and JavaScript that creates a toast
+message using the new interface when the user clicks a button:</p>
+
+<pre>
+&lt;input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /&gt;
+
+&lt;script type="text/javascript"&gt;
+ function showAndroidToast(toast) {
+ Android.showToast(toast);
+ }
+&lt;/script&gt;
+</pre>
+
+<p>There's no need to initialize the {@code Android} interface from JavaScript. The {@link
+android.webkit.WebView} automatically makes it
+available to your web page. So, at the click of the button, the {@code showAndroidToast()}
+function uses the {@code Android} interface to call the {@code JavaScriptInterface.showToast()}
+method.</p>
+
+<p class="note"><strong>Note:</strong> The object that is bound to your JavaScript runs in
+another thread and not in the thread in which it was constructed.</p>
+
+<p class="caution"><strong>Caution:</strong> Using {@link
+android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} allows
+JavaScript to control your Android application. This can be a very useful feature or a dangerous
+security issue. When the HTML in the {@link android.webkit.WebView} is untrustworthy (for example,
+part or all of the HTML
+is provided by an unknown person or process), then an attacker can include HTML that executes
+your client-side code and possibly any code of the attacker's choosing. As such, you should not use
+{@link android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} unless
+you wrote all of the HTML and JavaScript that appears in your {@link android.webkit.WebView}. You
+should also not allow the user to
+navigate to other web pages that are not your own, within your {@link android.webkit.WebView}
+(instead, allow the user's
+default browser application to open foreign links&mdash;by default, the user's web browser
+opens all URL links, so be careful only if you handle page navigation as described in the
+following section).</p>
+
+
+
+
+<h2 id="HandlingNavigation">Handling Page Navigation</h2>
+
+<p>When the user clicks a link from a web page in your {@link android.webkit.WebView}, the default
+behavior is
+for Android to launch an application that handles URLs. Usually, the default web browser opens and
+loads the destination URL. However, you can override this behavior for your {@link
+android.webkit.WebView},
+so links open within your {@link android.webkit.WebView}. You can then allow the user to navigate
+backward and forward through their web page history that's maintained by your {@link
+android.webkit.WebView}.</p>
+
+<p>To open links clicked by the user, simply provide a {@link
+android.webkit.WebViewClient} for your {@link android.webkit.WebView}, using {@link
+android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient()}. For example:</p>
+
+<pre>
+WebView myWebView = (WebView) findViewById(R.id.webview);
+myWebView.{@link android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient}(new WebViewClient());
+</pre>
+
+<p>That's it. Now all links the user clicks load in your {@link android.webkit.WebView}.</p>
+
+<p>If you want more control over where a clicked link load, create your own {@link
+android.webkit.WebViewClient} that overrides the {@link
+android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String)
+shouldOverrideUrlLoading()} method. For example:</p>
+
+<pre>
+private class MyWebViewClient extends WebViewClient {
+ &#64;Override
+ public boolean {@link android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String) shouldOverrideUrlLoading}(WebView view, String url) {
+ if (Uri.parse(url).getHost().equals("www.example.com")) {
+ // This is my web site, so do not override; let my WebView load the page
+ return false;
+ }
+ // Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ startActivity(intent);
+ return true;
+ }
+}
+</pre>
+
+<p>Then create an instance of this new {@link android.webkit.WebViewClient} for the {@link
+android.webkit.WebView}:</p>
+
+<pre>
+WebView myWebView = (WebView) findViewById(R.id.webview);
+myWebView.{@link android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient}(new MyWebViewClient());
+</pre>
+
+<p>Now when the user clicks a link, the system calls
+{@link android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String)
+shouldOverrideUrlLoading()}, which checks whether the URL host matches a specific domain (as defined
+above). If it does match, then the method returns false in order to <em>not</em> override the URL
+loading (it allows the {@link android.webkit.WebView} to load the URL as usual). If the URL host
+does not match, then an {@link android.content.Intent} is created to
+launch the default Activity for handling URLs (which resolves to the user's default web
+browser).</p>
+
+
+
+
+<h3 id="NavigatingHistory">Navigating web page history</h3>
+
+<p>When your {@link android.webkit.WebView} overrides URL loading, it automatically accumulates a
+history of visited web
+pages. You can navigate backward and forward through the history with {@link
+android.webkit.WebView#goBack()} and {@link android.webkit.WebView#goForward()}.</p>
+
+<p>For example, here's how your {@link android.app.Activity} can use the device BACK key to navigate
+backward:</p>
+
+<pre>
+&#64;Override
+public boolean {@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown}(int keyCode, KeyEvent event) {
+ // Check if the key event was the BACK key and if there's history
+ if ((keyCode == KeyEvent.KEYCODE_BACK) &amp;&amp; myWebView.{@link android.webkit.WebView#canGoBack() canGoBack}() {
+ myWebView.{@link android.webkit.WebView#goBack() goBack}();
+ return true;
+ }
+ // If it wasn't the BACK key or there's no web page history, bubble up to the default
+ // system behavior (probably exit the activity)
+ return super.onKeyDown(keyCode, event);
+}
+</pre>
+
+<p>The {@link android.webkit.WebView#canGoBack()} method returns
+true if there is actually web page history for the user to visit. Likewise, you can use {@link
+android.webkit.WebView#canGoForward()} to check whether there is a forward history. If you don't
+perform this check, then once the user reaches the end of the history, {@link
+android.webkit.WebView#goBack()} or {@link android.webkit.WebView#goForward()} does nothing.</p>
+
+
+
+
+
+
diff --git a/docs/html/images/admin/device-admin-activate-prompt.png b/docs/html/images/admin/device-admin-activate-prompt.png
new file mode 100755
index 0000000..fd001bd
--- /dev/null
+++ b/docs/html/images/admin/device-admin-activate-prompt.png
Binary files differ
diff --git a/docs/html/images/admin/device-admin-app.png b/docs/html/images/admin/device-admin-app.png
new file mode 100755
index 0000000..d966a28
--- /dev/null
+++ b/docs/html/images/admin/device-admin-app.png
Binary files differ
diff --git a/docs/html/images/axis_device.png b/docs/html/images/axis_device.png
new file mode 100644
index 0000000..f1f666a
--- /dev/null
+++ b/docs/html/images/axis_device.png
Binary files differ
diff --git a/docs/html/images/axis_globe.png b/docs/html/images/axis_globe.png
new file mode 100644
index 0000000..dccb58b
--- /dev/null
+++ b/docs/html/images/axis_globe.png
Binary files differ
diff --git a/docs/html/images/axis_globe_inverted.png b/docs/html/images/axis_globe_inverted.png
new file mode 100644
index 0000000..bd78c7f
--- /dev/null
+++ b/docs/html/images/axis_globe_inverted.png
Binary files differ
diff --git a/docs/html/images/developing/avd-dialog.png b/docs/html/images/developing/avd-dialog.png
new file mode 100755
index 0000000..693aa42
--- /dev/null
+++ b/docs/html/images/developing/avd-dialog.png
Binary files differ
diff --git a/docs/html/images/developing/lib-migration-0.png b/docs/html/images/developing/lib-migration-0.png
new file mode 100644
index 0000000..226b0a5
--- /dev/null
+++ b/docs/html/images/developing/lib-migration-0.png
Binary files differ
diff --git a/docs/html/images/developing/lib-migration-1.png b/docs/html/images/developing/lib-migration-1.png
new file mode 100644
index 0000000..f413dab
--- /dev/null
+++ b/docs/html/images/developing/lib-migration-1.png
Binary files differ
diff --git a/docs/html/images/developing/lib-migration-2.png b/docs/html/images/developing/lib-migration-2.png
new file mode 100644
index 0000000..0aa5849
--- /dev/null
+++ b/docs/html/images/developing/lib-migration-2.png
Binary files differ
diff --git a/docs/html/images/home/market-intl.png b/docs/html/images/home/market-intl.png
new file mode 100644
index 0000000..2bb22f1
--- /dev/null
+++ b/docs/html/images/home/market-intl.png
Binary files differ
diff --git a/docs/html/images/licensing_add_library.png b/docs/html/images/licensing_add_library.png
new file mode 100644
index 0000000..90b4435
--- /dev/null
+++ b/docs/html/images/licensing_add_library.png
Binary files differ
diff --git a/docs/html/images/licensing_arch.png b/docs/html/images/licensing_arch.png
new file mode 100644
index 0000000..ba7484a
--- /dev/null
+++ b/docs/html/images/licensing_arch.png
Binary files differ
diff --git a/docs/html/images/licensing_device_signin.png b/docs/html/images/licensing_device_signin.png
new file mode 100644
index 0000000..a4f5f88
--- /dev/null
+++ b/docs/html/images/licensing_device_signin.png
Binary files differ
diff --git a/docs/html/images/licensing_flow.png b/docs/html/images/licensing_flow.png
new file mode 100644
index 0000000..b33119e
--- /dev/null
+++ b/docs/html/images/licensing_flow.png
Binary files differ
diff --git a/docs/html/images/licensing_gapis_8.png b/docs/html/images/licensing_gapis_8.png
new file mode 100644
index 0000000..43ad262
--- /dev/null
+++ b/docs/html/images/licensing_gapis_8.png
Binary files differ
diff --git a/docs/html/images/licensing_package.png b/docs/html/images/licensing_package.png
new file mode 100644
index 0000000..5da5632
--- /dev/null
+++ b/docs/html/images/licensing_package.png
Binary files differ
diff --git a/docs/html/images/licensing_public_key.png b/docs/html/images/licensing_public_key.png
new file mode 100644
index 0000000..1630209
--- /dev/null
+++ b/docs/html/images/licensing_public_key.png
Binary files differ
diff --git a/docs/html/images/licensing_test_response.png b/docs/html/images/licensing_test_response.png
new file mode 100644
index 0000000..ead2152
--- /dev/null
+++ b/docs/html/images/licensing_test_response.png
Binary files differ
diff --git a/docs/html/images/location/content-tagging.png b/docs/html/images/location/content-tagging.png
new file mode 100644
index 0000000..d58bfee
--- /dev/null
+++ b/docs/html/images/location/content-tagging.png
Binary files differ
diff --git a/docs/html/images/location/getting-location.png b/docs/html/images/location/getting-location.png
new file mode 100644
index 0000000..a5905ec
--- /dev/null
+++ b/docs/html/images/location/getting-location.png
Binary files differ
diff --git a/docs/html/images/location/where-to-go.png b/docs/html/images/location/where-to-go.png
new file mode 100644
index 0000000..59f5983
--- /dev/null
+++ b/docs/html/images/location/where-to-go.png
Binary files differ
diff --git a/docs/html/images/resources/clip.png b/docs/html/images/resources/clip.png
new file mode 100644
index 0000000..9196b3f
--- /dev/null
+++ b/docs/html/images/resources/clip.png
Binary files differ
diff --git a/docs/html/images/resources/layers.png b/docs/html/images/resources/layers.png
new file mode 100644
index 0000000..f7e6929
--- /dev/null
+++ b/docs/html/images/resources/layers.png
Binary files differ
diff --git a/docs/html/images/screens_support/screens-ranges.png b/docs/html/images/screens_support/screens-ranges.png
new file mode 100644
index 0000000..dce6264
--- /dev/null
+++ b/docs/html/images/screens_support/screens-ranges.png
Binary files differ
diff --git a/docs/html/images/sdk_manager_packages.png b/docs/html/images/sdk_manager_packages.png
index 463be8f..027cce7 100755
--- a/docs/html/images/sdk_manager_packages.png
+++ b/docs/html/images/sdk_manager_packages.png
Binary files differ
diff --git a/docs/html/images/testing/android_test_framework.png b/docs/html/images/testing/android_test_framework.png
index 6f80530..459975c 100755
--- a/docs/html/images/testing/android_test_framework.png
+++ b/docs/html/images/testing/android_test_framework.png
Binary files differ
diff --git a/docs/html/images/testing/eclipse_test_results.png b/docs/html/images/testing/eclipse_test_results.png
new file mode 100644
index 0000000..105e149
--- /dev/null
+++ b/docs/html/images/testing/eclipse_test_results.png
Binary files differ
diff --git a/docs/html/images/testing/eclipse_test_run_failure.png b/docs/html/images/testing/eclipse_test_run_failure.png
new file mode 100644
index 0000000..8111127
--- /dev/null
+++ b/docs/html/images/testing/eclipse_test_run_failure.png
Binary files differ
diff --git a/docs/html/images/testing/test_framework.png b/docs/html/images/testing/test_framework.png
new file mode 100644
index 0000000..fbc5fc2
--- /dev/null
+++ b/docs/html/images/testing/test_framework.png
Binary files differ
diff --git a/docs/html/images/webapps/compare-default.png b/docs/html/images/webapps/compare-default.png
new file mode 100644
index 0000000..129cb33
--- /dev/null
+++ b/docs/html/images/webapps/compare-default.png
Binary files differ
diff --git a/docs/html/images/webapps/compare-initialscale-devicedpi.png b/docs/html/images/webapps/compare-initialscale-devicedpi.png
new file mode 100644
index 0000000..3b0fb6a
--- /dev/null
+++ b/docs/html/images/webapps/compare-initialscale-devicedpi.png
Binary files differ
diff --git a/docs/html/images/webapps/compare-initialscale.png b/docs/html/images/webapps/compare-initialscale.png
new file mode 100644
index 0000000..09314bb
--- /dev/null
+++ b/docs/html/images/webapps/compare-initialscale.png
Binary files differ
diff --git a/docs/html/images/webapps/compare-width-devicedpi-css.png b/docs/html/images/webapps/compare-width-devicedpi-css.png
new file mode 100644
index 0000000..3efa386
--- /dev/null
+++ b/docs/html/images/webapps/compare-width-devicedpi-css.png
Binary files differ
diff --git a/docs/html/images/webapps/compare-width400.png b/docs/html/images/webapps/compare-width400.png
new file mode 100644
index 0000000..d654381
--- /dev/null
+++ b/docs/html/images/webapps/compare-width400.png
Binary files differ
diff --git a/docs/html/images/webapps/webapps.png b/docs/html/images/webapps/webapps.png
new file mode 100644
index 0000000..6ad6205
--- /dev/null
+++ b/docs/html/images/webapps/webapps.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 01940e8..1302188 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -11,16 +11,18 @@ home=true
</div><!-- end homeTitle -->
<div id="announcement-block">
<!-- total max width is 520px -->
- <img src="{@docRoot}images/home/io-logo.png" alt="Google IO
-2010" width="200" height="41" style="padding:22px 12px;"/>
+ <img src="{@docRoot}images/home/market-intl.png" alt="Android
+Market" width="104" height="120" style="padding:10px 60px 5px" />
<div id="announcement" style="width:295px">
-<p>Thanks to everyone who visited us at Google I/O in San Francisco! Stay tuned for
-videos and slides from the Android sessions, which will be posted at the Google I/O web site.</p><p><a
-href="http://code.google.com/events/io/2010/sessions.html#Android">Learn more &raquo;</a></p>
+<p>We're pleased to announce that paid apps are available in more locations of the world! Developers
+from 20 more locations can now sell paid apps on Android Market. Users in more locations will also
+soon be able to purchase apps.</p><p><a
+href="http://android-developers.blogspot.com/2010/09/more-countries-more-sellers-more-buyers.html">
+Learn more &raquo;</a></p>
</div> <!-- end annoucement -->
</div> <!-- end annoucement-block -->
</div><!-- end topAnnouncement -->
- <div id="carouselMain" style="height:200px"> <!-- this height can be
+ <div id="carouselMain" style="height:205px"> <!-- this height can be
adjusted based on the content height -->
</div>
<div class="clearer"></div>
@@ -127,14 +129,14 @@ href="{@docRoot}resources/dashboard/platform-versions.html">Learn more &raquo;</
'sdk': {
'layout':"imgLeft",
'icon':"sdk-small.png",
- 'name':"Android 2.2",
- 'img':"froyo-android.png",
- 'title':"Get Android 2.2!",
- 'desc': "<p>The Android 2.2 platform is now available for the Android SDK, along with new "
-+ "tools, documentation, and a new NDK. "
-+ "For information about new features and APIs, read the "
-+ "<a href='{@docRoot}sdk/android-2.2.html'>version notes</a>.</p>"
-+ "<p>If you have an existing SDK, add Android 2.2 as an "
+ 'name':"Android 2.3",
+ 'img':"gingerdroid.png",
+ 'title':"Android 2.3 is here!",
+ 'desc': "<p>Android 2.3 is now available for the Android SDK. In addition, new "
++ "tools and documentation are available, plus a new NDK that offers more than ever. "
++ "For more information about what's in Android 2.3, read the "
++ "<a href='{@docRoot}sdk/android-2.3.html'>version notes</a>.</p>"
++ "<p>If you have an existing SDK, add Android 2.3 as an "
+ "<a href='{@docRoot}sdk/adding-components.html'>SDK "
+ "component</a>. If you're new to Android, install the "
+ "<a href='{@docRoot}sdk/index.html'>SDK starter package</a>."
@@ -163,12 +165,11 @@ href="{@docRoot}resources/dashboard/platform-versions.html">Learn more &raquo;</
'img':"devphone-large.png",
'title':"Android Dev Phones",
'desc': "<p>Run and debug your Android applications directly on one of these "
- + "device. Modify and rebuild the Android operating system, and flash it onto "
- + "the phone. The Android Dev Phones are carrier independent, and available for "
- + "purchase by any developer registered with <a "
- + "href='http://market.android.com/publish'>Android Market</a>.</p><p><a "
- + "href='/guide/developing/device.html#dev-phone-1'>Learn more about the "
- + "Android Dev Phones &raquo;</a></p>"
+ + "devices. Modify and rebuild the Android operating system, and flash it onto "
+ + "the phone. The Android Dev Phones are carrier-independent, and available for "
+ + "purchase by developers through their Android Market publisher accounts.</p><p> "
+ + "<a href='http://market.android.com/publish'>Visit Android Market "
+ + "to learn more &raquo;</a></p>"
},
'mapskey': {
diff --git a/docs/html/resources/articles/layout-tricks-reuse.jd b/docs/html/resources/articles/layout-tricks-reuse.jd
index 072ba89..396e212 100644
--- a/docs/html/resources/articles/layout-tricks-reuse.jd
+++ b/docs/html/resources/articles/layout-tricks-reuse.jd
@@ -53,12 +53,24 @@ attributes of the included layout. The above example shows that you can use
layout; it will also override the id of the included layout if one is defined.
Similarly, you can override all the layout parameters. This means that any
<code>android:layout_*</code> attribute can be used with the <code>&lt;include
-/&gt;</code> tag. Here is an example:</p>
+/&gt;</code> tag. Here is an example in
+which the same layout is included twice, but only the first one overrides the layout properties:</p>
-<pre class="prettyprint">&lt;include android:layout_width="fill_parent" layout="@layout/image_holder" /&gt;
-&lt;include android:layout_width="256dip" layout="@layout/image_holder" /&gt;
+<pre>
+&lt;!-- override the layout height and width --&gt;
+&lt;include layout="@layout/image_holder"
+ android:layout_height="fill_parent"
+ android:layout_width="fill_parent" /&gt;
+&lt;!-- do not override layout dimensions; inherit them from image_holder --&gt;
+&lt;include layout="@layout/image_holder" /&gt;
</pre>
+<p class="caution"><strong>Caution:</strong> If you want to override the layout dimensions,
+you must override both <code>android:layout_height</code> and
+<code>android:layout_width</code>&mdash;you cannot override only the height or only the width.
+If you override only one, it will not take effect. (Other layout properties, such as weight,
+are still inherited from the source layout.)</p>
+
<p>This tag is particularly useful when you need to customize only part of your
UI depending on the device's configuration. For instance, the main layout of
your activity can be placed in the <code>layout/</code> directory and can
diff --git a/docs/html/resources/community-groups.jd b/docs/html/resources/community-groups.jd
index 6d59648..599c4ae 100644
--- a/docs/html/resources/community-groups.jd
+++ b/docs/html/resources/community-groups.jd
@@ -87,27 +87,27 @@ phrasing your questions, read <a href="http://www.catb.org/%7Eesr/faqs/smart-que
<h3 id="ApplicationDeveloperLists">Application developer mailing lists</h3>
<ul>
<li><strong><a href="http://groups.google.com/group/android-developers">android-developers</a></strong>
-(<a href="mailto:android-developers-subscribe@googlegroups.com">subscribe via email</a>)<br>
+(<a href="http://groups.google.com/group/android-developers/subscribe">subscribe</a>)<br>
You're now an experienced Android application developer. You've grasped the basics of Android app development, you're comfortable using the SDK, now you want to move to advanced topics. Get help here with troubleshooting applications, advice on implementation, and strategies for improving your application's performance and user experience. This is the not the right place to discuss user issues (use android-discuss for that) or beginner questions with the Android SDK (use android-beginners for that).
</li>
<li><strong><a href="http://groups.google.com/group/android-discuss">android-discuss</a></strong>
-(<a href="mailto:android-discuss-subscribe@googlegroups.com">subscribe via email</a>)<br>
+(<a href="http://groups.google.com/group/android-discuss/subscribe">subscribe</a>)<br>
The "water cooler" of Android discussion. You can discuss just about anything Android-related here, ideas for the Android platform, announcements about your applications, discussions about Android devices, community resources... As long as your discussion is related to Android, it's on-topic here. However, if you have a discussion here that could belong on another list, you are probably not reaching all of your target audience here and may want to consider shifting to a more targeted list.
</li>
<li><strong><a href="http://groups.google.com/group/android-ndk">android-ndk</a></strong>
-(<a href="mailto:android-ndk-subscribe@googlegroups.com">subscribe via email</a>)<br>
+(<a href="http://groups.google.com/group/android-ndk/subscribe">subscribe</a>)<br>
A place for discussing the Android NDK and topics related to using native code in Android applications.
</li>
<li><strong><a href="http://groups.google.com/group/android-security-discuss">android-security-discuss</a></strong>
-(<a href="mailto:android-security-discuss-subscribe@googlegroups.com">subscribe via email</a>)<br>
+(<a href="http://groups.google.com/group/android-security-discuss/subscribe">subscribe</a>)<br>
A place for open discussion on secure development, emerging security concerns, and best practices for and by android developers. Please don't disclose vulnerabilities directly on this list, you'd be putting all Android users at risk.
</li>
<li><strong><a href="http://groups.google.com/group/android-security-announce">android-security-announce</a></strong>
-(<a href="mailto:android-security-announce-subscribe@googlegroups.com">subscribe via email</a>)<br>
+(<a href="http://groups.google.com/group/android-security-announce/subscribe">subscribe</a>)<br>
A low-volume group for security-related announcements by the Android Security Team.
</li>
</ul>
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index 5e75105..cef057e 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -43,29 +43,72 @@ the development of your application features for the devices currently in
the hands of users. For information about how to target your application to devices based on
platform version, see <a href="{@docRoot}guide/appendix/api-levels.html">API Levels</a>.</p>
-<p class="note"><strong>Note:</strong> This data is based on the number
-of Android devices that have accessed Android Market within a 14-day period
-ending on the data collection date noted below.</p>
+
+<h3 id="Current">Current Distribution</h3>
+
+<p>The following pie chart and table is based on the number of Android devices that have accessed
+Android Market within a 14-day period ending on the data collection date noted below.</p>
<div class="dashboard-panel">
-<img alt="" width="460" height="250"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.1,24.6,25.0,0.1,0.3,50.0&chl=
-Android%201.1|Android%201.5|Android%201.6|Android%202.0|Android%202.0.1|Android%202.1&chco=c4df9b,
+<img alt="" height="250" width="460"
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:7.9,15.0,0.1,40.8,36.2&chl=
+Android%201.5|Android%201.6|Other*|Android%202.1|Android%202.2&chco=c4df9b,
6fad0c" />
<table>
<tr>
- <th>Android Platform</th>
- <th>Percent of Devices</th>
+ <th>Platform</th>
+ <th>API Level</th>
+ <th>Distribution</th>
</tr>
-<tr><td>Android 1.1</td><td>0.1%</td></tr>
-<tr><td>Android 1.5</td><td>24.6%</td></tr>
-<tr><td>Android 1.6</td><td>25.0%</td></tr>
-<tr><td>Android 2.0</td><td>0.1%</td></tr>
-<tr><td>Android 2.0.1</td><td>0.3%</td></tr>
-<tr><td>Android 2.1</td><td>50.0%</td></tr>
+<tr><td>Android 1.5</td><td>3</td><td>7.9%</td></tr>
+<tr><td>Android 1.6</td><td>4</td><td>15.0%</td></tr>
+<tr><td>Android 2.1</td><td>7</td><td>40.8%</td></tr>
+<tr><td>Android 2.2</td><td>8</td><td>36.2%</td></tr>
</table>
-<p><em>Data collected during two weeks ending on June 16, 2010</em></p>
-</div>
+
+<p><em>Data collected during two weeks ending on November 1, 2010</em></p>
+<p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
+
+</div><!-- end dashboard-panel -->
+
+
+<h3 id="Historical">Historical Distribution</h3>
+
+<p>The following stacked line graph provides a history of the relative number of
+active Android devices running different versions of the Android platform. It also provides a
+valuable perspective of how many devices your application is compatible with, based on the
+platform version.</p>
+
+<p>Notice that the platform versions are stacked on top of each other with the oldest active
+version at the top. This format indicates the total percent of active devices that are compatible
+with a given version of Android. For example, if you develop your application for
+the version that is at the very top of the chart, then your application is
+compatible with 100% of active devices (and all future versions), because all Android APIs are
+forward compatible. Or, if you develop your application for a version lower on the chart,
+then it is currently compatible with the percentage of devices indicated on the y-axis, where the
+line for that version meets the y-axis on the right.</p>
+
+<p>Each dataset in the timeline is based on the number of Android devices that accessed
+Android Market within a 14-day period ending on the date indicated on the x-axis.</p>
+
+<div class="dashboard-panel">
+
+<img alt="" height="250" width="660" style="padding:5px;background:#fff"
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,y,r&chxr=0,0,12|1,0,100|2,0,100&
+chxl=0%3A%7C2010/05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C09/15%7C10/
+01%7C10/15%7C2010/11/01%7C1%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C2%3A%7C0%25%7C25%25%7C50%25
+%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:98.9,99.3,100.3,100.8,99.7,99.
+8,99.8,99.7,99.8,99.9,99.9,99.9,99.9|61.6,63.1,72.7,76.1,78.4,80.9,84.3,86.5,87.9,89.2,90.2,91.1,92.
+0|32.0,34.9,45.9,51.0,54.9,58.8,64.0,68.1,70.3,72.1,73.8,75.3,77.0|0.0,0.0,0.8,1.2,1.8,3.3,4.3,11.3,
+27.8,32.1,33.4,34.5,36.2&chm=tAndroid%201.5,7caa36,0,0,15,,t::-5|b,c3df9b,0,1,0|tAndroid%201.6,
+5b831d,1,0,15,,t::-5|b,aadb5e,1,2,0|tAndroid%202.1,38540b,2,0,15,,t::-5|b,91da1e,2,3,0|tAndroid%202.
+2,131d02,3,7,15,,t::-5|B,6fad0c,3,4,0&chg=7,25&chdl=Android%201.5|Android%201.6|Android%202.1|
+Android%202.2&chco=add274,94d134,73ad18,507d08" />
+
+<p><em>Last historical dataset collected during two weeks ending on November 1, 2010</em></p>
+
+
+</div><!-- end dashboard-panel -->
diff --git a/docs/html/resources/dashboard/screens.jd b/docs/html/resources/dashboard/screens.jd
index f8130ea..90f3f1a 100644
--- a/docs/html/resources/dashboard/screens.jd
+++ b/docs/html/resources/dashboard/screens.jd
@@ -49,8 +49,8 @@ ending on the data collection date noted below.</p>
<div class="dashboard-panel">
<img alt="" width="460" height="250"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:1.1,57.8,41.0&chl=Small%20/%20ldpi|
-Normal%20/%20mdpi|Normal%20/%20hdpi&chco=c4df9b,6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:2.3,0.4,45.9,51.2&chl=Small%20/%
+20ldpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Normal%20/%20hdpi&chco=c4df9b,6fad0c" />
<table>
<tr>
@@ -60,14 +60,14 @@ Normal%20/%20mdpi|Normal%20/%20hdpi&chco=c4df9b,6fad0c" />
<th scope="col">High Density</th>
</tr>
<tr><th scope="row">Small</th>
-<td class='cent hi'>1.1%</td>
+<td class='cent hi'>2.3%</td>
<td></td>
<td></td>
</tr>
<tr><th scope="row">Normal</th>
-<td></td>
-<td class='cent hi'>57.8%</td>
-<td class='cent hi'>41.0%</td>
+<td class='cent '>0.4%</td>
+<td class='cent hi'>45.9%</td>
+<td class='cent hi'>51.2%</td>
</tr>
<tr><th scope="row">Large</th>
<td></td>
@@ -76,6 +76,6 @@ Normal%20/%20mdpi|Normal%20/%20hdpi&chco=c4df9b,6fad0c" />
</tr>
</table>
-<p><em>Data collected during two weeks ending on June 16, 2010</em></p>
+<p><em>Data collected during two weeks ending on August 2, 2010</em></p>
</div>
diff --git a/docs/html/resources/faq/commontasks.jd b/docs/html/resources/faq/commontasks.jd
index 2f09b00..9c32e9c 100644
--- a/docs/html/resources/faq/commontasks.jd
+++ b/docs/html/resources/faq/commontasks.jd
@@ -158,7 +158,7 @@ It is not necessary to put external JARs in the assets folder.
<ul>
<li>Create an {@link android.app.Dialog app.Dialog} class </li>
<li>Create an {@link android.app.AlertDialog app.AlertDialog} class </li>
- <li>Set the {@link android.R.style#Theme_Dialog} <em>theme</em> attribute to <code>&#064;android:style/Theme.Dialog</code>
+ <li>Set the {@link android.R.style#Theme_Dialog} <em>theme</em> attribute to <code>&#64;android:style/Theme.Dialog</code>
in your AndroidManifest.xml file. For example:
<pre>&lt;activity class=&quot;AddRssItem&quot; android:label=&quot;Add an item&quot; android:theme=&quot;&#064;android:style/Theme.Dialog&quot;/&gt;</pre></li>
</ul>
diff --git a/docs/html/resources/faq/framework.jd b/docs/html/resources/faq/framework.jd
index f4b8db0..4a7a3fc 100644
--- a/docs/html/resources/faq/framework.jd
+++ b/docs/html/resources/faq/framework.jd
@@ -68,12 +68,17 @@ Preferences</a> storage mechanism.</p>
<p>For sharing complex non-persistent user-defined objects for short
duration, the following approaches are recommended:
</p>
- <h4>The android.app.Application class</h4>
- <p>The android.app.Application is a base class for those who need to
-maintain global application state. It can be accessed via
-getApplication() from any Activity or Service. It has a couple of
-life-cycle methods and will be instantiated by Android automatically if
-your register it in AndroidManifest.xml.</p>
+ <h4>Singleton class</h4>
+ <p>You can take advantage of the fact that your application
+components run in the same process through the use of a singleton.
+This is a class that is designed to have only one instance. It
+has a static method with a name such as <code>getInstance()</code>
+that returns the instance; the first time this method is called,
+it creates the global instance. Because all callers get the same
+instance, they can use this as a point of interaction. For
+example activity A may retrieve the instance and call setValue(3);
+later activity B may retrieve the instance and call getValue() to
+retrieve the last set value.</p>
<h4>A public static field/method</h4>
<p>An alternate way to make data accessible across Activities/Services is to use <em>public static</em>
@@ -90,18 +95,6 @@ Long based on a counter or time stamp) to the recipient activity via
intent extras. The recipient activity retrieves the object using this
key.</p>
- <h4>A Singleton class</h4>
- <p>There are advantages to using a static Singleton, such as you can
-refer to them without casting getApplication() to an
-application-specific class, or going to the trouble of hanging an
-interface on all your Application subclasses so that your various
-modules can refer to that interface instead. </p>
-<p>But, the life cycle of a static is not well under your control; so
-to abide by the life-cycle model, the application class should initiate and
-tear down these static objects in the onCreate() and onTerminate() methods
-of the Application Class</p>
-</p>
-
<h3>Persistent Objects</h3>
<p>Even while an application appears to continue running, the system
@@ -146,15 +139,11 @@ call.</p>
<h2>If an Activity starts a remote service, is there any way for the
Service to pass a message back to the Activity?</h2>
-<p>The remote service can define a callback interface and register it with the
-clients to callback into the clients. The
-{@link android.os.RemoteCallbackList RemoteCallbackList} class provides methods to
-register and unregister clients with the service, and send and receive
-messages.</p>
-
-<p>The sample code for remote service callbacks is given in <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">ApiDemos/RemoteService</a></p>
-
+<p>See the {@link android.app.Service} documentation's for examples of
+how clients can interact with a service. You can take advantage of the
+fact that your components run in the same process to greatly simplify
+service interaction from the generic remote case, as shown by the "Local
+Service Sample". In some cases techniques like singletons may also make sense.
<a name="6" id="6"></a>
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index 52689b6..ed23c7c 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -167,14 +167,12 @@
</a></li>
<li><a href="<?cs var:toroot ?>resources/tutorials/testing/helloandroid_test.html">
<span class="en">Hello Testing</span></a>
- <span class="new">new!</span>
</li>
<li><a href="<?cs var:toroot ?>resources/tutorials/notepad/index.html">
<span class="en">Notepad Tutorial</span>
</a></li>
<li><a href="<?cs var:toroot ?>resources/tutorials/testing/activity_test.html">
<span class="en">Activity Testing</span></a>
- <span class="new">new!</span>
</li>
</ul>
</li>
@@ -204,7 +202,7 @@
</a></li>
<li><a href="<?cs var:toroot ?>resources/samples/BackupRestore/index.html">
<span class="en">Backup and Restore</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>resources/samples/BluetoothChat/index.html">
<span class="en">Bluetooth Chat</span>
</a></li>
@@ -229,6 +227,9 @@
<li><a href="<?cs var:toroot ?>resources/samples/MultiResolution/index.html">
<span class="en">Multiple Resolutions</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>resources/samples/NFCDemo/index.html">
+ <span class="en">NFCDemo</span>
+ </a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>resources/samples/NotePad/index.html">
<span class="en">Note Pad</span>
</a></li>
@@ -237,7 +238,10 @@
</a></li>
<li><a href="<?cs var:toroot ?>resources/samples/SearchableDictionary/index.html">
<span class="en">Searchable Dictionary v2</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
+ <li><a href="<?cs var:toroot ?>resources/samples/SipDemo/index.html">
+ <span class="en">SIP Demo</span>
+ </a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>resources/samples/Snake/index.html">
<span class="en">Snake</span>
</a></li>
@@ -246,16 +250,16 @@
</a></li>
<li><a href="<?cs var:toroot ?>resources/samples/Spinner/index.html">
<span class="en">Spinner</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>resources/samples/SpinnerTest/index.html">
<span class="en">SpinnerTest</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>resources/samples/TicTacToeLib/index.html">
<span class="en">TicTacToeLib</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>resources/samples/TicTacToeMain/index.html">
<span class="en">TicTacToeMain</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>resources/samples/Wiktionary/index.html">
<span class="en">Wiktionary</span>
</a></li>
diff --git a/docs/html/resources/samples/images/NfcDemo.png b/docs/html/resources/samples/images/NfcDemo.png
new file mode 100644
index 0000000..c175d12
--- /dev/null
+++ b/docs/html/resources/samples/images/NfcDemo.png
Binary files differ
diff --git a/docs/html/resources/samples/images/SipDemo.png b/docs/html/resources/samples/images/SipDemo.png
new file mode 100755
index 0000000..999bea9
--- /dev/null
+++ b/docs/html/resources/samples/images/SipDemo.png
Binary files differ
diff --git a/docs/html/resources/samples/index.jd b/docs/html/resources/samples/index.jd
index 9fc8e0b..5749728 100644
--- a/docs/html/resources/samples/index.jd
+++ b/docs/html/resources/samples/index.jd
@@ -58,6 +58,9 @@ href="{@docRoot}resources/samples/get.html">Getting the Samples</a>.</p>
<dd>A sample application that shows how to use resource directory qualifiers to
provide different resources for different screen configurations.</dd>
+ <dt><a href="NFCDemo/index.html">NFCDemo</a></dt>
+ <dd>An application for reading NFC Forum Type 2 Tags using platform NFC apis.</a>.</dd>
+
<dt><a href="NotePad/index.html">Note Pad</a></dt>
<dd>An application for saving notes. Similar (but not identical) to the
<a href="{@docRoot}resources/tutorials/notepad/index.html">Notepad tutorial</a>.</dd>
@@ -73,6 +76,10 @@ adapter).</dd>
<dd>A sample application that demonstrates Android's search framework,
including how to provide search suggestions for Quick Search Box.</dd>
+ <dt><a href="SipDemo/index.html">SIP Demo</a></dt>
+ <dd>An application that demonstrates how to make an internet-based call using the SIP
+ API.</dd>
+
<dt><a href="Snake/index.html">Snake</a></dt>
<dd>An implementation of the classic game "Snake."</dd>
diff --git a/docs/html/resources/tutorials/notepad/codelab/NotepadCodeLab.zip b/docs/html/resources/tutorials/notepad/codelab/NotepadCodeLab.zip
index 502a326..cd30f29 100644
--- a/docs/html/resources/tutorials/notepad/codelab/NotepadCodeLab.zip
+++ b/docs/html/resources/tutorials/notepad/codelab/NotepadCodeLab.zip
Binary files differ
diff --git a/docs/html/resources/tutorials/notepad/notepad-ex2.jd b/docs/html/resources/tutorials/notepad/notepad-ex2.jd
index a945a62..289b5fe 100644
--- a/docs/html/resources/tutorials/notepad/notepad-ex2.jd
+++ b/docs/html/resources/tutorials/notepad/notepad-ex2.jd
@@ -393,7 +393,11 @@ case ACTIVITY_EDIT:
<pre>setContentView(R.layout.note_edit);</pre>
</li>
<li>
- Find the edit and button components we need:
+ Change the Activity title to the "Edit Note" string:
+ <pre>setTitle(R.string.edit_note);</pre>
+ </li>
+ <li>
+ Find the {@link android.widget.EditText} and {@link android.widget.Button} components we need:
<p>These are found by the
IDs associated to them in the R class, and need to be cast to the right
type of <code>View</code> (<code>EditText</code> for the two text views,
diff --git a/docs/html/resources/tutorials/views/hello-formstuff.jd b/docs/html/resources/tutorials/views/hello-formstuff.jd
index 3dd5f21..b9f6c16 100644
--- a/docs/html/resources/tutorials/views/hello-formstuff.jd
+++ b/docs/html/resources/tutorials/views/hello-formstuff.jd
@@ -32,9 +32,19 @@ public void onCreate(Bundle savedInstanceState) {
}
</pre>
+<p>Now select which kind of form widget you'd like to create:</p>
+<ul>
+ <li><a href="#CustomButton">Custom Button</a></li>
+ <li><a href="#EditText">Edit Text</a></li>
+ <li><a href="#Checkbox">Checkbox</a></li>
+ <li><a href="#RadioButtons">Radio Buttons</a></li>
+ <li><a href="#ToggleButton">Toggle Button</a></li>
+ <li><a href="#RatingBar">Rating Bar</a></li>
+</ul>
-<h2>Custom Button</h2>
+
+<h2 id="CustomButton">Custom Button</h2>
<p>In this section, you will create a button with a custom image instead of text, using the {@link
android.widget.Button} widget and an XML file that defines three different images to use for the
@@ -111,7 +121,8 @@ defines the action to be made when the button is clicked. In this example, a
</ol>
-<h2>EditText</h2>
+
+<h2 id="EditText">Edit Text</h2>
<p>In this section, you will create a text field for user input, using the {@link
android.widget.EditText} widget. Once text has been entered into the field, the "Enter" key will
@@ -158,7 +169,8 @@ result in a carriage return in the text field).</p>
</ol>
-<h2>CheckBox</h2>
+
+<h2 id="Checkbox">Checkbox</h2>
<p>In this section, you will create a checkbox for selecting items, using the {@link
android.widget.CheckBox} widget. When the checkbox is pressed, a toast message will
@@ -209,7 +221,8 @@ use the {@link android.widget.CompoundButton#setChecked(boolean)} or {@link
android.widget.CompoundButton#toggle()} method.</p>
-<h2>RadioButton</h2>
+
+<h2 id="RadioButtons">Radio Buttons</h2>
<p>In this section, you will create two mutually-exclusive radio buttons (enabling one disables
the other), using the {@link android.widget.RadioGroup} and {@link android.widget.RadioButton}
@@ -274,7 +287,8 @@ use the {@link android.widget.CompoundButton#setChecked(boolean)} or {@link
android.widget.CompoundButton#toggle()} method.</p>
-<h2>ToggleButton</h2>
+
+<h2 id="ToggleButton">Toggle Button</h2>
<p>In this section, you'll create a button used specifically for toggling between two
states, using the {@link android.widget.ToggleButton} widget. This widget is an excellent
@@ -330,7 +344,7 @@ android.widget.CompoundButton#toggle()} method.</p>
-<h2>RatingBar</h2>
+<h2 id="RatingBar">Rating Bar</h2>
<p>In this section, you'll create a widget that allows the user to provide a rating,
with the {@link android.widget.RatingBar} widget.</p>
diff --git a/docs/html/sdk/adding-components.jd b/docs/html/sdk/adding-components.jd
index 63c577e..d2e55d8 100644
--- a/docs/html/sdk/adding-components.jd
+++ b/docs/html/sdk/adding-components.jd
@@ -6,7 +6,7 @@ page.title=Adding SDK Components
<div id="qv">
<h2>Quickview</h2>
<ul>
- <li>Use the Android SDK and AVD Manager to
+ <li>Use the Android SDK and AVD Manager to
set up your SDK and keep it up-to-date.</li>
</ul>
@@ -22,11 +22,9 @@ page.title=Adding SDK Components
</div>
</div>
-<p>Adding and updating components in your Android SDK is fast and easy. To
-perform an update, use the <strong>Android SDK and AVD Manager</strong> to
-install or update the individual SDK components that you need. The Android SDK
-and AVD Manager tool is included in the <a href="index.html">Android SDK
-download</a>.</p>
+<p>Adding and updating components in your Android SDK is fast and easy. To add or
+update the individual SDK components that you need, use the <em>Android SDK and AVD
+Manager</em> (included in the SDK Tools).</p>
<p>It only takes a couple of clicks to install individual versions of the
Android platform, new development tools, new documentation, and SDK add-ons. The
@@ -34,47 +32,26 @@ new SDK components are automatically installed into your existing SDK directory,
so you don't need to update your development environment to specify a new SDK
location.</p>
-<p>Because each version of the Android platform can be installed as an
-individual component of your SDK, you can customize your development environment
-to the Android platforms you are targetting. Testing your app on multiple
-versions of the platform is very important in order to successfully operate on
-as many devices as possible. Be sure to install each version of the Android
-platform with which your app is compatible, then test your apps on <a
-href="{@docRoot}guide/developing/tools/avd.html">AVDs</a> that run each
-platform.</p>
-
-<p>If you are just getting started and you are not sure what components to install,
-see <a href="installing.html#components">Adding Platforms and Other
-Components</a> for information. </p>
-
-<p>If you develop applications using Eclipse, you may also need to update your
-ADT plugin when you update your development tools, in order to compile against
-a new version of the platform. See the revisions listed in the <a
-href="{@docRoot}sdk/tools-notes.html">SDK Tools</a> document for ADT
-Plugin compatibility.</p>
-
-<div style="TEXT-ALIGN:left; width:600px;">
-<img src="{@docRoot}images/sdk_manager_packages.png"
-style="padding-bottom:0;margin-bottom:0;" />
-<p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0
-1em;"><strong>Figure 1.</strong> The Android SDK and AVD Manager's
-<strong>Available Packages</strong>
-panel, which shows the SDK components that are
+<p>If you're setting up your Android SDK for the first time,
+see <a href="{@docRoot}sdk/installing.html#components">Installing the SDK</a> for information about
+what components to install.</p>
+
+<p class="note"><strong>Note:</strong> If you develop in Eclipse, you might also need
+to update your ADT plugin when you update your development tools. See the revisions listed in the
+<a href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin for Eclipse</a> document.</p>
+
+<img src="{@docRoot}images/sdk_manager_packages.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> The Android SDK and AVD Manager's
+<strong>Available Packages</strong> panel, which shows the SDK components that are
available for you to download into your environment. </p>
-</div>
+</div>
<h2 id="launching">Launching the Android SDK and AVD Manager</h2>
-<p>The Android SDK and AVD Manager is the tool that you use to install and
+<p>The Android SDK and AVD Manager is the tool that you use to install and
upgrade SDK components in your development environment. </p>
-<p>You can access the tool in any of three ways:</p>
-<ul>
-<li>If you are developing in the Eclipse IDE with the ADT Plugin, you can access
-the tool directly from the Eclipse UI.</li>
-<li>On Windows only, you can launch he tool by double-clicking a script file.</li>
-<li>In all environments, you can access the tool from a command line.</li>
-</ul>
+<p>You can launch the Android SDK and AVD Manager in one of the following ways.</p>
<h4>Launching from Eclipse/ADT</h4>
@@ -83,15 +60,15 @@ follow these steps to access the Android SDK and AVD Manager tool:</p>
<ol>
<li>Open Eclipse</li>
-<li>Select <strong>Window</strong> &gt; <strong>Android SDK and AVD
+<li>Select <strong>Window</strong> &gt; <strong>Android SDK and AVD
Manager</strong>.</li>
</ol>
-<h4>Launching from the setup script (Windows only)</h4>
+<h4>Launching from the SDK Manager script (Windows only)</h4>
<p>For Windows only, the SDK includes a script that invokes the Android SDK and
-AVD Manager. To launch the tool using the script, double-click "SDK
-Setup.exe" at the root of the the SDK directory.</p>
+AVD Manager. To launch the tool using the script, double-click {@code SDK
+Manager.exe} at the root of the the SDK directory.</p>
<h4>Launching from a command line</h4>
@@ -100,39 +77,41 @@ and AVD Manager tool from the command line: </p>
<ol>
<li>Navigate to the <code>&lt;<em>sdk</em>&gt;/tools/</code> directory.</li>
-<li>Execute the {@code android} tool command with no options.
+<li>Execute the {@code android} tool command with no options.
<pre style="width:400px">$ android</pre></li>
</ol>
<h2 id="InstallingComponents">Installing SDK Components</h2>
-<p class="caution"><strong>Important:</strong> Before you install SDK components,
-we recommend that you disable any antivirus programs that may be running on
-your computer.</p>
+<p class="caution"><strong>Caution:</strong> Before you install SDK components,
+we recommend that you disable any antivirus software that may be running on
+your computer. There are cases in which antivirus software on Windows is known to interfere with the
+installation process, so we suggest you disable your antivirus until installation is
+complete.</p>
<p>Follow these steps to install new SDK components in your environment:</p>
<ol>
<li>Launch the Android SDK and AVD Manager as described in the section above.</li>
<li>Select <strong>Available Packages</strong> in the left panel.
- This will reveal all of the components that are currently available for download
+ This will reveal all of the components that are currently available for download
from the SDK repository.</li>
<li>Select the component(s) you'd like to install and click <strong>Install
- Selected</strong>. If you aren't sure which packages to select, read <a
- href="installing.html#which">Which components do I need?</a>.</li>
- <li>Verify and accept the components you want and click <strong>Install
- Accepted</strong>. The components will now be installed into your existing
- Android SDK directories.</li>
+ Selected</strong>. (If you aren't sure which packages to select, read <a
+ href="installing.html#which">Recommended Components</a>.)</li>
+ <li>Verify and accept the components you want (ensure each one is selected with a green
+checkmark) and click <strong>Install</strong>. The components will now be installed into
+your existing Android SDK directories.</li>
</ol>
-<p>New platforms are automatically saved into the
-<code>&lt;<em>sdk</em>&gt;/platforms/</code> directory of your SDK;
-new add-ons are saved in the <code>&lt;<em>sdk</em>&gt;/add-ons/</code>
-directory; samples are saved in the
-<code>&lt;<em>sdk</em>&gt;/samples/android-&lt;<em>level</em>&gt;/</code>;
+<p>New platforms are automatically saved into the
+<code>&lt;sdk&gt;/platforms/</code> directory of your SDK;
+new add-ons are saved in the <code>&lt;sdk&gt;/add-ons/</code>
+directory; samples are saved in the
+<code>&lt;sdk&gt;/samples/android-&lt;level&gt;/</code>;
and new documentation is saved in the existing
-<code>&lt;<em>sdk</em>&gt;/docs/</code> directory (old docs are replaced).</p>
+<code>&lt;sdk&gt;/docs/</code> directory (old docs are replaced).</p>
<h2 id="UpdatingComponents">Updating SDK Components</h2>
@@ -171,27 +150,32 @@ the "Downloadable SDK Components" section at left.</p>
<p>For example, there may be a dependency between the ADT Plugin for Eclipse and
the SDK Tools component. When you install the SDK Tools
-component, you would then need to upgrade to the required version of ADT (if you
-are developing in Eclipse). In this case, you would find dependencies listed in
-"Revisions" section of the <a href="{@docRoot}sdk/eclipse-adt.html#notes">ADT
-Plugin Notes</a> and <a href="{@docRoot}sdk/tools-notes.html#notes">SDK Tools
-Notes</a> documents. </p>
+component, you should also upgrade to the required version of ADT (if you
+are developing in Eclipse). In this case, the major version number for your ADT plugin should
+always match the revision number of your SDK Tools (for example, ADT 8.x requires SDK Tools r8).
+</p>
+
+<p>Also make sure that, each time you install a new version of the Android platform, you have
+the latest version of the SDK Platform-tools component. The SDK Platform-tools contain
+tools that are backward compatible with all versions of the Android platform and are
+often updated to support new features in the latest version of the Android platform.</p>
-<p>Additionally, the development tools will notify you with debug warnings
-if there is dependency that you need to address. </p>
+<p>The development tools will notify you with debug warnings if there is dependency that you need to
+address. The SDK and AVD Manager also enforces dependencies by requiring that you download any
+components that are needed by those you have selected.</p>
<h2 id="AddingSites">Adding New Sites</h2>
-<p>By default, <strong>Available Packages</strong> only shows the default
-repository site, which offers platforms, SDK tools, documentation, the
-Google APIs Add-on, and other components. You can add other sites that host
+<p>By default, <strong>Available Packages</strong> displays components available from the
+<em>Android Repository</em> and <em>Third party Add-ons</em>. You can add other sites that host
their own Android SDK add-ons, then download the SDK add-ons
-from those sites.</p>
+from those sites.</p>
<p>For example, a mobile carrier or device manufacturer might offer additional
API libraries that are supported by their own Android-powered devices. In order
-to develop using their libraries, you must install their Android SDK add-on. </p>
+to develop using their libraries, you must install their Android SDK add-on, if it's not already
+available under <em>Third party Add-ons</em>. </p>
<p>If a carrier or device manufacturer has hosted an SDK add-on repository file
on their web site, follow these steps to add their site to the SDK and AVD
@@ -199,11 +183,12 @@ Manager:</p>
<ol>
<li>Select <strong>Available Packages</strong> in the left panel.</li>
- <li>Click <strong>Add Site</strong> and enter the URL of the
+ <li>Click <strong>Add Add-on Site</strong> and enter the URL of the
{@code repository.xml} file. Click <strong>OK</strong>.</li>
</ol>
-<p>Any SDK components available from the site will now be listed under
-<strong>Available Packages</strong>.</p>
+<p>Any SDK components available from the site will now be listed under a new item named
+<strong>User Add-ons</strong>.</p>
+
<h2 id="troubleshooting">Troubleshooting</h2>
diff --git a/docs/html/sdk/adt_download.jd b/docs/html/sdk/adt_download.jd
index f98caf5..33e480a 100644
--- a/docs/html/sdk/adt_download.jd
+++ b/docs/html/sdk/adt_download.jd
@@ -22,11 +22,32 @@ ADT Installation</a>.</p>
<th>Notes</th>
</tr>
<tr>
+ <td>8.0.0</td>
+ <td><a href="http://dl-ssl.google.com/android/ADT-8.0.0.zip">ADT-8.0.0.zip</a></td>
+ <td><nobr> bytes</nobr></td>
+ <td></td>
+ <td>Requires SDK Tools, Revision 8 <em><nobr>November 2010</nobr></em></td>
+ </tr>
+ <tr>
+ <td>0.9.9</td>
+ <td><a href="http://dl-ssl.google.com/android/ADT-0.9.9.zip">ADT-0.9.9.zip</a></td>
+ <td><nobr>8301681 bytes</nobr></td>
+ <td>7deff0c9b25940a74cea7a0815a3bc36</td>
+ <td>Requires SDK Tools, Revision 7 <em><nobr>September 2010</nobr></em></td>
+ </tr>
+ <tr>
+ <td>0.9.8</td>
+ <td><a href="http://dl-ssl.google.com/android/ADT-0.9.8.zip">ADT-0.9.8.zip</a></td>
+ <td><nobr>8301417 bytes</nobr></td>
+ <td>27e0de800512f13feae46fb554e6ee2f</td>
+ <td>Requires SDK Tools, Revision 7 <em><nobr>September 2010</nobr></em></td>
+ </tr>
+ <tr>
<td>0.9.7</td>
<td><a href="http://dl-ssl.google.com/android/ADT-0.9.7.zip">ADT-0.9.7.zip</a></td>
- <td><nobr>{@adtZipBytes} bytes</nobr></td>
- <td>{@adtZipChecksum}</td>
- <td>Requires SDK Tools, Revision 6 <em><nobr>May 2010</nobr></em></td>
+ <td><nobr>8033750 bytes</nobr></td>
+ <td>de2431c8d4786d127ae5bfc95b4605df</td>
+ <td>Requires SDK Tools, Revision 5 <em><nobr>May 2010</nobr></em></td>
</tr>
<tr>
<td>0.9.6</td>
diff --git a/docs/html/sdk/android-1.5.jd b/docs/html/sdk/android-1.5.jd
index 1d6e0ad..9ed798c 100644
--- a/docs/html/sdk/android-1.5.jd
+++ b/docs/html/sdk/android-1.5.jd
@@ -2,8 +2,6 @@ page.title=Android 1.5 Platform
sdk.platform.version=1.5
sdk.platform.apiLevel=3
sdk.platform.majorMinor=major
-sdk.platform.releaseDate=April 2009
-sdk.platform.deployableDate=May 2009
@jd:body
@@ -43,7 +41,7 @@ Differences Report &raquo;</a> </li>
<em>API Level:</em>&nbsp;<strong>{@sdkPlatformApiLevel}</strong></p>
<p>Android {@sdkPlatformVersion} is a {@sdkPlatformMajorMinor} platform release
-deployable to Android-powered handsets starting in {@sdkPlatformDeployableDate}.
+deployable to Android-powered handsets starting in May 2009.
The release includes new features for users and developers, as well as changes
in the Android framework API. </p>
@@ -139,7 +137,7 @@ function toggleDiv(link) {
<div class="toggleable closed">
<a href="#" onclick="return toggleDiv(this)">
- <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
Android 1.5, Revision 3</a> <em>(July 2009)</em></a>
<div class="toggleme">
<dl>
diff --git a/docs/html/sdk/android-1.6.jd b/docs/html/sdk/android-1.6.jd
index c2651b6..a01a5f6 100644
--- a/docs/html/sdk/android-1.6.jd
+++ b/docs/html/sdk/android-1.6.jd
@@ -2,8 +2,6 @@ page.title=Android 1.6 Platform
sdk.platform.version=1.6
sdk.platform.apiLevel=4
sdk.platform.majorMinor=minor
-sdk.platform.releaseDate=December 2009
-sdk.platform.deployableDate=October 2009
@jd:body
@@ -43,7 +41,7 @@ Differences Report &raquo;</a> </li>
<em>API Level:</em>&nbsp;<strong>{@sdkPlatformApiLevel}</strong></p>
<p>Android {@sdkPlatformVersion} is a {@sdkPlatformMajorMinor} platform release
-deployable to Android-powered handsets since {@sdkPlatformDeployableDate}.
+deployable to Android-powered handsets since October 2009.
The platform includes new features for users and developers, as well as changes
in the Android framework API. </p>
@@ -138,7 +136,7 @@ function toggleDiv(link) {
<div class="toggleable closed">
<a href="#" onclick="return toggleDiv(this)">
- <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
Android 1.6, Revision 2</a> <em>(December 2009)</em></a>
<div class="toggleme">
<dl>
diff --git a/docs/html/sdk/android-2.0.1.jd b/docs/html/sdk/android-2.0.1.jd
index cacb6bf..0c8afb6 100644
--- a/docs/html/sdk/android-2.0.1.jd
+++ b/docs/html/sdk/android-2.0.1.jd
@@ -2,8 +2,6 @@ page.title=Android 2.0.1, Release 1
sdk.platform.version=2.0.1
sdk.platform.apiLevel=6
sdk.platform.majorMinor=minor
-sdk.platform.releaseDate=December 2009
-sdk.platform.deployableDate=December 2009
@jd:body
@@ -44,7 +42,7 @@ differences report &raquo;</a> </li>
<em>API Level:</em>&nbsp;<strong>{@sdkPlatformApiLevel}</strong></p>
<p>Android {@sdkPlatformVersion} is a {@sdkPlatformMajorMinor} platform release
-deployable to Android-powered handsets starting in {@sdkPlatformDeployableDate}.
+deployable to Android-powered handsets starting in December 2009.
This release includes minor API
changes, bug fixes and framework behavioral changes. For information on changes
and fixes, see the <a href="#api">Framework API</a> section.</p>
diff --git a/docs/html/sdk/android-2.0.jd b/docs/html/sdk/android-2.0.jd
index a430f34..2c31923 100644
--- a/docs/html/sdk/android-2.0.jd
+++ b/docs/html/sdk/android-2.0.jd
@@ -2,8 +2,6 @@ page.title=Android 2.0, Release 1
sdk.platform.version=2.0
sdk.platform.apiLevel=5
sdk.platform.majorMinor=major
-sdk.platform.releaseDate=October 2009
-sdk.platform.deployableDate=November 2009
@jd:body
@@ -38,7 +36,7 @@ sdk.platform.deployableDate=November 2009
<em>API Level:</em>&nbsp;<strong>{@sdkPlatformApiLevel}</strong></p>
<p>Android {@sdkPlatformVersion} is a {@sdkPlatformMajorMinor} platform release
-deployable to Android-powered handsets starting in {@sdkPlatformDeployableDate}.
+deployable to Android-powered handsets starting in November 2009.
The release includes new features for users and developers, as well as changes
in the Android framework API. </p>
diff --git a/docs/html/sdk/android-2.1.jd b/docs/html/sdk/android-2.1.jd
index 7490bae..6eba6f0 100644
--- a/docs/html/sdk/android-2.1.jd
+++ b/docs/html/sdk/android-2.1.jd
@@ -2,7 +2,6 @@ page.title=Android 2.1 Platform
sdk.platform.version=2.1
sdk.platform.apiLevel=7
sdk.platform.majorMinor=minor
-sdk.platform.deployableDate=January 2010
@jd:body
@@ -42,7 +41,7 @@ Differences Report &raquo;</a> </li>
<em>API Level:</em>&nbsp;<strong>{@sdkPlatformApiLevel}</strong></p>
<p>Android {@sdkPlatformVersion} is a {@sdkPlatformMajorMinor} platform release
-deployable to Android-powered handsets starting in {@sdkPlatformDeployableDate}.
+deployable to Android-powered handsets starting in January 2010.
This release includes new API
changes and bug fixes. For information on changes, see the <a href="#api">Framework API</a>
section.</p>
@@ -139,7 +138,7 @@ function toggleDiv(link) {
<div class="toggleable closed">
<a href="#" onclick="return toggleDiv(this)">
- <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
Android 2.1, Revision 1</a> <em>(January 2010)</em></a>
<div class="toggleme">
<dl>
diff --git a/docs/html/sdk/android-2.2.jd b/docs/html/sdk/android-2.2.jd
index f82edf9..063a10f 100644
--- a/docs/html/sdk/android-2.2.jd
+++ b/docs/html/sdk/android-2.2.jd
@@ -2,7 +2,6 @@ page.title=Android 2.2 Platform
sdk.platform.version=2.2
sdk.platform.apiLevel=8
sdk.platform.majorMinor=minor
-sdk.platform.deployableDate=May 2010
@jd:body
@@ -43,7 +42,7 @@ Differences Report &raquo;</a> </li>
<p>Android {@sdkPlatformVersion} is a {@sdkPlatformMajorMinor} platform release including user
features, developer features, API changes, and bug
-fixes. For information on developer features and API changes, see the
+fixes. For information on developer features and API changes, see the
<a href="#api">Framework API</a> section.</p>
<p>For developers, the Android {@sdkPlatformVersion} platform is available as a
@@ -63,7 +62,7 @@ first.</p>
<h2 id="features">Platform Highlights</h2>
-<p>For a list of new user features and platform highlights, see the <a
+<p>For a list of new user features and platform highlights, see the <a
href="http://developer.android.com/sdk/android-2.2-highlights.html">Android
2.2 Platform Highlights</a> document.</p>
@@ -118,6 +117,30 @@ function toggleDiv(link) {
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+ Android {@sdkPlatformVersion}, Revision 2</a> <em>(July 2010)</em></a>
+ <div class="toggleme">
+<dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>Requires SDK Tools r6 or higher.</p>
+</dd>
+
+<dt>System Image:</dt>
+<dd>
+<ul>
+<li>Adds default Search Widget.</li>
+<li>Includes proper provisioning for the platform's Backup Manager. For more information about how to use the Backup Manager, see <a href="{@docRoot}guide/topics/data/backup.html">Data Backup</a>.</li>
+<li>Updates the Android 2.2 system image to FRF91.</li>
+</ul>
+</dd>
+
+</dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
Android {@sdkPlatformVersion}, Revision 1</a> <em>(May 2010)</em></a>
<div class="toggleme">
<dl>
@@ -135,7 +158,6 @@ function toggleDiv(link) {
</div>
</div>
-
<h2 id="api-level">API Level</h2>
<p>The Android {@sdkPlatformVersion} platform delivers an updated version of
@@ -294,8 +316,8 @@ href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/Devi
<ul>
<li> New <code>android:backupAgent</code> attribute of the
-<code>&lt;application&gt;</code> element. Specifies the component name of the
-BackupAgent subclass provided by the application to handle backup/restore
+<code>&lt;application&gt;</code> element. Specifies the component name of the
+BackupAgent subclass provided by the application to handle backup/restore
operations, if any.</li>
<li> New <code>android:restoreAnyVersion</code> attribute of the
<code>&lt;application&gt;</code> element. Boolean value that indicates whether
@@ -414,6 +436,11 @@ descriptor).</p>
<p>Localized UI strings match the locales that are accessible
through Settings.</p>
+<p class="note"><strong>Note:</strong> Android supports more locales than are listed above. However,
+the entire collection of locale strings cannot fit on a single system image, so the above list is
+only what's included in the system image for the SDK. All of Android's supported locales are
+available in the <a href="http://source.android.com/">Android Open Source Project</a>.</p>
+
<h2 id="skins">Emulator Skins</h2>
<p>The downloadable platform includes a set of emulator skins that you can use
@@ -444,4 +471,4 @@ emulator skins are:</p>
<p>For more information about how to develop an application that displays
and functions properly on all Android-powered devices, see <a
href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
-Screens</a>.</p> \ No newline at end of file
+Screens</a>.</p>
diff --git a/docs/html/sdk/download.jd b/docs/html/sdk/download.jd
new file mode 100644
index 0000000..81b4ff6
--- /dev/null
+++ b/docs/html/sdk/download.jd
@@ -0,0 +1,4 @@
+sdk.redirect=true
+
+@jd:body
+
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index f5558ab..8f6f518 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,5 +1,9 @@
page.title=ADT Plugin for Eclipse
sdk.preview=0
+adt.zip.version=0.9.9
+adt.zip.download=ADT-0.9.9.zip
+adt.zip.bytes=8301681
+adt.zip.checksum=7deff0c9b25940a74cea7a0815a3bc36
@jd:body
@@ -18,13 +22,12 @@ sdk.preview=0
</ol>
</li>
<li><a href="#updating">Updating the ADT Plugin</a></li>
- <li><a href="#uninstalling">Uninstalling the ADT Plugin</a></li>
</ol>
</div>
</div>
-<p>Android Development Tools (ADT) is a plugin for the Eclipse IDE
+<p>Android Development Tools (ADT) is a plugin for the Eclipse IDE
that is designed to give you a powerful, integrated environment in which
to build Android applications. </p>
@@ -44,7 +47,7 @@ before you can install or use ADT, you must have compatible versions of both the
Eclipse IDE and the Android SDK installed. For details, make sure to read <a
href="#installing">Installing the ADT Plugin</a>, below. </p>
-<p>If you are already using ADT, this document also provides instructions on
+<p>If you are already using ADT, this document also provides instructions on
how to update ADT to the latest version or how to uninstall it, if necessary.
</p>
@@ -92,8 +95,131 @@ padding: .25em 1em;
}
</style>
+
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+ADT 8.0.0</a> <em>(December 2010)</em>
+ <div class="toggleme">
+
+<dl>
+
+<dt>Dependencies:</dt>
+
+<p><p>ADT 8.0.0 is designed for use with SDK Tools r8. If you haven't
+already installed SDK Tools r8 into your SDK, use the Android SDK and AVD Manager to do
+so.</p></dd>
+
+<dt>General notes:</dt>
+<dd>
+<ul>
+ <li>New version number scheme that follows the SDK Tools revision number. The major version
+number for your ADT plugin should now always match the revision number of your SDK Tools. For
+example, ADT 8.x is for SDK Tools r8.</li>
+ <li>Support for true debug build. You no longer need to change the value of the
+ <code>debuggable</code> attribute in the Android Manifest.
+ <p>Incremental builds automatically insert <code>debuggable="true"</code>, but if you perform
+ "export signed/unsigned application package", ADT does <em>not</em> insert it.
+ If you manually set <code>debuggable="true"</code> in the manifest file, then release builds will
+ actually create a debug build (it does not remove it if you placed it there).</p></li>
+ <li>Automatic <a href="{@docRoot}guide/developing/tools/proguard.html">Proguard</a> support in
+release builds. For it to work, you need to have a <code>proguard.config</code>
+ property in the <code>default.properties</code> file that points to a proguard config file.</li>
+ <li>Completely rewritten Visual Layout Editor. (This is still a work in progress.) Now includes:
+ <ul>
+ <li>Full drag and drop from palette to layout for all Layout classes.</li>
+ <li>Move widgets inside a Layout view, from one Layout view to another and from one layout file to another.</li>
+ <li>Contextual menu with enum/flag type properties.</li>
+ <li>New zoom controls.</li>
+ </ul></li>
+ <li>New HierarchyViewer plug-in integrated in Eclipse.</li>
+ <li>Android launch configurations don't recompile the whole workspace on launch anymore.</li>
+ <li><code>android.jar</code> source and javadoc location can now be configured.</li>
+</ul>
+</dd>
+</dl>
+ </div>
+</div>
+
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
+ADT 0.9.9</a> <em>(September 2010)</em>
+ <div class="toggleme">
+
+<dl>
+
+<dt>Dependencies:</dt>
+
+<dd><p>ADT 0.9.9 replaces ADT 0.9.8 and is designed for use with SDK Tools r7
+and later. ADT 0.9.9 includes the ADT 0.9.8 features as well as an important
+bugfix, so we recommend that you upgrade as soon as possible. If you haven't
+already installed SDK Tools r7 into your SDK, use the Android SDK Manager to do
+so.</p></dd>
+
+<dt>General notes:</dt>
+<dd>
+<ul>
+<li>Fixes a problem in project import, in which source files were deleted in some cases.</li>
+<li>Includes all other ADT 0.9.8 features (see below).</li>
+</ul>
+</dd>
+</dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
+ADT 0.9.8</a> <em>(September 2010)</em>
+ <div class="toggleme">
+
+
+</ul>
+</dd>
+
+<dl>
+
+<dt>Dependencies:</dt>
+
+<dd><p>ADT 0.9.8 is now deprecated. Please use ADT 0.9.9 instead.</p></dd>
+
+<dt>General notes:</dt>
+<dd>
+<ul>
+<li>Adds a new Action, "Rename Application Package", to the Android Tools
+contextual menu. The Action does a full application package refactoring.
+<li>Adds support for library projects that don't have a source folder
+called <code>src/</code>. There is now support for any number of source folders,
+with no name restriction. They can even be in subfolder such as
+<code>src/java</code>. If you are already working with library projects created
+in ADT 0.9.7, see <a
+href="{@docRoot}guide/developing/eclipse-adt.html#libraryMigrating">Migrating
+library projects to ADT 0.9.8</a> for important information about moving
+to the new ADT environment.</li>
+<li>Adds support for library projects that depend on other library
+projects.</li>
+<li>Adds support for additional resource qualifiers:
+<code>car</code>/<code>desk</code>, <code>night</code>/<code>notnight</code> and
+<code>navexposed</code>/<code>navhidden</code>.</li>
+<li>Adds more device screen types in the layout editor. All screen
+resolution/density combinations listed in the <a
+href="{@docRoot}guide/practices/screens_support.html#range">Supporting
+Multiple Screens</a> are now available.</li>
+<li>Fixes problems with handling of library project names that
+contain characters that are incompatible with the Eclipse path variable.
+Now properly sets up the link between the main project and the library
+project.</li>
+</ul>
+</dd>
+</dl>
+ </div>
+</div>
+
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
ADT 0.9.7</a> <em>(May 2010)</em>
<div class="toggleme">
@@ -107,16 +233,17 @@ code and resources in a separate development project. You can then reference the
library project from other Android projects and, at build time, the tools
compile the shared code and resources as part of the dependent applications.
More information about this feature is available in the <a
-href="{@docRoot}guide/developing/eclipse-adt.html#libraryProject">Developing
+href="{@docRoot}guide/developing/eclipse-adt.html#libraryProject">Developing
in Eclipse with ADT</a> document. </p>
-<p>If you are not developing in Eclipse, <a
-href="tools-notes.html">SDK Tools r6</a> provides the equivalent library
+<p>If you are not developing in Eclipse, <a
+href="tools-notes.html">SDK Tools r6</a> provides the equivalent library
project support through the Ant build system.</p>
</dd>
</dl>
</div>
</div>
+
<div class="toggleable closed">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
@@ -126,7 +253,7 @@ ADT 0.9.6</a> <em>(March 2010)</em>
<dl>
<dt>Dependencies:</dt>
-<dd><p>ADT 0.9.6 is designed for use with SDK Tools r5 and later. Before
+<dd><p>ADT 0.9.6 is designed for use with SDK Tools r5 and later. Before
updating to ADT 0.9.6, we highly recommend that you use the Android SDK and
AVD Manager to install SDK Tools r5 into your SDK.</p></dd>
@@ -250,7 +377,7 @@ bigger than the screen.</li>
<ul>
<li>Includes the improvements from the standlone DDMS, revision 3.</li>
<li>Adds an option to open HPROF files into eclipse instead of writing them on
-disk. If a profiler such as MAT (<a href="http://eclipse.org/mat">Memory Analyzer
+disk. If a profiler such as MAT (<a href="http://eclipse.org/mat">Memory Analyzer
Tool</a>) is installed, it'll open the file.</li>
</ul>
</dd>
@@ -258,7 +385,7 @@ Tool</a>) is installed, it'll open the file.</li>
<dt>Android SDK and AVD Manager integration:</dt>
<dd>
<ul>
-<li>Includes the improvements from the standalone Android SDK and AVD Manager,
+<li>Includes the improvements from the standalone Android SDK and AVD Manager,
revision 3.</li>
</ul>
</dd>
@@ -266,12 +393,15 @@ revision 3.</li>
</div>
</div>
+
+
<h2 id="installing">Installing the ADT Plugin</h2>
<p>The sections below provide instructions on how to download and install
ADT into your Eclipse environment. If you encounter problems, see the <a
href="#troubleshooting">Troubleshooting</a> section.</p>
+
<h3 id="preparing">Preparing Your Development Computer</h3>
<p>ADT is a plugin for the Eclipse IDE. Before you can install or use ADT,
@@ -290,12 +420,13 @@ location:
"http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a>
</p>
-<p>A Java or RCP version of Eclipse is recommended.</p></li>
+<p>For Eclipse 3.5 or newer, the "Eclipse Classic" version is recommended. Otherwise, a Java or RCP
+version of Eclipse is recommended.</p></li>
</ul>
<p>Additionally, before you can configure or use ADT, you must install the
Android SDK starter package, as described in <a
-href="installing.html#Installing">Downloading the SDK Starter Pacskage</a>.
+href="installing.html#Installing">Downloading the SDK Starter Package</a>.
Specifically, you need to install a compatible version of the Android SDK Tools
and at least one development platform. To simplify ADT setup, we recommend
installing the Android SDK prior to installing ADT. </p>
@@ -314,55 +445,52 @@ these steps to download the ADT plugin and install it in your Eclipse
environment. </p>
<table style="font-size:100%">
-<tr><th>Eclipse 3.4 (Ganymede)</th><th>Eclipse 3.5 (Galileo)</th></tr>
+<tr><th>Eclipse 3.5 (Galileo) and 3.6 (Helios)</th><th>Eclipse 3.4 (Ganymede)</th></tr>
<tr>
<td width="45%">
-<!-- 3.4 steps -->
+<!-- 3.5+ steps -->
<ol>
- <li>Start Eclipse, then select <strong>Help</strong> &gt; <strong>Software Updates...</strong>.
- In the dialog that appears, click the <strong>Available Software</strong> tab. </li>
- <li>Click <strong>Add Site...</strong> </li>
- <li>In the Add Site dialog that appears, enter this URL in the "Location" field:
- <pre style="margin-left:0">https://dl-ssl.google.com/android/eclipse/</pre>
+ <li>Start Eclipse, then select <strong>Help</strong> &gt; <strong>Install New
+Software...</strong>.</li>
+ <li>Click <strong>Add</strong>, in the top-right corner.</li>
+ <li>In the Add Repository dialog that appears, enter "ADT Plugin" for the <em>Name</em> and the
+following URL for the <em>Location</em>:
+ <pre>https://dl-ssl.google.com/android/eclipse/</pre>
<p>Note: If you have trouble acquiring the plugin, try using "http" in the Location URL,
- instead of "https" (https is preferred for security reasons).</p>
+ instead of "https" (https is preferred for security reasons).</p>
<p>Click <strong>OK</strong>.</p></li>
- <li>Back in the Available Software view, you should see the plugin listed by the URL,
- with "Developer Tools" nested within it. Select the checkbox next to
- Developer Tools and click <strong>Install...</strong></li>
- <li>On the subsequent Install window, "Android DDMS" and "Android Development Tools"
- should both be checked. Click <strong>Next</strong>. </li>
- <li>Read and accept the license agreement, then click <strong>Finish</strong>.</li>
- <li>Restart Eclipse. </li>
+ <li>In the Available Software dialog, select
+the checkbox next to Developer Tools and click <strong>Next</strong>.</li>
+ <li>In the next window, you'll see a list of the tools to be downloaded. Click
+<strong>Next</strong>. </li>
+ <li>Read and accept the license agreements, then click <strong>Finish</strong>.</li>
+ <li>When the installation completes, restart Eclipse. </li>
</ol>
</td>
-<td>
-<!-- 3.5 steps -->
+<td width="50%">
+
+<!-- 3.4 steps -->
<ol>
- <li>Start Eclipse, then select <strong>Help</strong> &gt; <strong>Install
- New Software</strong>. </li>
- <li>In the Available Software dialog, click <strong>Add...</strong>.</li>
- <li>In the Add Site dialog that appears, enter a name for the remote site
- (for example, "Android Plugin") in the "Name" field.
- <p>In the "Location" field, enter this URL:</p>
+ <li>Start Eclipse, then select <strong>Help</strong> &gt; <strong>Software Updates...</strong>.
+In the dialog that appears, click the <strong>Available Software</strong> tab.</li>
+ <li>Click <strong>Add Site</strong>.</li>
+ <li>In the Add Site dialog that appears, enter this URL in the "Location" field:
<pre>https://dl-ssl.google.com/android/eclipse/</pre>
<p>Note: If you have trouble acquiring the plugin, you can try
- using "http" in the URL, instead of "https" (https is preferred for
+ using "http" in the URL, instead of "https" (https is preferred for
security reasons).</p>
<p>Click <strong>OK</strong>.</p>
</li>
- <li>Back in the Available Software view, you should now see "Developer
- Tools" added to the list. Select the checkbox next to Developer Tools,
- which will automatically select the nested tools Android DDMS and Android
- Development Tools.
- Click <strong>Next</strong>. </li>
- <li>In the resulting Install Details dialog, the Android DDMS and Android
- Development Tools features are listed. Click <strong>Next</strong> to
- read and accept the license agreement and install any dependencies,
- then click <strong>Finish</strong>. </li>
- <li>Restart Eclipse. </li>
-
+ <li>Back in the Available Software view, you should see the plugin listed by the URL,
+ with "Developer Tools" nested within it. Select the checkbox next to Developer Tools,
+ which will automatically select the nested tools. Then click
+ <strong>Install</strong></li>
+ <li>On the subsequent Install window, all of the included tools
+ should be checked. Click <strong>Next</strong>. </li>
+ <li>Read and accept the license agreements, then click <strong>Finish</strong>.</li>
+ <li>When the installation completes, restart Eclipse. </li>
+
</ol>
</td>
</tr>
@@ -370,22 +498,22 @@ environment. </p>
<h3 id="preparing">Configuring the ADT Plugin</h3>
-<p>Once you've successfully downnloaded ADT as described above, the next step
+<p>Once you've successfully downloaded ADT as described above, the next step
is to modify your ADT preferences in Eclipse to point to the Android SDK directory:</p>
<ol>
<li>Select <strong>Window</strong> &gt; <strong>Preferences...</strong> to open the Preferences
panel (Mac OS X: <strong>Eclipse</strong> &gt; <strong>Preferences</strong>).</li>
<li>Select <strong>Android</strong> from the left panel. </li>
- <li>For the <em>SDK Location</em> in the main panel, click <strong>Browse...</strong> and
+ <li>For the <em>SDK Location</em> in the main panel, click <strong>Browse...</strong> and
locate your downloaded SDK directory. </li>
<li>Click <strong>Apply</strong>, then <strong>OK</strong>.</li>
</ol>
<p>Done! If you haven't encountered any problems, then the installation is
-complete. Now read <a href="installing.html#components">Adding Platforms and
-Other Components</a> for instructions on how to complete the setup of your
-SDK environment. </p>
+complete. If you're installing the Android SDK for the first time, return to <a
+href="{@docRoot}sdk/installing.html#InstallingADT">Installing the SDK</a> to complete your setup.
+</p>
<h3 id="troubleshooting">Troubleshooting ADT Installation</h3>
@@ -397,9 +525,9 @@ steps above, here are some suggestions: </p>
<li>If Eclipse can not find the remote update site containing the ADT plugin,
try changing the remote site URL to use http, rather than https. That is, set
the Location for the remote site to:
-<pre>http://dl-ssl.google.com/android/eclipse/</pre></li>
+<pre>http://dl-ssl.google.com/android/eclipse/</pre></li>
<li>If you are behind a firewall (such as a corporate firewall), make sure that
-you have properly configured your proxy settings in Eclipse. In Eclipse 3.3/3.4,
+you have properly configured your proxy settings in Eclipse. In Eclipse,
you can configure proxy information from the main Eclipse menu in
<strong>Window</strong> (on Mac OS X, <strong>Eclipse</strong>) &gt;
<strong>Preferences</strong> &gt; <strong>General</strong> &gt; <strong>Network
@@ -432,14 +560,14 @@ manually install it:</p>
</li>
</li>
- <li>Follow steps 1 and 2 in the <a href="#installing">default install
+ <li>Follow steps 1 and 2 in the <a href="#installing">default install
instructions</a> (above).</li>
<li>In the Add Site dialog, click <strong>Archive</strong>.</li>
<li>Browse and select the downloaded zip file.</li>
- <li>In Eclipse 3.5 only, enter a name for the local update site (e.g.,
+ <li>Enter a name for the local update site (e.g.,
"Android Plugin") in the "Name" field.</li>
<li>Click <strong>OK</strong>.
- <li>Follow the remaining procedures as listed for
+ <li>Follow the remaining procedures as listed for
<a href="#installing">default installation</a> above,
starting from step 4.</li>
</ol>
@@ -449,16 +577,16 @@ to follow these steps again instead of the default update instructions.</p>
<h4>Other install errors</h4>
-<p>Note that there are features of ADT that require some optional
-Eclipse components (for example, WST). If you encounter an error when
-installing ADT, your Eclipse installion might not include these components.
-For information about how to quickly add the necessary components to your
-Eclipse installation, see the troubleshooting topic
-<a href="{@docRoot}resources/faq/troubleshooting.html#installeclipsecomponents">ADT
+<p>Note that there are features of ADT that require some optional
+Eclipse components (for example, WST). If you encounter an error when
+installing ADT, your Eclipse installion might not include these components.
+For information about how to quickly add the necessary components to your
+Eclipse installation, see the troubleshooting topic
+<a href="{@docRoot}resources/faq/troubleshooting.html#installeclipsecomponents">ADT
Installation Error: "requires plug-in org.eclipse.wst.sse.ui"</a>.</p>
<h4>For Linux users</h4>
-<p>If you encounter this error when installing the ADT Plugin for Eclipse:
+<p>If you encounter this error when installing the ADT Plugin for Eclipse:
<pre>
An error occurred during provisioning.
Cannot connect to keystore.
@@ -483,48 +611,43 @@ described in <a href="adding-components.html">Adding SDK Components</a>.</p>
<p>To learn about new features of each ADT revision and also any dependencies on
the SDK Tools, see the listings in the <a href="#notes">Revisions</a>
-section. To determine the version currently installed, open the
+section. To determine the version currently installed, open the
Eclipse Installed Software window using <strong>Help</strong>
-&gt; <strong>Software Updates</strong> and refer to the version listed for
+&gt; <strong>Software Updates</strong> and refer to the version listed for
"Android Development Tools".</p>
-<p>Follow the steps below to check whether an update is available and, if so,
+<p>Follow the steps below to check whether an update is available and, if so,
to install it. </p>
<table style="font-size:100%">
-<tr><th>Eclipse 3.4 (Ganymede)</th><th>Eclipse 3.5 (Galileo)</th></tr>
+<tr><th>Eclipse 3.5 (Galileo) and 3.6 (Helios)</th><th>Eclipse 3.4 (Ganymede)</th></tr>
<tr>
-<td width="50%">
-<!-- 3.4 steps -->
+<td>
+<!-- 3.5+ steps -->
<ol>
- <li>Select <strong>Help</strong> &gt; <strong>Software Updates</strong>.</li>
- <li>Select the <strong>Available Software</strong> tab.</li>
- <li>Select the checkboxes next to Android DDMS and Android Developer Tools,
- then click <strong>Update</strong>.</li>
- <li>In the resulting Available Updates dialog, ensure that both Android DDMS
- and Android Development Tools are selected, then click
- <strong>Next</strong>.</li>
+ <li>Select <strong>Help</strong> &gt; <strong>Check for Updates</strong>.
+ <p>If there are no updates available, a dialog will say so and you're done.</p></li>
+ <li>If there are updates available, select Android DDMS, Android Development Tools,
+ and Android Hierarchy Viewer, then click <strong>Next</strong>.</li>
+ <li>In the Update Details dialog, click <strong>Next</strong>.</li>
<li>Read and accept the license agreement and then click <strong>Finish</strong>.
- This will download and install the latest version of Android DDMS and
+ This will download and install the latest version of Android DDMS and
Android Development Tools.</li>
<li>Restart Eclipse.</li>
</ol>
</td>
-<td>
-<!-- 3.5 steps -->
+
+<td width="50%">
+<!-- 3.4 steps -->
<ol>
- <li>Select <strong>Help</strong> &gt; <strong>Check for Updates</strong>. </li>
- <li>In the resulting Available Updates dialog, locate the Android DDMS and
- Android Development Tools features in the list and ensure that the checkboxes
- next to them are selected. Click <strong>Next</strong>.
- <p>If the Available Updates dialog does not list Android DDMS and Android
- Development tools, make sure that you have set up a remote update site
- for them, as described in
- <a href="#installing">Installing the ADT Plugin</a>.
- </p></li>
- <li>In the Update Details dialog, click <strong>Next</strong>.</li>
+ <li>Select <strong>Help</strong> &gt; <strong>Software Updates</strong>.</li>
+ <li>Select the <strong>Available Software</strong> tab.</li>
+ <li>If there are updates available, select Android DDMS, Android Development Tools,
+ and Android Hierarchy Viewer, then click <strong>Update</strong>.</li>
+ <li>In the resulting Available Updates dialog, ensure that each of the listed tools
+ are selected, then click <strong>Next</strong>.</li>
<li>Read and accept the license agreement and then click <strong>Finish</strong>.
- This will download and install the latest version of Android DDMS and
+ This will download and install the latest version of Android DDMS and
Android Development Tools.</li>
<li>Restart Eclipse.</li>
</ol>
@@ -533,45 +656,10 @@ to install it. </p>
</table>
-<p>If you encounter problems during the update of ADT, you
+<p>If you encounter problems during the update of ADT, you
can try removing the existing ADT plugin and then performing a fresh
installation. To remove the plugin, follow the instructions in <a
-href="#uninstalling">Uninstalling the ADT Plugin</a>, below. To reinstall
+href="#uninstalling">Uninstalling the ADT Plugin</a>, below. To reinstall
the plugin, follow the instructions in <a
href="#installing">Installing the ADT Plugin</a>, above.</p>
-
-<h2 id="uninstalling">Uninstalling the ADT plugin</h2>
-
-<p><p>If you encounter problems when installing or updating ADT, you
-can try removing the existing ADT plugin and then performing a fresh
-installation. To remove ADT, follow these steps: </p>
-
-<table style="font-size:100%">
-<tr><th>Eclipse 3.4 (Ganymede)</th><th>Eclipse 3.5 (Galileo)</th></tr>
-<tr>
-<td width="50%">
-<!-- 3.4 steps -->
-<ol>
- <li>Select <strong>Help</strong> &gt; <strong>Software Updates</strong> &gt;
- <strong>Manage Configuration</strong>. </li>
- <li>Expand the list in the left panel to reveal the installed tools.</li>
- <li>Right-click "Android Editors" and click <strong>Uninstall</strong>. Click <strong>OK</strong>
- to confirm.</li>
- <li>Restart Eclipse.
- <p>(Do not uninstall "Android Development Tools".)</p></li>
-</ol>
-</td>
-<td>
-<!-- 3.5 steps -->
-<ol>
- <li>Select <strong>Help</strong> &gt; <strong>Install New Software</strong>.</li>
- <li>In the "Details" panel, click the "What is already installed?" link.</li>
- <li>In the <strong>Eclipse Installation Details</strong> dialog, select "Android DDMS" and "Android Development Tools" and then click <strong>Uninstall</strong>.</li>
- <li>In the next window, confirm that the ADT features are selected for uninstall and then click <strong>Finish</strong> to uninstall.</li>
- <li>Restart Eclipse.</li>
-</ol>
-</td>
-</tr>
-</table>
-
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 5e92253..8b77303 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,71 +1,34 @@
page.title=Android SDK
sdk.redirect=0
-sdk.win_download=android-sdk_r06-windows.zip
-sdk.win_bytes=23293160
-sdk.win_checksum=7c7fcec3c6b5c7c3df6ae654b27effb5
+sdk.win_installer=installer_r08-windows.exe
+sdk.win_installer_bytes=TODO
+sdk.win_installer_checksum=TODO
-sdk.mac_download=android-sdk_r06-mac_86.zip
-sdk.mac_bytes=19108077
-sdk.mac_checksum=c92abf66a82c7a3f2b8493ebe025dd22
+sdk.win_download=android-sdk_r08-windows.zip
+sdk.win_bytes=TODO
+sdk.win_checksum=TODO
-sdk.linux_download=android-sdk_r06-linux_86.tgz
-sdk.linux_bytes=16971139
-sdk.linux_checksum=848371e4bf068dbb582b709f4e56d903
+sdk.mac_download=android-sdk_r08-mac_x86.zip
+sdk.mac_bytes=TODO
+sdk.mac_checksum=TODO
-@jd:body
-
-
-<h2 id="quickstart">Quick Start</h2>
-
-<p>The steps below provide an overview of how to get started with the Android
-SDK. For detailed instructions, start with the <a
-href="{@docRoot}sdk/installing.html">Installing the SDK</a> guide. </p>
-
-<p><strong>1. Prepare your development computer</strong></p>
-
-<p>Read the <a href="{@docRoot}sdk/requirements.html">System Requirements</a>
-document and make sure that your development computer meets the hardware and
-software requirements for the Android SDK. Install any additional software
-needed before downloading the Android SDK. In particular, you may need to
-install the <a href="http://java.sun.com/javase/downloads/index.jsp">JDK</a>
- (version 5 or 6 required) and <a href="http://www.eclipse.org/downloads/">Eclipse</a>
- (version 3.4 or 3.5, needed only if you want develop using the ADT Plugin).
-
-<p><strong>2. Download and install the SDK starter package</strong></p>
+sdk.linux_download=android-sdk_r08-linux_x86.tgz
+sdk.linux_bytes=TODO
+sdk.linux_checksum=TODO
-<p>Select a starter package from the table at the top of this page and download
-it to your development computer. To install the SDK, simply unpack the starter
-package to a safe location and then add the location to your PATH. </p>
-
-<p><strong>3. Install the ADT Plugin for Eclipse</strong></p>
-
-<p>If you are developing in Eclipse, set up a remote update site at
-<code>https://dl-ssl.google.com/android/eclipse/</code>. Install the Android
-Development Tools (ADT) Plugin, restart Eclipse, and set the "Android"
-preferences in Eclipse to point to the SDK install location. For detailed
-instructions, see <a href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin
-for Eclipse</a>.</p>
-
-<p><strong>4. Add Android platforms and other components to your SDK</strong></p>
-
-<p>Use the Android SDK and AVD Manager, included in the SDK starter package, to
-add one or more Android platforms (for example, Android 1.6 or Android 2.0) and
-other components to your SDK. If you aren't sure what to add, see <a
-href="installing.html#which">Which components do I need?</a></p>
-
-<p>To launch the Android SDK and AVD Manager on Windows, execute <code>SDK
-Setup.exe</code>, at the root of the SDK directory. On Mac OS X or Linux,
-execute the <code>android</code> tool in the <code>&lt;sdk&gt;/tools/</code>
-folder. For detailed instructions, see <a
-href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a>.</p>
+@jd:body
-<p><strong>Done!</strong></p>
+<p>Here's an overview of the steps you must follow to set up the Android SDK:</p>
-<p>If you are new to Android, you can use the <a
-href="{@docRoot}resources/tutorials/hello-world.html">Hello World</a> tutorial to
-get started quickly. <a href="{@docRoot}sdk/installing.html#NextSteps">Next
-Steps</a> offers other suggestions of how to begin.</p>
+<ol>
+ <li>Prepare your development computer and ensure it meets the system requirements.</li>
+ <li>Install the SDK starter package from the table above. (If you're on Windows, download the
+installer for help with the initial setup.)</li>
+ <li>Install the ADT Plugin for Eclipse (if you'll be developing in Eclipse).</li>
+ <li>Add Android platforms and other components to your SDK.</li>
+ <li>Explore the contents of the Android SDK (optional).</li>
+</ol>
-<p>For a more detailed guide to installing and setting up the SDK, read <a
+<p>To get started, download the appropriate package from the table above, then read the guide to <a
href="installing.html">Installing the SDK</a>.</p>
diff --git a/docs/html/sdk/installing.jd b/docs/html/sdk/installing.jd
index 73190a0..4cb1bb2 100644
--- a/docs/html/sdk/installing.jd
+++ b/docs/html/sdk/installing.jd
@@ -3,19 +3,63 @@ sdk.preview=0
@jd:body
+
+<script type="text/javascript">
+function toggleDiv(link) {
+ var toggleable = $(link).parent();
+ if (toggleable.hasClass("closed")) {
+ //$(".toggleme", toggleable).slideDown("fast");
+ toggleable.removeClass("closed");
+ toggleable.addClass("open");
+ $(".toggle-img", toggleable).attr("title", "hide").attr("src", (toRoot +
+"assets/images/triangle-opened.png"));
+ } else {
+ //$(".toggleme", toggleable).slideUp("fast");
+ toggleable.removeClass("open");
+ toggleable.addClass("closed");
+ $(".toggle-img", toggleable).attr("title", "show").attr("src", (toRoot +
+"assets/images/triangle-closed.png"));
+ }
+ return false;
+}
+</script>
+<style>
+.toggleable {
+ padding: .25em 1em 0em 1em;
+ margin-bottom: 0;
+}
+.toggleme {
+ padding: 1em 1em 0 2em;
+ line-height:1em;
+}
+.toggleable a {
+ text-decoration:none;
+}
+.toggleme a {
+ text-decoration:underline;
+}
+.toggleable.closed .toggleme {
+ display:none;
+}
+#jd-content .toggle-img {
+ margin:0;
+}
+</style>
+
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
- <li><a href="#Preparing">Preparing Your Development Computer</a></li>
- <li><a href="#Installing">Downloading the SDK Starter Package</a></li>
- <li><a href="#InstallingADT">Installing the ADT Plugin for Eclipse</a></li>
- <li><a href="#components">Adding Platforms and Other Components</a>
- <ol>
- <li><a href="#which">Which components do I need?</a></li>
- </ol></li>
- <li><a href="#sdkContents">Exploring the SDK</a></li>
+ <li><a href="#Preparing">1. Preparing Your Development Computer</a></li>
+ <li><a href="#Installing">2. Downloading the SDK Starter Package</a></li>
+ <li><a href="#InstallingADT">3. Installing the ADT Plugin for Eclipse</a></li>
+ <li><a href="#components">4. Adding Platforms and Other Components</a>
+ <ol>
+ <li><a href="#components">Available Components</a></li>
+ <li><a href="#which">Recommended Components</a></li>
+ </ol></li>
+ <li><a href="#sdkContents">5. Exploring the SDK (Optional)</a></li>
<li><a href="#NextSteps">Next Steps</a></li>
<li><a href="#troubleshooting">Troubleshooting</a></li>
</ol>
@@ -29,98 +73,60 @@ sdk.preview=0
</div>
</div>
-<p>This page describes how to install the Android SDK
+<p>This page describes how to install the Android SDK
and set up your development environment for the first time.</p>
-<p>If you encounter any problems during installation, see the
+<p>If you encounter any problems during installation, see the
<a href="#troubleshooting">Troubleshooting</a> section at the bottom of
this page.</p>
<h4>Updating?</h4>
-<p>If you are currently using the Android 1.6 SDK or later and want to update
-to the latest tools or platforms, you do not need to install a new SDK. Instead,
-you can simply update the individual components in your SDK using the
-Android SDK and AVD Manager tool. For information about how to do that, see <a
-href="{@docRoot}sdk/adding-components.html#UpdatingComponents">Updating SDK
-Components</a></p>
-
-<p>If you are using Android 1.5 SDK or earlier, you should install a new SDK as
-described in this document and move your application projects to the new
-SDK environment. </p>
+<p>If you already have an Android SDK, use the <em>Android SDK and AVD Manager</em> tool to install
+updated tools and new Android platforms into your existing environment. For information about how to
+do that, see <a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a></p>
<h2 id="Preparing">Step 1. Preparing Your Development Computer</h2>
<p>Before getting started with the Android SDK, take a moment to confirm that
your development computer meets the <a href="requirements.html">System
-Requirements</a>. In particular, you may need to install the <a
-href="http://java.sun.com/javase/downloads/index.jsp">JDK</a> before
-continuing, if it's not already installed on your computer. </p>
+Requirements</a>. In particular, you might need to install the <a
+href="http://java.sun.com/javase/downloads/index.jsp">JDK</a>, if you don't have it already. </p>
<p>If you will be developing in Eclipse with the Android Development
-Tools (ADT) Plugin &mdash; the recommended path if you are new to
-Android &mdash; make sure that you have a suitable version of Eclipse
-installed on your computer (3.4 or newer is recommended). If you need
-to install Eclipse, you can download it from this location: </p>
-
+Tools (ADT) Plugin&mdash;the recommended path if you are new to
+Android&mdash;make sure that you have a suitable version of Eclipse
+installed on your computer (3.4 or newer is recommended). If you need
+to install Eclipse, you can download it from this location: </p>
+
<p style="margin-left:2em;"><a href=
-"http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a></p>
-
-<p>A Java or RCP version of Eclipse is recommended. For Eclipse 3.5, the
-"Eclipse Classic" version is recommended.</p>
+"http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a></p>
+<p>For Eclipse 3.5 or newer, the "Eclipse Classic" version is recommended. Otherwise, a Java or
+RCP version of Eclipse is recommended.</p>
-<h2 id="Installing">Step 2. Downloading the SDK Starter Package</h2>
-<p>The first step in setting up your environment for developing Android applications
-is downloading the Android SDK starter package. The starter package is not a full
-development environment &mdash; it includes only the core SDK Tools, which you can
-use to download the rest of the SDK components. </p>
-
-<p>You can get the latest version of the SDK starter package from the <a
-href="{@docRoot}sdk/index.html">SDK download page</a>. Make sure to download the
-package that is appropriate for your development computer.</p>
-
-<p>After downloading, unpack the Android SDK archive to a safe location on your
-machine. By default, the SDK files are unpacked into a directory named
-<code>android-sdk-&lt;machine-platform&gt;</code>. Make a note of the name and
-location of the unpacked SDK directory on your system &mdash; you will need to
-refer to the SDK directory later, when setting up the ADT plugin or when using
-the SDK tools.</p>
-
-<p>Optionally, you may want to add the location of the SDK's primary
-<code>tools</code> directory to your system <code>PATH</code>. The primary
-<code>tools/</code> directory is located at the root of the SDK folder. Adding
-<code>tools</code> to your path lets you run Android Debug Bridge (adb) and the
-other command line <a
-href="{@docRoot}guide/developing/tools/index.html">tools</a> without needing to
-supply the full path to the tools directory. </p>
+<h2 id="Installing">Step 2. Downloading the SDK Starter Package</h2>
-<ul>
- <li>On Linux, edit your <code>~/.bash_profile</code> or <code>~/.bashrc</code> file. Look
- for a line that sets the PATH environment variable and add the
- full path to the <code>tools/</code> directory to it. If you don't
- see a line setting the path, you can add one:</li>
+<p>The SDK starter package is not a full
+development environment&mdash;it includes only the core SDK Tools, which you can
+use to download the rest of the SDK components (such as the latest Android platform).</p>
- <ul><code>export PATH=${PATH}:<em>&lt;your_sdk_dir&gt;</em>/tools</code></ul>
+<p>If you haven't already, get the latest version of the SDK starter package from the <a
+href="{@docRoot}sdk/index.html">SDK download page</a>.</p>
- <li>On a Mac OS X, look in your home directory for <code>.bash_profile</code> and
- proceed as for Linux. You can create the <code>.bash_profile</code> if
- you haven't already set one up on your machine. </li>
+<p>If you downloaded a {@code .zip} or {@code .tgz} package (instead of the SDK installer), unpack
+it to a safe location on your machine. By default, the SDK files are unpacked
+into a directory named <code>android-sdk-&lt;machine-platform&gt;</code>.</p>
- <li>On Windows, right-click on My Computer, and select Properties.
- Under the Advanced tab, hit the Environment Variables button, and in the
- dialog that comes up, double-click on Path (under System Variables). Add the full path to the
- <code>tools/</code> directory to the path. </li>
- </ul>
+<p>If you downloaded the Windows installer ({@code .exe} file), run it now and it will check
+whether the proper Java SE Development Kit (JDK) is installed (installing it, if necessary), then
+install the SDK Tools into a default location (which you can modify).</p>
-<p>If you will be using the Eclipse IDE as your development environment, the
-next section describes how to install the Android Development Tools (ADT) plugin
-and set up Eclipse. If you choose not to use Eclipse, you can develop Android
-applications in an IDE of your choice and then compile, debug and deploy using
-the tools included in the SDK (skip to <a href="#components">Adding Platforms
-and Other Components</a>).</p>
+<p>Make a note of the name and location of the SDK directory on your system&mdash;you will need to
+refer to the SDK directory later, when setting up the ADT plugin and when using
+the SDK tools from command line.</p>
<h2 id="InstallingADT">Step 3. Installing the ADT Plugin for Eclipse</h2>
@@ -129,64 +135,87 @@ and Other Components</a>).</p>
Development Tools (ADT), that is designed to give you a powerful, integrated
environment in which to build Android applications. It extends the capabilites
of Eclipse to let you quickly set up new Android projects, create an application
-UI, add components based on the Android Framework API, debug your applications
+UI, debug your applications
using the Android SDK tools, and even export signed (or unsigned) APKs in order
to distribute your application. In general, developing in Eclipse with ADT is a
highly recommended approach and is the fastest way to get started with Android.
</p>
<p>If you'd like to use ADT for developing Android applications, install it now.
-Read <a href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin for Eclipse</a> for
-step-by-step installation instructions, then return here to continue with the
-last step in setting up your SDK: adding platforms and other
-components.</p>
+Read <a href="{@docRoot}sdk/eclipse-adt.html#installing">Installing the ADT Plugin</a> for
+step-by-step installation instructions, then return here to continue the
+last step in setting up your Android SDK.</p>
-<p>If you prefer to work in an IDE other than Eclipse, you do not need to
+<p>If you prefer to work in a different IDE, you do not need to
install Eclipse or ADT, instead, you can directly use the SDK tools to build and
-debug your application.</p>
+debug your application. The developer guide has more information about <a
+href="{@docRoot}guide/developing/other-ide.html">Developing in Other IDEs</a>.</p>
+
<h2 id="components">Step 4. Adding Android Platforms and Other Components</h2>
-<div class="sidebox-wrapper" style="margin-right:2.5em;">
-<div class="sidebox"> <h2>Using the Android SDK and AVD Manager</h2>
+<p>The last step in setting up your SDK is using the <em>Android SDK and AVD Manager</em> (a
+tool included in the SDK starter package) to download
+essential SDK components into your development environment.</p>
+
+<p>The SDK uses a modular structure that separates the major parts of the SDK&mdash;Android platform
+versions, add-ons, tools, samples, and documentation&mdash;into a set of separately installable
+components. The SDK starter package, which you've already downloaded, includes only a single
+component: the latest version of the SDK Tools. To develop an Android
+application, you also need to download at least one Android platform and the SDK Platform-tools
+(tools that the latest platform depend upon). However, downloading
+additional components is highly recommended.</p>
+
+<p>If you used the Windows installer, when you complete the installation wizard, it will launch the
+Android SDK and AVD Manager with a default set of platforms and other components selected
+for you to install. Simply click <strong>Install</strong> to accept the recommended set of
+components and install them. You can then skip to <a href="#sdkContents">Step 5</a>, but we
+recommend you first read the section about the <a href="#components">Available Components</a> to
+better understand the components available from the Android SDK and AVD Manager.</p>
+
+<p>You can launch the Android SDK and AVD Manager in one of the following ways:</p>
+<ul>
+ <li>From within Eclipse, select <strong>Window &gt; Android SDK and AVD Manager</strong>.</li>
+ <li>On Windows, double-click the <code>SDK Manager.ext</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: <pre>android</pre> </li>
+</ul>
+
+<p>To download components, use the graphical UI of the Android SDK and AVD
+Manager, shown in Figure 1, to browse the SDK repository and select new or updated
+components. The Android SDK and AVD Manager will install the selected components in
+your SDK environment. For information about which components you should download, see the following
+section about <a href="#which">Recommended Components</a>.</p>
-<p>The <em>Android SDK and AVD Manager</em> is a tool that you will use often,
-to add components to your SDK environment and manage Android Virtual Devices.
-</p>
+<img src="/images/sdk_manager_packages.png" />
+<p class="img-caption"><strong>Figure 1.</strong> The Android SDK and AVD Manager's
+<strong>Available Packages</strong> panel, which shows the SDK components that are
+available for you to download into your environment.</p>
-<p style="margin-top:.5em;">The tool is pre-installed in your SDK. See <a
-href="adding-components.html">Adding SDK Components</a> for details on how to
-launch and use the tool.</p>
-</div>
-</div>
-<p>The last step in setting up your SDK is using a tool included the SDK starter
-package &mdash; the <em>Android SDK and AVD Manager</em> &mdash; to download
-essential components into your development environment. Read the information
-below to understand what components you'll need, then see <a
-href="adding-components.html">Adding SDK Components</a> for step-by-step
-instructions on how to launch the Android SDK and AVD Manager and download the
-components into your environment.</p>
-
-<p>The SDK uses a modular structure that separates the major parts of the SDK
-&mdash; Android platform versions, add-ons, tools, samples, and the API
-documentation &mdash; into a set of separately installable components. The SDK
-starter package, which you've already downloaded, includes only a single
-component: the latest version of the SDK Tools. To develop any Android
-application, you also need to download at least one Android platform into your
-environment, although downloading additional components is highly recommended.
-See <a href="#which">Which components do I need?</a> for information about
-which components are required and which are optional.</p>
-
-<p>The SDK repository offers these types of components:</p>
+<h3 id="components">Available Components</h3>
+
+<p>By default, there are two repositories of components for your SDK: <em>Android
+Repository</em> and <em>Third party Add-ons</em>.</p>
+
+<p>The <em>Android Repository</em> offers these types of components:</p>
<ul>
<li><strong>SDK Tools</strong> (pre-installed in the Android SDK starter
-package) &mdash; Contains the full set of SDK tools for developing, debugging,
-and testing your application code and UI. You can read about the tools in the <a
-href="{@docRoot}guide/developing/tools/index.html">Dev Guide</a> and access them
-in the <code>&lt;sdk&gt;/tools/</code> directory. </li>
+package) &mdash; Contains tools for debugging
+and testing your application and other utility tools. You can access these
+in the <code>&lt;sdk&gt;/tools/</code> directory of your SDK and read more about them in the <a
+href="{@docRoot}guide/developing/tools/index.html">Tools</a> section of the developer guide. </li>
+
+<li><strong>SDK Platform-tools</strong> &mdash; Contains tools that are required to develop and
+debug your application, but which are developed alongside the Android platform in order to support
+the latest features. These tools are typically updated only when a new platform becomes
+available. You can access these
+in the <code>&lt;sdk&gt;/platform-tools/</code> directory. Read more about them in
+the <a href="{@docRoot}guide/developing/tools/index.html">Tools</a> section of the developer guide.
+</li>
<li><strong>Android platforms</strong> &mdash; An SDK platform is
available for every production Android platform deployable to Android-powered
@@ -195,20 +224,14 @@ system image, sample code, emulator skins, and any version specific tools. For
detailed information about each platform, see the overview documents available
under the section "Downloadable SDK Components," at left. </li>
-<li><strong>SDK Add-Ons</strong> &mdash; SDK add-ons provide a development
-environment for specific Android external
-library or a customized (but fully compliant) Android system image. The Android
-SDK repository offers the Google APIs Add-On, which gives your application
-access to powerful mapping capabilities through the
-<code>com.google.android.maps</code> library. You can also add additional
-repositories, so that you can download other SDK add-ons, where available. </li>
-
-<li><strong>USB Driver for Windows</strong> &mdash; Contains driver files
+<li><strong>USB Driver for Windows</strong> (Windows only) &mdash; Contains driver files
that you can install on your Windows computer, so that you can run and debug
your applications on an actual device. You <em>do not</em> need the USB driver unless
you plan to debug your application on an actual Android-powered device. If you
-develop on Mac OS X or Linux, you do not need a special driver to debug
-your application on an Android-powered device.</li>
+develop on Mac OS X or Linux, you do not need a special driver to debug
+your application on an Android-powered device. (See <a
+href="{@docRoot}guide/developing/device.html">Developing on a Device</a> for more information
+about developing on a real device.)</li>
<li><strong>Samples</strong> &mdash; Contains the sample code and apps available
for each Android development platform. If you are just getting started with
@@ -221,28 +244,18 @@ tutorials. --></li>
multiversion documentation for the Android framework API. </li>
</ul>
-<p>To download components, use the graphical UI of the Android SDK and AVD
-Manager, shown in Figure 1, to browse the SDK repository, select new or updated
-components for download, and then install the selected components in your SDK
-environment. </p>
+<p>The <em>Third party Add-ons</em> provide components that allow you to create a development
+environment using a specific Android external library (such as the Google Maps library) or a
+customized (but fully compliant) Android system image. You can add additional Add-on repositories,
+by clicking <strong>Add Add-on Site</strong>.</p>
-<div style="TEXT-ALIGN:left;width:600px;">
-<img src="/images/sdk_manager_packages.png"
-style="padding-bottom:0;margin-bottom:0;" />
-<p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0
-1em;"><strong>Figure 1.</strong> The Android SDK and AVD Manager's
-<strong>Available Packages</strong>
-panel, which shows the SDK components that are
-available for you to download into your environment. </p>
-</div>
-
-<h3 id="which">Which components do I need?</h3>
+<h3 id="which">Recommended Components</h3>
<p>The SDK repository contains a range of components that you can download.
Use the table below to determine which components you need, based on whether you
-want to set up a basic (but functionnal) development environment or a
-recommended or full development environment: </p>
+want to set up a basic, recommended, or full development environment:
+</p>
<table style="width:95%">
@@ -253,12 +266,21 @@ recommended or full development environment: </p>
</tr>
<tr>
-<td rowspan="2" style="font-size:.9em;background-color:#FFE;">Basic</td>
-<td style="font-size:.9em;background-color:#FFE;color:gray">SDK Tools</td>
-<td style="font-size:.9em;background-color:#FFE;color:gray">If you've installed
-the SDK starter package, then you already have this component preinstalled. The
-SDK Tools component is required &mdash; you can't develop or build an application
-without it. </td>
+<td rowspan="3" style="font-size:.9em;background-color:#FFE;">Basic</td>
+<td style="font-size:.9em;background-color:#FFE;">SDK Tools</td>
+<td style="font-size:.9em;background-color:#FFE;">If you've just installed
+the SDK starter package, then you already have the latest version of this component. The
+SDK Tools component is required to develop an Android application. Make sure you keep this up to
+date.</td>
+</tr>
+
+<tr>
+<td style="font-size:.9em;background-color:#FFE;">SDK Platform-tools</td>
+<td style="font-size:.9em;background-color:#FFE;">This includes more tools that are required
+for application development. These tools are platform-dependent and typically update only when
+a new SDK platform is made available, in order to support new features in the platform. These
+tools are always backward compatible with older platforms, but you must be sure that you have
+the latest version of these tools when you install a new SDK platform.</td>
</tr>
<tr>
@@ -269,14 +291,15 @@ you will be able to compile your application and set up an Android Virtual
Device (AVD) to run it on (in the emulator). To start with, just download the
latest version of the platform. Later, if you plan to publish your application,
you will want to download other platforms as well, so that you can test your
-application on the full range of Android platform versions that your customers
-are using.</td>
+application on the full range of Android platform versions that your application supports.</td>
</tr>
<tr>
-<td colspan="3" style="border:none;text-align:center;font-size:1.5em;font-weight:bold;">+</td>
+<td colspan="2"
+style="border:none;text-align:center;font-size:1.5em;font-weight:bold;">+</td><td
+style="border:none"></td>
</tr>
<tr>
-<td rowspan="3">Recommended</td>
+<td rowspan="3">Recommended<br/>(plus Basic)</td>
<td>Documentation</td>
<td>The Documentation component is useful because it lets you work offline and
also look up API reference information from inside Eclipse.</td>
@@ -298,10 +321,12 @@ debugging and testing. For Mac OS X and Linux platforms, no
special driver is needed.</td>
</tr>
<tr>
-<td colspan="3" style="border:none;text-align:center;font-size:1.5em;font-weight:bold;">+</td>
+<td colspan="2"
+style="border:none;text-align:center;font-size:1.5em;font-weight:bold;">+</td><td
+style="border:none"></td>
</tr>
<tr>
-<td rowspan="3">Full</td>
+<td rowspan="3">Full<br/>(plus Recommended)</td>
<td>Google APIs</td>
<td>The Google APIs add-on gives your application access to the Maps external
library, which makes it easy to display and manipulate Maps data in your
@@ -320,22 +345,21 @@ applications on different platforms by running in an Android Virtual Device
</table>
-<p>For step-by-step instructions on how to use the Android SDK and AVD Manager
-to add components, see the <a href="{@docRoot}sdk/adding-components.html">Adding
-SDK Components</a> document. </p>
+<p>Once you've installed at least the basic configuration of SDK components, you're ready to start
+developing Android apps. The next section describes the contents of the Android SDK to familiarize
+you with the components you've just installed.</p>
-<p>For revision notes and other detailed information about individual SDK
-components, see the documents listed under "Downloadable SDK Components" in
-the navigation at left.</p>
+<p>For more information about using the Android SDK and AVD Manager, see the <a
+href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a> document. </p>
-<h2 id="sdkContents">Step 5. Exploring the SDK</h2>
+<h2 id="sdkContents">Step 5. Exploring the SDK (Optional)</h2>
<p>Once you've installed the SDK and downloaded the platforms, documentation,
-and add-ons that you need, open the SDK directory and take a look at what's
+and add-ons that you need, we suggest that you open the SDK directory and take a look at what's
inside.</p>
-<p>The table below describes the full SDK directory contents, with components
+<p>The table below describes the full SDK directory contents, with components
installed. </p>
<table>
@@ -351,10 +375,19 @@ devices. </td>
<tr>
<td colspan="3"><code>docs/</code></td>
<td>A full set of documentation in HTML format, including the Developer's Guide,
-API Reference, and other information. To read the documentation, load the
+API Reference, and other information. To read the documentation, load the
file <code>offline.html</code> in a web browser.</td>
</tr>
<tr>
+<td colspan="3"><code>platform-tools/</code></td>
+<td>Contains development tools that may be updated with each platform release (from the <em>Android
+SDK Platform-tools</em> component). Tools in here include {@code adb}, {@code dexdump}, and others
+others that you don't typically use directly. These tools are separate from the generic development
+tools in the {@code tools/} directory, because these tools may be updated in order to support new
+features in the latest Android platform, whereas the other tools have no dependencies on the
+platform version.</td>
+</tr>
+<tr>
<td colspan="3"><code>platforms/</code></td>
<td>Contains a set of Android platform versions that you can develop
applications against, each in a separate directory. </td>
@@ -362,7 +395,7 @@ applications against, each in a separate directory. </td>
<tr>
<td style="width:2em;border-bottom-color:white;"></td>
<td colspan="2"><code><em>&lt;platform&gt;</em>/</code></td>
-<td>Platform version directory, for example "android-1.6". All platform version
+<td>Platform version directory, for example "android-1.6". All platform version
directories contain a similar set of files and subdirectory structure.</td>
</tr>
@@ -376,8 +409,8 @@ directories contain a similar set of files and subdirectory structure.</td>
<td style="width:2em;border-bottom-color:white;"></td>
<td style="width:2em;border-bottom-color:white;"></td>
<td><code>images/</code></td>
-<td>Storage area for default disk images, including the Android system image,
-the default userdata image, the default ramdisk image, and more. The images
+<td>Storage area for default disk images, including the Android system image,
+the default userdata image, the default ramdisk image, and more. The images
are used in emulator sessions.</td>
</tr>
<tr>
@@ -397,7 +430,8 @@ designed for a specific screen resolution.</td>
<td style="width:2em;border-bottom-color:white;"></td>
<td style="width:2em;border-bottom-color:white;"></td>
<td><code>tools/</code></td>
-<td>Any development tools that are specific to the platform version.</td>
+<td>This directory is used only by SDK Tools r7 and below for development tools that are specific to
+this platform version&mdash;it's not used by SDK Tools r8 and above.</td>
</tr>
<tr>
<td style="width:2em;"></td>
@@ -411,18 +445,21 @@ version.</td>
<td>Sample code and apps that are specific to platform version.</td>
</tr>
<td colspan="3"><code>tools/</code></td>
-<td>Contains the set of development and profiling tools available to you, such
-as the emulator, the <code>android</code> tool, adb, ddms, and more.</td>
+<td>Contains the set of development and profiling tools that are platform-independent, such
+as the emulator, the AVD and SDK Manager, adb, ddms, hierarchyviewer and more. The tools in
+this directory may be updated at any time (from the <em>Android SDK Tools</em> component),
+independent of platform releases, whereas the tools in {@code platform-tools/} may be updated based
+on the latest platform release.</td>
</tr>
<tr>
<td colspan="3"><code>SDK Readme.txt</code></td>
-<td>A file that explains how to perform the initial setup of your SDK,
-including how to launch the Android SDK and AVD Manager tool on all
+<td>A file that explains how to perform the initial setup of your SDK,
+including how to launch the Android SDK and AVD Manager tool on all
platforms</td>
</tr>
<tr>
-<td colspan="3"><code>SDK Setup.exe</code></td>
-<td>Windows SDK only. A shortcut that launches the Android SDK and AVD
+<td colspan="3"><code>SDK Manager.exe</code></td>
+<td>Windows SDK only. A shortcut that launches the Android SDK and AVD
Manager tool, which you use to add components to your SDK. </td>
</tr>
<!--<tr>
@@ -433,6 +470,47 @@ documentation.</td>
</table>
+
+<p>Optionally, you might want to add the location of the SDK's <code>tools/</code> and
+<code>platform-tools</code> to your <code>PATH</code> environment variable, to provide easy
+access to the tools.</p>
+
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+width="9px" />
+ How to update your PATH</a>
+ <div class="toggleme">
+
+<p>Adding both <code>tools/</code> and <code>platform-tools/</code> to your PATH lets you run
+command line <a href="{@docRoot}guide/developing/tools/index.html">tools</a> without needing to
+supply the full path to the tool directories. Depending on your operating system, you can
+include these directories in your PATH in the following way:</p>
+
+<ul>
+
+ <li>On Windows, right-click on My Computer, and select Properties.
+ Under the Advanced tab, hit the Environment Variables button, and in the
+ dialog that comes up, double-click on Path (under System Variables). Add the full path to the
+ <code>tools/</code> and <code>platform-tools/</code> directories to the path. </li>
+
+ <li>On Linux, edit your <code>~/.bash_profile</code> or <code>~/.bashrc</code> file. Look
+ for a line that sets the PATH environment variable and add the
+ full path to the <code>tools/</code> and <code>platform-tools</code> directories to it. If you
+ don't see a line setting the path, you can add one:
+ <pre>export PATH=${PATH}:&lt;sdk&gt;/tools:&lt;sdk&gt;/platform-tools</pre>
+ </li>
+
+ <li>On a Mac OS X, look in your home directory for <code>.bash_profile</code> and
+ proceed as for Linux. You can create the <code>.bash_profile</code> if
+ you don't already have one. </li>
+</ul>
+
+</div><!-- end toggleme -->
+</div><!-- end toggleable -->
+
+
<h2 id="NextSteps">Next Steps</h2>
<p>Once you have completed installation, you are ready to
begin developing applications. Here are a few ways you can get started: </p>
@@ -447,7 +525,7 @@ begin developing applications. Here are a few ways you can get started: </p>
</li>
</ul>
-<p class="caution">Following the Hello World tutorial is an essential
+<p class="note">Following the Hello World tutorial is an essential
first step in getting started with Android development. </p>
<p><strong>Learn about Android</strong></p>
@@ -481,20 +559,20 @@ Android-powered device to run and test your application.</li>
<ul>
<li>The <a href="{@docRoot}resources/tutorials/notepad/index.html">
- Notepad Tutorial</a> shows you how to build a full Android application
- and provides helpful commentary on the Android system and API. The
+ Notepad Tutorial</a> shows you how to build a full Android application
+ and provides helpful commentary on the Android system and API. The
Notepad tutorial helps you bring together the important design
- and architectural concepts in a moderately complex application.
+ and architectural concepts in a moderately complex application.
</li>
</ul>
-<p class="caution">Following the Notepad tutorial is an excellent
+<p class="note">Following the Notepad tutorial is an excellent
second step in getting started with Android development. </p>
<p><strong>Explore some code</strong></p>
<ul>
<li>The Android SDK includes sample code and applications for each platform
-version. You can browse the samples in the <a
+version. You can browse the samples in the <a
href="{@docRoot}resources/index.html">Resources</a> tab or download them
into your SDK using the Android SDK and AVD Manager. Once you've downloaded the
samples, you'll find them in
@@ -517,7 +595,7 @@ samples, you'll find them in
<ul>
<li>If you need help installing and configuring Java on your
- development machine, you might find these resources helpful:
+ development machine, you might find these resources helpful:
<ul>
<li><a href="https://help.ubuntu.com/community/Java">https://help.ubuntu.com/community/Java </a></li>
<li><a href="https://help.ubuntu.com/community/Java">https://help.ubuntu.com/community/JavaInstallation</a></li>
@@ -537,7 +615,7 @@ samples, you'll find them in
eclipse.org (<a
href="http://www.eclipse.org/downloads/">http://www.eclipse.org/
downloads/</a>). A Java or RCP version of Eclipse is recommended.</li>
- <li>Follow the steps given in previous sections to install the SDK
+ <li>Follow the steps given in previous sections to install the SDK
and the ADT plugin. </li>
</ol>
</li>
diff --git a/docs/html/sdk/ndk/index.jd b/docs/html/sdk/ndk/index.jd
index 69cc73d..0f36345 100644
--- a/docs/html/sdk/ndk/index.jd
+++ b/docs/html/sdk/ndk/index.jd
@@ -1,16 +1,16 @@
ndk=true
-ndk.win_download=android-ndk-r4-windows.zip
-ndk.win_bytes=45778965
-ndk.win_checksum=1eded98a7f5cd5e71f8ac74565f73f11
+ndk.win_download=android-ndk-r4b-windows.zip
+ndk.win_bytes=45792835
+ndk.win_checksum=e397145e155a639be53ee4b6db8ad511
-ndk.mac_download=android-ndk-r4-darwin-x86.zip
-ndk.mac_bytes=50572163
-ndk.mac_checksum=b7d5f149fecf951c05a79b045f00419f
+ndk.mac_download=android-ndk-r4b-darwin-x86.zip
+ndk.mac_bytes=50586041
+ndk.mac_checksum=41dbd54335fb828ee408eab17103a1b0
-ndk.linux_download=android-ndk-r4-linux-x86.zip
-ndk.linux_bytes=49450682
-ndk.linux_checksum=0892b0637d45d145e045cc68e163dee3
+ndk.linux_download=android-ndk-r4b-linux-x86.zip
+ndk.linux_bytes=49464776
+ndk.linux_checksum=2deabcb125c219b34140975b710f00ec
page.title=Android NDK
@jd:body
@@ -60,504 +60,522 @@ padding: .25em 1em;
</style>
<div class="toggleable open">
- <a href="#" onclick="return toggleDiv(this)">
- <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
-Android NDK, Revision 4</a> <em>(May 2010)</em>
- <div class="toggleme">
-
-<dl>
-<dt>General notes:</dt>
-
-<dd>
-<ul>
-<li>Provides a simplified build system through the new <code>ndk-build</code> build
-command. </li>
-<li>Adds support for easy native debugging of generated machine code on production
-devices through the new <code>ndk-gdb</code> command.</li>
-<li>Adds a new Android-specific ABI for ARM-based CPU architectures,
-<code>armeabi-v7a</code>. The new ABI extends the existing <code>armeabi</code>
-ABI to include these CPU instruction set extensions:
-<ul>
-<li>Thumb-2 instructions</li>
-<li>VFP hardware FPU instructions (VFPv3-D16)</li>
-<li>Optional support for ARM Advanced SIMD (NEON) GCC intrinsics and VFPv3-D32.
-Supported by devices such as Verizon Droid by Motorola, Google Nexus One, and
-others.</li>
-</ul>
-<li>Adds a new <code>cpufeatures</code> static library (with sources) that lets
-your app detect the host device's CPU features at runtime. Specifically,
-applications can check for ARMv7-A support, as well as VFPv3-D32 and NEON
-support, then provide separate code paths as needed.</li>
-<li>Adds a sample application, <code>hello-neon</code>, that illustrates how to
-use the <code>cpufeatures</code> library to check CPU features and then provide
-an optimized code path using NEON instrinsics, if
-supported by the CPU.</li>
-<li>Lets you generate machine code for either or both of the instruction sets
-supported by the NDK. For example, you can build for both ARMv5 and ARMv7-A
-architectures at the same time and have everything stored to your application's
-final <code>.apk</code>.</li>
-<li>To ensure that your applications are available to users only if their
-devices are capable of running them, Android Market now filters applications
-based on the instruction set information included in your application &mdash; no
-action is needed on your part to enable the filtering. Additionally, the Android
-system itself also checks your application at install time and allows the
-installation to continue only if the application provides a library that is
-compiled for the device's CPU architecture.</li>
-<li>Adds support for Android 2.2, including a new stable API for accessing
-the pixel buffers of {@link android.graphics.Bitmap} objects from native
-code.</li>
-</ul>
-</dd>
-</dl>
-</div>
-</div>
-
-<div class="toggleable closed">
- <a href="#" onclick="return toggleDiv(this)">
- <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
-Android NDK, Revision 3</a> <em>(March 2010)</em>
- <div class="toggleme">
-
-<dl>
-<dt>General notes:</dt>
-
-<dd>
-<ul>
-<li>Adds OpenGL ES 2.0 native library support.</li>
-<li>Adds a sample application,<code>hello-gl2</code>, that illustrates the use of
-OpenGL ES 2.0 vertex and fragment shaders.</li>
-<li>The toolchain binaries have been refreshed for this release with GCC 4.4.0, which should generate slightly more compact and efficient machine code than the previous one (4.2.1). The NDK also still provides the 4.2.1 binaries, which you can optionally use to build your machine code.</li>
-</ul>
-</dd>
-</dl>
-</div>
-</div>
-
-<div class="toggleable closed">
- <a href="#" onclick="return toggleDiv(this)">
- <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
-Android NDK, Revision 2</a> <em>(September 2009)</em>
- <div class="toggleme">
-
-<p>Originally released as "Android 1.6 NDK, Release 1".</p>
-<dl>
-<dt>General notes:</dt>
-<dd>
-<ul>
-<li>Adds OpenGL ES 1.1 native library support.</li>
-<li>Adds a sample application, <code>san-angeles</code>, that renders 3D
-graphics through the native OpenGL ES APIs, while managing activity
-lifecycle with a {@link android.opengl.GLSurfaceView} object.
-</li>
-</ul>
-</dd>
-</dl>
- </div>
-</div>
-
-<div class="toggleable closed">
- <a href="#" onclick="return toggleDiv(this)">
- <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
-Android NDK, Revision 1</a> <em>(June 2009)</em>
- <div class="toggleme">
-
-<p>Originally released as "Android 1.5 NDK, Release 1".</p>
-<dl>
-<dt>General notes:</dt>
-<dd>
-<ul>
-<li>Includes compiler support (GCC) for ARMv5TE instructions, including Thumb-1
-instructions. </li>
-<li>Includes system headers for stable native APIs, documentation, and sample
-applications.</li>
-</ul>
-</dd>
-
-</dl>
- </div>
-</div>
-
-
-<h2 id="overview">What is the Android NDK?</h2>
-
-<p>The Android NDK is a toolset that lets you embed components that make use
-of native code in your Android applications.
-</p>
-
-<p>Android applications run in the Dalvik virtual machine. The NDK allows
-you to implement parts of your applications using native-code languages
-such as C and C++. This can provide benefits to certain classes of applications,
-in the form of reuse of existing code and in some cases increased speed.</p>
-
-<p>The NDK provides:</p>
-
-<ul>
-<li>A set of tools and build files used to generate native code libraries from C
-and C++ sources</li>
-<li>A way to embed the corresponding native libraries into an application package
-file (<code>.apk</code>) that can be deployed on Android devices</li>
-<li>A set of native system headers and libraries that will be supported in all
-future versions of the Android platform, starting from Android 1.5 </li>
-<li>Documentation, samples, and tutorials</li>
-</ul>
-
-<p>The latest release of the NDK supports these ARM instruction sets:</p>
-<ul>
-<li>ARMv5TE (including Thumb-1 instructions)</li>
-<li>ARMv7-A (including Thumb-2 and VFPv3-D16 instructions, with
-optional support for NEON/VFPv3-D32 instructions)</li>
-</ul>
-
-<p>Future releases of the NDK will also support:</p>
-
-<ul>
-<li>x86 instructions (see CPU-ARCH-ABIS.TXT for more information)</li>
-</ul>
-
-<p>ARMv5TE machine code will run on all ARM-based Android devices. ARMv7-A will
-run only on devices such as the Verizon Droid or Google Nexus One that have a
-compatible CPU. The main difference between the two instruction sets is that
-ARMv7-A supports hardware FPU, Thumb-2, and NEON instructions. You can target
-either or both of the instruction sets &mdash; ARMv5TE is the default, but
-switching to ARMv7-A is as easy as adding a single line to the application's
-Application.mk file, without needing to change anything else in the file. You
-can also build for both architectures at the same time and have everything
-stored in the final <code>.apk</code>. For complete information is provided in the
-CPU-ARCH-ABIS.TXT in the NDK package. </p>
-
-<p>The NDK provides stable headers for libc (the C library), libm (the Math
-library), OpenGL ES (3D graphics library), the JNI interface, and other
-libraries, as listed in the section below.</p>
-
-<p>The NDK will not benefit most applications. As a developer, you will need
-to balance its benefits against its drawbacks; notably, using native code does
-not result in an automatic performance increase, but does always increase
-application complexity. Typical good candidates for the NDK are self-contained,
-CPU-intensive operations that don't allocate much memory, such as signal processing,
-physics simulation, and so on. Simply re-coding a method to run in C usually does
-not result in a large performance increase. The NDK can, however, can be
-an effective way to reuse a large corpus of existing C/C++ code.</p>
-
-<p>Please note that the NDK <em>does not</em> enable you to develop native-only
-applications. Android's primary runtime remains the Dalvik virtual machine.</p>
-
-<h2 id="contents">Contents of the NDK</h2>
-
-<h4>Development tools</h4>
-
-<p>The NDK includes a set of cross-toolchains (compilers, linkers, etc..) that
-can generate native ARM binaries on Linux, OS X, and Windows (with Cygwin)
-platforms.</p>
-
-<p>It provides a set of system headers for stable native APIs that are
-guaranteed to be supported in all later releases of the platform:</p>
-
-<ul>
-<li>libc (C library) headers</li>
-<li>libm (math library) headers</li>
-<li>JNI interface headers</li>
-<li>libz (Zlib compression) headers</li>
-<li>liblog (Android logging) header</li>
-<li>OpenGL ES 1.1 and OpenGL ES 2.0 (3D graphics libraries) headers</li>
-<li>libjnigraphics (Pixel buffer access) header (for Android 2.2 and above).</li>
-<li>A Minimal set of headers for C++ support</li>
-</ul>
-
-<p>The NDK also provides a build system that lets you work efficiently with your
-sources, without having to handle the toolchain/platform/CPU/ABI details. You
-create very short build files to describe which sources to compile and which
-Android application will use them &mdash; the build system compiles the sources
-and places the shared libraries directly in your application project. </p>
-
-<p class="caution"><strong>Important:</strong> With the exception of the
-libraries listed above, native system libraries in the Android platform are
-<em>not</em> stable and may change in future platform versions.
-Your applications should <em>only</em> make use of the stable native system
-libraries provided in this NDK. </p>
-
-<h4>Documentation</h4>
-
-<p>The NDK package includes a set of documentation that describes the
-capabilities of the NDK and how to use it to create shared libraries for your
-Android applications. In this release, the documentation is provided only in the
-downloadable NDK package. You can find the documentation in the
-<code>&lt;ndk&gt;/docs/</code> directory. Included are these files:</p>
-
-<ul>
-<li>INSTALL.TXT &mdash; describes how to install the NDK and configure it for
-your host system</li>
-<li>OVERVIEW.TXT &mdash; provides an overview of the NDK capabilities and
-usage</li>
-<li>ANDROID-MK.TXT &mdash; describes the use of the Android.mk file, which
-defines the native sources you want to compile</li>
-<li>APPLICATION-MK.TXT &mdash; describes the use of the Application.mk file,
-which describes the native sources required by your Android application</li>
-<li>HOWTO.TXT &mdash; information about common tasks associated with NDK
-development.</li>
-<li>SYSTEM-ISSUES.TXT &mdash; known issues in the Android system images
-that you should be aware of, if you are developing using the NDK. </li>
-<li>STABLE-APIS.TXT &mdash; a complete list of the stable APIs exposed
-by headers in the NDK.</li>
-<li>CPU-ARCH-ABIS.TXT &mdash; a description of supported CPU architectures
-and how to target them. </li>
-<li>CPU-FEATURES.TXT &mdash; a description of the <code>cpufeatures</code>
-static library that lets your application code detect the target device's
-CPU family and the optional features at runtime. </li>
-<li>CPU-ARM-NEON.TXT &mdash; a description of how to build with optional
-ARM NEON / VFPv3-D32 instructions. </li>
-<li>CHANGES.TXT &mdash; a complete list of changes to the NDK across all
-releases.</li>
-</ul>
-
-<p>Additionally, the package includes detailed information about the "bionic"
-C library provided with the Android platform that you should be aware of, if you
-are developing using the NDK. You can find the documentation in the
-<code>&lt;ndk&gt;/docs/system/libc/</code> directory:</p>
-
-<ul>
-<li>OVERVIEW.TXT &mdash; provides an overview of the "bionic" C library and the
-features it offers.</li>
-</ul>
-
-<h4>Sample applications</h4>
-
-<p>The NDK includes sample Android applications that illustrate how to use
-native code in your Android applications. For more information, see
-<a href="#samples">Using the Sample Applications</a>.</p>
-
-<h2 id="requirements">System and Software Requirements</h2>
-
-<p>The sections below describe the system and software requirements for using
-the Android NDK, as well as platform compatibility considerations that affect
-appplications using libraries produced with the NDK. </p>
-
-<h4>The Android SDK</h4>
-<ul>
- <li>A complete Android SDK installation (including all dependencies) is
-required.</li>
- <li>Android 1.5 SDK or later version is required.</li>
-</ul>
-
-<h4>Supported operating systems</h4>
-<ul>
- <li>Windows XP (32-bit) or Vista (32- or 64-bit)</li>
- <li>Mac OS X 10.4.8 or later (x86 only)</li>
- <li>Linux (32- or 64-bit, tested on Linux Ubuntu Dapper Drake)</li>
-</ul>
-
-<h4>Required development tools</h4>
-<ul>
- <li>For all development platforms, GNU Make 3.81 or later is required. Earlier
-versions of GNU Make might work but have not been tested.</li>
- <li>A recent version of awk (either GNU Awk or Nawk) is also required.</li>
- <li>For Windows, <a
-href="http://www.cygwin.com">Cygwin</a> 1.7 or higher is required. The NDK
-will <em>not</em> work with Cygwin 1.5 installations.</li>
-</ul>
-
-<h4>Android platform compatibility</h4>
-<ul>
- <li>The native libraries created by the Android NDK can only be used on
-devices running the Android 1.5 platform version or later. This is due to
-toolchain and ABI related changes that make the native libraries incompatible
-with 1.0 and 1.1 system images.</li>
- <li>For this reason, you should use native libraries produced with the NDK in
-applications that are deployable to devices running the Android 1.5 platform
-version or later. </li>
- <li>To ensure compatibility, an application using a native library
-produced with the NDK <em>must</em> declare a <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code>&lt;uses-sdk&gt;</code></a>
-element in its manifest file, with an <code>android:minSdkVersion</code> attribute
-value of "3" or higher. For example:
-
-<pre style="margin:1em;">&lt;manifest&gt;
- ...
- &lt;uses-sdk android:minSdkVersion="3" /&gt;
- ...
-&lt;/manifest&gt;</pre>
-</li>
-
-<li>If you use this NDK to create a native library that uses the
-OpenGL ES APIs, the application containing the library can be deployed only to
-devices running the minimum platform versions described in the table below.
-To ensure compatibility, make sure that your application declares the proper
-<code>android:minSdkVersion</code></a> attribute value, as given in the table.</p>
-
-<table style="margin:1em;">
-<tr>
-<th>OpenGL ES Version Used</th>
-<th>Compatible Android Platform(s)</th>
-<th>Required uses-sdk Attribute</th>
-</tr>
-<tr><td>OpenGL ES 1.1</td><td>Android 1.6 and higher</td><td><code>android:minSdkVersion="4"</code></td></tr>
-<tr><td>OpenGL ES 2.0</td><td>Android 2.0 and higher</td><td><code>android:minSdkVersion="5"</code></td></tr>
-</table>
-
-<p>For more information about API Level and its relationship to Android
-platform versions, see <a href="{@docRoot}guide/appendix/api-levels.html">
-Android API Levels</a>.</p></li>
-
-<li>Additionally, an application using the OpenGL ES APIs should declare a
-<code>&lt;uses-feature&gt;</code> element in its manifest, with an
-<code>android:glEsVersion</code> attribute that specifies the minimum OpenGl ES
-version required by the application. This ensures that Android Market will show
-your application only to users whose devices are capable of supporting your
-application. For example:
-
-<pre style="margin:1em;">&lt;manifest&gt;
- ...
-<!-- Declare that the application uses the OpenGL ES 2.0 API and is designed
- to run only on devices that support OpenGL ES 2.0 or higher. -->
- &lt;uses-feature android:glEsVersion="0x00020000" /&gt;
- ...
-&lt;/manifest&gt;</pre>
-
-<p>For more information, see the <a
-href="{@docRoot}guide/topics/manifest/uses-feature-element.html"><code>&lt;uses-feature&gt;</code></a>
-documentation.</p></li>
-
-<li>If you use this NDK to create a native library that uses the API to access
-Android {@link android.graphics.Bitmap} pixel buffers, the application
-containing the library can be deployed only to devices running Android 2.2 (API
-level 8) or higher. To ensure compatibility, make sure that your application
-declares <code>&lt;uses-sdk android:minSdkVersion="8" /&gt;</code>attribute
-value in its manifest.</li>
-</ul>
-
-<h2 id="installing">Installing the NDK</h2>
-
-<p>Installing the NDK on your development computer is straightforward and
-involves extracting the NDK from its download package. Unlike previous releases,
-there is no need to run a host-setup script.</p>
-
-<p>Before you get started make sure that you have downloaded the latest <a
-href="{@docRoot}sdk/index.html">Android SDK</a> and upgraded your applications
-and environment as needed. The NDK will not work with older versions of the
-Android SDK. Also, take a moment to review the <a href="#requirements">System
-and Software Requirements</a> for the NDK, if you haven't already. </p>
-
-<p>To install the NDK, follow these steps:</p>
-
-<ol>
-<li>From the table at the top of this page, select the NDK package that is
-appropriate for your development computer and download the package.</li>
-<li>Uncompress the NDK download package using tools available on your computer.
-When uncompressed, the NDK files are contained in a directory called
-<code>android-ndk-&lt;version&gt;</code>. You can rename the NDK directory if
-necessary and you can move it to any location on your computer. This
-documentation refers to the NDK directory as <code>&lt;ndk&gt;</code>. </li>
-</ol>
-
-<p>You are now ready start working with the NDK. </p>
-
-<h2 id="gettingstarted">Getting Started with the NDK</h2>
-
-<p>Once you've installed the NDK successfully, take a few minutes to read the
-documentation included in the NDK. You can find the documentation in the
-<code>&lt;ndk&gt;/docs/</code> directory. In particular, please read the
-OVERVIEW.TXT document completely, so that you understand the intent of the NDK
-and how to use it.</p>
-
-<p>If you used a previous version of the NDK, take a moment to review the
-list of NDK changes in the CHANGES.TXT document. </p>
-
-<p>Here's the general outline of how you work with the NDK tools:</p>
-
-<ol>
-<li>Place your native sources under
-<code>&lt;project&gt;/jni/...</code></li>
-<li>Create <code>&lt;project&gt;/jni/Android.mk</code> to
-describe your native sources to the NDK build system</li>
-<li>Optional: Create <code>&lt;project&gt;/jni/Application.mk</code>.</li>
-<li>Build your native code by running the 'ndk-build' script from your projet's directory.
-It is located in the top-level NDK directory:
-
-<p><pre>
-$ cd &lt;project&gt;
-$ &lt;ndk&gt;/ndk-build
-</pre></p>
-
-<p>The build tools copy the stripped, shared libraries needed by your
-application to the proper location in the application's project directory.</p>
-</li>
-
-<li>Finally, compile your application using the SDK tools in the usual way. The
-SDK build tools will package the shared libraries in the application's
-deployable <code>.apk</code> file. </p></li>
-
-</ol>
-
-<p>For complete information on all of the steps listed above, please see the
-documentation included with the NDK package. </p>
-
-
-<h2 id="samples">Using the Sample Applications</h2>
-
-<p>The NDK includes sample applications that illustrate how to use native
-code in your Android applications:</p>
-
-<ul>
-<li><code>hello-jni</code> &mdash; a simple application that loads a string from
-a native method implemented in a shared library and then displays it in the
-application UI. </li>
-<li><code>two-libs</code> &mdash; a simple application that loads a shared
-library dynamically and calls a native method provided by the library. In this
-case, the method is implemented in a static library imported by the shared
-library. </li>
-<li><code>san-angeles</code> &mdash; a simple application that renders 3D
-graphics through the native OpenGL ES APIs, while managing activity lifecycle
-with a {@link android.opengl.GLSurfaceView} object. </li>
-<li><code>hello-gl2</code> &mdash; a simple application that renders a triangle
-using OpenGL ES 2.0 vertex and fragment shaders.</li>
-<li><code>hello-neon</code> &mdash; a simple application that shows how to use
-the <code>cpufeatures</code> library to check CPU capabilities at runtime,
-then use NEON intrinsics if supported by the CPU. Specifically, the
-application implements two versions of a tiny benchmark for a FIR filter
-loop, a C version and a NEON-optimized version for devices that support it.</li>
-<li><code>bitmap-plasma</code> &mdash; a simple application that demonstrates
-how to access the pixel buffers of Android {@link android.graphics.Bitmap}
-objects from native code, and uses this to generate an old-school "plasma"
-effect. </li>
-</ul>
-
-<p>For each sample, the NDK includes the corresponding C source code and the
-necessary Android.mk and Application.mk files. There are located under
-<code>&lt;ndk&gt;/samples/&lt;name&gt;/</code> and their source code can be found under
-<code>&lt;ndk&gt;/samples/&lt;name&gt;/jni/</code>. </p>
-
-<p>You can build the shared libraries for the sample apps by going into <code>&lt;ndk&gt;/samples/&lt;name&gt;/</code>
-then calling the <code>ndk-build</code> command. The generated shared libraries will be located under
-<code>&lt;ndk&gt;/samples/&lt;name&gt;/libs/armeabi/</code> for (ARMv5TE machine code) and/or
-<code>&lt;ndk&gt;/samples/&lt;name&gt;/libs/armeabi-v7a/</code> for (ARMv7 machine code).
-</p>
-
-<p>Next, build the sample Android applications that use the shared
-libraries:</p>
-
-<ul>
-<li>If you are developing in Eclipse with ADT, use the New Project Wizard to
-create a new Android project for each sample, using the "Import from Existing
-Source" option and importing the source from
-<code>&lt;ndk&gt;/apps/&lt;app_name&gt;/project/</code>. Then, set up an AVD, if
-necessary, and build/run the application in the emulator. For more information
-about creating a new Android project in Eclipse, see <a
-href="{@docRoot}guide/developing/eclipse-adt.html">Developing in
-Eclipse</a>.</li>
-<li>If you are developing with Ant, use the <code>android</code> tool to create
-the build file for each of the sample projects at
-<code>&lt;ndk&gt;/apps/&lt;app_name&gt;/project/</code>. Then set up an AVD, if
-necessary, build your project in the usual way, and run it in the emulator.
-For more information, see <a
-href="{@docRoot}guide/developing/other-ide.html">Developing in Other
-IDEs</a>.</li>
-</ul>
-
-<h2>Discussion Forum and Mailing List</h2>
-
-<p>If you have questions about the NDK or would like to read or contribute to
-discussions about it, please visit the <a
-href="http://groups.google.com/group/android-ndk">android-ndk</a> group and
-mailing list.</p>
+ <a href="#"
+ onclick="return toggleDiv(this)"><img src="{@docRoot}assets/images/triangle-opened.png"
+ class="toggle-img"
+ height="9px"
+ width="9px" /> Android NDK, Revision 5</a> <em>(November 2010)</em>
+
+ <div class="toggleme">
+ <dl>
+ <dt>NDK r5 notes:</dt>
+
+ <dd>
+ <p>The r5 release of the NDK includes many new APIs, many of which are introduced to
+ support native game development and applications that require similar requirements. Most
+ notably, native activities are now supported, which allow you to write an application
+ entirely with native code. For detailed information describing the changes in this
+ release, read the CHANGES.HTML document included in the downloaded NDK package.</p>
+ </dd>
+ </dl>
+
+ <dl>
+ <dt>General notes:</dt>
+
+ <dd>
+ <ul>
+
+ <li>A new toolchain (based on GCC 4.4.3), which generates better code, and can also now
+be used as a standalone cross-compiler, for people who want to build their stuff with
+<code>./configure &amp;&amp; make</code>. See
+docs/STANDALONE-TOOLCHAIN.html for the details. The binaries for GCC 4.4.0 are still provided,
+but the 4.2.1 binaries were removed.</li>
+
+ <li>Support for prebuilt static and shared libraries (docs/PREBUILTS.html), module
+exports and imports to make sharing and reuse of third-party modules much easier
+(docs/IMPORT-MODULE.html explains why).</li>
+
+ <li>A C++ STL implementation (based on STLport) is now provided as a helper module. It
+can be used either as a static or shared library (details and usage exemple under
+sources/android/stlport/README). <strong>Note:</strong> For now, C++ Exceptions and RTTI are still
+not supported.</li>
+
+ <li>Improvements to the <code>cpufeatures</code> helper library to deal with buggy
+kernel that incorrectly report they run on an ARMv7 CPU (while the device really is an ARMv6). We
+recommend developers that use it to simply rebuild their applications to benefit from it, then
+upload to Market.</li>
+
+ <li>Adds support for native activities, which allows you to write completely native
+ applications.</li>
+
+ <li>Adds an EGL library that lets you create and manage OpenGL ES textures and
+ services.</li>
+
+ <li>Adds native support for the following:
+
+ <ul>
+ <li>Input subsystem (such as the keyboard and touch screen)</li>
+
+ <li>Window and surface subsystem</li>
+
+ <li>Audio APIs based on the OpenSL ES standard that support playback and recording
+ as well as control over platform audio effects</li>
+
+ <li>Event loop APIs to wait for things such as input and sensor events</li>
+
+ <li>Access to assets packaged in the <code>.apk</code></li>
+
+ <li>Access to sensor data (accelerometer, compass, gyroscope, etc.)</li>
+ </ul>
+ </li>
+
+ <li>New sample applications, <code>native-plasma</code> and
+ <code>native-activity</code>, to demonstrate how to write a native activity.</li>
+
+ <li>Plus many bugfixes and other small improvements; see docs/CHANGES.html for a more
+detailed list of changes.</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div class="toggleable closed">
+ <a href="#"
+ onclick="return toggleDiv(this)"><img src="{@docRoot}assets/images/triangle-closed.png"
+ class="toggle-img"
+ height="9px"
+ width="9px" /> Android NDK, Revision 4b</a> <em>(June 2010)</em>
+
+ <div class="toggleme">
+ <dl>
+ <dt>NDK r4b notes:</dt>
+
+ <dd>
+ <p>Includes fixes for several issues in the NDK build and debugging scripts &mdash; if
+ you are using NDK r4, we recommend downloading the NDK r4b build. For detailed
+ information describing the changes in this release, read the CHANGES.TXT document
+ included in the downloaded NDK package.</p>
+ </dd>
+ </dl>
+
+ <dl>
+ <dt>General notes:</dt>
+
+ <dd>
+ <ul>
+ <li>Provides a simplified build system through the new <code>ndk-build</code> build
+ command.</li>
+
+ <li>Adds support for easy native debugging of generated machine code on production
+ devices through the new <code>ndk-gdb</code> command.</li>
+
+ <li>Adds a new Android-specific ABI for ARM-based CPU architectures,
+ <code>armeabi-v7a</code>. The new ABI extends the existing <code>armeabi</code> ABI to
+ include these CPU instruction set extensions:
+
+ <ul>
+ <li>Thumb-2 instructions</li>
+
+ <li>VFP hardware FPU instructions (VFPv3-D16)</li>
+
+ <li>Optional support for ARM Advanced SIMD (NEON) GCC intrinsics and VFPv3-D32.
+ Supported by devices such as Verizon Droid by Motorola, Google Nexus One, and
+ others.</li>
+ </ul>
+ </li>
+
+ <li>Adds a new <code>cpufeatures</code> static library (with sources) that lets your
+ app detect the host device's CPU features at runtime. Specifically, applications can
+ check for ARMv7-A support, as well as VFPv3-D32 and NEON support, then provide separate
+ code paths as needed.</li>
+
+ <li>Adds a sample application, <code>hello-neon</code>, that illustrates how to use the
+ <code>cpufeatures</code> library to check CPU features and then provide an optimized
+ code path using NEON instrinsics, if supported by the CPU.</li>
+
+ <li>Lets you generate machine code for either or both of the instruction sets supported
+ by the NDK. For example, you can build for both ARMv5 and ARMv7-A architectures at the
+ same time and have everything stored to your application's final
+ <code>.apk</code>.</li>
+
+ <li>To ensure that your applications are available to users only if their devices are
+ capable of running them, Android Market now filters applications based on the
+ instruction set information included in your application &mdash; no action is needed on
+ your part to enable the filtering. Additionally, the Android system itself also checks
+ your application at install time and allows the installation to continue only if the
+ application provides a library that is compiled for the device's CPU architecture.</li>
+
+ <li>Adds support for Android 2.2, including a new stable API for accessing the pixel
+ buffers of {@link android.graphics.Bitmap} objects from native code.</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div class="toggleable closed">
+ <a href="#"
+ onclick="return toggleDiv(this)"><img src="{@docRoot}assets/images/triangle-closed.png"
+ class="toggle-img"
+ height="9px"
+ width="9px" /> Android NDK, Revision 3</a> <em>(March 2010)</em>
+
+ <div class="toggleme">
+ <dl>
+ <dt>General notes:</dt>
+
+ <dd>
+ <ul>
+ <li>Adds OpenGL ES 2.0 native library support.</li>
+
+ <li>Adds a sample application,<code>hello-gl2</code>, that illustrates the use of
+ OpenGL ES 2.0 vertex and fragment shaders.</li>
+
+ <li>The toolchain binaries have been refreshed for this release with GCC 4.4.0, which
+ should generate slightly more compact and efficient machine code than the previous one
+ (4.2.1). The NDK also still provides the 4.2.1 binaries, which you can optionally use
+ to build your machine code.</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div class="toggleable closed">
+ <a href="#"
+ onclick="return toggleDiv(this)"><img src="{@docRoot}assets/images/triangle-closed.png"
+ class="toggle-img"
+ height="9px"
+ width="9px" /> Android NDK, Revision 2</a> <em>(September 2009)</em>
+
+ <div class="toggleme">
+ <p>Originally released as "Android 1.6 NDK, Release 1".</p>
+
+ <dl>
+ <dt>General notes:</dt>
+
+ <dd>
+ <ul>
+ <li>Adds OpenGL ES 1.1 native library support.</li>
+
+ <li>Adds a sample application, <code>san-angeles</code>, that renders 3D graphics
+ through the native OpenGL ES APIs, while managing activity lifecycle with a {@link
+ android.opengl.GLSurfaceView} object.</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div class="toggleable closed">
+ <a href="#"
+ onclick="return toggleDiv(this)"><img src="{@docRoot}assets/images/triangle-closed.png"
+ class="toggle-img"
+ height="9px"
+ width="9px" /> Android NDK, Revision 1</a> <em>(June 2009)</em>
+
+ <div class="toggleme">
+ <p>Originally released as "Android 1.5 NDK, Release 1".</p>
+
+ <dl>
+ <dt>General notes:</dt>
+
+ <dd>
+ <ul>
+ <li>Includes compiler support (GCC) for ARMv5TE instructions, including Thumb-1
+ instructions.</li>
+
+ <li>Includes system headers for stable native APIs, documentation, and sample
+ applications.</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <h2 id="installing">Installing the NDK</h2>
+ <p>Installing the NDK on your development computer is straightforward and involves extracting the
+ NDK from its download package. Unlike previous releases, there is no need to run a host-setup
+ script.</p>
+
+ <p>Before you get started make sure that you have downloaded the latest <a href=
+ "{@docRoot}sdk/index.html">Android SDK</a> and upgraded your applications and environment as
+ needed. The NDK will not work with older versions of the Android SDK. Also, take a moment to
+ review the <a href="{@docRoot}sdk/ndk/reqs.html">System and Software Requirements</a> for the
+ NDK, if you haven't already.</p>
+
+ <p>To install the NDK, follow these steps:</p>
+
+ <ol>
+ <li>From the table at the top of this page, select the NDK package that is appropriate for your
+ development computer and download the package.</li>
+
+ <li>Uncompress the NDK download package using tools available on your computer. When
+ uncompressed, the NDK files are contained in a directory called
+ <code>android-ndk-&lt;version&gt;</code>. You can rename the NDK directory if necessary and you
+ can move it to any location on your computer. This documentation refers to the NDK directory as
+ <code>&lt;ndk&gt;</code>.</li>
+ </ol>
+
+ <p>You are now ready start working with the NDK.</p>
+
+ <h2 id="gettingstarted">Getting Started with the NDK</h2>
+
+ <p>Once you've installed the NDK successfully, take a few minutes to read the documentation
+ included in the NDK. You can find the documentation in the <code>&lt;ndk&gt;/docs/</code>
+ directory. In particular, please read the OVERVIEW.HTML document completely, so that you
+ understand the intent of the NDK and how to use it.</p>
+
+ <p>If you used a previous version of the NDK, take a moment to review the list of NDK changes in
+ the CHANGES.HTML document.</p>
+
+ <p>Here's the general outline of how you work with the NDK tools:</p>
+
+ <ol>
+ <li>Place your native sources under <code>&lt;project&gt;/jni/...</code></li>
+
+ <li>Create <code>&lt;project&gt;/jni/Android.mk</code> to describe your native sources to the
+ NDK build system</li>
+
+ <li>Optional: Create <code>&lt;project&gt;/jni/Application.mk</code>.</li>
+
+ <li>Build your native code by running the 'ndk-build' script from your project's directory. It
+ is located in the top-level NDK directory:
+ <pre class="no-pretty-print">
+cd &lt;project&gt;
+&lt;ndk&gt;/ndk-build
+</pre>
+
+ <p>The build tools copy the stripped, shared libraries needed by your application to the
+ proper location in the application's project directory.</p>
+ </li>
+
+ <li>Finally, compile your application using the SDK tools in the usual way. The SDK build tools
+ will package the shared libraries in the application's deployable <code>.apk</code> file.</li>
+ </ol>
+ <p>For complete information on all of the steps listed above, please see the documentation
+ included with the NDK package.</p>
+ <h2 id="samples">Sample Applications</h2>
+
+ <p>The NDK includes sample applications that illustrate how to use native code in your Android
+ applications:</p>
+ <ul>
+ <li><code>hello-jni</code> &mdash; a simple application that loads a string from a native
+ method implemented in a shared library and then displays it in the application UI.</li>
+
+ <li><code>two-libs</code> &mdash; a simple application that loads a shared library dynamically
+ and calls a native method provided by the library. In this case, the method is implemented in a
+ static library imported by the shared library.</li>
+
+ <li><code>san-angeles</code> &mdash; a simple application that renders 3D graphics through the
+ native OpenGL ES APIs, while managing activity lifecycle with a {@link
+ android.opengl.GLSurfaceView} object.</li>
+
+ <li><code>hello-gl2</code> &mdash; a simple application that renders a triangle using OpenGL ES
+ 2.0 vertex and fragment shaders.</li>
+
+ <li><code>hello-neon</code> &mdash; a simple application that shows how to use the
+ <code>cpufeatures</code> library to check CPU capabilities at runtime, then use NEON intrinsics
+ if supported by the CPU. Specifically, the application implements two versions of a tiny
+ benchmark for a FIR filter loop, a C version and a NEON-optimized version for devices that
+ support it.</li>
+
+ <li><code>bitmap-plasma</code> &mdash; a simple application that demonstrates how to access the
+ pixel buffers of Android {@link android.graphics.Bitmap} objects from native code, and uses
+ this to generate an old-school "plasma" effect.</li>
+
+ <li><code>native-activity</code> &mdash; a simple application that demonstrates how to use the
+ native-app-glue static library to create a native activity</li>
+
+ <li><code>native-plasma</code> &mdash; a version of bitmap-plasma implemented with a native
+ activity.</li>
+ </ul>
+
+ <p>For each sample, the NDK includes the corresponding C source code and the necessary Android.mk
+ and Application.mk files. There are located under <code>&lt;ndk&gt;/samples/&lt;name&gt;/</code>
+ and their source code can be found under <code>&lt;ndk&gt;/samples/&lt;name&gt;/jni/</code>.</p>
+
+ <p>You can build the shared libraries for the sample apps by going into
+ <code>&lt;ndk&gt;/samples/&lt;name&gt;/</code> then calling the <code>ndk-build</code> command.
+ The generated shared libraries will be located under
+ <code>&lt;ndk&gt;/samples/&lt;name&gt;/libs/armeabi/</code> for (ARMv5TE machine code) and/or
+ <code>&lt;ndk&gt;/samples/&lt;name&gt;/libs/armeabi-v7a/</code> for (ARMv7 machine code).</p>
+
+ <p>Next, build the sample Android applications that use the shared libraries:</p>
+
+ <ul>
+ <li>If you are developing in Eclipse with ADT, use the New Project Wizard to create a new
+ Android project for each sample, using the "Import from Existing Source" option and importing
+ the source from <code>&lt;ndk&gt;/apps/&lt;app_name&gt;/project/</code>. Then, set up an AVD,
+ if necessary, and build/run the application in the emulator. For more information about
+ creating a new Android project in Eclipse, see <a href=
+ "{@docRoot}guide/developing/eclipse-adt.html">Developing in Eclipse</a>.</li>
+
+ <li>If you are developing with Ant, use the <code>android</code> tool to create the build file
+ for each of the sample projects at <code>&lt;ndk&gt;/apps/&lt;app_name&gt;/project/</code>.
+ Then set up an AVD, if necessary, build your project in the usual way, and run it in the
+ emulator. For more information, see <a href=
+ "{@docRoot}guide/developing/other-ide.html">Developing in Other IDEs</a>.</li>
+ </ul>
+
+ <h3 id="hello-jni">Exploring the hello-jni Sample</h3>
+
+ <p>The hello-jni sample is a simple demonstration on how to use JNI from an Android application.
+ The HelloJni activity receives a string from a simple C function and displays it in a
+ TextView.</p>
+
+ <p>The main components of the sample include:</p>
+
+ <ul>
+ <li>The familiar basic structure of an Android application (an <code>AndroidManifest.xml</code>
+ file, a <code>src/</code> and <code>res</code> directories, and a main activity)</li>
+
+ <li>A <code>jni/</code> directory that includes the implemented source file for the native code
+ as well as the Android.mk file</li>
+
+ <li>A <code>tests/</code> directory that contains unit test code.</li>
+ </ul>
+
+ <ol>
+ <li>Create a new project in Eclipse from the existing sample source or use the
+ <code>android</code> tool to update the project so it generates a build.xml file that you can
+ use to build the sample.
+
+ <ul>
+ <li>In Eclipse:
+
+ <ol type="a">
+ <li>Click <strong>File &gt; New Android Project...</strong></li>
+
+ <li>Select the <strong>Create project from existing source</strong> radio button.</li>
+
+ <li>Select any API level above Android 1.5.</li>
+
+ <li>In the <strong>Location</strong> field, click <strong>Browse...</strong> and select
+ the <code>&lt;ndk-root&gt;/samples/hello-jni</code> directory.</li>
+
+ <li>Click <strong>Finish</strong>.</li>
+ </ol>
+ </li>
+
+ <li>On the command line:
+
+ <ol type="a">
+ <li>Change to the <code>&lt;ndk-root&gt;/samples/hello-jni</code> directory.</li>
+
+ <li>Run the following command to generate a build.xml file:
+ <pre class="no-pretty-print">
+android update project -p . -s
+</pre>
+ </li>
+ </ol>
+ </li>
+ </ul>
+ </li>
+
+ <li>Compile the native code using the <code>ndk-build</code> command.
+ <pre class="no-pretty-print">
+cd &lt;ndk-root&gt;/samples/hello-jni
+&lt;ndk_root&gt;/ndk-build
+</pre>
+ </li>
+
+ <li>Build and install the application as you would a normal Android application. If you are
+ using Eclipse, run the application to build and install it on a device. If you are using Ant,
+ run the following commands from the project directory:
+ <pre class="no-pretty-print">
+ant debug
+adb install bin/HelloJni-debug.apk
+</pre>
+ </li>
+ </ol>
+
+ <p>When you run the application on the device, the string <code>Hello JNI</code> should appear on
+ your device. You can explore the rest of the samples that are located in the
+ <code>&lt;ndk-root&gt;/samples</code> directory for more examples on how to use the JNI.</p>
+
+ <h3 id="native-activity">Exploring the native-activity Sample Application</h3>
+
+ <p>The native-activity sample provided with the Android NDK demonstrates how to use the
+ android_native_app_glue static library. This static library makes creating a native activity
+ easier by providing you with an implementation that handles your callbacks in another thread, so
+ you do not have to worry about them blocking your main UI thread. The main parts of the sample
+ are described below:</p>
+
+ <ul>
+ <li>The familiar basic structure of an Android application (an <code>AndroidManifest.xml</code>
+ file, a <code>src/</code> and <code>res</code> directories). The AndroidManifest.xml declares
+ that the application is native and specifies the .so file of the native activity. See {@link
+ android.app.NativeActivity} for the source or see the
+ <code>&lt;ndk_root&gt;/platforms/samples/native-activity/AndroidManifest.xml</code> file.</li>
+
+ <li>A <code>jni/</code> directory contains the native activity, main.c, which uses the
+ <code>android_native_app_glue.h</code> interface to implement the activity. The Android.mk that
+ describes the native module to the build system also exists here.</li>
+ </ul>
+
+ <p>To build this sample application:</p>
+
+ <ol>
+ <li>Create a new project in Eclipse from the existing sample source or use the
+ <code>android</code> tool to update the project so it generates a build.xml file that you can
+ use to build the sample.
+
+ <ul>
+ <li>In Eclipse:
+
+ <ol type="a">
+ <li>Click <strong>File &gt; New Android Project...</strong></li>
+
+ <li>Select the <strong>Create project from existing source</strong> radio button.</li>
+
+ <li>Select any API level above Android 2.3.</li>
+
+ <li>In the <strong>Location</strong> field, click <strong>Browse...</strong> and select
+ the <code>&lt;ndk-root&gt;/samples/native-activity</code> directory.</li>
+
+ <li>Click <strong>Finish</strong>.</li>
+ </ol>
+ </li>
+
+ <li>On the command line:
+
+ <ol type="a">
+ <li>Change to the <code>&lt;ndk-root&gt;/samples/native-activity</code> directory.</li>
+
+ <li>Run the following command to generate a build.xml file:
+ <pre class="no-pretty-print">
+android update project -p . -s
+</pre>
+ </li>
+ </ol>
+ </li>
+ </ul>
+ </li>
+
+ <li>Compile the native code using the <code>ndk-build</code> command.
+ <pre class="no-pretty-print">
+cd &lt;ndk-root&gt;/platforms/samples/android-9/samples/native-activity
+&lt;ndk_root&gt;/ndk-build
+</pre>
+ </li>
+
+ <li>Build and install the application as you would a normal Android application. If you are
+ using Eclipse, run the application to build and install it on a device. If you are using Ant,
+ run the following commands in the project directory, then run the application on the device:
+ <pre class="no-pretty-print">
+ant debug
+adb install bin/NativeActivity-debug.apk
+</pre>
+ </li>
+ </ol>
+
+ <h2 id="forum">Discussion Forum and Mailing List</h2>
+
+ <p>If you have questions about the NDK or would like to read or contribute to discussions about
+ it, please visit the <a href="http://groups.google.com/group/android-ndk">android-ndk</a> group
+ and mailing list.</p>
diff --git a/docs/html/sdk/ndk/overview.jd b/docs/html/sdk/ndk/overview.jd
new file mode 100644
index 0000000..a7ec5d4
--- /dev/null
+++ b/docs/html/sdk/ndk/overview.jd
@@ -0,0 +1,334 @@
+page.title=What is the NDK?
+@jd:body
+
+ <div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+
+ <ol>
+ <li><a href="#choosing">When to Develop in Native Code</a></li>
+
+ <li>
+ <a href="#contents">Contents of the NDK</a>
+
+ <ol>
+ <li><a href="#tools">Development tools</a></li>
+
+ <li><a href="#docs">Documentation</a></li>
+
+ <li><a href="#samples">Sample applications</a></li>
+ </ol>
+ </li>
+
+ <li><a href="#reqs">System and Software Requirements</a></li>
+
+ </ol>
+ </div>
+ </div>
+
+ <p>The Android NDK is a toolset that lets you embed components that make use of native code in
+ your Android applications.</p>
+
+ <p>Android applications run in the Dalvik virtual machine. The NDK allows you to implement parts
+ of your applications using native-code languages such as C and C++. This can provide benefits to
+ certain classes of applications, in the form of reuse of existing code and in some cases
+ increased speed.</p>
+
+ <p>The NDK provides:</p>
+
+ <ul>
+ <li>A set of tools and build files used to generate native code libraries from C and C++
+ sources</li>
+
+ <li>A way to embed the corresponding native libraries into an application package file
+ (<code>.apk</code>) that can be deployed on Android devices</li>
+
+ <li>A set of native system headers and libraries that will be supported in all future versions
+ of the Android platform, starting from Android 1.5. Applications that use native activities
+ must be run on Android 2.3 or later.</li>
+
+ <li>Documentation, samples, and tutorials</li>
+ </ul>
+
+ <p>The latest release of the NDK supports these ARM instruction sets:</p>
+
+ <ul>
+ <li>ARMv5TE (including Thumb-1 instructions)</li>
+
+ <li>ARMv7-A (including Thumb-2 and VFPv3-D16 instructions, with optional support for
+ NEON/VFPv3-D32 instructions)</li>
+ </ul>
+
+ <p>Future releases of the NDK will also support:</p>
+
+ <ul>
+ <li>x86 instructions (see CPU-ARCH-ABIS.HTML for more information)</li>
+ </ul>
+
+ <p>ARMv5TE machine code will run on all ARM-based Android devices. ARMv7-A will run only on
+ devices such as the Verizon Droid or Google Nexus One that have a compatible CPU. The main
+ difference between the two instruction sets is that ARMv7-A supports hardware FPU, Thumb-2, and
+ NEON instructions. You can target either or both of the instruction sets &mdash; ARMv5TE is the
+ default, but switching to ARMv7-A is as easy as adding a single line to the application's
+ <code>Application.mk</code> file, without needing to change anything else in the file. You can also build for
+ both architectures at the same time and have everything stored in the final <code>.apk</code>.
+ Complete information is provided in the CPU-ARCH-ABIS.HTML in the NDK package.</p>
+
+ <p>The NDK provides stable headers for libc (the C library), libm (the Math library), OpenGL ES
+ (3D graphics library), the JNI interface, and other libraries, as listed in the <a href=
+ "#tools">Development Tools</a> section.</p>
+
+ <h2 id="choosing">When to Develop in Native Code</h2>
+
+ <p>The NDK will not benefit most applications. As a developer, you need to balance its benefits
+ against its drawbacks; notably, using native code does not result in an automatic performance
+ increase, but always increases application complexity. In general, you should only use native
+ code if it is essential to your application, not just because you prefer to program in C/C++.</p>
+
+ <p>Typical good candidates for the NDK are self-contained, CPU-intensive operations that don't
+ allocate much memory, such as signal processing, physics simulation, and so on. Simply re-coding
+ a method to run in C usually does not result in a large performance increase. When examining
+ whether or not you should develop in native code, think about your requirements and see if the
+ Android framework APIs provide the functionality that you need. The NDK can, however, can be an
+ effective way to reuse a large corpus of existing C/C++ code.</p>
+
+ <p>The Android framework provides two ways to use native code:</p>
+
+ <ul>
+ <li>Write your application using the Android framework and use JNI to access the APIs provided
+ by the Android NDK. This technique allows you to take advantage of the convenience of the
+ Android framework, but still allows you to write native code when necessary. You can install
+ applications that use native code through the JNI on devices that run Android 1.5 or
+ later.</li>
+
+ <li>
+ <p>Write a native activity, which allows you to potentially create an application completely in native
+ code, because you can implement the lifecycle callbacks natively. The Android SDK provides
+ the {@link android.app.NativeActivity} class, which is a convenience class that notifies your
+ native code of any activity lifecycle callbacks (<code>onCreate()</code>, <code>onPause()</code>,
+ <code>onResume()</code>, etc). You can implement the callbacks in your native code to handle
+ these events when they occur. Applications that use native activities must be run on Android
+ 2.3 (API Level 9) or later.</p>
+
+ <p>You cannot access features such as Services and Content Providers natively, so if you want
+ to use them or any other framework API, you can still write JNI code to do so.</p>
+ </li>
+ </ul>
+
+ <h2 id="contents">Contents of the NDK</h2>The NDK contains the APIs, documentation, and sample
+ applications that help you write your native code.
+
+ <h3 id="tools">Development tools</h3>
+
+ <p>The NDK includes a set of cross-toolchains (compilers, linkers, etc..) that can generate
+ native ARM binaries on Linux, OS X, and Windows (with Cygwin) platforms.</p>
+
+ <p>It provides a set of system headers for stable native APIs that are guaranteed to be supported
+ in all later releases of the platform:</p>
+
+ <ul>
+ <li>libc (C library) headers</li>
+
+ <li>libm (math library) headers</li>
+
+ <li>JNI interface headers</li>
+
+ <li>libz (Zlib compression) headers</li>
+
+ <li>liblog (Android logging) header</li>
+
+ <li>OpenGL ES 1.1 and OpenGL ES 2.0 (3D graphics libraries) headers</li>
+
+ <li>libjnigraphics (Pixel buffer access) header (for Android 2.2 and above).</li>
+
+ <li>A Minimal set of headers for C++ support</li>
+ </ul>
+
+ <p>The NDK also provides a build system that lets you work efficiently with your sources, without
+ having to handle the toolchain/platform/CPU/ABI details. You create very short build files to
+ describe which sources to compile and which Android application will use them &mdash; the build
+ system compiles the sources and places the shared libraries directly in your application
+ project.</p>
+
+ <p class="caution"><strong>Important:</strong> With the exception of the libraries listed above,
+ native system libraries in the Android platform are <em>not</em> stable and may change in future
+ platform versions. Your applications should <em>only</em> make use of the stable native system
+ libraries provided in this NDK.</p>
+
+ <h3 id="docs">Documentation</h3>
+
+ <p>The NDK package includes a set of documentation that describes the capabilities of the NDK and
+ how to use it to create shared libraries for your Android applications. In this release, the
+ documentation is provided only in the downloadable NDK package. You can find the documentation in
+ the <code>&lt;ndk&gt;/docs/</code> directory. Included are these files:</p>
+
+ <ul>
+ <li>INSTALL.HTML &mdash; describes how to install the NDK and configure it for your host
+ system</li>
+
+ <li>OVERVIEW.HTML &mdash; provides an overview of the NDK capabilities and usage</li>
+
+ <li>ANDROID-MK.HTML &mdash; describes the use of the Android.mk file, which defines the native
+ sources you want to compile</li>
+
+ <li>APPLICATION-MK.HTML &mdash; describes the use of the Application.mk file, which describes
+ the native sources required by your Android application</li>
+
+ <li>HOWTO.HTML &mdash; information about common tasks associated with NDK development.</li>
+
+ <li>SYSTEM-ISSUES.HTML &mdash; known issues in the Android system images that you should be
+ aware of, if you are developing using the NDK.</li>
+
+ <li>STABLE-APIS.HTML &mdash; a complete list of the stable APIs exposed by headers in the
+ NDK.</li>
+
+ <li>CPU-ARCH-ABIS.HTML &mdash; a description of supported CPU architectures and how to target
+ them.</li>
+
+ <li>CPU-FEATURES.HTML &mdash; a description of the <code>cpufeatures</code> static library that
+ lets your application code detect the target device's CPU family and the optional features at
+ runtime.</li>
+
+ <li>CPU-ARM-NEON.HTML &mdash; a description of how to build with optional ARM NEON / VFPv3-D32
+ instructions.</li>
+
+ <li>CHANGES.HTML &mdash; a complete list of changes to the NDK across all releases.</li>
+ </ul>
+
+ <p>Additionally, the package includes detailed information about the "bionic" C library provided
+ with the Android platform that you should be aware of, if you are developing using the NDK. You
+ can find the documentation in the <code>&lt;ndk&gt;/docs/system/libc/</code> directory:</p>
+
+ <ul>
+ <li>OVERVIEW.HTML &mdash; provides an overview of the "bionic" C library and the features it
+ offers.</li>
+ </ul>
+
+ <h3 id="samples">Sample applications</h3>
+
+ <p>The NDK includes sample Android applications that illustrate how to use native code in your
+ Android applications. For more information, see <a href=
+ "{@docRoot}sdk/ndk/installing.html#samples">Sample Applications</a>.</p>
+
+ <h2 id="reqs">System and Software Requirements</h2>
+
+ <p>The sections below describe the system and software requirements for using the Android NDK, as
+ well as platform compatibility considerations that affect appplications using libraries produced
+ with the NDK.</p>
+
+ <h4>The Android SDK</h4>
+
+ <ul>
+ <li>A complete Android SDK installation (including all dependencies) is required.</li>
+
+ <li>Android 1.5 SDK or later version is required.</li>
+ </ul>
+
+ <h4>Supported operating systems</h4>
+
+ <ul>
+ <li>Windows XP (32-bit) or Vista (32- or 64-bit)</li>
+
+ <li>Mac OS X 10.4.8 or later (x86 only)</li>
+
+ <li>Linux (32- or 64-bit, tested on Linux Ubuntu Dapper Drake)</li>
+ </ul>
+
+ <h4>Required development tools</h4>
+
+ <ul>
+ <li>For all development platforms, GNU Make 3.81 or later is required. Earlier versions of GNU
+ Make might work but have not been tested.</li>
+
+ <li>A recent version of awk (either GNU Awk or Nawk) is also required.</li>
+
+ <li>For Windows, <a href="http://www.cygwin.com">Cygwin</a> 1.7 or higher is required. The NDK
+ will <em>not</em> work with Cygwin 1.5 installations.</li>
+ </ul>
+
+ <h4>Android platform compatibility</h4>
+
+ <ul>
+ <li>The native libraries created by the Android NDK can only be used on devices running the
+ Android 1.5 platform version or later. This is due to toolchain and ABI related changes that
+ make the native libraries incompatible with 1.0 and 1.1 system images.</li>
+
+ <li>For this reason, you should use native libraries produced with the NDK in applications that
+ are deployable to devices running the Android 1.5 platform version or later.</li>
+
+ <li>To ensure compatibility, an application using a native library produced with the NDK
+ <em>must</em> declare a <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code>
+ &lt;uses-sdk&gt;</code></a> element in its manifest file, with an
+ <code>android:minSdkVersion</code> attribute value of "3" or higher. For example:
+ <pre style="margin:1em;">
+&lt;manifest&gt;
+ ...
+ &lt;uses-sdk android:minSdkVersion="3" /&gt;
+ ...
+&lt;/manifest&gt;
+</pre>
+ </li>
+
+ <li>If you use this NDK to create a native library that uses the OpenGL ES APIs, the
+ application containing the library can be deployed only to devices running the minimum platform
+ versions described in the table below. To ensure compatibility, make sure that your application
+ declares the proper <code>android:minSdkVersion</code> attribute value, as given in the
+ table.</li>
+
+ <li style="list-style: none; display: inline">
+ <table style="margin:1em;">
+ <tr>
+ <th>OpenGL ES Version Used</th>
+
+ <th>Compatible Android Platform(s)</th>
+
+ <th>Required uses-sdk Attribute</th>
+ </tr>
+
+ <tr>
+ <td>OpenGL ES 1.1</td>
+
+ <td>Android 1.6 and higher</td>
+
+ <td><code>android:minSdkVersion="4"</code></td>
+ </tr>
+
+ <tr>
+ <td>OpenGL ES 2.0</td>
+
+ <td>Android 2.0 and higher</td>
+
+ <td><code>android:minSdkVersion="5"</code></td>
+ </tr>
+ </table>
+
+ <p>For more information about API Level and its relationship to Android platform versions,
+ see <a href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a>.</p>
+ </li>
+
+ <li>Additionally, an application using the OpenGL ES APIs should declare a
+ <code>&lt;uses-feature&gt;</code> element in its manifest, with an
+ <code>android:glEsVersion</code> attribute that specifies the minimum OpenGl ES version
+ required by the application. This ensures that Android Market will show your application only
+ to users whose devices are capable of supporting your application. For example:
+ <pre style="margin:1em;">
+&lt;manifest&gt;
+ ...
+<!-- Declare that the application uses the OpenGL ES 2.0 API and is designed
+ to run only on devices that support OpenGL ES 2.0 or higher. -->
+ &lt;uses-feature android:glEsVersion="0x00020000" /&gt;
+ ...
+&lt;/manifest&gt;
+</pre>
+
+ <p>For more information, see the <a href=
+ "{@docRoot}guide/topics/manifest/uses-feature-element.html"><code>&lt;uses-feature&gt;</code></a>
+ documentation.</p>
+ </li>
+
+ <li>If you use this NDK to create a native library that uses the API to access Android {@link
+ android.graphics.Bitmap} pixel buffers or utilizes native activities, the application
+ containing the library can be deployed only to devices running Android 2.2 (API level 8) or
+ higher. To ensure compatibility, make sure that your application declares <code>&lt;uses-sdk
+ android:minSdkVersion="8" /&gt;</code> attribute value in its manifest.</li>
+ </ul> \ No newline at end of file
diff --git a/docs/html/sdk/older_releases.jd b/docs/html/sdk/older_releases.jd
index c3ba495..77f7e43 100644
--- a/docs/html/sdk/older_releases.jd
+++ b/docs/html/sdk/older_releases.jd
@@ -47,7 +47,7 @@ Notes</a></em></p>
<td>Windows</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-windows-1.6_r1.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-windows-1.6_r1.zip">android-sdk-
windows-1 .6_r1.zip</a>
</td>
<td>260529085 bytes</td>
@@ -57,7 +57,7 @@ windows-1 .6_r1.zip</a>
<td>Mac OS X (intel)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-mac_x86-1.6_r1.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-mac_x86-1.6_r1.zip">android-sdk-
mac_x86-1 .6_r1.zip</a>
</td>
<td>247412515 bytes</td>
@@ -67,7 +67,7 @@ mac_x86-1 .6_r1.zip</a>
<td>Linux (i386)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-linux_x86-1.6_r1.tgz">android-
+href="http://dl.google.com/android/archives/android-sdk-linux_x86-1.6_r1.tgz">android-
sdk- linux_x86-1.6_r1.tgz</a>
</td>
<td>238224860 bytes</td>
@@ -92,7 +92,7 @@ Notes</a></em></p>
<td>Windows</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-windows-1.5_r3.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-windows-1.5_r3.zip">android-sdk-
windows-1 .5_r3.zip</a>
</td>
<td>191477853 bytes</td>
@@ -102,7 +102,7 @@ windows-1 .5_r3.zip</a>
<td>Mac OS X (intel)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-mac_x86-1.5_r3.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-mac_x86-1.5_r3.zip">android-sdk-
mac_x86-1 .5_r3.zip</a>
</td>
<td>183024673 bytes</td>
@@ -112,7 +112,7 @@ mac_x86-1 .5_r3.zip</a>
<td>Linux (i386)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-linux_x86-1.5_r3.zip">android-
+href="http://dl.google.com/android/archives/android-sdk-linux_x86-1.5_r3.zip">android-
sdk- linux_x86-1.5_r3.zip</a>
</td>
<td>178117561 bytes</td>
@@ -137,7 +137,7 @@ Notes</a></em></p>
<td>Windows</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-windows-1.1_r1.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-windows-1.1_r1.zip">android-sdk-
windows-1
.1_r1.zip</a>
</td>
@@ -148,7 +148,7 @@ windows-1
<td>Mac OS X (intel)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-mac_x86-1.1_r1.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-mac_x86-1.1_r1.zip">android-sdk-
mac_x86-1
.1_r1.zip</a>
</td>
@@ -159,7 +159,7 @@ mac_x86-1
<td>Linux (i386)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-linux_x86-1.1_r1.zip">android-
+href="http://dl.google.com/android/archives/android-sdk-linux_x86-1.1_r1.zip">android-
sdk-
linux_x86-1.1_r1.zip</a>
</td>
@@ -185,7 +185,7 @@ Notes</a></em></p>
<td>Windows</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-windows-1.0_r2.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-windows-1.0_r2.zip">android-sdk-
windows-1
.0_r2.zip</a>
</td>
@@ -196,7 +196,7 @@ windows-1
<td>Mac OS X (intel)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-mac_x86-1.0_r2.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-mac_x86-1.0_r2.zip">android-sdk-
mac_x86-1
.0_r2.zip</a>
</td>
@@ -207,7 +207,7 @@ mac_x86-1
<td>Linux (i386)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-linux_x86-1.0_r2.zip">android-
+href="http://dl.google.com/android/archives/android-sdk-linux_x86-1.0_r2.zip">android-
sdk-
linux_x86-1.0_r2.zip</a>
</td>
@@ -241,7 +241,7 @@ Notes</a></em></p>
<td>Windows</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-windows-1.5_r2.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-windows-1.5_r2.zip">android-sdk-
windows-1 .5_r2.zip</a>
</td>
<td>178346828 bytes</td>
@@ -251,7 +251,7 @@ windows-1 .5_r2.zip</a>
<td>Mac OS X (intel)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-mac_x86-1.5_r2.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-mac_x86-1.5_r2.zip">android-sdk-
mac_x86-1 .5_r2.zip</a>
</td>
<td>169945128 bytes</td>
@@ -261,7 +261,7 @@ mac_x86-1 .5_r2.zip</a>
<td>Linux (i386)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-linux_x86-1.5_r2.zip">android-
+href="http://dl.google.com/android/archives/android-sdk-linux_x86-1.5_r2.zip">android-
sdk- linux_x86-1.5_r2.zip</a>
</td>
<td>165035130 bytes</td>
@@ -286,7 +286,7 @@ Notes</a></em></p>
<td>Windows</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-windows-1.5_r1.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-windows-1.5_r1.zip">android-sdk-
windows-1 .5_r1.zip</a>
</td>
<td>176263368 bytes</td>
@@ -296,7 +296,7 @@ windows-1 .5_r1.zip</a>
<td>Mac OS X (intel)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-mac_x86-1.5_r1.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-mac_x86-1.5_r1.zip">android-sdk-
mac_x86-1 .5_r1.zip</a>
</td>
<td>167848675 bytes</td>
@@ -306,7 +306,7 @@ mac_x86-1 .5_r1.zip</a>
<td>Linux (i386)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-linux_x86-1.5_r1.zip">android-
+href="http://dl.google.com/android/archives/android-sdk-linux_x86-1.5_r1.zip">android-
sdk- linux_x86-1.5_r1.zip</a>
</td>
<td>162938845 bytes</td>
@@ -331,7 +331,7 @@ Notes</a></em></p>
<td>Windows</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-windows-1.0_r1.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-windows-1.0_r1.zip">android-sdk-
windows-1 .0_r1.zip</a>
</td>
<td>89.7 MB bytes</td>
@@ -341,7 +341,7 @@ windows-1 .0_r1.zip</a>
<td>Mac OS X (intel)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-mac_x86-1.0_r1.zip">android-sdk-
+href="http://dl.google.com/android/archives/android-sdk-mac_x86-1.0_r1.zip">android-sdk-
mac_x86-1 .0_r1.zip</a>
</td>
<td>87.5 MB bytes</td>
@@ -351,7 +351,7 @@ mac_x86-1 .0_r1.zip</a>
<td>Linux (i386)</td>
<td>
<a
-href="/sdk/download.html?v=archives/android-sdk-linux_x86-1.0_r1.zip">android-
+href="http://dl.google.com/android/archives/android-sdk-linux_x86-1.0_r1.zip">android-
sdk- linux_x86-1.0_r1.zip</a>
</td>
<td>87.8 MB bytes</td>
diff --git a/docs/html/sdk/requirements.jd b/docs/html/sdk/requirements.jd
index cb9cdf3..3679d44 100644
--- a/docs/html/sdk/requirements.jd
+++ b/docs/html/sdk/requirements.jd
@@ -6,9 +6,9 @@ Android applications using the Android SDK. </p>
<h3>Supported Operating Systems</h3>
<ul>
- <li>Windows XP (32-bit) or Vista (32- or 64-bit)</li>
+ <li>Windows XP (32-bit), Vista (32- or 64-bit), or Windows 7 (32- or 64-bit)</li>
<li>Mac OS X 10.5.8 or later (x86 only)</li>
- <li>Linux (tested on Linux Ubuntu Hardy Heron)
+ <li>Linux (tested on Linux Ubuntu Hardy Heron and Lucid Lynx)
<ul>
<li>64-bit distributions must be capable of running 32-bit applications.
For information about how to add support for 32-bit applications, see
@@ -22,7 +22,7 @@ installation notes</a>.</li>
<h4 style="margin-top:.25em"><em>Eclipse IDE</em></h4>
<ul>
- <li>Eclipse 3.4 (Ganymede) or 3.5 (Galileo)
+ <li>Eclipse 3.4 (Ganymede) or greater</li>
<li>Eclipse <a href="http://www.eclipse.org/jdt">JDT</a> plugin (included
in most Eclipse IDE packages) </li>
<li>If you need to install or update Eclipse, you can download it from <a
@@ -32,23 +32,22 @@ href="http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a>.
developing Android applications, we recommend that you install one of these
packages: </p>
<ul>
- <li>Eclipse IDE for Java EE Developers</li>
<li>Eclipse IDE for Java Developers</li>
- <li>Eclipse for RCP/Plug-in Developers</li>
<li>Eclipse Classic (versions 3.5.1 and higher)</li>
+ <li>Eclipse IDE for Java EE Developers</li>
</ul>
</li>
- <li><a href="http://java.sun.com/javase/downloads/index.jsp">JDK 5 or JDK
+ <li><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">JDK 5 or JDK
6</a> (JRE alone is not sufficient)</li>
<li><a href="eclipse-adt.html">Android Development Tools plugin</a>
-(optional)</li>
+(recommended)</li>
<li><strong>Not</strong> compatible with Gnu Compiler for Java (gcj)</li>
</ul>
<h4><em>Other development environments or IDEs</em></h4>
<ul>
- <li><a href="http://java.sun.com/javase/downloads/index.jsp">JDK 5 or JDK
+ <li><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">JDK 5 or JDK
6</a> (JRE alone is not sufficient)</li>
<li><a href="http://ant.apache.org/">Apache Ant</a> 1.6.5 or later for
Linux and Mac, 1.7 or later for Windows</li>
@@ -72,7 +71,12 @@ particular, note that some Linux distributions may include JDK 1.4 or Gnu Compil
</tr>
<tr>
<td>SDK Tools</td>
-<td>50 MB</td>
+<td>35 MB</td>
+<td>Required.</td>
+</tr>
+<tr>
+<td>SDK Platform-tools</td>
+<td>6 MB</td>
<td>Required.</td>
</tr>
<tr>
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index a80981c..057d9e0 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -1,5 +1,5 @@
<?cs if:!sdk.redirect ?>
-<ul><?cs
+<ul><?cs
if:android.whichdoc == "online" ?>
<li>
<h2>
@@ -35,7 +35,7 @@
</a></li>
</ul>
- </li><?cs
+ </li><?cs
/if ?>
<li>
<h2>
@@ -61,13 +61,13 @@
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/android-2.2.html">Android 2.2 Platform</a> <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/android-2.2.html">Android 2.2 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-2.1.html">Android 2.1 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-1.6.html">Android 1.6 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-1.5.html">Android 1.5 Platform</a></li>
<li class="toggle-list">
<div><a href="#" onclick="toggle(this.parentNode.parentNode,true); return false;">Older Platforms</a></div>
- <ul>
+ <ul>
<li><a href="<?cs var:toroot ?>sdk/android-2.0.1.html">Android 2.0.1 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-2.0.html">Android 2.0 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-1.1.html">Android 1.1 Platform</a></li>
@@ -75,7 +75,7 @@
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r6</a> <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r8</a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/win-usb.html">USB Driver for
Windows, r3</a>
</li>
@@ -93,7 +93,7 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 0.9.7
+ <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 8.0
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
<span style="display:none" class="fr"></span>
@@ -101,8 +101,7 @@
<span style="display:none" class="ja"></span>
<span style="display:none" class="zh-CN"></span>
<span style="display:none" class="zh-TW"></span></a>
- <span class="new">new!</span>
- </li>
+ <span class="new">new!</span></li>
</ul>
</li>
<li>
@@ -116,10 +115,12 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r4</a>
- <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Download the Android NDK, r5</a>
+ <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/ndk/overview.html">What is the NDK?</a></li>
</ul>
</li>
+
<li>
<h2>
<span class="en">More Information</span>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index c9be6ff..9316fae 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -64,6 +64,103 @@ padding: .25em 1em;
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+SDK Tools, Revision 8</a> <em>(December 2010)</em>
+ <div class="toggleme">
+
+<dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>If you are developing in Eclipse with ADT, note that SDK Tools r8 is
+designed for use with ADT 8.0.0 and later. After installing SDK Tools r8, we
+highly recommend updating your ADT Plugin to 8.0.0.</p>
+
+<p>Also note that SDK Tools r8 requires a new SDK component called
+<em>Platform-tools</em>. The new Platform-tools component lets all SDK platforms
+(Android 2.1, Android 2.2, and so on) use the same (latest) version of build
+tools such as <code>adb</code>, <code>aapt</code>, <code>aidl</code>, and
+<code>dx</code>. To download the Platform-tools component, use the Android SDK
+Manager, as described in <a href="adding-components.html">Adding SDK
+Components</a></p>
+
+<dt>Upgrading from SDK Tools r7:</dt>
+<dd>
+<p>If you are upgrading to SDK Tools r8 from an earlier version, note that the
+the default installed location for the <code>adb</code> tool has changed from
+<code>&lt;<em>SDK</em>&gt;/tools/adb</code> to
+<code>&lt;<em>SDK</em>&gt;/platform-tools/adb</code>. This means that you should
+add the new location to your PATH and modify any custom build scripts to
+reference the new location. Copying the <code>adb</code> executable from the new
+location to the old is not recommended, since subsequent updates to the SDK
+Tools will delete the file.</p>
+</dd>
+
+<dt>General notes:</dt>
+<dd>
+<ul>
+<li>All SDK platforms now support Library Projects.</li>
+<li>Support for a true debug build. Developers no longer need to add the
+<code>android:debuggable</code> attribute to the
+<code>&lt;application&gt;</code> tag in the manifest &mdash; the build tools add
+the attribute automatically. In Eclipse/ADT, all incremental builds are assumed
+to be debug builds, so the tools insert <code>android:debuggable="true"</code>.
+When exporting a signed release build, the tools do not add the attribute. In
+Ant, a <code>ant debug</code> command automatically inserts the
+<code>android:debuggable="true"</code> attribute, while <code>ant release</code>
+does not. If <code>android:debuggable="true"</code> is manually set, then
+<code>ant release</code> will actually do a debug build, rather than a release
+build.</li>
+<li>Automatic ProGuard support in release builds. Developers generate a ProGuard
+configuration file using the <code>android</code> tool &mdash; the build tools
+then automatically run ProGuard against the project sources during the build.
+For more information, see the <a
+href="{@docRoot}guide/developing/tools/proguard.html">ProGuard</a>
+documentation. </li>
+<li>New overridable Ant javac properties: <code>java.encoding</code>,
+<code>java.source</code>, and <code>java.target</code> (default values are
+"ascii", "1.5", and "1.5", respectively).</li>
+<li>New UI for the HierarchyViewer tool.</li>
+</ul>
+</dd>
+</dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
+SDK Tools, Revision 7</a> <em>(September 2010)</em>
+ <div class="toggleme">
+
+<dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>If you are developing in Eclipse with ADT, note that SDK Tools r7 is
+designed for use with ADT 0.9.8 and later. After installing SDK Tools r7, we
+highly recommend updating your ADT Plugin to 0.9.8.</p>
+</dd>
+
+<dt>General notes:</dt>
+<dd>
+<ul>
+<li>Added support for library projects that depend on other library projects.</li>
+<li>Adds support for aidl files in library projects.</li>
+<li>Adds support for extension targets in Ant build to perform tasks between the
+normal tasks: <code>-pre-build</code>, <code>-pre-compile</code>, and
+<code>-post-compile</code>.</li>
+<li>Adds support for "headless" SDK update. See <code>android -h update sdk</code>
+for more information.</li>
+<li>Fixes location control in DDMS to work in any locale not using '.' as a
+decimal point.</li>
+</li>
+</ul>
+</dd>
+</dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
SDK Tools, Revision 6</a> <em>(May 2010)</em>
<div class="toggleme">
@@ -94,7 +191,7 @@ provides the equivalent library project support.</p>
<div class="toggleable closed">
<a href="#" onclick="return toggleDiv(this)">
- <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
SDK Tools, Revision 5</a> <em>(March 2010)</em>
<div class="toggleme">
diff --git a/docs/html/sitemap.txt b/docs/html/sitemap.txt
index d5be8f1..7a0b8ac 100644
--- a/docs/html/sitemap.txt
+++ b/docs/html/sitemap.txt
@@ -164,6 +164,11 @@ http://developer.android.com/guide/practices/ui_guidelines/menu_design.html
http://developer.android.com/guide/practices/design/performance.html
http://developer.android.com/guide/practices/design/responsiveness.html
http://developer.android.com/guide/practices/design/seamlessness.html
+http://developer.android.com/guide/webapps/targetting.html
+http://developer.android.com/guide/webapps/webview.html
+http://developer.android.com/guide/webapps/debugging.html
+http://developer.android.com/guide/webapps/best-practices.html
+http://developer.android.com/guide/topics/admin/device-admin.html
http://developer.android.com/guide/appendix/api-levels.html
http://developer.android.com/guide/appendix/media-formats.html
http://developer.android.com/guide/appendix/g-app-intents.html
diff --git a/docs/html/videos/index.jd b/docs/html/videos/index.jd
index 157c077..0274095 100644
--- a/docs/html/videos/index.jd
+++ b/docs/html/videos/index.jd
@@ -2,7 +2,7 @@ videos=true
page.title=Videos
@jd:body
-<script src="http://swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js" type="text/javascript"></script>
+<script src="http://swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js" type="text/javascript"></script>
<script src="{@docRoot}assets/jquery-history.js" type="text/javascript"></script>
<script type="text/javascript">
// for debugging in FF, so other browsers ignore the console commands.
@@ -33,32 +33,32 @@ var playlists = {
*/
var playlistsWithTitleInDescription = "734A052F802C96B9";
-/* This 'featured' object defines the Feature Videos list.
+/* This 'featured' object defines the Feature Videos list.
* Each playlist ID is paired with a custom video description.
*/
var featured = {
-// Android 2.0 Release
- 'opZ69P-0Jbc' : "The Android 2.0 platform adds exciting new user features and developer APIs. Here's an introduction to what's new.",
-// How to Make your Android UI Fast..
- 'N6YdwzAvwOA' : "Make your user interface fast, with more efficient AdapterViews, better bitmap scaling, faster redrawing, ViewStub layouts, fewer Views, and more.",
-// How Do I Code Thee?
- 'GARMe7Km_gk' : "If you'd like to augment your Android applications with pieces written in JavaScript or native code, watch this video."
+// Android UI design patterns
+ 'M1ZBjlCRfz0' : "The Android user experience team provides suggestions for how to make your applications more useable and engaging.",
+// The world of ListView
+ 'wDBM6wVEO70' : "ListView is a common widget that's customizable, but can be tricky to polish, so this talk shows how you can provide the best performance.",
+// Debugging Arts of the Ninja Masters
+ 'Dgnx0E7m1GQ' : "The Android SDK includes tools to debug your apps like a ninja. Enter the dojo and become a master at debugging your apps."
};
-
+
/* When an event on the browser history occurs (back, forward, load),
- * load the video found in the URL hash
- */
-$(window).history(function(e, hash) {
- if (location.href.indexOf("#v=") != -1) {
- videoId = location.href.split("#v=");
- clickVideo(videoId[1]); // click the link with a matching class
- }
+ * load the video found in the URL hash
+ */
+$(window).history(function(e, hash) {
+ if (location.href.indexOf("#v=") != -1) {
+ videoId = location.href.split("#v=");
+ clickVideo(videoId[1]); // click the link with a matching class
+ }
});
/* Load a video into the player box.
* @param id The YouTube video ID
* @param title The video title to display in the player box (character escaped)
- * @param autoplay Whether to automatically play the video
+ * @param autoplay Whether to automatically play the video
*/
function loadVideo(id, title, autoplay) {
if($("." + id).hasClass("noplay")) {
@@ -66,51 +66,51 @@ function loadVideo(id, title, autoplay) {
autoplay = false;
$("." + id).removeClass("noplay");
}
- swfobject.embedSWF('http://www.youtube.com/v/' + id + '&rel=1&border=0&fs=1&autoplay=' +
+ swfobject.embedSWF('http://www.youtube.com/v/' + id + '&rel=1&border=0&fs=1&autoplay=' +
(autoplay?1:0), 'player', '500', '334', '9.0.0', false, false, {allowfullscreen: 'true'});
$("#videoPlayerTitle").html("<h2>" + unescape(title) + "</h2>");
-
+
$.history.add('v=' + id); // add the current video to the browser history
- document.getElementById("doc-content").scrollTop = 0; // scroll the window to the top
+ document.getElementById("doc-content").scrollTop = 0; // scroll the window to the top
}
/* Draw all videos from a playlist into a 'videoPreviews' list
* @param data The feed data returned from the youtube request
*/
-function renderPlaylist(data) {
+function renderPlaylist(data) {
var MAX_DESC_LENGTH = 390; // the length at which we will trim the description
var feed = data.feed;
var entries = feed.entry || [];
var playlistId = feed.yt$playlistId.$t;
-
+
var ul = $('<ul class="videoPreviews" />');
-
+
// Loop through each entry (each video) and add it to the 'videoPreviews' list
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
-
+
var title = entry.title.$t;
var id = entry.media$group.yt$videoid.$t;
var thumbUrl = entry.media$group.media$thumbnail[0].url;
var fullDescription = entry.media$group.media$description.$t;
var playerUrl = entry.media$group.media$content[0].url;
-
+
// Check whether this playlist includes the video title inside the description meta-data, so we can remove it
if (playlistsWithTitleInDescription.indexOf(playlistId) != -1) {
var lines = fullDescription.split("\n");
// If the first line includes the first 17 chars from the title, let's use the title from the description instead (because it's a more complete title)
// This accounts for, literally, "Google I/O 2009 -", which is (so far) the min AND max for properly identifying a title in the only playlist with titles in the description
- if (lines[0].indexOf(title.slice(0,16)) != -1) {
- h3Title = "<h3>" + lines[0] + "</h3>";
+ if (lines[0].indexOf(title.slice(0,16)) != -1) {
+ h3Title = "<h3>" + lines[0] + "</h3>";
if (lines[2].length < 30) lines = lines.slice(3); // also, if the second line is very short (the speaker name), slice it out too
else lines = lines.slice(1); // otherwise, slice after the first line
}
fullDescription = lines.join("");
- }
-
+ }
+
var shortDescription = fullDescription.substr(0, MAX_DESC_LENGTH);
shortDescription += shortDescription.length == MAX_DESC_LENGTH ? "..." : ""; // add ellipsis if we've chopped the description
-
+
var img = $('<img src="' + thumbUrl + '" width="120" height="90"/>');
var a = $('<a class="' + id + '" href="#" onclick="loadVideo(\'' + id + '\',\'' + escape(title) + '\',true); return setSelected(this);" />');
var pShortDescription = $('<p class="short">' + shortDescription + '</p>');
@@ -118,19 +118,19 @@ function renderPlaylist(data) {
var h3Title = "<h3>" + title + "</h3>";
var pToggle = "<p class='toggle'><a href='#' onclick='return toggleDescription(this)'><span class='more'>more</span><span class='less'>less</span></a></p>";
var li = $('<li/>');
-
+
li.append(a);
a.append(img).append(h3Title).append(pShortDescription);
-
+
// Add the full description and "more/less" toggle, if necessary
if (fullDescription.length > MAX_DESC_LENGTH) {
a.append(pFullDescription);
li.append(pToggle);
}
-
+
ul.append(li);
}
-
+
// Now add the 'videoPreviews' list to the page, and be sure we put it in the right tab
// This is the part that allows us to put multiple playlists in one tab
for (var x in playlists) {
@@ -141,13 +141,13 @@ function renderPlaylist(data) {
break;
}
}
- }
+ }
}
-/* Draw a featured video into the existing 'videoPreviews' list
+/* Draw a featured video into the existing 'videoPreviews' list
* @param data The video data returned from the youtube request
*/
-function renderFeatured(data) {
+function renderFeatured(data) {
var MAX_TITLE_LENGTH = 48;
var entry = data.entry || [];
var id = entry.media$group.yt$videoid.$t;
@@ -155,15 +155,15 @@ function renderFeatured(data) {
var title = entry.title.$t;
var thumbUrl = entry.media$group.media$thumbnail[0].url;
var playerUrl = entry.media$group.media$content[0].url;
-
+
var ellipsis = title.length > MAX_TITLE_LENGTH ? "..." : "";
-
+
var h3Title = "<h3>"+ title.substr(0,MAX_TITLE_LENGTH) + ellipsis + "</h3>";
var img = $('<img src="' + thumbUrl + '" width="120" height="90"/>');
var p = $('<p>' + description + '</p>');
var a = $('<a class="' + id + '" href="#" onclick="loadVideo(\'' + id + '\',\'' + title + '\',true); return setSelected(this);" />');
var li = $("<li/>");
-
+
a.append(h3Title).append(img).append(p);
li.append(a);
@@ -175,8 +175,8 @@ function showPlaylists() {
for (var x in playlists) {
var ids = playlists[x].ids;
for (var i in ids) {
- var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/playlists/"
- + ids[i] +
+ var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/playlists/"
+ + ids[i] +
"?v=2&alt=json-in-script&callback=renderPlaylist'><\/script>";
$("body").append(script);
}
@@ -186,14 +186,14 @@ function showPlaylists() {
/* Request the featured videos from YouTube */
function showFeatured() {
for (var id in featured) {
- var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/videos/"
- + id +
+ var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/videos/"
+ + id +
"?v=2&alt=json-in-script&callback=renderFeatured'><\/script>";
$("body").append(script);
}
}
-/* Reveal a tab (playlist) box
+/* Reveal a tab (playlist) box
* @param name The name of the tab
*/
function showBox(name) {
@@ -202,7 +202,7 @@ function showBox(name) {
return false;
}
-/* Highlight a video thumbnail, including all duplicates that there may be
+/* Highlight a video thumbnail, including all duplicates that there may be
* @param link The link <a> object that was clicked
*/
function setSelected(link) {
@@ -220,8 +220,8 @@ function setSelected(link) {
return false;
}
-/* Reveal and hide the long/short descriptions for a video in the playlist
- * @param link The link <a> object that was clicked
+/* Reveal and hide the long/short descriptions for a video in the playlist
+ * @param link The link <a> object that was clicked
*/
function toggleDescription(link) {
var aToggle = $(link);
@@ -238,9 +238,9 @@ function toggleDescription(link) {
}
/* Add actions to the page onload event so that we load a video right away */
-addLoadEvent(function () {
- // if there's a video url in the hash, click that video
- if (location.href.indexOf("#v=") != -1) {
+addLoadEvent(function () {
+ // if there's a video url in the hash, click that video
+ if (location.href.indexOf("#v=") != -1) {
var videoId = location.href.split("#v=");
clickVideo(videoId[1]);
} else { // otherwise, click the default video
@@ -251,20 +251,20 @@ addLoadEvent(function () {
var clickVideoAttempts = 0; // Used with clickVideo()
-/* Click a video in order to load it and select it
+/* Click a video in order to load it and select it
* @param videoId The ID of the video to click
*/
function clickVideo(videoId) {
if ($("." + videoId).length != 0) { // if we find the video, click it and return
- $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo)
+ $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo)
$("." + videoId + ":first").click();
return;
} else { // if we don't find it, increment clickVideoAttempts
console.log("video NOT found: " + videoId);
clickVideoAttempts++;
}
-
- // if we don't find it after 20 attempts (2 seconds), click the first feature video
+
+ // if we don't find it after 20 attempts (2 seconds), click the first feature video
if (clickVideoAttempts > 10) {
console.log("video never found, clicking default...");
clickVideoAttempts = 0;
@@ -278,15 +278,15 @@ function clickVideo(videoId) {
function clickDefaultVideo() {
if ($("#mainBodyRight .videoPreviews a:first").length != 0) {
var videoId = $("#mainBodyRight .videoPreviews a:first").attr("class");
- $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo)
+ $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo)
$("." + videoId + ":first").click();
return;
} else { // if we don't find it, increment clickVideoAttempts
console.log("default video NOT found");
clickVideoAttempts++;
}
-
- // if we don't find it after 50 attempts (5 seconds), just fail
+
+ // if we don't find it after 50 attempts (5 seconds), just fail
if (clickVideoAttempts > 50) {
console.log("default video never found...");
} else { // try again after 100 milliseconds
@@ -296,8 +296,8 @@ function clickDefaultVideo() {
</script>
<div id="mainBodyFixed">
-
- <div id="mainBodyLeft" class="videoPlayer" >
+
+ <div id="mainBodyLeft" class="videoPlayer" >
<div id="videoPlayerBox">
<div id="videoBorder">
<div id="videoPlayerTitle"></div>
@@ -307,32 +307,32 @@ function clickDefaultVideo() {
</div>
</div>
</div><!-- end mainBodyLeft -->
-
+
<div id="mainBodyRight" class="videoPlayer">
<h2>Featured Videos</h2>
<ul class="videoPreviews"></ul>
</div><!-- end mainBodyRight -->
-
+
<ul id="videoTabs">
<li id="aboutTab" class="selected"><a onclick="return showBox('about');" href="#">About the Platform</a></li>
<li id="developertipsTab"><a onclick="return showBox('developertips');" href="#">Developer Tips</a></li>
<li id="googleioTab"><a onclick="return showBox('googleio');" href="#">Google I/O Sessions</a></li>
<li id="developersandboxTab"><a onclick="return showBox('developersandbox');" href="#">Developer Sandbox</a></li>
</ul>
-
+
<div id="videos">
<div id="aboutBox" class="selected"></div>
<div id="developertipsBox"></div>
<div id="googleioBox"></div>
<div id="developersandboxBox"></div>
</div>
-
+
</div><!-- end mainBodyFixed -->
-
+
<script type="text/javascript">
// Initialization actions
showFeatured(); // load featured videos
showPlaylists(); // load playlists
</script>
-
+
diff --git a/docs/knowntags.txt b/docs/knowntags.txt
new file mode 100644
index 0000000..5bebabb
--- /dev/null
+++ b/docs/knowntags.txt
@@ -0,0 +1,38 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# The grandfathered list. We should get rid of these if possible.
+#
+@ToBeFixed
+@stable
+@com.intel.drl.spec_ref
+@ar.org.fitc.spec_ref
+
+# Something about CTS?
+@cts
+
+# Auto-generated info about the SDK
+@sdkCurrent
+@sdkCurrentVersion
+@sdkCurrentRelId
+@sdkPlatformVersion
+@sdkPlatformApiLevel
+@sdkPlatformMajorMinor
+@sdkPlatformReleaseDate
+@sdkPlatformDeployableDate
+@adtZipVersion
+@adtZipDownload
+@adtZipBytes
+@adtZipChecksum