diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/html/about/about_toc.cs | 2 | ||||
-rw-r--r-- | docs/html/about/versions/android-5.0.jd | 23 | ||||
-rw-r--r-- | docs/html/about/versions/lollipop.jd | 245 | ||||
-rw-r--r-- | docs/html/guide/components/recents.jd | 256 | ||||
-rw-r--r-- | docs/html/guide/components/tasks-and-back-stack.jd | 152 | ||||
-rw-r--r-- | docs/html/guide/guide_toc.cs | 3 | ||||
-rw-r--r-- | docs/html/guide/topics/manifest/activity-element.jd | 101 | ||||
-rw-r--r-- | docs/html/images/components/recents.png | bin | 0 -> 961683 bytes | |||
-rw-r--r-- | docs/html/images/versions/battery_historian.png | bin | 0 -> 56657 bytes | |||
-rw-r--r-- | docs/html/images/versions/battery_historian@2x.png | bin | 0 -> 175020 bytes | |||
-rw-r--r-- | docs/html/images/versions/notification-headsup.png | bin | 0 -> 142431 bytes | |||
-rw-r--r-- | docs/html/images/versions/recents_screen.png | bin | 0 -> 490653 bytes | |||
-rw-r--r-- | docs/html/images/versions/rivalknights.png | bin | 0 -> 1081508 bytes | |||
-rw-r--r-- | docs/html/training/training_toc.cs | 4 | ||||
-rw-r--r-- | docs/html/training/tv/playback/index.jd | 3 | ||||
-rw-r--r-- | docs/html/training/tv/playback/now-playing.jd | 167 |
16 files changed, 868 insertions, 88 deletions
diff --git a/docs/html/about/about_toc.cs b/docs/html/about/about_toc.cs index 95688a9..133cccb 100644 --- a/docs/html/about/about_toc.cs +++ b/docs/html/about/about_toc.cs @@ -7,7 +7,7 @@ </ul> </li> <li class="nav-section"> - <div class="nav-section-header"><a href="<?cs var:toroot ?>about/versions/android-5.0.html"> + <div class="nav-section-header"><a href="<?cs var:toroot ?>about/versions/lollipop.html"> <span class="en">Lollipop</span></a></div> <ul> <li><a href="<?cs var:toroot ?>about/versions/android-5.0.html">Android 5.0 APIs</a></li> diff --git a/docs/html/about/versions/android-5.0.jd b/docs/html/about/versions/android-5.0.jd index 6f7e272..2e3663b 100644 --- a/docs/html/about/versions/android-5.0.jd +++ b/docs/html/about/versions/android-5.0.jd @@ -123,12 +123,23 @@ Differences Report (L Developer Preview to 21) »</a> </li> offers new features for users and app developers. This document provides an introduction to the most notable new APIs.</p> -<p>As an app developer, you should download the Android 5.0 system image and -SDK platform from the <a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> -as soon as possible. If you don’t have a device running Android 5.0 on which to -test your app, use the Android 5.0 system image to test your app on the -<a href="{@docRoot}tools/devices/emulator.html">Android emulator</a>. Then -build your apps against the Android 5.0 platform to begin using the latest APIs.</p> + +<h3 id="Start">Start developing</h3> + +<p>To start building apps for Android 5.0, you must first <a href="{@docRoot}sdk/index.html">get +the Android SDK</a>. Then use the <a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> +to download the Android 5.0 SDK Platform and System Images.</p> + +<p style=" + padding: 10px; + background: #eee; + width: 445px; + border: 1px solid #ccc; + margin-top: 20px; +">To test your apps on a real device, flash a Nexus 5 or Nexus 7 with the <br> +<a href="/preview/index.html#Start"><b>ANDROID PREVIEW SYSTEM IMAGE</b></a>.</p> + + <h3 id="ApiLevel">Update your target API level</h3> diff --git a/docs/html/about/versions/lollipop.jd b/docs/html/about/versions/lollipop.jd new file mode 100644 index 0000000..110ff4b --- /dev/null +++ b/docs/html/about/versions/lollipop.jd @@ -0,0 +1,245 @@ +page.title=Android Lollipop + +@jd:body + + + + + + + + + + + <div style="padding:0px 0px 0px 20px;float:right;margin:0 -10px 0 0"> + <img src="{@docRoot}images/home/l-hero_2x.png" srcset="{@docRoot}images/home/l-hero.png 1x, {@docRoot}images/home/l-hero_2x.png 2x" width="460" > + </div> + + <div class="landing-docs" style="float:right;clear:both;margin:68px 0 2em 3em;"> + <div class="col-4 normal-links highlights" style="font-size:12px;"> + <h3 id="thisd" >Key Developer Features</h3> + <ul style="list-style-type:none;"> + <li><a href="#Material">Material design</a></li> + <li><a href="#Perf">Performance focus</a></li> + <li><a href="#Notifications">Notifications</a></li> + <li><a href="#TV">Your apps on the big screen</a></li> + <li><a href="#Documents">Document-centric apps</a></li> + <li><a href="#Connectivity">Advanced connectivity</a></li> + <li><a href="#Graphics">High-performance graphics</a></li> + <li><a href="#Audio">More Powerful Audio</a></li> + <li><a href="#Camera">Enhanced Camera & Video</a></li> + <li><a href="#ScreenCapture">Screen capturing and sharing</a></li> + <li><a href="#Sensors">New types of sensors</a></li> + <li><a href="#WebView">Chromium WebView</a></li> + <li><a href="#Accessibility">Accessibility & Input</a></li> + <li><a href="#Battery">Tools for building battery-efficient apps</a></li> + </ul> + </div> +</div> + + + + + + + +<p>Welcome to Android 5.0 Lollipop—-the largest and most ambitious release for Android yet!</p> + +<p>This release is packed with new features for users and thousands of new APIs for developers. It extends Android even further, from phones, tablets, and wearables, to TVs and cars.</p> + +<p>For a closer look at the new developer APIs, see the Android 5.0 API Overview. Or, read more about Android 5.0 for consumers at www.android.com.</p> + + +<p style=" + padding: 10px; + background: #eee; + width: 250px; + border: 1px solid #ccc; + margin-top: 20px; +">To test your apps on a real device, flash a Nexus 5 or Nexus 7 with the <br> +<a href="/preview/index.html#Start"><b>ANDROID PREVIEW SYSTEM IMAGE</b></a>.</p> + + +<h2 id="Material">Material design</h2> + +<p>Android 5.0 brings <a href="http://www.google.com/design/spec">Material design</a> to Android and gives you an expanded UI toolkit for integrating the new design patterns easily in your apps. </p> + + + +<p>New<em>* 3D views</em>* let you set a Z-level to raise elements off of the main view hierarchy and cast <strong>realtime shadows</strong> from your views, even as they move.</p> + + +<p>Built-in <strong>activity transitions</strong> take the user seamlessly from one state to another with beautiful, animated motion. The material theme adds transitions for your activities, including the ability to use <strong>shared visual elements</strong> across activities.</p> + + + +<div style="width:290px;margin-right:35px;float:left"> + <div class="framed-nexus5-port-span-5"> + <video class="play-on-hover" autoplay=""> + <source src="/design/material/videos/ContactsAnim.mp4"> + <source src="/design/videos/ContactsAnim.webm"> + <source src="/design/videos/ContactsAnim.ogv"> + </video> + </div> + <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> + <em>To replay the movie, click on the device screen</em> + </div> +</div> + + +<p>Ripple animations are available for buttons, checkboxes, and other touch controls in your app.</p> + +<p>A new system-managed processing thread called <strong>RenderThread</strong> keeps animations smooth even when there are delays in the main UI thread. </p> + + + +<h2 id="Perf">Performance focus</h2> + +<p>Android 5.0 provides a faster, smoother and more powerful computing experience.</p> + +<p>Android now runs exclusively on the new <strong>ART runtime</strong> — built from the ground up to support a mix of ahead-of-time (AOT), just-in-time (JIT), and interpreted code. It’s truly cross platform and is supported on ARM, x86, and MIPS architectures. It is also fully 64-bit compatible.</p> + +<p>ART improves app performance and responsiveness. Efficient garbage collection reduces the number and duration of pauses for GC events, which fit comfortably within the v-sync window so your app doesn’t skip frames. ART also dynamically moves memory to optimize performance for foreground uses. </p> + +<p>Android 5.0 introduces platform support for <strong>64-bit architectures</strong>, such as used in the Nexus 9’s NVIDIA Tegra K1. Optimizations provide larger address space and improved performance for certain compute workloads. Apps written in the Java language run as 64-bit apps automatically — no modifications are needed. If your app uses native code, we’ve extended NDK to support new ABIs for ARM v8, and x86-64, and MIPS-64.</p> + + + +<h2 id="Notifications">Notifications</h2> + +<p>Notifications in Android 5.0 are more visible, accessible, and configurable. </p> + +<img src="{@docRoot}images/versions/notification-headsup.png" style="float:right; margin:0 0 40px 60px" width="300" /> + +<p>Varying notification details may appear <strong>on the lock screen</strong> if desired by the user. Users may elect to allow none, some, or all notification content to be shown on a secure lock screen. </p> + + +<p>Key notification alerts such as incoming calls appear in a <strong>heads-up notification</strong>—-a small floating window that allows the user to respond or dismiss without leaving the current app.</p> + +<p>You can now add <strong>new metadata</strong> to notifications to collect associated contacts (for ranking), category, and priority.</p> + +<p>A new MediaStyle notification template provides consistent media controls for notifications, including on the lock screen, with options for custom controls such as "thumbs up."</p> + + + +<h2 id="TV">Your apps on the big screen</h2> + +<p><a href="http://developer.android.com/tv/index.html">Android TV</a> provides a complete TV platform for your app’s big screen experience. Android TV is centered around a simplified home screen experience that allows users to discover content easily, with personalized recommendations and voice search.</p> + +<p>With Android TV you can now <strong>create big, bold experiences</strong> for your app or game content and support interactions with game controllers and other input devices. To help you build cinematic, 10-foot UIs for television, Android 5.0 provides a <strong>leanback UI framework</strong> in the v17 Support Library.</p> + +<p>The <strong>Android TV Input Framework</strong> (TIF) allows TV apps to handle video streams from sources such as HDMI inputs, TV tuners, and IPTV receivers. It also enables live TV search and recommendations via metadata published by the TV Input and includes an HDMI-CEC Control Service to handle multiple devices with a single remote. </p> + +<p>The TV Input Framework provides access to a wide variety of live TV input sources and brings them together in a single user interface for users to browse, view, and enjoy content. Building a TV input service for your content can help make your content more accessible on TV devices.</p> + + + +<img src="{@docRoot}images/versions/recents_screen.png" style="float:right; margin:0 0 40px 60px" width="300" /> + +<h2 id="Documents">Document-centric apps</h2> + +<p>Android 5.0 introduces an redesigned Overview space (formerly called Recents) that’s more versatile and useful for multitasking.</p> + +<p>New APIs allow you to show individual activities in your app as individual documents alongside other recent screens.</p> + +<p>You can take advantage of concurrent documents to provide users instant access to more of your content or services. For example, you could use concurrent documents to represent files in a productivity app, player matches in a game, or chats in a messaging app. </p> + + + +<h2 id="Connectivity">Advanced connectivity</h2> + +<p>Android 5.0 adds new APIs that allow apps to perform concurrent operations with <strong>Bluetooth Low Energy</strong> (BLE), allowing both scanning (central mode) and advertising (peripheral mode).</p> + +<p>New <strong>multi-networking</strong> features allow apps to query available networks for available features such as whether they are Wi-Fi, cellular, metered, or provide certain network features, then request a connection and respond to connectivity loss or other network changes.</p> + +<p><strong>NFC</strong> APIs now allow apps to register an NFC application ID (AID) dynamically. They can also set the preferred card emulation service per active service and create an NDEF record containing UTF-8 text data.</p> + +<p>The <strong>Android Beam</strong> feature for wirelessly sharing files between devices is now available in the ShareActionProvider, so users can select Android Beam as the share action before touching the other device.</p> + + + +<h2 id="Graphics">High-performance graphics</h2> + +<p>Support for <strong><a href="http://www.khronos.org/opengles/3_X/">Khronos OpenGL ES 3.1</a></strong> now provides games and other apps the highest-performance 2D and 3D graphics capabilities on supported devices. </p> + +<p>OpenGL ES 3.1 adds compute shaders, geometry shaders, stencil textures, accelerated visual effects, high quality ETC2/EAC texture compression, advanced texture rendering, standardized texture size and render-buffer formats, and more.</p> + + +<div class="figure" style="width:350px; margin:0 0 0 60px"> +<img src="{@docRoot}images/versions/rivalknights.png" style="float:right;" width="350" /> +<p class="img-caption">Gameloft's Rival Knights uses ASTC from AEP and Compute Shaders from ES 3.1 to deliver HDR Bloom effects and provide more graphical detail.</p> +</div> + +<p>Android 5.0 also introduces the <strong>Android Extension Pack</strong> (AEP), a set of OpenGL ES extensions that give you access to features like tessellation shaders, geometry shaders, ASTC texture compression, per-sample interpolation and shading, and other advanced rendering capabilities. With AEP you can deliver high-performance graphics across a range of GPUs.</p> + + +<h2 id="Audio">More Powerful Audio</h2> + +<p>A new audio-capture design offers <strong>low-latency audio input</strong>. The new design includes: a fast capture thread that never blocks except during a read; fast track capture clients at native sample rate, channel count, and bit depth; and normal capture clients offer resampling, up/down channel mix, and up/down bit depth.</p> + +<p>Multi-channel <strong>audio stream mixing</strong> allows professional audio apps to mix up to eight channels including 5.1 and 7.1 channels.</p> + +<p>Apps can expose their media content and <strong>browse media</strong> from other apps, then request playback. Content is exposed through a queryable interface and does not need to reside on the device.</p> + +<p>Apps have finer-grain control over <strong>text-to-speech synthesis</strong> through voice profiles that are associated with specific locales, quality and latency rating. New APIs also improve support for synthesis error checking, network synthesis, language discovery, and network fallback.</p> + +<p>Android now includes support for standard <strong>USB audio</strong> peripherals, allowing users to connect USB headsets, speakers, microphones, or other high performance digital peripherals. Android 5.0 also adds support for <strong>Opus</strong> audio codecs.</p> + +<p>New <strong>MediaSession</strong> APIs for controlling media playback make it easier to provide consistent media controls across screens.</p> + + +<h2 id="Camera">Enhanced Camera & Video</h2> + +<p>Android 5.0 introduces a <strong>new camera API</strong> that lets you capture raw formats such as YUV and Bayer RAW, and control parameters such as exposure time, ISO sensitivity, and frame duration, on a per-frame basis. Burst capture mode lets you uncompressed 8 megapixel YUV images at 30 FPS on supported devices. </p> + +<p>Along with images, you can also capture metadata like noise models and optical information from the camera.</p> + +<p>Apps sending video streams over the network can now take advantage of H.265 <strong>High Efficiency Video Coding (HEVC)</strong> for optimized encoding and decoding of video data. </p> + +<p>Android 5.0 also adds support for <strong>multimedia tunneling</strong> to provide the best experience for ultra-high definition (4K) content and the ability to play compressed audio and video data together. </p> + + +<h2 id="ScreenCapture">Screen capturing and sharing</h2> + +<p>Android 5.0 lets you add screen capturing and screen sharing capabilities to your app. </p> + +<p>With user permission, you can capture non-secure video from the display and deliver it over the network if you choose.</p> + + +<h2 id="Sensors">New types of sensors</h2> + +<p>In Android 5.0 a new <strong>tilt detector</strong> sensor helps improve activity recognition on supported devices, and a <strong>heart rate sensor</strong> reports the heart rate of the person touching the device. </p> + +<p>New <strong>interaction composite sensors</strong> are now available to detect special interactions such as a <em>wake up</em> gesture, a <em>pick up</em> gesture, and a <em>glance</em> gesture.</p> + + + +<h2 id="WebView">Chromium WebView</h2> + +<div style="float:right;margin:1em 2em 1em 2em;"> + <img src="/images/kk-chromium-icon.png" alt="" height="160" style="margin-bottom:0em;"> +</div> + +<p>The initial release for Android 5.0 includes a version of Chromium for WebView based on the Chromium M37 release, adding support for <strong>WebRTC</strong>, <strong>WebAudio</strong>, and <strong>WebGL</strong>. </p> + +<p>Although WebView has been based on Chromium since Android 4.4, the Chromium layer is now updatable from Google Play.</p> + +<p>As new versions of Chromium become available, users can update from Google Play to ensure they get the latest enhancements and bug fixes for WebView, providing the latest web APIs and bug fixes for apps using WebView.</p> + + + +<h2 id="Accessibility">Accessibility & Input</h2> + +<p>Accessibility APIs can retrieve detailed information about the properties of windows on the screen that sighted users can interact with and define standard or customized input actions for UI elements.</p> + +<p>New Input method editor (IME) APIs enable faster switching to other IMEs directly from the input method.</p> + + + +<h2 id="Battery">Tools for building battery-efficient apps</h2> + +<p>New <strong>job scheduling</strong> APIs allow you optimize battery life by deferring jobs for the system to run at a later time or under specified conditions, such as when the device is charging or connected to Wi-Fi.</p> + +<p>A new <code>dumpsys batterystats</code> command generates <strong>battery usage statistics</strong> that you can use to understand system-wide power use and understand the impact of your app on the device battery. You can look at a history of power events, approximate power use per UID and system component, and more.</p> + +<img src="{@docRoot}images/versions/battery_historian.png" srcset="{@docRoot}images/versions/battery_historian@2x.png 2x" alt="" width="760" height="462" />
\ No newline at end of file diff --git a/docs/html/guide/components/recents.jd b/docs/html/guide/components/recents.jd new file mode 100644 index 0000000..b44c682 --- /dev/null +++ b/docs/html/guide/components/recents.jd @@ -0,0 +1,256 @@ +page.title=Overview Screen +page.tags="recents","overview" + +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + + <h2>In this document</h2> + <ol> + <li><a href="#adding">Adding Tasks to the Overview Screen</a> + <ol> + <li><a href="#flag-new-doc">Using the Intent flag to add a task</a></li> + <li><a href="#attr-doclaunch">Using the Activity attribute to add a task</a></li> + </ol> + </li> + <li><a href="#removing">Removing Tasks</a> + <ol> + <li><a href="#apptask-remove">Using the AppTask class to remove tasks</a></li> + <li><a href="#retain-finished">Retaining finished tasks</a></li> + </ol> + </li> + </ol> + + <h2>Key classes</h2> + <ol> + <li>{@link android.app.ActivityManager.AppTask}</li> + <li>{@link android.content.Intent}</li> + </ol> + + <h2>Sample code</h2> + <ol> + <li><a href="{@docRoot}samples/activitytasks/index.html">Document-centric Apps</a></li> + </ol> + +</div> +</div> + +<p>The overview screen (also referred to as the recents screen, recent task list, or recent apps) +is a system-level UI that lists recently accessed <a href="{@docRoot}guide/components/activities.html"> +activities</a> and <a href="{@docRoot}guide/components/tasks-and-back-stack.html">tasks</a>. The +user can navigate through the list and select a task to resume, or the user can remove a task from +the list by swiping it away. With the Android 5.0 release (API level 21), multiple instances of the +same activity containing different documents may appear as tasks in the overview screen. For example, +Google Drive may have a task for each of several Google documents. Each document appears as a +task in the overview screen.</p> + +<img src="{@docRoot}images/components/recents.png" alt="" width="284" /> +<p class="img-caption"><strong>Figure 1.</strong> The overview screen showing three Google Drive +documents, each represented as a separate task.</p> + +<p>Normally you should allow the system to define how your tasks and +activities are represented in the overview screen, and you don't need to modify this behavior. +However, your app can determine how and and when activities appear in the overview screen. The +{@link android.app.ActivityManager.AppTask} class lets you manage tasks, and the activity flags of +the {@link android.content.Intent} class let you specify when an activity is added or removed from +the overview screen. Also, the <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"> +<activity></a></code> attributes let you set the behavior in the manifest.</p> + +<h2 id="adding">Adding Tasks to the Overview Screen</h2> + +<p>Using the flags of the {@link android.content.Intent} class to add a task affords greater control +over when and how a document gets opened or reopened in the overview screen. When you use the +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +attributes you can choose between always opening the document in a new task or reusing an +existing task for the document.</p> + +<h3 id="flag-new-doc">Using the Intent flag to add a task</h3> + +<p>When you create a new document for your activity, you call the +{@link android.app.ActivityManager.AppTask#startActivity(android.content.Context, android.content.Intent, android.os.Bundle) startActivity()} +method of the {@link android.app.ActivityManager.AppTask} class, passing to it the intent that +launches the activity. To insert a logical break so that the system treats your activity as a new +task in the overview screen, pass the {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} flag +in the {@link android.content.Intent#addFlags(int) addFlags()} method of the {@link android.content.Intent} +that launches the activity.</p> + +<p class="note"><strong>Note:</strong> The {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} +flag replaces the {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET} flag, +which is deprecated as of Android 5.0 (API level 21).</p> + +<p>If you set the {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} flag when you create +the new document, the system always creates a new task with the target activity as the root. +This setting allows the same document to be opened in more than one task. The following code demonstrates +how the main activity does this:</p> + +<p class="code-caption"><a href="{@docRoot}samples/activitytasks/src/com/example/android/documentcentricrecents/DocumentCentricActivity.html"> +DocumentCentricActivity.java</a></p> +<pre> +public void createNewDocument(View view) { + final Intent newDocumentIntent = newDocumentIntent(); + if (useMultipleTasks) { + newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); + } + startActivity(newDocumentIntent); + } + + private Intent newDocumentIntent() { + boolean useMultipleTasks = mCheckbox.isChecked(); + final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class); + newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); + newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet()); + return newDocumentIntent; + } + + private static int incrementAndGet() { + Log.d(TAG, "incrementAndGet(): " + mDocumentCounter); + return mDocumentCounter++; + } +} +</pre> + +<p class="note"><strong>Note:</strong> Activities launched with the {@code FLAG_ACTIVITY_NEW_DOCUMENT} +flag must have the {@code android:launchMode="standard"} attribute value (the default) set in the +manifest.</p> + +<p>When the main activity launches a new activity, the system searches through existing tasks for +one whose intent matches the intent component name and the Intent data for the activity. If the task +is not found, or the intent contained the {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} +flag, a new task will be created with the activity as its root. If it finds one, it brings that task +to the front and passes the new intent to {@link android.app.Activity#onNewIntent onNewIntent()}. +The new activity gets the intent and creates a new document in the overview screen, as in the +following example:</p> + +<p class="code-caption"><a href="{@docRoot}samples/activitytasks/src/com/example/android/documentcentricrecents/NewDocumentActivity.html"> +NewDocumentActivity.java</a></p> +<pre> +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_new_document); + mDocumentCount = getIntent() + .getIntExtra(DocumentCentricActivity.KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0); + mDocumentCounterTextView = (TextView) findViewById( + R.id.hello_new_document_text_view); + setDocumentCounterText(R.string.hello_new_document_counter); +} + +@Override +protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + /* If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this activity + is reused to create a new document. + */ + setDocumentCounterText(R.string.reusing_document_counter); +} +</pre> + + +<h3 id="#attr-doclaunch">Using the activity attribute to add a task</h3> + +<p>An activity can also specify in its manifest that it always launches into a new task by using +the <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +attribute, <a href="{@docRoot}guide/topics/manifest/activity-element.html#dlmode"> +{@code android:documentLaunchMode}</a>. This attribute has four values which produce the following +effects when the user opens a document with the application:</p> + +<dl> + <dt>"{@code intoExisting}"</dt> + <dd>The activity reuses an existing task for the document. This is the same as setting the + {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} flag <em>without</em> setting the + {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} flag, as described in + <a href="#flag-new-doc">Using the Intent flag to add a task</a>, above.</dd> + + <dt>"{@code always}"</dt> + <dd>The activity creates a new task for the document, even if the document is already opened. Using + this value is the same as setting both the {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} + and {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} flags.</dd> + + <dt>"{@code none”}"</dt> + <dd>The activity does not create a new task for the document. The overview screen treats the + activity as it would by default: it displays a single task for the app, which + resumes from whatever activity the user last invoked.</dd> + + <dt>"{@code never}"</dt> + <dd>The activity does not create a new task for the document. Setting this value overrides the + behavior of the {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} + and {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} flags, if either of these are set + in the intent, and the overview screen displays a single task for the app, which resumes from + whatever activity the user last invoked.</dd> +</dl> + +<p class="note"><strong>Note:</strong> For values other than {@code none} and {@code never} the +activity must be defined with {@code launchMode="standard"}. If this attribute is not specified, +{@code documentLaunchMode="none"} is used.</p> + +<h2 id="removing">Removing Tasks</h2> + +<p>By default a document task is automatically removed from the overview screen when its activity +finishes. You can override this behavior with the {@link android.app.ActivityManager.AppTask} class, +with an {@link android.content.Intent} flag, or with an<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"> +<activity></a></code> attribute.</p> + +<p>You can always exclude a task from the overview screen entirely by setting the +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +attribute, <a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude"> +{@code android:excludeFromRecents}</a> to {@code true}.</p> + +<p>You can set the maximum number of tasks that your app can include in the overview screen by setting +the <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +attribute <a href="{@docRoot}guide/topics/manifest/activity-element.html#maxrecents">{@code android:maxRecents} +</a> to an integer value. The default is 16. When the maximum number of tasks is reached, the least +recently used task is removed from the overview screen. The {@code android:maxRecents} maximum value +is 50 (25 on low memory devices); values less than 1 are not valid.</p> + +<h3 id="#apptask-remove">Using the AppTask class to remove tasks</h3> + +<p>In the activity that creates a new task in the overview screen, you can +specify when to remove the task and finish all activities associated with it by calling +the {@link android.app.ActivityManager.AppTask#finishAndRemoveTask() finishAndRemoveTask()} method.</p> + +<p class="code-caption"><a href="{@docRoot}samples/activitytasks/index.html"> +NewDocumentActivity.java</a></p> +<pre> +public void onRemoveFromRecents(View view) { + // The document is no longer needed; remove its task. + finishAndRemoveTask(); +} +</pre> + +<p class="note"><strong>Note:</strong> Using the +{@link android.app.ActivityManager.AppTask#finishAndRemoveTask() finishAndRemoveTask()} method +overrides the use of the {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} tag, +discussed below.</p> + +<h3 id="#retain-finished">Retaining finished tasks</h3> + +<p>If you want to retain a task in the overview screen, even if its activity has finished, pass +the {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} flag in the +{@link android.content.Intent#addFlags(int) addFlags()} method of the Intent that launches the activity.</p> + +<p class="code-caption"><a href="{@docRoot}samples/activitytasks/src/com/example/android/documentcentricrecents/DocumentCentricActivity.html"> +DocumentCentricActivity.java</a></p> +<pre> +private Intent newDocumentIntent() { + final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class); + newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | + android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); + newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet()); + return newDocumentIntent; +} +</pre> + +<p>To achieve the same effect, set the +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +attribute <a href="{@docRoot}guide/topics/manifest/activity-element.html#autoremrecents"> +{@code android:autoRemoveFromRecents}</a> to {@code false}. The default value is {@code true} +for document activities, and {@code false} for regular activities. Using this attribute overrides +the {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} flag, discussed previously.</p> + + + + + + + diff --git a/docs/html/guide/components/tasks-and-back-stack.jd b/docs/html/guide/components/tasks-and-back-stack.jd index e054313..aaef10e 100644 --- a/docs/html/guide/components/tasks-and-back-stack.jd +++ b/docs/html/guide/components/tasks-and-back-stack.jd @@ -21,7 +21,8 @@ parent.link=activities.html <h2>Articles</h2> <ol> - <li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html">Multitasking the Android Way</a></li> + <li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html"> + Multitasking the Android Way</a></li> </ol> <h2>See also</h2> @@ -31,6 +32,7 @@ Navigation</a></li> <li><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>} manifest element</a></li> + <li><a href="{@docRoot}guide/components/recents.html">Overview Screen</a></li> </ol> </div> </div> @@ -39,12 +41,12 @@ element</a></li> <p>An application usually contains multiple <a href="{@docRoot}guide/components/activities.html">activities</a>. Each activity should be designed around a specific kind of action the user can perform and can start other -activities. For example, an email application might have one activity to show a list of new email. -When the user selects an email, a new activity opens to view that email.</p> +activities. For example, an email application might have one activity to show a list of new messages. +When the user selects a message, a new activity opens to view that message.</p> <p>An activity can even start activities that exist in other applications on the device. For -example, if your application wants to send an email, you can define an intent to perform a "send" -action and include some data, such as an email address and a message. An activity from another +example, if your application wants to send an email message, you can define an intent to perform a +"send" action and include some data, such as an email address and a message. An activity from another application that declares itself to handle this kind of intent then opens. In this case, the intent is to send an email, so an email application's "compose" activity starts (if multiple activities support the same intent, then the system lets the user select which one to use). When the email is @@ -53,8 +55,8 @@ though the activities may be from different applications, Android maintains this experience by keeping both activities in the same <em>task</em>.</p> <p>A task is a collection of activities that users interact with -when performing a certain job. The activities are arranged in a stack (the "back stack"), in the -order in which each activity is opened.</p> +when performing a certain job. The activities are arranged in a stack (the <em>back stack</em>), in +the order in which each activity is opened.</p> <!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED <div class="sidebox-wrapper"> @@ -134,7 +136,8 @@ started Task A. Now, Task A comes to the foreground—all three activities in its stack are intact and the activity at the top of the stack resumes. At this point, the user can also switch back to Task B by going Home and selecting the application icon -that started that task (or by selecting the app's task from the <em>recent apps</em> screen). +that started that task (or by selecting the app's task from the +<a href="{@docRoot}guide/components/recents.html">overview screen</a>). This is an example of multitasking on Android.</p> <p class="note"><strong>Note:</strong> Multiple tasks can be held in the background at once. @@ -195,8 +198,8 @@ system memory. When this happens, information about the activity state is lost. system still knows that the activity has a place in the back stack, but when the activity is brought to the top of the stack the system must recreate it (rather than resume it). In order to -avoid losing the user's work, you should proactively retain it by implementing the {@link -android.app.Activity#onSaveInstanceState onSaveInstanceState()} callback +avoid losing the user's work, you should proactively retain it by implementing the +{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} callback methods in your activity.</p> <p>For more information about how to save your activity state, see the <a @@ -218,27 +221,26 @@ instance on top of the back stack); or, you want your back stack to be cleared o activities except for the root activity when the user leaves the task.</p> <p>You can do these things and more, with attributes in the -<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code -<activity>}</a> manifest element and with flags in the intent that you pass to {@link -android.app.Activity#startActivity startActivity()}.</p> +<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> +manifest element and with flags in the intent that you pass to +{@link android.app.Activity#startActivity startActivity()}.</p> -<p>In this regard, the principal <a -href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> -attributes you can use are:</p> +<p>In this regard, the principal <a href="{@docRoot}guide/topics/manifest/activity-element.html"> +{@code <activity>}</a> attributes you can use are:</p> <ul class="nolist"> - <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code -taskAffinity}</a></li> - <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code -launchMode}</a></li> - <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">{@code -allowTaskReparenting}</a></li> - <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code -clearTaskOnLaunch}</a></li> - <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always">{@code -alwaysRetainTaskState}</a></li> - <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code -finishOnTaskLaunch}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff"> + {@code taskAffinity}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode"> + {@code launchMode}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> + {@code allowTaskReparenting}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear"> + {@code clearTaskOnLaunch}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> + {@code alwaysRetainTaskState}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish"> + {@code finishOnTaskLaunch}</a></li> </ul> <p>And the principal intent flags you can use are:</p> @@ -250,15 +252,18 @@ finishOnTaskLaunch}</a></li> </ul> <p>In the following sections, you'll see how you can use these manifest attributes and intent -flags to define how activities are associated with tasks and how the behave in the back stack.</p> +flags to define how activities are associated with tasks and how they behave in the back stack.</p> +<p>Also, discussed separately are the considerations for how tasks and activites may be represented +and managed in the overview screen. See <a href="{@docRoot}guide/components/recents.html">Overview Screen</a> +for more information. Normally you should allow the system to define how your task and +activities are represented in the overview screen, and you don't need to modify this behavior.</p> <p class="caution"><strong>Caution:</strong> Most applications should not interrupt the default behavior for activities and tasks. If you determine that it's necessary for your activity to modify the default behaviors, use caution and be sure to test the usability of the activity during launch and when navigating back to it from other activities and tasks with the <em>Back</em> button. -Be sure -to test for navigation behaviors that might conflict with the user's expected behavior.</p> +Be sure to test for navigation behaviors that might conflict with the user's expected behavior.</p> <h3 id="TaskLaunchModes">Defining launch modes</h3> @@ -389,7 +394,7 @@ default behavior are:</p> <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt> <dd>Start the activity in a new task. If a task is already running for the activity you are now starting, that task is brought to the foreground with its last state restored and the activity -receives the new intent in {@link android.app.Activity#onNewIntent onNewIntent()}. +receives the new intent in {@link android.app.Activity#onNewIntent onNewIntent()}. <p>This produces the same behavior as the {@code "singleTask"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> value, discussed in the previous section.</p></dd> @@ -408,11 +413,13 @@ through {@link android.app.Activity#onNewIntent onNewIntent()}). <p>There is no value for the <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> attribute that produces this behavior.</p> - <p>{@code FLAG_ACTIVITY_CLEAR_TOP} is most often used in conjunction with {@code -FLAG_ACTIVITY_NEW_TASK}. When used together, these flags are a way of locating an existing activity + <p>{@code FLAG_ACTIVITY_CLEAR_TOP} is most often used in conjunction with + {@code FLAG_ACTIVITY_NEW_TASK}. +When used together, these flags are a way of locating an existing activity in another task and putting it in a position where it can respond to the intent. </p> - <p class="note"><strong>Note:</strong> If the launch mode of the designated activity is {@code -"standard"}, it too is removed from the stack and a new instance is launched in its place to handle + <p class="note"><strong>Note:</strong> If the launch mode of the designated activity is + {@code "standard"}, +it too is removed from the stack and a new instance is launched in its place to handle the incoming intent. That's because a new instance is always created for a new intent when the launch mode is {@code "standard"}. </p> </dd> @@ -439,21 +446,23 @@ element.</p> <p>The <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> attribute takes a string value, which must be unique from the default package name -declared in the <a href="{@docRoot}guide/topics/manifest/manifest-element.html">{@code -<manifest>}</a> element, because the system uses that name to identify the default task +declared in the <a href="{@docRoot}guide/topics/manifest/manifest-element.html"> +{@code <manifest>} +</a> element, because the system uses that name to identify the default task affinity for the application.</p> <p>The affinity comes into play in two circumstances:</p> <ul> - <li>When the intent that launches an activity contains the {@link -android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag. + <li>When the intent that launches an activity contains the + {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} + flag. <p>A new activity is, by default, launched into the task of the activity that called {@link android.app.Activity#startActivity startActivity()}. It's pushed onto the same -back stack as the caller. However, if the intent passed to {@link -android.app.Activity#startActivity startActivity()} contains the {@link -android.content.Intent#FLAG_ACTIVITY_NEW_TASK} -flag, the system looks for a different task to house the new activity. Often, it's a new task. +back stack as the caller. However, if the intent passed to +{@link android.app.Activity#startActivity startActivity()} +contains the {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} +flag, the system looks for a different task to house the new activity. Often, it's a new task. However, it doesn't have to be. If there's already an existing task with the same affinity as the new activity, the activity is launched into that task. If not, it begins a new task.</p> @@ -461,17 +470,17 @@ new activity, the activity is launched into that task. If not, it begins a new to leave it, there must be some way for the user to navigate back to the task. Some entities (such as the notification manager) always start activities in an external task, never as part of their own, so -they always put {@code FLAG_ACTIVITY_NEW_TASK} in the intents they pass to {@link -android.app.Activity#startActivity startActivity()}. If you have an activity that can be invoked by +they always put {@code FLAG_ACTIVITY_NEW_TASK} in the intents they pass to +{@link android.app.Activity#startActivity startActivity()}. +If you have an activity that can be invoked by an external entity that might use this flag, take care that the user has a independent way to get back to the task that's started, such as with a launcher icon (the root activity of the task has a {@link android.content.Intent#CATEGORY_LAUNCHER} intent filter; see the <a href="#Starting">Starting a task</a> section below).</p> </li> - <li>When an activity has its <a -href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">{@code -allowTaskReparenting}</a> attribute set to {@code "true"}. + <li>When an activity has its <a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> +{@code allowTaskReparenting}</a> attribute set to {@code "true"}. <p>In this case, the activity can move from the task it starts to the task it has an affinity for, when that task comes to the foreground.</p> <p>For example, suppose that an activity that reports weather conditions in selected cities is @@ -511,9 +520,9 @@ The task retains all activities in its stack even after a long period.</dd> href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt> <dd>If this attribute is set to {@code "true"} in the root activity of a task, the stack is cleared down to the root activity whenever the user leaves the task -and returns to it. In other words, it's the opposite of <a -href="{@docRoot}guide/topics/manifest/activity-element.html#always">{@code -alwaysRetainTaskState}</a>. The user always returns to the task in its +and returns to it. In other words, it's the opposite of +<a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> +{@code alwaysRetainTaskState}</a>. The user always returns to the task in its initial state, even after a leaving the task for only a moment.</dd> <dt><code><a @@ -534,8 +543,9 @@ leaves and then returns to the task, it is no longer present.</dd> <h3 id="Starting">Starting a task</h3> <p>You can set up an activity as the entry point for a task by giving it an intent filter with -{@code "android.intent.action.MAIN"} as the specified action and {@code -"android.intent.category.LAUNCHER"} as the specified category. For example:</p> +{@code "android.intent.action.MAIN"} as the specified action and +{@code "android.intent.category.LAUNCHER"} +as the specified category. For example:</p> <pre> <activity ... > @@ -553,27 +563,25 @@ to return to the task that it creates any time after it has been launched. </p> <p>This second ability is important: Users must be able to leave a task and then come back to it -later using this activity launcher. For this reason, the two <a href="#LaunchModes">launch -modes</a> that mark activities as always initiating a task, {@code "singleTask"} and "{@code -"singleInstance"}, should be used only when the activity has an {@link -android.content.Intent#ACTION_MAIN} -and a {@link android.content.Intent#CATEGORY_LAUNCHER} -filter. Imagine, for example, what could happen if the filter is missing: An intent launches a -{@code "singleTask"} activity, initiating a new task, and the user spends some time working in -that task. The user then presses the <em>Home</em> button. The task is now sent to the background -and is -not visible. Now the user has no way to return to the task, because it is not represented in the -application launcher. -</p> +later using this activity launcher. For this reason, the two <a href="#LaunchModes">launch +modes</a> that mark activities as always initiating a task, {@code "singleTask"} and +{@code "singleInstance"}, should be used only when the activity has an +{@link android.content.Intent#ACTION_MAIN} +and a {@link android.content.Intent#CATEGORY_LAUNCHER} filter. Imagine, for example, what could +happen if the filter is missing: An intent launches a {@code "singleTask"} activity, initiating a +new task, and the user spends some time working in that task. The user then presses the <em>Home</em> +button. The task is now sent to the background and is not visible. Now the user has no way to return +to the task, because it is not represented in the application launcher.</p> <p>For those cases where you don't want the user to be able to return to an activity, set the - <code><a -href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> element's -<a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code -finishOnTaskLaunch}</a> to {@code "true"} (see <a -href="#Clearing">Clearing the stack</a>).</p> - +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +element's +<a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code finishOnTaskLaunch}</a> +to {@code "true"} (see <a href="#Clearing">Clearing the stack</a>).</p> +<p>Further information about how tasks and activites are represented and managed in +the overview screen is available in <a href="{@docRoot}guide/components/recents.html"> +Overview Screen</a>.</p> <!-- <h2>Beginner's Path</h2> diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index ea36405..8d010a1 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -55,6 +55,9 @@ <li><a href="<?cs var:toroot ?>guide/components/tasks-and-back-stack.html"> <span class="en">Tasks and Back Stack</span> </a></li> + <li><a href="<?cs var:toroot ?>guide/components/recents.html"> + <span class="en">Overview Screen</span> + </a></li> </ul> </li> <li class="nav-section"> diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd index f0e93b9..ade05c9 100644 --- a/docs/html/guide/topics/manifest/activity-element.jd +++ b/docs/html/guide/topics/manifest/activity-element.jd @@ -8,11 +8,14 @@ parent.link=manifest-intro.html <dd><pre class="stx"><activity android:<a href="#embedded">allowEmbedded</a>=["true" | "false"] android:<a href="#reparent">allowTaskReparenting</a>=["true" | "false"] android:<a href="#always">alwaysRetainTaskState</a>=["true" | "false"] + android:<a href="#autoremrecents">autoRemoveFromRecents</a>=["true" | "false"] android:<a href="#clear">clearTaskOnLaunch</a>=["true" | "false"] android:<a href="#config">configChanges</a>=["mcc", "mnc", "locale", "touchscreen", "keyboard", "keyboardHidden", "navigation", "screenLayout", "fontScale", "uiMode", "orientation", "screenSize", "smallestScreenSize"] + android:<a href="#dlmode">documentLaunchMode</a>=["intoExisting", "always", + "none", "never"] android:<a href="#enabled">enabled</a>=["true" | "false"] android:<a href="#exclude">excludeFromRecents</a>=["true" | "false"] android:<a href="#exported">exported</a>=["true" | "false"] @@ -22,12 +25,14 @@ parent.link=manifest-intro.html android:<a href="#label">label</a>="<i>string resource</i>" android:<a href="#lmode">launchMode</a>=["multiple" | "singleTop" | "singleTask" | "singleInstance"] + android:<a href="#maxRecents">maxRecents</a>="<i>integer</i>" android:<a href="#multi">multiprocess</a>=["true" | "false"] android:<a href="#nm">name</a>="<i>string</i>" android:<a href="#nohist">noHistory</a>=["true" | "false"] <!-- ##api level 3## --> android:<a href="#parent">parentActivityName</a>="<i>string</i>" <!-- api level 16 --> android:<a href="#prmsn">permission</a>="<i>string</i>" android:<a href="#proc">process</a>="<i>string</i>" + android:<a href="#relinquish">relinquishTaskIdentity</a>=["true" | "false"] android:<a href="#screen">screenOrientation</a>=["unspecified" | "behind" | "landscape" | "portrait" | "reverseLandscape" | "reversePortrait" | @@ -139,6 +144,15 @@ useful, for example, in an application like the web browser where there is a lot of state (such as multiple open tabs) that users would not like to lose. </p></dd> +<dt><a name="autoremrecents"></a>{@code android:autoRemoveFromRecents}</dt> +<dd>Whether or not tasks launched by activities with this attribute remains in the +<a href="{@docRoot}guide/components/recents.html">overview screen</a> until the last activity in the +task is completed. If {@code true}, the task is +automatically removed from the overview screen. This overrides the caller's use of +{@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS}. It must be a boolean value, either +"{@code true}" or "{@code false}".</dd> + + <dt><a name="clear"></a>{@code android:clearTaskOnLaunch}</dt> <dd>Whether or not all activities will be removed from the task, except for the root activity, whenever it is re-launched from the home screen — @@ -177,7 +191,7 @@ as described above. <dd>Lists configuration changes that the activity will handle itself. When a configuration change occurs at runtime, the activity is shut down and restarted by default, but declaring a configuration with this attribute will prevent the activity from being restarted. Instead, the -activity remains running and its <code>{@link android.app.Activity#onConfigurationChanged +activity remains running and its <code>{@link android.app.Activity#onConfigurationChanged(android.content.res.Configuration) onConfigurationChanged()}</code> method is called. <p class="note"><strong>Note:</strong> Using this attribute should be @@ -271,20 +285,67 @@ restart your activity, even when running on an Android 3.2 or higher device). <p> All of these configuration changes can impact the resource values seen by the -application. Therefore, when <code>{@link android.app.Activity#onConfigurationChanged +application. Therefore, when <code>{@link android.app.Activity#onConfigurationChanged(android.content.res.Configuration) onConfigurationChanged()}</code> is called, it will generally be necessary to again retrieve all resources (including view layouts, drawables, and so on) to correctly handle the change. </p></dd> +<dt><a name="dlmode"></a>{@code android:documentLaunchMode}</dt> +<dd>Specifies how a new instance of an activity should be added to a task each time it is +launched. This attribute permits the user to have multiple documents from the same application +appear in the <a href="{@docRoot}guide/components/recents.html">overview screen</a>. + +<p>This attribute has four values which produce the following effects when the user opens a document +with the application:</p> + +<table> +<tr> + <th>Value</th> + <th>Description</th> +</tr><tr> + <td>"{@code intoExisting}"</td> + <td>The activity reuses the existing task for the document. Using this value is the same as setting + the {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} flag, <em>without</em> setting the + {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} flag, as described in + <a href="{@docRoot}guide/components/recents.html#flag-new-doc">Using the Intent flag to add a task + </a>.</td> +</tr><tr> + <td>"{@code always}"</td> + <td>The activity creates a new task for the document, even if the document is already opened. + This is the same as setting both the {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} + and {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} flags.</td> +</tr><tr> + <td>"{@code none}"</td> + <td>The activity does not create a new task for the activity. This is the default value, which + creates a new task only when {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} is set. + The overview screen treats the activity as it would by default: it displays a single task for + the app, which resumes from whatever activity the user last invoked.</td> +</tr><tr> + <td>"{@code never}"</td> + <td>This activity is not launched into a new document even if the Intent contains + {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}. Setting this overrides the behavior + of the {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} and + {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} flags, if either of these are set in + the activity, and the overview screen displays a single task for the app, which resumes from + whatever activity the user last invoked.</td> +</tr> +</table> + +<p class="note"><strong>Note:</strong> For values other than "{@code none}" and "{@code never}" the +activity must be defined with {@code launchMode="standard"}. If this attribute is not specified, +{@code documentLaunchMode="none"} is used.</p> +</dd> + <dt><a name="enabled"></a>{@code android:enabled}</dt> <dd>Whether or not the activity can be instantiated by the system — -"{@code true}" if it can be, and "{@code false}" if not. The default value +{@code "true"} if it can be, and "{@code false}" if not. The default value is "{@code true}". <p> -The <code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> element has its own -<code><a href="{@docRoot}guide/topics/manifest/application-element.html#enabled">enabled</a></code> +The <code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a> +</code> element has its own<code> +<a href="{@docRoot}guide/topics/manifest/application-element.html#enabled">enabled</a></code> attribute that applies to all application components, including activities. The <code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> and {@code <activity>} attributes must both be "{@code true}" (as they both @@ -294,10 +355,11 @@ is "{@code false}", it cannot be instantiated. <dt><a name="exclude"></a>{@code android:excludeFromRecents}</dt> <dd>Whether or not the task initiated by this activity should be excluded from the list of recently -used applications ("recent apps"). That is, when this activity is the root activity of a new task, -this attribute determines whether the task should not appear in the list of recent apps. Set "{@code -true}" if the task should be <em>excluded</em> from the list; set "{@code false}" if it should be -<em>included</em>. The default value is "{@code false}". +used applications, the <a href="{@docRoot}guide/components/recents.html"> +overview screen</a>. That is, when this activity is the root activity of a new +task, this attribute determines whether the task should not appear in the list of recent apps. Set +"{@code true}" if the task should be <em>excluded</em> from the list; set "{@code false}" if it +should be <em>included</em>. The default value is "{@code false}". </p></dd> <dt><a name="exported"></a>{@code android:exported}</dt> @@ -550,6 +612,13 @@ document. </p> </dd> +<dt><a name="maxrecents"></a>{@code android:maxRecents}</dt> +<dd>The maximum number of tasks rooted at this activity in the <a href="{@docRoot}guide/components/recents.html"> +overview screen</a>. When this number of entries is reached, the system removes the least-recently +used instance from the overview screen. Valid values are 1 through 50 (25 on low memory devices); +zero is invalid. This must be an integer value, such as 50. The default value is 16. +</dd> + <dt><a name="multi"></a>{@code android:multiprocess}</dt> <dd>Whether an instance of the activity can be launched into the process of the component that started it — "{@code true}" if it can be, and "{@code false}" if not. @@ -685,6 +754,20 @@ resource usage. attribute can set a different default process name for all components. </dd> +<dt><a name="relinquish"></a>{@code android:relinquishTaskIdentity}</dt> +<dd>Whether or not the activity relinquishes its task identifiers to an activity above it in the +task stack. A task whose root activity has this attribute set to "{@code true}" replaces the base +Intent with that of the next activity in the task. If the next activity also has this attribute set +to "{@code true}" then it will yield the base Intent to any activity that it launches in the same +task. This continues for each activity until an activity is encountered which has this attribute set +to "{@code false}". The default value is "{@code false}". + +<p>This attribute set to "{@code true}" also permits the activity's use of the +{@link android.app.ActivityManager.TaskDescription} to change labels, colors +and icons in the <a href="{@docRoot}guide/components/recents.html">overview screen</a>.</p> +</dd> + + <dt><a name="screen"></a>{@code android:screenOrientation}</dt> <dd>The orientation of the activity's display on the device. diff --git a/docs/html/images/components/recents.png b/docs/html/images/components/recents.png Binary files differnew file mode 100644 index 0000000..9809f04 --- /dev/null +++ b/docs/html/images/components/recents.png diff --git a/docs/html/images/versions/battery_historian.png b/docs/html/images/versions/battery_historian.png Binary files differnew file mode 100644 index 0000000..f1d4e40 --- /dev/null +++ b/docs/html/images/versions/battery_historian.png diff --git a/docs/html/images/versions/battery_historian@2x.png b/docs/html/images/versions/battery_historian@2x.png Binary files differnew file mode 100644 index 0000000..8c8a87f --- /dev/null +++ b/docs/html/images/versions/battery_historian@2x.png diff --git a/docs/html/images/versions/notification-headsup.png b/docs/html/images/versions/notification-headsup.png Binary files differnew file mode 100644 index 0000000..7c374c8 --- /dev/null +++ b/docs/html/images/versions/notification-headsup.png diff --git a/docs/html/images/versions/recents_screen.png b/docs/html/images/versions/recents_screen.png Binary files differnew file mode 100644 index 0000000..a6619c5 --- /dev/null +++ b/docs/html/images/versions/recents_screen.png diff --git a/docs/html/images/versions/rivalknights.png b/docs/html/images/versions/rivalknights.png Binary files differnew file mode 100644 index 0000000..6b467ef --- /dev/null +++ b/docs/html/images/versions/rivalknights.png diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index ad9eb3a..8b233a3 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -892,6 +892,10 @@ include the action bar on devices running Android 2.1 or higher." <a href="<?cs var:toroot ?>training/tv/playback/details.html"> Building a Details View</a> </li> + <li> + <a href="<?cs var:toroot ?>training/tv/playback/now-playing.html"> + Displaying a Now Playing Card</a> + </li> </ul> </li> diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd index d7167e7..118fc6c 100644 --- a/docs/html/training/tv/playback/index.jd +++ b/docs/html/training/tv/playback/index.jd @@ -46,4 +46,7 @@ startpage=true <dt><b><a href="details.html">Building a Details View</a></b></dt> <dd>Learn how to use the Leanback support library to build a details page for media items.</dd> + + <dt><b><a href="now-playing.html">Displaying a Now Playing Card</a></b></dt> + <dd>Learn how to use a MediaSession to display a Now Playing card on the home screen.</dd> </dl> diff --git a/docs/html/training/tv/playback/now-playing.jd b/docs/html/training/tv/playback/now-playing.jd new file mode 100644 index 0000000..b64beb0 --- /dev/null +++ b/docs/html/training/tv/playback/now-playing.jd @@ -0,0 +1,167 @@ +page.title=Displaying a Now Playing Card +page.tags="nowplaying","mediasession" + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + <h2>This lesson teaches you to</h2> + <ol> + <li><a href="#session">Start a Media Session</a></li> + <li><a href="#card">Display a Now Playing Card</a></li> + <li><a href="#state">Update the Playback State</a></li> + <li><a href="#respond">Respond to User Action</a></li> + </ol> + +</div> +</div> + +<p>TV apps may allow users to play music or other media in the background while using other +applications. If your app allows this type of use, it must must +provide a means for the user to return to the app to pause the music or switch to a new song. The +Android framework enables TV apps to do this by displaying a <em>Now Playing</em> card on the home +screen in the recommendations row.</p> + +<p>The Now Playing card is a system artifact that displays on the +home screen in the recommendations row for an active media session. It includes the media metadata +such as the album art, title, and app icon. When the user selects it, the system opens the the app +that owns the session.</p> + +<p>This lesson shows how to use the {@link android.media.session.MediaSession} class to implement +the Now Playing card.</p> + +<h2 id="session">Start a Media Session</h2> + +<p>A playback app can run as an <a href="{@docRoot}guide/components/activities">activity</a> or +as a <a href="{@docRoot}guide/components/services">service</a>. The service is required for +background playback because it can continue to play media even after the activity that launched it +has been destroyed. For this discussion, the media playback app is assumed to be running in a +{@link android.service.media.MediaBrowserService}.</p> + +<p>In your service's {@link android.service.media.MediaBrowserService#onCreate() onCreate()} +method, create a new {@link android.media.session.MediaSession#MediaSession(android.content.Context, java.lang.String) MediaSession}, +set the callback and flags appropriate to a media app, and set the session token for the +{@link android.service.media.MediaBrowserService}.</p> + +<pre> +mSession = new MediaSession(this, "MusicService"); +mSession.setCallback(new MediaSessionCallback()); +mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | + MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); + +// for the MediaBrowserService +setSessionToken(mSession.getSessionToken()); +</pre> + +<p class="note"<strong>Note:</strong> The Now Playing card will display only for a media session with +the {@link android.media.session.MediaSession#FLAG_HANDLES_TRANSPORT_CONTROLS} flag set.</p> + +<h2 id="card">Display a Now Playing Card</h2> + +<p>The Now Playing card shows up after {@link android.media.session.MediaSession#setActive(boolean) setActive(true)} +is called, if the session is the highest priority session in the system. Also, note that your app +must request the audio focus, as described in <a href="{@docRoot}training/managing-audio/audio-focus"> +Managing Audio Focus</a>.</p> + +<pre> +private void handlePlayRequest() { + + tryToGetAudioFocus(); + + if (!mSession.isActive()) { + mSession.setActive(true); + } +... +</pre> + +<p>The card is removed from the home screen when {@link android.media.session.MediaSession#setActive(boolean) setActive(false)} +is called or if another app initiates media playback. You may want to remove the card from the home +screen some time after playback is paused, depending on how long you want to keep the card up, +usually 5 to 30 minutes.</p> + +<h2 id="state">Update the Playback State</h2> + +<p>As with any media app, update the playback state in the {@link android.media.session.MediaSession} +so that the card can display the current metadata, as shown in the following example:</p> + +<pre> +private void updatePlaybackState() { + long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN; + if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { + position = mMediaPlayer.getCurrentPosition(); + } + PlaybackState.Builder stateBuilder = new PlaybackState.Builder() + .setActions(getAvailableActions()); + stateBuilder.setState(mState, position, 1.0f); + mSession.setPlaybackState(stateBuilder.build()); +} +private long getAvailableActions() { + long actions = PlaybackState.ACTION_PLAY | + PlaybackState.ACTION_PLAY_FROM_MEDIA_ID | + PlaybackState.ACTION_PLAY_FROM_SEARCH; + if (mPlayingQueue == null || mPlayingQueue.isEmpty()) { + return actions; + } + if (mState == PlaybackState.STATE_PLAYING) { + actions |= PlaybackState.ACTION_PAUSE; + } + if (mCurrentIndexOnQueue > 0) { + actions |= PlaybackState.ACTION_SKIP_TO_PREVIOUS; + } + if (mCurrentIndexOnQueue < mPlayingQueue.size() - 1) { + actions |= PlaybackState.ACTION_SKIP_TO_NEXT; + } + return actions; +} +</pre> + +<h2 id="metadata">Display the Media Metadata</h2> + +<p>For the track currently playing, set the {@link android.media.MediaMetadata} with the +{@link android.media.session.MediaSession#setMetadata(android.media.MediaMetadata) setMetadata()} +method. This method of the media session object lets you provide information to the Now Playing card +about the track such as the title, subtitle, and various icons. The following example assumes your +track's data is stored in a custom data class, {@code MediaData}.</p> + +<pre> +private void updateMetadata(MediaData myData) { + MediaMetadata.Builder metadataBuilder = new MediaMetadata.Builder(); + // To provide most control over how an item is displayed set the + // display fields in the metadata + metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, + myData.displayTitle); + metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE, + myData.displaySubtitle); + metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, + myData.artUri); + // And at minimum the title and artist for legacy support + metadataBuilder.putString(MediaMetadata.METADATA_KEY_TITLE, + myData.title); + metadataBuilder.putString(MediaMetadata.METADATA_KEY_ARTIST, + myData.artist); + // A small bitmap for the artwork is also recommended + metadataBuilder.putString(MediaMetadata.METADATA_KEY_ART, + myData.artBitmap); + // Add any other fields you have for your data as well + mSession.setMetadata(metadataBuilder.build()); +} +</pre> + +<h2 id="respond">Respond to User Action</h2> + +<p>When the user selects the Now Playing card, the system opens the app that owns the session. +If your app provides a {@link android.app.PendingIntent} to pass to +{@link android.media.session.MediaSession#setSessionActivity(android.app.PendingIntent) setSessionActivity()}, +the system launches the activity you specify, as demonstrated below. If not, the default system +intent opens. The activity you specify must provide playback controls that allow users to pause or +stop playback.</p> + +<pre> +Intent intent = new Intent(mContext, MyActivity.class); + PendingIntent pi = PendingIntent.getActivity(context, 99 /*request code*/, + intent, PendingIntent.FLAG_UPDATE_CURRENT); + mSession.setSessionActivity(pi); +</pre> + |