Merge "docs: Battery performance, networking analysis and optimization" into mnc-docs
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fe95864..f959ac4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1417,15 +1417,17 @@
}
/**
- * An app can use this method to check if it is currently allowed to draw on top of other
- * apps. In order to be allowed to do so, an app must first declare the
- * {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission in its manifest. If it
- * is currently disallowed, it can prompt the user to grant it this capability through a
- * management UI by sending an Intent with action
- * {@link android.provider.Settings#ACTION_MANAGE_OVERLAY_PERMISSION}.
+ * Checks if the specified context can draw on top of other apps. As of API
+ * level 23, an app cannot draw on top of other apps unless it declares the
+ * {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission in its
+ * manifest, <em>and</em> the user specifically grants the app this
+ * capability. To prompt the user to grant this approval, the app must send an
+ * intent with the action
+ * {@link android.provider.Settings#ACTION_MANAGE_OVERLAY_PERMISSION}, which
+ * causes the system to display a permission management screen.
*
- * @param context A context
- * @return true if the calling app can draw on top of other apps, false otherwise.
+ * @param context App context.
+ * @return true if the specified context can draw on top of other apps, false otherwise
*/
public static boolean canDrawOverlays(Context context) {
int uid = Binder.getCallingUid();
@@ -1439,7 +1441,7 @@
* {@link android.Manifest.permission#CHANGE_NETWORK_STATE} or
* {@link android.Manifest.permission#WRITE_SETTINGS} permission in its manifest. If it
* is currently disallowed, it can prompt the user to grant it this capability through a
- * management UI by sending an Intent with action
+ * management UI by sending an intent with action
* {@link android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}.
*
* @param context A context
@@ -3727,14 +3729,16 @@
Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS;
/**
- * An app can use this method to check if it is currently allowed to write or modify system
- * settings. In order to gain write access to the system settings, an app must declare the
- * {@link android.Manifest.permission#WRITE_SETTINGS} permission in its manifest. If it is
- * currently disallowed, it can prompt the user to grant it this capability through a
- * management UI by sending an Intent with action
- * {@link android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}.
+ * Checks if the specified app can modify system settings. As of API
+ * level 23, an app cannot modify system settings unless it declares the
+ * {@link android.Manifest.permission#WRITE_SETTINGS}
+ * permission in its manifest, <em>and</em> the user specifically grants
+ * the app this capability. To prompt the user to grant this approval,
+ * the app must send an intent with the action {@link
+ * android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}, which causes
+ * the system to display a permission management screen.
*
- * @param context A context
+ * @param context App context.
* @return true if the calling app can write to system settings, false otherwise
*/
public static boolean canWrite(Context context) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1939003..fb31871 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1408,11 +1408,21 @@
<!-- ================================== -->
<eat-comment />
- <!-- Allows an application to open windows using the type
+ <!-- Allows an app to create windows using the type
{@link android.view.WindowManager.LayoutParams#TYPE_SYSTEM_ALERT},
- shown on top of all other applications. Very few applications
+ shown on top of all other apps. Very few apps
should use this permission; these windows are intended for
- system-level interaction with the user. -->
+ system-level interaction with the user.
+
+ <p class="note"><strong>Note:</strong> If the app
+ targets API level 23 or higher, the app user must explicitly grant
+ this permission to the app through a permission management screen. The app requests
+ the user's approval by sending an intent with action
+ {@link android.provider.Settings#ACTION_MANAGE_OVERLAY_PERMISSION}.
+ The app can check whether it has this authorization by calling
+ {@link android.provider.Settings#canDrawOverlays
+ Settings.canDrawOverlays()}.
+ <p>Protection level: signature -->
<permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
android:label="@string/permlab_systemAlertWindow"
android:description="@string/permdesc_systemAlertWindow"
@@ -1535,7 +1545,16 @@
android:protectionLevel="signature|privileged|development" />
<!-- Allows an application to read or write the system settings.
- <p>Protection level: signature
+
+ <p class="note"><strong>Note:</strong> If the app targets API level 23
+ or higher, the app user
+ must explicitly grant this permission to the app through a permission management screen.
+ The app requests the user's approval by sending an intent with action
+ {@link android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}. The app
+ can check whether it has this authorization by calling {@link
+ android.provider.Settings.System#canWrite Settings.System.canWrite()}.
+
+ <p>Protection level: signature
-->
<permission android:name="android.permission.WRITE_SETTINGS"
android:label="@string/permlab_writeSettings"
diff --git a/docs/html/about/versions/marshmallow/android-6.0-changes.jd b/docs/html/about/versions/marshmallow/android-6.0-changes.jd
index 2619310..bae4717 100644
--- a/docs/html/about/versions/marshmallow/android-6.0-changes.jd
+++ b/docs/html/about/versions/marshmallow/android-6.0-changes.jd
@@ -66,7 +66,7 @@
<p>For details on supporting the new permissions model in your app, see
<a href="{@docRoot}training/permissions/index.html">
-Working with System Permissionss</a>. For tips on how to assess the impact on your app,
+Working with System Permissions</a>. For tips on how to assess the impact on your app,
see <a href="{@docRoot}training/permissions/best-practices.html#testing">Permissions Best Practices</a>.</p>
<h2 id="behavior-power">Doze and App Standby</h2>
@@ -189,7 +189,7 @@
<p>If you are using <a href="{@docRoot}tools/support-library/index.html">
Android Support Library</a> revision 22.2, be aware that floating toolbars are not
-backward-compatible and appcompat takes control over {@link android.view.ActionMode} objects bywith th
+backward-compatible and appcompat takes control over {@link android.view.ActionMode} objects by
default. This prevents floating toolbars from being displayed. To enable
{@link android.view.ActionMode} support in an
{@link android.support.v7.app.AppCompatActivity}, call
diff --git a/docs/html/guide/topics/resources/drawable-resource.jd b/docs/html/guide/topics/resources/drawable-resource.jd
index 74727fb..f974a5f 100644
--- a/docs/html/guide/topics/resources/drawable-resource.jd
+++ b/docs/html/guide/topics/resources/drawable-resource.jd
@@ -8,6 +8,7 @@
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}guide/topics/graphics/2d-graphics.html">2D Graphics</a></li>
+ <li><a href="{@docRoot}tools/help/vector-asset-studio.html">Vector Asset Studio</a></li>
</ol>
</div>
</div>
diff --git a/docs/html/images/tools/vas-codepreview.png b/docs/html/images/tools/vas-codepreview.png
new file mode 100644
index 0000000..ea8482c
--- /dev/null
+++ b/docs/html/images/tools/vas-codepreview.png
Binary files differ
diff --git a/docs/html/images/tools/vas-imageincode.png b/docs/html/images/tools/vas-imageincode.png
new file mode 100644
index 0000000..8295cfa
--- /dev/null
+++ b/docs/html/images/tools/vas-imageincode.png
Binary files differ
diff --git a/docs/html/images/tools/vas-layout.png b/docs/html/images/tools/vas-layout.png
new file mode 100644
index 0000000..f70461b
--- /dev/null
+++ b/docs/html/images/tools/vas-layout.png
Binary files differ
diff --git a/docs/html/images/tools/vas-materialicon.png b/docs/html/images/tools/vas-materialicon.png
new file mode 100644
index 0000000..d04a831
--- /dev/null
+++ b/docs/html/images/tools/vas-materialicon.png
Binary files differ
diff --git a/docs/html/images/tools/vas-rtl.png b/docs/html/images/tools/vas-rtl.png
new file mode 100644
index 0000000..0d45b94
--- /dev/null
+++ b/docs/html/images/tools/vas-rtl.png
Binary files differ
diff --git a/docs/html/images/tools/vas-rtlmenu.png b/docs/html/images/tools/vas-rtlmenu.png
new file mode 100644
index 0000000..aaf95de
--- /dev/null
+++ b/docs/html/images/tools/vas-rtlmenu.png
Binary files differ
diff --git a/docs/html/images/tools/vas-svgerror.png b/docs/html/images/tools/vas-svgerror.png
new file mode 100644
index 0000000..8c85247
--- /dev/null
+++ b/docs/html/images/tools/vas-svgerror.png
Binary files differ
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 8b21984..9f39602 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -1409,14 +1409,6 @@
"https://support.google.com/googleplay/answer/2651410"
]
},
- "marshmallow/landing/resources": {
- "title": "",
- "resources": [
- "about/versions/marshmallow/android-6.0-changes.html",
- "about/versions/marshmallow/android-6.0.html",
- "about/versions/marshmallow/samples.html"
- ]
- },
"autolanding": {
"title": "",
"resources": [
@@ -1643,9 +1635,9 @@
"marshmallow/landing/resources": {
"title": "",
"resources": [
- "about/versions/marshmallow/android-6.0-changes.html",
"about/versions/marshmallow/android-6.0.html",
- "about/versions/marshmallow/samples.html"
+ "about/versions/marshmallow/samples.html",
+ "https://developers.google.com/android/nexus/images"
]
},
"marshmallow/landing/videos": {
diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js
index be24220..dda5277 100644
--- a/docs/html/jd_extras.js
+++ b/docs/html/jd_extras.js
@@ -584,6 +584,19 @@
"titleFriendly": ""
},
{
+ "lang": "en",
+ "group": "",
+ "tags": [],
+ "url": "https://developers.google.com/android/nexus/images",
+ "timestamp": 1194884220000,
+ "image": "images/cards/card-download_16-9_2x.png",
+ "title": "System Images",
+ "summary": "Download system images for Marshmallow.",
+ "keywords": [],
+ "type": "support",
+ "titleFriendly": ""
+ },
+ {
"lang": "zh-cn",
"group": "",
"tags": [],
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index bbbf86a..b274738 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -31,22 +31,22 @@
-sdk.linux_download=android-sdk_r24.4-linux.tgz
-sdk.linux_bytes=320008735
-sdk.linux_checksum=eec87cdb9778718e4073b4ca326a46cdd084f901
+sdk.linux_download=android-sdk_r24.4.1-linux.tgz
+sdk.linux_bytes=326412652
+sdk.linux_checksum=725bb360f0f7d04eaccff5a2d57abdd49061326d
-sdk.mac_download=android-sdk_r24.4-macosx.zip
-sdk.mac_bytes=101886955
-sdk.mac_checksum=a9b6f025a9691aef430b19b52e01844dbbcbf6b4
+sdk.mac_download=android-sdk_r24.4.1-macosx.zip
+sdk.mac_bytes=102781947
+sdk.mac_checksum=85a9cccb0b1f9e6f1f616335c5f07107553840cd
-sdk.win_download=android-sdk_r24.4-windows.zip
-sdk.win_bytes=197290202
-sdk.win_checksum=6ab463b85544398c20ab5520f380af7d91379864
+sdk.win_download=android-sdk_r24.4.1-windows.zip
+sdk.win_bytes=199701062
+sdk.win_checksum=66b6a6433053c152b22bf8cab19c0f3fef4eba49
-sdk.win_installer=installer_r24.4-windows.exe
-sdk.win_installer_bytes=149239901
-sdk.win_installer_checksum=c82ae81c0437a230c2fc0ab4fc7915942a6b3afb
+sdk.win_installer=installer_r24.4.1-windows.exe
+sdk.win_installer_bytes=151659917
+sdk.win_installer_checksum=f9b59d72413649d31e633207e31f456443e7ea0b
diff --git a/docs/html/support.jd b/docs/html/support.jd
index 94d6478..9ef4a16 100644
--- a/docs/html/support.jd
+++ b/docs/html/support.jd
@@ -42,8 +42,6 @@
<p>
<a href="http://code.google.com/p/android/issues/entry?template=Developer%20Documentation">
Report documentation bug</a><br />
- <a href="https://code.google.com/p/android/issues/entry?template=User%20bug%20report">
- Report device bug</a><br />
<a href="https://code.google.com/p/android/issues/entry?template=Developer%20bug%20report">
Report platform bug</a><br />
</p>
diff --git a/docs/html/tools/help/index.jd b/docs/html/tools/help/index.jd
index f90d029..d49a279 100644
--- a/docs/html/tools/help/index.jd
+++ b/docs/html/tools/help/index.jd
@@ -134,6 +134,10 @@
WYSIWYG editor. It also previews stretched versions of the image, and highlights the area in which
content is allowed.</dd>
+<dt><a href="{@docRoot}tools/help/vector-asset-studio.html">Vector Asset Studio</a></dt>
+ <dd>Helps you add material icons and import Scalable Vector Graphic (SVG) files into your
+ Android Studio project as a drawable resource.</dd>
+
<dt><a href="{@docRoot}tools/help/etc1tool.html">etc1tool</a></dt>
<dd>A command line utility that lets you encode PNG images to the ETC1 compression standard and
decode ETC1 compressed images back to PNG.</dd>
diff --git a/docs/html/tools/help/vector-asset-studio.jd b/docs/html/tools/help/vector-asset-studio.jd
new file mode 100644
index 0000000..58e53cc
--- /dev/null
+++ b/docs/html/tools/help/vector-asset-studio.jd
@@ -0,0 +1,487 @@
+page.title=Vector Asset Studio
+parent.title=Tools
+parent.link=index.html
+page.tags=vector
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>In this document</h2>
+<ol>
+ <li><a href="#about">About Vector Asset Studio</a></li>
+ <li><a href="#running">Running Vector Asset Studio</a></li>
+ <li><a href="#importing">Importing a Vector Graphic</a></li>
+ <li><a href="#layout">Adding a Vector Drawable to a Layout</a></li>
+ <li><a href="#referring">Referring to a Vector Drawable in Code</a></li>
+ <li><a href="#code">Modifying XML Code Generated by Vector Asset Studio</a></li>
+ <li><a href="#delete">Deleting a Vector Asset from a Project</a></li>
+ <li><a href="#apk">Delivering an App Containing Vector Drawables</a></li>
+</ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}training/material/drawables.html#VectorDrawables">Create Vector Drawables</a></li>
+ <li><a href="http://www.google.com/design/icons" class="external-link">Material Icons</a></li>
+ <li><a href="{@docRoot}reference/android/graphics/drawable/Drawable.html">Drawable Class</a></li>
+ <li><a href="{@docRoot}reference/android/graphics/drawable/VectorDrawable.html">VectorDrawable Class</a></li>
+ </ol>
+
+ <h2>Videos</h2>
+ <ol>
+ <li><a href="http://www.youtube.com/watch?t=126&v=wlFVIIstKmA" class="external-link">DevBytes: Android Vector Graphics</a></li>
+ <li><a href="http://www.youtube.com/watch?v=8e3I-PYJNHg" class="external-link">Android Studio Support for Vector Graphics</a></li>
+ </ol>
+
+ <h2>Dependencies and Prerequisites</h2>
+ <ul>
+ <li>Gradle 1.4.0 or higher</li>
+ </ul>
+
+</div>
+</div>
+
+<p>Vector Asset Studio helps you add material icons
+and import Scalable Vector Graphic (SVG) files into your app project as a drawable resource.
+Compared to raster images, vector drawables can reduce the size of your app and be resized without
+loss of image quality. They help you to more easily support different Android devices with varying
+screen sizes and resolutions because you can display one vector drawable on all of them. </p>
+
+<h2 id="about">About Vector Asset Studio</h2>
+
+<p>Vector Asset Studio adds a vector graphic to the project as an XML file that describes the image.
+Maintaining one XML file can be easier than updating multiple raster graphics at various resolutions.</p>
+
+<p>Android 4.4 (API level 20) and lower doesn't support vector drawables. If your minimum API level
+is set at one of these API levels, Vector Asset Studio also directs Gradle to generate raster images
+of the vector drawable for backward-compatibility. You can refer to vector assets as
+{@link android.graphics.drawable.Drawable} in Java code or <code>@drawable</code> in XML code; when
+your app runs, the corresponding vector or raster image displays automatically depending on the API
+level.</p>
+
+
+<h3 id="types">Supported vector graphic types</h3>
+
+<p>The Google material design specification provides <a href="http://www.google.com/design/icons" class="external-link">material icons</a>
+that you can use in your Android apps. Vector
+Asset Studio helps you choose, import, and size material icons, as well as define opacity and the
+Right-to-Left (RTL) mirroring setting.</p>
+
+<p>Vector Asset Studio also helps you to import your own SVG files. SVG is an XML-based open
+standard of the World Wide Web Consortium (W3C). Vector Asset Studio supports the essential
+standard, but not all features. When you specify an SVG file, Vector Asset Studio gives immediate
+feedback about whether the graphics code is supported or not. If the SVG code is supported, it
+converts the file into an XML file containing {@link
+android.graphics.drawable.VectorDrawable} code.</p>
+
+<h3 id="when">Considerations for SVG files</h3>
+
+<p>A vector drawable is appropriate for simple icons. The
+<a href="http://www.google.com/design/icons" class="external-link">material icons</a> provide good
+examples of the types
+of images that work well as vector drawables in an app. In contrast, many app launch icons do have
+many details, so they work better as raster images.</p>
+
+<p>The initial loading of a vector graphic can cost more CPU cycles than the corresponding raster
+image. Afterward, memory use and performance are similar between the two. We recommend that you
+limit a vector image to a maximum of 200 x 200 dp; otherwise, it can take too long to draw.</p>
+
+<p>Although vector drawables do support one or more colors, in many cases it makes sense to color
+icons black (<code>android:fillColor="#FF000000"</code>). Using this approach, you can add a
+<a href="{@docRoot}training/material/drawables.html#DrawableTint">tint</a> to the vector drawable
+that you placed in a layout, and the icon color changes to the tint color. If the icon color
+isn't black, the icon color might instead blend with the tint color.</p>
+
+<h3 id="apilevel">Vector drawable support at different API levels</h3>
+
+<p>Android 5.0 (API level 21) and higher provides vector drawable support. If your app has a
+minimum API level that is lower, Vector Asset Studio adds the vector drawable file to your
+project; also, at build time, Gradle creates Portable Network Graphic (PNG) raster images at various
+resolutions. Gradle generates the PNG densities specified by the Domain Specific Language (DSL)
+<a href="http://google.github.io/android-gradle-dsl/1.4/com.android.build.gradle.internal.dsl.ProductFlavor.html#com.android.build.gradle.internal.dsl.ProductFlavor:generatedDensities" class="external-link">generatedDensities</a> property
+in a <code>build.gradle</code> file. To generate PNGs, the build system requires Gradle 1.4.0 or higher.</p>
+
+<p>For Android 5.0 (API level 21) and higher, Vector Asset Studio supports all of the {@link
+android.graphics.drawable.VectorDrawable} elements. For backward compatibility with Android 4.4 (API
+level 20) and lower, Vector Asset Studio supports the following XML elements:</p>
+
+<div class="wrap">
+ <div class="cols">
+ <div class="col-1of2">
+
+<p><code><vector></code></p>
+<ul>
+ <li><code>android:width</code></li>
+ <li><code>android:height</code></li>
+ <li><code>android:viewportWidth</code></li>
+ <li><code>android:viewportHeight</code></li>
+ <li><code>android:alpha</code></li>
+</ul>
+
+</div>
+
+
+<div class="col-1of2">
+
+<p><code><path></code></p>
+<ul>
+ <li><code>android:pathData</code></li>
+ <li><code>android:fillColor</code></li>
+ <li><code>android:strokeColor</code></li>
+ <li><code>android:strokeWidth</code></li>
+ <li><code>android:strokeAlpha</code></li>
+ <li><code>android:fillAlpha</code></li>
+</ul>
+
+</div>
+
+</div>
+</div>
+
+<p>Only Android 5.0 (API level 21) and higher supports dynamic attributes, for example, <code>android:fillColor="?android:attr/colorControlNormal"</code>.</p>
+
+<p>You can change the XML code that Vector Asset Studio generates, although it’s not a best practice.
+Changing the values in the code should not cause any issues, as long as they’re valid and static. If
+you want to add XML elements, you need to make sure that they’re supported based on your minimum API
+level.</p>
+
+<p>For Android 5.0 (API level 21) and higher, you can use the {@link
+android.graphics.drawable.AnimatedVectorDrawable} class to animate the properties of {@link
+android.graphics.drawable.VectorDrawable}. For more information, see
+<a href="{@docRoot}training/material/animations.html#AnimVector">Animating Vector Drawables</a>.</p>
+
+<h2 id="running">Running Vector Asset Studio</h2>
+
+<p>Follow these steps to start Vector Asset Studio:</p>
+
+<ol>
+ <li>In Android Studio, open an Android app project.</li>
+ <li>In the <em>Project</em> window, select the
+ <a href="{@docRoot}sdk/installing/create-project.html#ProjectView">Android view</a>.</li>
+ <li>Right-click the <strong>res</strong> folder and select <strong>New</strong> >
+ <strong>Vector Asset</strong>.</li>
+ <p>Some other project views and folders have this menu item as well.</p>
+ <p>Vector Asset Studio appears.</p>
+ <img src="{@docRoot}images/tools/vas-materialicon.png" />
+ <li>If a <em>Need newer Android plugin for Gradle</em> dialog appears instead, correct
+ your Gradle version as follows.</li>
+ <ol type="a">
+ <li>Select <strong>File</strong> > <strong>Project Structure</strong>.</li>
+ <li>In the <em>Project Structure</em> dialog, select <strong>Project</strong>.</li>
+ <li>In the <strong>Android Plugin Version</strong> field, change the Gradle version to
+ <strong>1.4.0</strong> or higher, and click <strong>OK</strong>.</li>
+ <p>Gradle syncs the project.</p>
+ <li>In the <a href="{@docRoot}sdk/installing/create-project.html#ProjectView">Android view</a>
+ of the <em>Project</em> window, right-click the <strong>res</strong> folder and select
+ <strong>New</strong> > <strong>Vector Asset</strong>.</li>
+ <p>Vector Asset Studio appears.</p>
+ </ol>
+ <li>Continue with <a href="#importing">Importing a Vector Graphic</a>.</li>
+</ol>
+
+<h2 id="importing">Importing a Vector Graphic</h2>
+
+<p>Vector Asset Studio helps you to import a vector graphics file into your app project. Follow one
+ of the following procedures:</p>
+<ul>
+ <li><a href="#materialicon">Adding a material icon</a></li>
+ <li><a href="#svg">Importing an SVG file</a></li>
+</ul>
+
+<h3 id="materialicon">Adding a material icon</h3>
+
+<p>After you <a href="#running">open Vector Asset Studio</a>, you can add a material icon as follows:</p>
+
+<ol>
+ <li>In Vector Asset Studio, select <strong>Material Icon</strong>.</li>
+ <li>Click <strong>Choose</strong>.</li>
+ <li>Select a material icon and click <strong>OK</strong>.</li>
+ <p>The icon appears in the <strong>Vector Drawable Preview</strong>.</p>
+ <li>Optionally change the resource name, size, opacity, and Right-To-Left (RTL) mirroring setting:
+ <ul>
+ <li><strong>Resource name</strong> - Type a new name if you don’t want to use the default name.
+ Vector Asset Studio automatically creates a unique name (adds a number to the end of the name)
+ if that resource name already exists in the project. The name can contain lowercase
+ characters, underscores, and digits only.</li>
+ <li><strong>Override default size from material design</strong> - Select this option if you
+ want to adjust the size of the image. When you type a new size, the change appears in the
+ preview area.</li>
+ <p>The default is 24 x 24 dp, which is defined in the
+ <a href="http://www.google.com/design/icons" class="external-link">material design</a>
+ specification. Deselect the checkbox to return to the default.</p>
+ <li><strong>Opacity</strong> - Use the slider to adjust the opacity of the image. The change
+ appears in the preview area.</li>
+ <li><strong>Enable auto mirroring for RTL layout</strong> - Select this option if you want a
+ mirror image to display when the layout is right to left, instead of left to right. For
+ example, some languages are read right to left; if you have an arrow icon, you might want to
+ display a mirror image of it in this case. Note that if you’re working with an older project,
+ you might also
+ need to add <code>android:supportsRtl="true"</code> to your app manifest. Auto-mirroring is
+ supported on Android 5.0 (API level 21) and higher only.</li>
+ </ul>
+ <li>Click <strong>Next</strong>.</li>
+ <li>Optionally change the module and resource directory:</li>
+ <ul>
+ <li><strong>Target Module</strong> - Select a module in the project where you want to add the
+ resource. For more information, see
+ <a href="{@docRoot}sdk/installing/create-project.html#CreatingAModule">Creating an Android Module</a>.</li>
+ <li><strong>Res Directory</strong> - Select the resource source set where you want to add the
+ vector asset: <code>src/main/res</code>, <code>src/debug/res</code>, <code>src/release/res</code>,
+ or a user-defined source set. The main source set applies to all build variants, including
+ debug and release. The debug and release source sets override the main source set and apply
+ to one version of a build. The debug source set is for debugging only. To define a new source
+ set, select <strong>File</strong> > <strong>Project Structure</strong> > <strong>app</strong> >
+ <strong>Build Types</strong>. For example, you could define a beta source set and create a
+ version of an icon that includes the text "BETA” in the bottom right corner. For more information, see
+ <a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants">Working with Build Variants</a>.</li>
+ </ul>
+ <p>The <strong>Output Directories</strong> area displays the vector image and the directory
+ where it will appear.</p>
+ <li>Click <strong>Finish</strong>.</li>
+ <p>Vector Asset Studio adds an XML file defining the vector drawable to the project in the
+ <code>app/src/main/res/drawable/</code> folder. From the
+ <a href="{@docRoot}sdk/installing/create-project.html#ProjectView">Android view</a> of the <em>Project</em>
+ window, you can view the generated vector XML file in the <strong>drawable</strong> folder.</p>
+ <li>Build the project.</li>
+ <p>If the minimum API level is Android 4.4 (API level 20) and lower, Vector Asset Studio generates
+ PNG files. From the <a href="{@docRoot}sdk/installing/create-project.html#ProjectView">Project view</a>
+ of the <em>Project</em> window, you can view the generated PNG and XML files in the
+ <code>app/build/generated/res/pngs/debug/</code> folder.</p>
+ <p>You should not edit these generated raster files, but instead work with the vector XML file. The
+ build system regenerates the raster files automatically when needed so you don’t need to maintain
+ them.</p>
+</ol>
+
+<h3 id="svg">Importing a Scalable Vector Graphic (SVG)</h3>
+
+<p>After you <a href="#running">open Vector Asset Studio</a>, you can import an SVG file as follows:</p>
+
+<ol>
+ <li>In Vector Asset Studio, select <strong>Local SVG file</strong>.</li>
+ <p>The file must be on a local drive. If it’s located on the network, for example, you need to
+ download it to a local drive first.</p>
+ <li>Specify an <strong>Image file</strong> by clicking <strong>…</strong> .</li>
+ <p>The image appears in the <strong>Vector Drawable Preview</strong>.</p>
+ <p>However, if the SVG file contains unsupported features, an error appears at the bottom left of
+ Vector Asset Studio, as shown in the following figure.</p>
+ <img src="{@docRoot}images/tools/vas-svgerror.png" />
+ <p>In this case, you can’t use Vector Asset Studio to add the graphics file. Click
+ <strong>More</strong> to view the errors. For a list of supported elements, see
+ <a href="#apilevel">Vector Drawable Support at Different API Levels</a>.</p>
+ <li>Optionally change the resource name, size, opacity, and Right-To-Left (RTL) mirroring setting:</li>
+ <ul>
+ <li><strong>Resource name</strong> - Type a new name if you don’t want to use the default
+ name. Vector Asset Studio automatically creates a unique name (adds a number to the end of the
+ name) if that resource name already exists in the project. The name can contain lowercase
+ characters, underscores, and digits only.</li>
+ <li><strong>Override default size from material design</strong> - Select this option if you
+ want to adjust the size of the image. After you select it, the size changes to the size of the
+ image itself. Whenever you change the size, the change appears in the preview area.</li>
+ <p>The default is 24 x 24 dp, which is defined in the
+ <a href="http://www.google.com/design/icons" class="external-link">material design</a>
+ specification. Deselect the checkbox to return to the default.</p>
+ <li><strong>Opacity</strong> - Use the slider to adjust the opacity of the image. The change
+ appears in the preview area.</li>
+ <li><strong>Enable auto mirroring for RTL layout</strong> - Select this option if you want a
+ mirror image to display when the layout is right to left, instead of left to right. For
+ example, some languages are read right to left; if you have an arrow icon, you might want to
+ display a mirror image of it in this case. Note that if you’re working with an older project,
+ you might
+ need to add <code>android:supportsRtl="true"</code> to your app manifest. Auto-mirroring is
+ supported on Android 5.0 (API level 21) and higher only.</li>
+ </ul>
+ <li>Click <strong>Next</strong>.</li>
+ <li>Optionally change the module and resource directory:</li>
+ <ul>
+ <li><strong>Target Module</strong> - Select a module in the project where you want to add the
+ resource. For more information, see
+ <a href="{@docRoot}sdk/installing/create-project.html#CreatingAModule">Creating an Android Module</a>.</li>
+ <li><strong>Res Directory</strong> - Select the resource source set where you want to add the
+ vector asset: <code>src/main/res</code>, <code>src/debug/res</code>, <code>src/release/res</code>,
+ or a user-defined source set. The main source set applies to all build variants, including
+ debug and release. The debug and release source sets override the main source set and apply
+ to one version of a build. The debug source set is for debugging only. To define a new source
+ set, select <strong>File</strong> > <strong>Project Structure</strong> > <strong>app</strong> >
+ <strong>Build Types</strong>. For example, you could define a beta source set and create a
+ version of an icon that includes the text "BETA” in the bottom right corner. For more information, see
+ <a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants">Working with Build Variants</a>.</li>
+ </ul>
+ <p>The <strong>Output Directories</strong> area displays the vector image and the directory
+ where it will appear.</p>
+ <li>Click <strong>Finish</strong>.</li>
+ <p>Vector Asset Studio adds an XML file defining the vector drawable to the project in the
+ <code>app/src/main/res/drawable/</code> folder. From the
+ <a href="{@docRoot}sdk/installing/create-project.html#ProjectView">Android view</a> of the <em>Project</em>
+ window, you can view the generated vector XML file in the <strong>drawable</strong> folder.</p>
+ <li>Build the project.</li>
+ <p>If the minimum API level is Android 4.4 (API level 20) and lower, Vector Asset Studio generates
+ PNG files. From the <a href="{@docRoot}sdk/installing/create-project.html#ProjectView">Project view</a>
+ of the <em>Project</em> window, you can view the generated PNG and XML files in the
+ <code>app/build/generated/res/pngs/debug/</code> folder.</p>
+ <p>You should not edit these generated raster files, but instead work with the vector XML file. The
+ build system regenerates the raster files automatically when needed so you don’t need to maintain
+ them.</p>
+</ol>
+
+<h2 id="layout">Adding a Vector Drawable to a Layout</h2>
+
+<p>In a layout file, you can set any icon-related widget, such as {@link android.widget.ImageButton},
+{@link android.widget.ImageView}, and so on, to point to a vector asset. For example, the following
+layout shows a vector asset displayed on a button:</p>
+
+<img src="{@docRoot}images/tools/vas-layout.png" />
+
+<p>Follow these steps to display a vector asset on a widget, as shown in the figure:</p>
+
+<ol>
+ <li>Open a project and <a href="#running">import a vector asset</a>.</li>
+ <li>In the <a href="{@docRoot}sdk/installing/create-project.html#ProjectView">Android view</a> of
+ the <em>Project</em> window, double-click a layout XML file, such as <code>content_main.xml</code>.</li>
+ <li>Click the <strong>Design</strong> tab to display the
+ <a href="{@docRoot}sdk/installing/studio-layout.html">Layout Editor</a>.</li>
+ <li>Drag the {@link
+android.widget.ImageButton} widget from the <em>Palette</em> window onto the Layout Editor.</li>
+ <li>In the <em>Properties</em> window, locate the <strong>src</strong> property of the
+ <code>ImageButton</code> instance and click <strong>…</strong> .</li>
+ <li>In the <em>Resources</em> dialog, select the <strong>Project</strong> tab, navigate to the
+ <strong>Drawable</strong> folder, and select a vector asset. Click <strong>OK</strong>.</li>
+ <p>The vector asset appears on the <code>ImageButton</code> in the layout.</p>
+ <li>To change the color of the image to the accent color defined in the theme, locate the
+ <strong>tint</strong> property in the <em>Properties</em> window and click <strong>…</strong> .</li>
+ <li>In the <em>Resources</em> dialog, select the <strong>Project</strong> tab, navigate to the
+ <strong>Color</strong> folder, and select <strong>colorAccent</strong>. Click <strong>OK</strong>.</li>
+ <p>The color of the image changes to the accent color in the layout.</p>
+</ol>
+
+<p>The <code>ImageButton</code> code should be similar to the following:</p>
+
+<pre>
+<ImageButton
+ android:id="@+id/imageButton"
+ android:src="@drawable/ic_build_24dp"
+ android:tint="@color/colorAccent"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/textView2"
+ android:layout_marginTop="168dp" />
+</pre>
+
+<h2 id="referring">Referring to a Vector Drawable in Code</h2>
+
+<p>You can normally refer to a vector drawable resource in a generic way in your code, and when
+your app runs, the corresponding vector or raster image displays automatically depending on the API
+level:</p>
+
+<ul>
+ <li>In most cases, you can refer to vector assets as <code>@drawable</code> in XML code or
+ {@link android.graphics.drawable.Drawable} in Java code. </li>
+ <p>For example, the following layout XML code applies the image to a view:</p>
+<pre>
+<ImageView
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:src="@drawable/myimage" />
+</pre>
+ <p>The following Java code retrieves the image as a {@link android.graphics.drawable.Drawable}:</p>
+<pre>
+Resources res = {@link android.content.Context#getResources()};
+Drawable drawable = res.{@link android.content.res.Resources#getDrawable(int) getDrawable}(R.drawable.myimage);
+</pre>
+ <li>Occasionally, you might need to typecast the drawable resource to its exact class, such as
+ when you need to use specific features of the {@link android.graphics.drawable.VectorDrawable}
+ class. To do so, you could use Java code such as the following:</li>
+<pre>
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ VectorDrawable vectorDrawable = (VectorDrawable) drawable;
+} else {
+ BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
+}
+</pre>
+</ul>
+
+
+<h2 id="code">Modifying XML Code Generated by Vector Asset Studio</h2>
+
+<p>You can modify the vector asset XML code, but not the PNGs and corresponding XML code generated
+at build time. However, we don't recommended it. Vector Asset Studio makes sure that the vector
+drawable and the PNGs match, and that the manifest contains the proper code. If you add code that's
+<a href="#apilevel">not supported</a> on Android 4.4 (API level 20) and lower, your vector and PNG
+images might differ. You also need to make sure that the manifest contains the code to support your
+changes.</p>
+
+<p>Follow these steps to modify the vector XML file:</p>
+
+<ol>
+ <li>In the <em>Project</em> window, double-click the generated vector XML file in the
+ <strong>drawable</strong> folder.</li>
+ <p>The XML file appears in the editor and <em>Preview</em> windows.</p>
+
+ <img src="{@docRoot}images/tools/vas-codepreview.png" />
+
+ <li>Edit the XML code based on what’s supported by the minimum API level:</li>
+ <ul>
+ <li>Android 5.0 (API level 21) and higher - Vector Asset Studio supports all of the
+ {@link android.graphics.drawable.Drawable} and
+ {@link android.graphics.drawable.VectorDrawable} elements. You can add XML elements and
+ change values.</li>
+ <li>Android 4.4 (API level 20) and lower - Vector Asset Studio supports all of the
+ {@link android.graphics.drawable.Drawable} elements and a subset of the
+ {@link android.graphics.drawable.VectorDrawable} elements. See
+ <a href="#apilevel">Support at Different API Levels</a> for a list. You can change values in
+ the generated code and add XML elements that are supported. Dynamic attributes aren't
+ supported.</li>
+ </ul>
+ <p>For example, if you didn’t select the RTL option in Vector Asset Studio but realize you now
+ need it, you can add the <a href="{@docRoot}reference/android/R.attr.html#autoMirrored">autoMirrored</a>
+ attribute later. To view the RTL version, select <strong>Preview Right-to-Left Layout</strong> in
+ the <img src="{@docRoot}images/tools/vas-rtlmenu.png" style="vertical-align:sub;margin:0;height:17px" alt="" />
+ menu of the <em>Preview</em> window. (Select <strong>None</strong> to remove the RTL preview.)</p>
+<img src="{@docRoot}images/tools/vas-rtl.png" />
+ <p class="note"><strong>Note:</strong> If you’re working with an older project, you might need to
+ add <code>android:supportsRtl="true"</code> to your app manifest. Also, because
+ <code>autoMirrored</code> is a dynamic attribute, it's supported on Android 5.0 (API level 21) and
+ higher only.</p>
+ <li>Build the project and check that the vector and raster images look the same.</li>
+ <p>Remember that the generated PNGs could display differently in the <em>Preview</em> window than
+ in the app due to different rendering engines and any changes made to the vector drawable before a
+ build. If you add code to the vector XML file created by Vector Asset Studio, any features
+ unsupported in Android 4.4 (API level 20) and lower don't appear in the generated PNG files. As a
+ result, when you add code, you should always check that the generated PNGs match the vector
+ drawable. To do so, you could double-click the PNG in the
+ <a href="{@docRoot}sdk/installing/create-project.html#ProjectView">Project view</a> of the <em>Project</em>
+ window; the left margin of the code editor also displays the PNG image when your code refers to
+ the drawable.</p>
+ <img src="{@docRoot}images/tools/vas-imageincode.png" />
+</ol>
+
+
+<h2 id="delete">Deleting a Vector Asset from a Project</h2>
+
+<p>Follow these steps to remove a vector asset from a project:</p>
+
+<ol>
+ <li>In the <em>Project</em> window, delete the generated vector XML file by selecting the file and
+ pressing the <strong>Delete</strong> key (or select <strong>Edit</strong> > <strong>Delete</strong>).</li>
+ <p>The <em>Safe Delete</em> dialog appears.</p>
+ <li>Optionally select options to find where the file is used in the project, and click
+ <strong>OK</strong>.</li>
+ <p>Android Studio deletes the file from the project and the drive. However, if you chose to search
+ for places in the project where the file is used and some usages are found, you can view them and
+ decide whether to delete the file.</p>
+ <li>Select <strong>Build</strong> > <strong>Clean Project</strong>.</li>
+ <p>Any auto-generated PNG and XML files corresponding to the deleted vector
+ asset are removed from the project and the drive.</p>
+</ol>
+
+<h2 id="apk">Delivering an App Containing Vector Drawables</h2>
+
+<p>When your minimum API level includes Android 4.4 (API level 20) or lower, you have corresponding
+ vector and raster images in your project. In this case, you have two options for delivering your
+ APK files:</p>
+
+<ul>
+ <li>Create one APK that includes both the vector images and the corresponding raster
+ representations. This is the easiest solution.</li>
+ <li>Create separate APKs for different API levels. When you don’t include the corresponding
+ raster images in the APK for Android 5.0 (API level 21) and higher, the APK can be much smaller in
+ size. For more information, see <a href="{@docRoot}google/play/publishing/multiple-apks.html">Multiple APK Support</a>.</li>
+</ul>
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index 8c27784..3859ecf 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -26,6 +26,40 @@
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>SDK Tools, Revision 24.4.1</a> <em>(October 2015)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+
+ <dl>
+ <dt>Dependencies:</dt>
+
+ <dd>
+ <ul>
+ <li>Android SDK Platform-tools revision 23 or later.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Fixed a problem where the emulator title bar was hidden off screen.
+ (<a href="http://code.google.com/p/android/issues/detail?id=178344">Issue 178344</a>)</li>
+ <li>Enabled the emulator to resize the user data partition by including e2fsprogs binaries.
+ (<a href="http://code.google.com/p/android/issues/detail?id=189030">Issue 189030</a>)</li>
+ <li>Fixed a regression on the 32-bit Windows OS where the emulator fails to boot Android 6.0
+ (API level 23) through Android 5.0 (API level 21) system images.
+ (<a href="http://code.google.com/p/android/issues/detail?id=188326">Issue 188326</a>)</li>
+ </ul>
+ </dd>
+
+ </div>
+</div>
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>SDK Tools, Revision 24.4.0</a> <em>(October 2015)</em>
</p>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index 969ca4a..d183f42 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -176,6 +176,7 @@
<li><a href="<?cs var:toroot ?>tools/help/systrace.html">Systrace</a></li>
<li><a href="<?cs var:toroot ?>tools/help/gltracer.html">Tracer for OpenGL ES</a></li>
<li><a href="<?cs var:toroot ?>tools/help/traceview.html">Traceview</a></li>
+ <li><a href="<?cs var:toroot ?>tools/help/vector-asset-studio.html">Vector Asset Studio</a></li>
<li><a href="<?cs var:toroot ?>tools/help/zipalign.html">zipalign</a></li>
</ul>
</li>
diff --git a/docs/html/training/auto/audio/index.jd b/docs/html/training/auto/audio/index.jd
index f5a797c..68aff75 100644
--- a/docs/html/training/auto/audio/index.jd
+++ b/docs/html/training/auto/audio/index.jd
@@ -29,8 +29,8 @@
<ul>
<li><a href="{@docRoot}samples/MediaBrowserService/index.html">
MediaBrowserService</a></li>
- <li><a href="//github.com/googlesamples/android-UniversalMusicPlayer">Universal Media
- Player</a></li>
+ <li><a href="//github.com/googlesamples/android-UniversalMusicPlayer"
+ class="external-link">Universal Media Player</a></li>
</ul>
<h2>See Also</h2>
@@ -290,13 +290,20 @@
<p>Your implementation of {@link android.service.media.MediaBrowserService#onGetRoot
onGetRoot()} returns information about the root node of the menu
-hierarchy. This root node is the parent of the top items your browse hierarchy.
+hierarchy. This root node is the parent of the top items of your browse hierarchy.
The method is passed information about the calling client. You can use this
information to decide if the client should have access to your content at all.
For example, if you want to limit your app's content to a list of approved
-clients, you can compare the passed {@code clientPackageName} to your whitelist.
-If the caller isn't an approved package, you can return null to deny access to
-your content.</p>
+clients, you can compare the passed {@code clientPackageName} to your whitelist
+and verify the certificate used to sign the caller's APK.
+If the caller can't be verified to be an approved package, return null to deny access to
+your content. For an example of an app that validates that the caller is an
+approved app, see the
+<a href="https://github.com/googlesamples/android-UniversalMusicPlayer/blob/master/mobile/src/main/java/com/example/android/uamp/PackageValidator.java"
+class="external-link"><code>PackageValidator</code></a> class in the
+<a href="https://github.com/googlesamples/android-UniversalMusicPlayer"
+class="external-link">Universal Android Music Player</a> sample app.
+</p>
<p>A typical implementation of {@link
android.service.media.MediaBrowserService#onGetRoot onGetRoot()} might
@@ -307,28 +314,23 @@
public BrowserRoot onGetRoot(String clientPackageName, int clientUid,
Bundle rootHints) {
- // To ensure you are not allowing any arbitrary app to browse your app's
- // contents, you need to check the origin:
- if (!PackageValidator.isCallerAllowed(this, clientPackageName, clientUid)) {
+ // Verify that the specified package is allowed to access your
+ // content! You'll need to write your own logic to do this.
+ if (!isValid(clientPackageName, clientUid)) {
// If the request comes from an untrusted package, return null.
// No further calls will be made to other media browsing methods.
- LogHelper.w(TAG, "OnGetRoot: IGNORING request from untrusted package "
- + clientPackageName);
+
return null;
}
- if (ANDROID_AUTO_PACKAGE_NAME.equals(clientPackageName)) {
- // Optional: if your app needs to adapt ads, music library or anything
- // else that needs to run differently when connected to the car, this
- // is where you should handle it.
- }
- return new BrowserRoot(MEDIA_ID_ROOT, null);
+
+ return new BrowserRoot(MY_MEDIA_ROOT_ID, null);
}
</pre>
<p>
The Auto device client builds the top-level menu by calling {@link
android.service.media.MediaBrowserService#onLoadChildren onLoadChildren()}
- with the root node object and getting it's children. The client builds
+ with the root node object and getting its children. The client builds
submenus by calling the same method with other child nodes. The following
example code shows a simple implementation of {@link
android.service.media.MediaBrowserService#onLoadChildren onLoadChildren()} method:
@@ -341,21 +343,30 @@
// Assume for example that the music catalog is already loaded/cached.
- List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>();
+ List<MediaItem> mediaItems = new ArrayList<>();
// Check if this is the root menu:
- if (MEDIA_BROWSER_ROOT.equals(parentMediaId)) {
+ if (MY_MEDIA_ROOT_ID.equals(parentMediaId)) {
// build the MediaItem objects for the top level,
- // and put them in the <result> list
+ // and put them in the mediaItems list
} else {
// examine the passed parentMediaId to see which submenu we're at,
- // and put the children of that menu in the <result> list
+ // and put the children of that menu in the mediaItems list
}
+ result.sendResult(mediaItems);
}
</pre>
+<p>
+ For examples of how to implement {@link
+ android.service.media.MediaBrowserService#onLoadChildren onLoadChildren()},
+ see the <a href="{@docRoot}samples/MediaBrowserService/index.html">
+ MediaBrowserService</a> and
+ <a href="https://github.com/googlesamples/android-UniversalMusicPlayer"
+ class="external-link">Universal Android Music Player</a> sample apps.
+</p>
<h2 id="implement_callback">Enable Playback Control</h2>
@@ -671,4 +682,4 @@
the
<a href="//github.com/googlesamples/android-UniversalMusicPlayer/">Universal Media Player</a>
sample.
-</p>
\ No newline at end of file
+</p>
diff --git a/docs/html/training/backup/autosyncapi.jd b/docs/html/training/backup/autosyncapi.jd
index d216f70..0e2a9a9 100644
--- a/docs/html/training/backup/autosyncapi.jd
+++ b/docs/html/training/backup/autosyncapi.jd
@@ -26,12 +26,20 @@
<p>
Users frequently invest time and effort to configure apps just the way they like them. Switching
- to a new device can cancel out all that careful configuration. Devices running Android 6.0 and
- higher automatically back up app data to the cloud. The system performs this automatic backup
+ to a new device can cancel out all that careful configuration. For apps whose <a href=
+ "{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">target SDK version</a>
+ is Android 6.0 (API level 23) and higher, devices running Android 6.0 and higher automatically
+ back up app data to the cloud. The system performs this automatic backup
for nearly all app data by default, and does so without your having to write any additional app
code.
</p>
+<p class="note">
+<strong>Note:</strong> To protect user privacy, the device user must have opted in to Google
+services for Auto Backup to work. The Google services opt-in dialog appears when the user goes
+through the Setup Wizard or configures the first Google account on the device.
+</p>
+
<p>
When a user installs your app on
a new device, or reinstalls your app on one (for example, after a factory reset), the system
@@ -82,8 +90,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.my.appexample">
- <uses-sdk android:minSdkVersion="MNC"/>
- <uses-sdk android:targetSdkVersion="MNC"/>
+ <uses-sdk android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="23"/>
<application ...
<strong> android:fullBackupContent="@xml/mybackupscheme"></strong>
</app>
@@ -222,8 +230,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.my.appexample">
- <uses-sdk android:minSdkVersion="MNC"/>
- <uses-sdk android:targetSdkVersion="MNC"/>
+ <uses-sdk android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="23"/>
<application ...
<strong> android:allowBackup="false"></strong>
</application>
diff --git a/docs/html/training/material/drawables.jd b/docs/html/training/material/drawables.jd
index c58075e..da8bea8 100644
--- a/docs/html/training/material/drawables.jd
+++ b/docs/html/training/material/drawables.jd
@@ -14,6 +14,7 @@
<ul>
<li><a href="http://www.google.com/design/spec">Material design specification</a></li>
<li><a href="{@docRoot}design/material/index.html">Material design on Android</a></li>
+ <li><a href="{@docRoot}tools/help/vector-asset-studio.html">Vector Asset Studio</a></li>
</ul>
</div>
</div>
diff --git a/docs/html/training/monitoring-device-state/doze-standby.jd b/docs/html/training/monitoring-device-state/doze-standby.jd
index e167254..50c3d11 100644
--- a/docs/html/training/monitoring-device-state/doze-standby.jd
+++ b/docs/html/training/monitoring-device-state/doze-standby.jd
@@ -217,7 +217,7 @@
The Doze restriction on network access is also likely to affect your app,
especially if the app relies on real-time messages such as tickles or
notifications. If your app requires a persistent connection to the network to
- receive messages, you should use <a href="#using_gcm">Google Cloud Messaging(GCM)</a>
+ receive messages, you should use <a href="#using_gcm">Google Cloud Messaging (GCM)</a>
if possible.
</p>
@@ -283,7 +283,7 @@
<p>
High-priority GCM messages do not otherwise affect Doze mode, and they don’t
- affect the state of any other app, This means that your app can use them to communicate
+ affect the state of any other app. This means that your app can use them to communicate
efficiently while minimizing battery impacts across the system and device.
</p>
@@ -377,13 +377,18 @@
<li>Run your app and leave it active.
</li>
- <li>Force the system to cycle through Doze modes by running the following
- commands:
+ <li>Shut off the device screen. (The app remains active.)
</li>
- <pre class="no-pretty-print">$ adb shell dumpsys battery unplug
-$ adb shell dumpsys deviceidle step
-$ adb shell dumpsys deviceidle -h</pre>
+ <li>Force the system to cycle through Doze modes by running the following
+ commands:
+
+ <pre class="no-pretty-print">
+$ adb shell dumpsys battery unplug
+$ adb shell dumpsys deviceidle step</pre>
+
+ <p>You may need to run the second command more than once. Repeat it until
+ the device state changes to idle.</p>
</li>
<li> Observe the behavior of your app after you reactivate the device. Make
diff --git a/docs/html/training/notepad/codelab/NotepadCodeLab.zip b/docs/html/training/notepad/codelab/NotepadCodeLab.zip
deleted file mode 100644
index cd30f29..0000000
--- a/docs/html/training/notepad/codelab/NotepadCodeLab.zip
+++ /dev/null
Binary files differ
diff --git a/docs/html/training/notepad/index.jd b/docs/html/training/notepad/index.jd
deleted file mode 100644
index 507b232..0000000
--- a/docs/html/training/notepad/index.jd
+++ /dev/null
@@ -1,136 +0,0 @@
-excludeFromSuggestions=true
-page.title=Notepad Tutorial
-parent.title=Tutorials
-@jd:body
-
-
-<p>This tutorial on writing a notepad application gives you a "hands-on" introduction
-to the Android framework and the tools you use to build applications on it.
-Starting from a preconfigured project file, it guides you through the process of
-developing a simple notepad application and provides concrete examples of how to
-set up the project, develop the application logic and user interface, and then
-compile and run the application. </p>
-
-<p>The tutorial presents the application development as a set of
-exercises (see below), each consisting of several steps. You should follow
-the steps in each exercise to gradually build and refine your
-application. The exercises explain each step in detail and provide all the
-sample code you need to complete the application. </p>
-
-<p><p>When you are finished with the tutorial, you will have created a functioning
-Android application and will have learned many of the most important
-concepts in Android development.</p>
-
-<a name="who"></a>
-<h2>Who Should Use this Tutorial</h2>
-
-<p>This tutorial is designed for experienced developers, especially those with
-knowledge of the Java programming language. If you haven't written Java
-applications before, you can still use the tutorial, but you might need to work
-at a slower pace. </p>
-
-<p>Also note that this tutorial uses
-the Eclipse development environment, with the Android plugin installed. If you
-are not using Eclipse, you can follow the exercises and build the application,
-but you will need to determine how to accomplish the Eclipse-specific
-steps in your environment. </p>
-
-<a name="preparing"></a>
-<h2>Preparing for the Exercises</h2>
-
-<p>The tutorial assumes that you have some familiarity with basic Android
-application concepts and terminology. If you are not, you
-should read <a href="{@docRoot}guide/components/fundamentals.html">Application
-Fundamentals</a> before continuing. </p>
-
-<p>This tutorial also builds on the introductory information provided in the
-<a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a>
-tutorial, which explains how to set up your Eclipse environment
-for building Android applications. We recommend you complete the Hello World
-tutorial before starting this one.</p>
-
-<p>To prepare for this lesson:</p>
-
-<ol>
- <li>Download the <a href="codelab/NotepadCodeLab.zip">project
- exercises archive (.zip)</a>.</li>
- <li>Unpack the archive file to a suitable location on your machine.</li>
- <li>Open the <code>NotepadCodeLab</code> folder.</li>
-</ol>
-
-<p>Inside the <code>NotepadCodeLab</code> folder, you should see six project
-files: <code>Notepadv1</code>,
- <code>Notepadv2</code>, <code>Notepadv3</code>,
- <code>Notepadv1Solution</code>, <code>Notepadv2Solution</code>
- and <code>Notepadv3Solution</code>. The <code>Notepadv#</code> projects are
-the starting points for each of the exercises, while the
-<code>Notepadv#Solution</code> projects are the exercise
- solutions. If you are having trouble with a particular exercise, you
- can compare your current work against the exercise solution.</p>
-
-<a name="exercises"></a>
-<h2> Exercises</h2>
-
- <p>The table below lists the tutorial exercises and describes the development
-areas that each covers. Each exercise assumes that you have completed any
-previous exercises.</p>
-
- <table border="0" style="padding:4px;spacing:2px;" summary="This
-table lists the
-tutorial examples and describes what each covers. ">
- <tr>
- <th width="120"><a href="{@docRoot}training/notepad/notepad-ex1.html">Exercise
-1</a></th>
- <td>Start here. Construct a simple notes list that lets the user add new notes but not
-edit them. Demonstrates the basics of <code>ListActivity</code> and creating
-and handling
- menu options. Uses a SQLite database to store the notes.</td>
- </tr>
- <tr>
- <th><a href="{@docRoot}training/notepad/notepad-ex2.html">Exercise 2</a></th>
- <td>Add a second Activity to the
-application. Demonstrates constructing a
-new Activity, adding it to the Android manifest, passing data between the
-activities, and using more advanced screen layout. Also shows how to
-invoke another Activity to return a result, using
-<code>startActivityForResult()</code>.</td>
- </tr>
- <tr>
- <th><a href="{@docRoot}training/notepad/notepad-ex3.html">Exercise 3</a></th>
- <td>Add handling of life-cycle events to
-the application, to let it
-maintain application state across the life cycle. </td>
- </tr>
- <tr>
- <th><a href="{@docRoot}training/notepad/notepad-extra-credit.html">Extra
-Credit</a></th>
- <td>Demonstrates how to use the Eclipse
-debugger and how you can use it to
-view life-cycle events as they are generated. This section is optional but
-highly recommended.</td>
- </tr>
-</table>
-
-
-<a name="other"></a>
-<h2>Other Resources and Further Learning</h2>
-<ul>
-<li>For a lighter but broader introduction to concepts not covered in the
-tutorial,
-take a look at <a href="{@docRoot}resources/faq/commontasks.html">Common Android Tasks</a>.</li>
-
-<li>This tutorial draws from the full Notepad application included in the
-<code>samples/legacy/NotePad</code> directory of the SDK, though it does not
-match it exactly. When you are done with the tutorial, it is highly recommended
-that you take a closer look at this version of the Notepad application, as it
-demonstrates a variety of interesting additions for your application, such
-as:</li>
- <ul>
- <li>Setting up a custom striped list for the list of notes.</li>
- <li>Creating a custom text edit view that overrides the <code>draw()</code>
- method to make it look like a lined notepad.</li>
- <li>Implementing a full <code>ContentProvider</code> for notes.</li>
- <li>Reverting and discarding edits instead of just automatically saving
- them.</li>
- </ul>
-</ul>
diff --git a/docs/html/training/notepad/notepad-ex1.jd b/docs/html/training/notepad/notepad-ex1.jd
deleted file mode 100644
index f680f15..0000000
--- a/docs/html/training/notepad/notepad-ex1.jd
+++ /dev/null
@@ -1,583 +0,0 @@
-excludeFromSuggestions=true
-page.title=Notepad Exercise 1
-parent.title=Notepad Tutorial
-parent.link=index.html
-@jd:body
-
-
-<p><em>In this exercise, you will construct a simple notes list that lets the
-user add new notes but not edit them. The exercise demonstrates:</em></p>
-<ul>
-<li><em>The basics of <code>ListActivities</code> and creating and handling menu
-options. </em></li>
-<li><em>How to use a SQLite database to store the notes.</em></li>
-<li><em>How to bind data from a database cursor into a ListView using a
-SimpleCursorAdapter.</em></li>
-<li><em>The basics of screen layouts, including how to lay out a list view, how
-you can add items to the activity menu, and how the activity handles those menu
-selections. </em></li>
-</ul>
-
-<div style="float:right;white-space:nowrap">
-<span style="color:#BBB;">
- [<a href="notepad-ex1.html" style="color:#BBB;">Exercise 1</a>]</span>
- [<a href="notepad-ex2.html">Exercise 2</a>]
- [<a href="notepad-ex3.html">Exercise 3</a>]
- [<a href="notepad-extra-credit.html">Extra Credit</a>]
-</div>
-
-
-
-<h2>Step 1</h2>
-
- <p>Open up the <code>Notepadv1</code> project in Eclipse.</p>
-
- <p><code>Notepadv1</code> is a project that is provided as a starting point. It
- takes care of some of the boilerplate work that you have already seen if you
- followed the <a href="{@docRoot}training/basics/firstapp/index.html">Hello,
- World</a> tutorial.</p>
-
- <ol>
- <li>
- Start a new Android Project by clicking <strong>File</strong> >
- <strong>New</strong> > <strong>Android Project</strong>.</li>
- <li>
- In the New Android Project dialog, select <strong>Create project from existing source</strong>.</li>
- <li>
- Click <strong>Browse</strong> and navigate to where you copied the <code>NotepadCodeLab</code>
- (downloaded during <a href="{@docRoot}training/notepad/index.html#preparing">setup</a>)
- and select <code>Notepadv1</code>.</li>
- <li>
- The Project Name and other properties should be automatically filled for you.
- You must select the Build Target—we recommend selecting a target with the
- lowest platform version available. Also add an integer to the Min SDK Version field
- that matches the API Level of the selected Build Target.</li>
- <li>
- Click <strong>Finish</strong>. The <code>Notepadv1</code> project should open and be
- visible in your Eclipse package explorer.</li>
- </ol>
-
- <p>If you see an error about <code>AndroidManifest.xml</code>, or some
- problems related to an Android zip file, right click on the project and
- select <strong>Android Tools</strong> > <strong>Fix Project Properties</strong>.
- (The project is looking in the wrong location for the library file,
- this will fix it for you.)</p>
-
- <h2>Step 2</h2>
-
- <div class="sidebox-wrapper">
- <div class="sidebox">
- <h2>Accessing and modifying data</h2>
- <p>For this
- exercise, we are using a SQLite database to store our data. This is useful
- if only <em>your</em> application will need to access or modify the data. If you wish for
- other activities to access or modify the data, you have to expose the data using a
- {@link android.content.ContentProvider ContentProvider}.</p>
- <p>If you are interested, you can find out more about
- <a href="{@docRoot}guide/topics/providers/content-providers.html">content providers</a> or the
-whole
- subject of <a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>.
- The NotePad sample in the <code>samples/</code> folder of the SDK also has an example of how
- to create a ContentProvider.</p>
- </div>
- </div>
-
- <p>Take a look at the <code>NotesDbAdapter</code> class — this class is provided to
- encapsulate data access to a SQLite database that will hold our notes data
- and allow us to update it.</p>
- <p>At the top of the class are some constant definitions that will be used in the application
- to look up data from the proper field names in the database. There is also a database creation
- string defined, which is used to create a new database schema if one doesn't exist already.</p>
- <p>Our database will have the name <code>data</code>, and have a single table called
- <code>notes</code>, which in turn has three fields: <code>_id</code>, <code>title</code> and
- <code>body</code>. The <code>_id</code> is named with an underscore convention used in a number of
- places inside the Android SDK and helps keep a track of state. The <code>_id</code>
- usually has to be specified when querying or updating the database (in the column projections
- and so on). The other two fields are simple text fields that will store data.
- </p>
- <p>The constructor for <code>NotesDbAdapter</code> takes a Context, which allows it to communicate with aspects
- of the Android operating system. This is quite common for classes that need to touch the
- Android system in some way. The Activity class implements the Context class, so usually you will just pass
- <code>this</code> from your Activity, when needing a Context.</p>
- <p>The <code>open()</code> method calls up an instance of DatabaseHelper, which is our local
- implementation of the SQLiteOpenHelper class. It calls <code>getWritableDatabase()</code>,
- which handles creating/opening a database for us.</p>
- <p><code>close()</code> just closes the database, releasing resources related to the
- connection.</p>
- <p><code>createNote()</code> takes strings for the title and body of a new note,
- then creates that note in the database. Assuming the new note is created successfully, the
- method also returns the row <code>_id</code> value for the newly created note.</p>
- <p><code>deleteNote()</code> takes a <var>rowId</var> for a particular note, and deletes that note from
- the database.</p>
-
- <p><code>fetchAllNotes()</code> issues a query to return a {@link android.database.Cursor} over all notes in the
- database. The <code>query()</code> call is worth examination and understanding. The first field is the
- name of the database table to query (in this case <code>DATABASE_TABLE</code> is "notes").
- The next is the list of columns we want returned, in this case we want the <code>_id</code>,
- <code>title</code> and <code>body</code> columns so these are specified in the String array.
- The remaining fields are, in order: <code>selection</code>,
- <code>selectionArgs</code>, <code>groupBy</code>, <code>having</code> and <code>orderBy</code>.
- Having these all <code>null</code> means we want all data, need no grouping, and will take the default
- order. See {@link android.database.sqlite.SQLiteDatabase SQLiteDatabase} for more details.</p>
- <p class="note"><b>Note:</b> A Cursor is returned rather than a collection of rows. This allows
- Android to use resources efficiently -- instead of putting lots of data straight into memory
- the cursor will retrieve and release data as it is needed, which is much more efficient for
- tables with lots of rows.</p>
-
- <p><code>fetchNote()</code> is similar to <code>fetchAllNotes()</code> but just gets one note
- with the <var>rowId</var> we specify. It uses a slightly different version of the
- {@link android.database.sqlite.SQLiteDatabase} <code>query()</code> method.
- The first parameter (set <em>true</em>) indicates that we are interested
- in one distinct result. The <var>selection</var> parameter (the fourth parameter) has been specified to search
- only for the row "where _id =" the <var>rowId</var> we passed in. So we are returned a Cursor on
- the one row.</p>
- <p>And finally, <code>updateNote()</code> takes a <var>rowId</var>, <var>title</var> and <var>body</var>, and uses a
- {@link android.content.ContentValues ContentValues} instance to update the note of the given
- <var>rowId</var>.</p>
-
-<h2 style="clear:right;">Step 3</h2>
-
- <div class="sidebox-wrapper">
- <div class="sidebox">
- <h2>Layouts and activities</h2>
- <p>Most Activity classes will have a layout associated with them. The layout
- will be the "face" of the Activity to the user. In this case our layout will
- take over the whole screen and provide a list of notes.</p>
- <p>Full screen layouts are not the only option for an Activity however. You
- might also want to use a <a
-href="{@docRoot}resources/faq/commontasks.html#floatingorfull">floating
- layout</a> (for example, a <a
-href="{@docRoot}resources/faq/commontasks.html#dialogsandalerts">dialog
- or alert</a>),
- or perhaps you don't need a layout at all (the Activity will be invisible
- to the user unless you specify some kind of layout for it to use).</p>
- </div>
- </div>
-
- <p>Open the <code>notepad_list.xml</code> file in <code>res/layout</code>
-and
- take a look at it. (You may have to
- hit the <em>xml</em> tab, at the bottom, in order to view the XML markup.)</p>
-
- <p>This is a mostly-empty layout definition file. Here are some
- things you should know about a layout file:</p>
-
-
- <ul>
- <li>
- All Android layout files must start with the XML header line:
- <code><?xml version="1.0" encoding="utf-8"?></code>. </li>
- <li>
- The next definition will often (but not always) be a layout
- definition of some kind, in this case a <code>LinearLayout</code>. </li>
- <li>
- The XML namespace of Android should always be defined in
- the top level component or layout in the XML so that <code>android:</code> tags can
- be used through the rest of the file:
- <p><code>xmlns:android="http://schemas.android.com/apk/res/android"</code></p>
- </li>
- </ul>
-
- <h2 style="clear:right;">Step 4</h2>
- <p>We need to create the layout to hold our list. Add code inside
- of the <code>LinearLayout</code> element so the whole file looks like this: </p>
- <pre>
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <ListView android:id="@android:id/list"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <TextView android:id="@android:id/empty"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/no_notes"/>
-
-</LinearLayout>
-</pre>
- <ul>
- <li>
- The <strong>@</strong> symbol in the id strings of the <code>ListView</code> and
- <code>TextView</code> tags means
- that the XML parser should parse and expand the rest of
- the id string and use an ID resource.</li>
- <li>
- The <code>ListView</code> and <code>TextView</code> can be
- thought as two alternative views, only one of which will be displayed at once.
- ListView will be used when there are notes to be shown, while the TextView
- (which has a default value of "No Notes Yet!" defined as a string
- resource in <code>res/values/strings.xml</code>) will be displayed if there
- aren't any notes to display.</li>
- <li>The <code>list</code> and <code>empty</code> IDs are
- provided for us by the Android platform, so, we must
- prefix the <code>id</code> with <code>android:</code> (e.g., <code>@android:id/list</code>).</li>
- <li>The View with the <code>empty</code> id is used
- automatically when the {@link android.widget.ListAdapter} has no data for the ListView. The
- ListAdapter knows to look for this name by default. Alternatively, you could change the
- default empty view by using {@link android.widget.AdapterView#setEmptyView(View)}
- on the ListView.
- <p>
- More broadly, the <code>android.R</code> class is a set of predefined
- resources provided for you by the platform, while your project's
- <code>R</code> class is the set of resources your project has defined.
- Resources found in the <code>android.R</code> resource class can be
- used in the XML files by using the <code>android:</code> name space prefix
- (as we see here).</p>
- </li>
- </ul>
-
- <h2 style="clear:right;">Step 5</h2>
-
- <div class="sidebox-wrapper">
- <div class="sidebox">
- <h2>Resources and the R class</h2>
- <p>The folders under res/ in the Eclipse project are for resources.
- There is a <a href="{@docRoot}resources/faq/commontasks.html#filelist">specific structure</a>
-to the
- folders and files under res/.</p>
- <p>Resources defined in these folders and files will have
- corresponding entries in the R class allowing them to be easily accessed
- and used from your application. The R class is automatically generated using the contents
- of the res/ folder by the eclipse plugin (or by aapt if you use the command line tools).
- Furthermore, they will be bundled and deployed for you as part of the application.</p>
- </p>
- </div>
- </div>
-
- <p>To make the list of notes in the ListView, we also need to define a View for each row:</p>
- <ol>
- <li>
- Create a new file under <code>res/layout</code> called
- <code>notes_row.xml</code>. </li>
- <li>
- Add the following contents (note: again the XML header is used, and the
- first node defines the Android XML namespace)<br>
- <pre style="overflow:auto">
-<?xml version="1.0" encoding="utf-8"?>
-<TextView android:id="@+id/text1"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/></pre>
- <p>
- This is the View that will be used for each notes title row — it has only
- one text field in it. </p>
- <p>In this case we create a new id called <code>text1</code>. The
- <strong>+</strong> after the <strong>@</strong> in the id string indicates that the id should
- be automatically created as a resource if it does not already exist, so we are defining
- <code>text1</code> on the fly and then using it.</p>
- </li>
- <li>Save the file.</li>
- </ol>
- <p>Open the <code>R.java</code> class in the
- project and look at it, you should see new definitions for
- <code>notes_row</code> and <code>text1</code> (our new definitions)
- meaning we can now gain access to these from the our code. </p>
-
- <h2 style="clear:right;">Step 6</h2>
-<p>Next, open the <code>Notepadv1</code> class in the source. In the following steps, we are going to
- alter this class to become a list adapter and display our notes, and also
- allow us to add new notes.</p>
-
-<p><code>Notepadv1</code> will inherit from a subclass
- of <code>Activity</code> called a <code>ListActivity</code>,
- which has extra functionality to accommodate the kinds of
- things you might want to do with a list, for
- example: displaying an arbitrary number of list items in rows on the screen,
- moving through the list items, and allowing them to be selected.</p>
-
-<p>Take a look through the existing code in <code>Notepadv1</code> class.
- There is a currently an unused private field called <code>mNoteNumber</code> that
- we will use to create numbered note titles.</p>
- <p>There are also three override methods defined:
- <code>onCreate</code>, <code>onCreateOptionsMenu</code> and
- <code>onOptionsItemSelected</code>; we need to fill these
- out:</p>
- <ul>
- <li><code>onCreate()</code> is called when the activity is
- started — it is a little like the "main" method for an Activity. We use
- this to set up resources and state for the activity when it is
- running.</li>
- <li><code>onCreateOptionsMenu()</code> is used to populate the
- menu for the Activity. This is shown when the user hits the menu button,
-and
- has a list of options they can select (like "Create
- Note"). </li>
- <li><code>onOptionsItemSelected()</code> is the other half of the
- menu equation, it is used to handle events generated from the menu (e.g.,
- when the user selects the "Create Note" item).
- </li>
- </ul>
-
- <h2>Step 7</h2>
- <p>Change the inheritance of <code>Notepadv1</code> from
-<code>Activity</code>
- to <code>ListActivity</code>:</p>
- <pre>public class Notepadv1 extends ListActivity</pre>
- <p>Note: you will have to import <code>ListActivity</code> into the
-Notepadv1
- class using Eclipse, <strong>ctrl-shift-O</strong> on Windows or Linux, or
- <strong>cmd-shift-O</strong> on the Mac (organize imports) will do this for you
- after you've written the above change.</p>
-
- <h2>Step 8</h2>
- <p>Fill out the body of the <code>onCreate()</code> method.</p>
- <p>Here we will set the title for the Activity (shown at the top of the
- screen), use the <code>notepad_list</code> layout we created in XML,
- set up the <code>NotesDbAdapter</code> instance that will
- access notes data, and populate the list with the available note
- titles:</p>
- <ol>
- <li>
- In the <code>onCreate</code> method, call <code>super.onCreate()</code> with the
- <code>savedInstanceState</code> parameter that's passed in.</li>
- <li>
- Call <code>setContentView()</code> and pass <code>R.layout.notepad_list</code>.</li>
- <li>
- At the top of the class, create a new private class field called <code>mDbHelper</code> of class
- <code>NotesDbAdapter</code>.
- </li>
- <li>
- Back in the <code>onCreate</code> method, construct a new
-<code>NotesDbAdapter</code>
- instance and assign it to the <code>mDbHelper</code> field (pass
- <code>this</code> into the constructor for <code>DBHelper</code>)
- </li>
- <li>
- Call the <code>open()</code> method on <code>mDbHelper</code> to open (or create) the
- database.
- </li>
- <li>
- Finally, call a new method <code>fillData()</code>, which will get the data and
- populate the ListView using the helper — we haven't defined this method yet. </li>
- </ol>
- <p>
- <code>onCreate()</code> should now look like this:</p>
- <pre>
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.notepad_list);
- mDbHelper = new NotesDbAdapter(this);
- mDbHelper.open();
- fillData();
- }</pre>
- <p>And be sure you have the <code>mDbHelper</code> field definition (right
- under the mNoteNumber definition): </p>
- <pre> private NotesDbAdapter mDbHelper;</pre>
-
- <h2>Step 9</h2>
-
- <div class="sidebox-wrapper">
- <div class="sidebox">
- <h2>More about menus</h2>
- <p>The notepad application we are constructing only scratches the
- surface with <a href="{@docRoot}resources/faq/commontasks.html#addmenuitems">menus</a>. </p>
- <p>You can also <a href="{@docRoot}resources/faq/commontasks.html#menukeyshortcuts">add
-shortcut keys for menu items</a>, <a
-href="{@docRoot}resources/faq/commontasks.html#menukeyshortcuts">create
-submenus</a> and even <a href="{@docRoot}resources/faq/commontasks.html#addingtoothermenus">add
-menu items to other applications!</a>. </p>
- </div>
- </div>
-
-<p>Fill out the body of the <code>onCreateOptionsMenu()</code> method.</p>
-
-<p>We will now create the "Add Item" button that can be accessed by pressing the menu
-button on the device. We'll specify that it occupy the first position in the menu.</p>
-
- <ol>
- <li>
- In <code>strings.xml</code> resource (under <code>res/values</code>), add
- a new string named "menu_insert" with its value set to <code>Add Item</code>:
- <pre><string name="menu_insert">Add Item</string></pre>
- <p>Then save the file and return to <code>Notepadv1</code>.</p>
- </li>
- <li>Create a menu position constant at the top of the class:
- <pre>public static final int INSERT_ID = Menu.FIRST;</pre>
- </li>
- <li>In the <code>onCreateOptionsMenu()</code> method, change the
- <code>super</code> call so we capture the boolean return as <code>result</code>. We'll return this value at the end.</li>
- <li>Then add the menu item with <code>menu.add()</code>.</li>
- </ol>
- <p>The whole method should now look like this:
- <pre>
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- boolean result = super.onCreateOptionsMenu(menu);
- menu.add(0, INSERT_ID, 0, R.string.menu_insert);
- return result;
- }</pre>
- <p>The arguments passed to <code>add()</code> indicate: a group identifier for this menu (none,
- in this case), a unique ID (defined above), the order of the item (zero indicates no preference),
- and the resource of the string to use for the item.</p>
-
-<h2 style="clear:right;">Step 10</h2>
- <p>Fill out the body of the <code>onOptionsItemSelected()</code> method:</p>
- <p>This is going
- to handle our new "Add Note" menu item. When this is selected, the
- <code>onOptionsItemSelected()</code> method will be called with the
- <code>item.getId()</code> set to <code>INSERT_ID</code> (the constant we
- used to identify the menu item). We can detect this, and take the
- appropriate actions:</p>
- <ol>
- <li>
- The <code>super.onOptionsItemSelected(item)</code> method call goes at the
- end of this method — we want to catch our events first! </li>
- <li>
- Write a switch statement on <code>item.getItemId()</code>.
- <p>In the case of <var>INSERT_ID</var>, call a new method, <code>createNote()</code>,
- and return true, because we have handled this event and do not want to
- propagate it through the system.</p>
- </li>
- <li>Return the result of the superclass' <code>onOptionsItemSelected()</code>
- method at the end.</li>
- </ol>
- <p>
- The whole <code>onOptionsItemSelect()</code> method should now look like
- this:</p>
- <pre>
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case INSERT_ID:
- createNote();
- return true;
- }
-
- return super.onOptionsItemSelected(item);
- }</pre>
-
-<h2>Step 11</h2>
- <p>Add a new <code>createNote()</code> method:</p>
- <p>In this first version of
- our application, <code>createNote()</code> is not going to be very useful.
-We will simply
- create a new note with a title assigned to it based on a counter ("Note 1",
- "Note 2"...) and with an empty body. At present we have no way of editing
- the contents of a note, so for now we will have to be content making one
- with some default values:</p>
- <ol>
- <li>Construct the name using "Note" and the counter we defined in the class: <code>
- String noteName = "Note " + mNoteNumber++</code></li>
- <li>
- Call <code>mDbHelper.createNote()</code> using <code>noteName</code> as the
- title and <code>""</code> for the body
- </li>
- <li>
- Call <code>fillData()</code> to populate the list of notes (inefficient but
- simple) — we'll create this method next.</li>
- </ol>
- <p>
- The whole <code>createNote()</code> method should look like this: </p>
- <pre>
- private void createNote() {
- String noteName = "Note " + mNoteNumber++;
- mDbHelper.createNote(noteName, "");
- fillData();
- }</pre>
-
-
-<h2>Step 12</h2>
- <div class="sidebox-wrapper">
- <div class="sidebox">
- <h2>List adapters</h2>
- <p>Our example uses a {@link android.widget.SimpleCursorAdapter
- SimpleCursorAdapter} to bind a database {@link android.database.Cursor Cursor}
- into a ListView, and this is a common way to use a {@link android.widget.ListAdapter
- ListAdapter}. Other options exist like {@link android.widget.ArrayAdapter ArrayAdapter} which
- can be used to take a List or Array of in-memory data and bind it in to
- a list as well.</p>
- </div>
- </div>
-
- <p>Define the <code>fillData()</code> method:</p>
- <p>This
- method uses <code>SimpleCursorAdapter,</code> which takes a database <code>Cursor</code>
- and binds it to fields provided in the layout. These fields define the row elements of our list
- (in this case we use the <code>text1</code> field in our
- <code>notes_row.xml</code> layout), so this allows us to easily populate the list with
- entries from our database.</p>
- <p>To do this we have to provide a mapping from the <code>title</code> field in the returned Cursor, to
- our <code>text1</code> TextView, which is done by defining two arrays: the first a string array
- with the list of columns to map <em>from</em> (just "title" in this case, from the constant
- <code>NotesDbAdapter.KEY_TITLE</code>) and, the second, an int array
- containing references to the views that we'll bind the data <em>into</em>
- (the <code>R.id.text1</code> TextView).</p>
- <p>This is a bigger chunk of code, so let's first take a look at it:</p>
-
- <pre>
- private void fillData() {
- // Get all of the notes from the database and create the item list
- Cursor c = mDbHelper.fetchAllNotes();
- startManagingCursor(c);
-
- String[] from = new String[] { NotesDbAdapter.KEY_TITLE };
- int[] to = new int[] { R.id.text1 };
-
- // Now create an array adapter and set it to display using our row
- SimpleCursorAdapter notes =
- new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);
- setListAdapter(notes);
- }</pre>
-
- <p>Here's what we've done:</p>
- <ol>
- <li>
- After obtaining the Cursor from <code>mDbHelper.fetchAllNotes()</code>, we
- use an Activity method called
- <code>startManagingCursor()</code> that allows Android to take care of the
- Cursor lifecycle instead of us needing to worry about it. (We will cover the implications
- of the lifecycle in exercise 3, but for now just know that this allows Android to do some
- of our resource management work for us.)</li>
- <li>
- Then we create a string array in which we declare the column(s) we want
- (just the title, in this case), and an int array that defines the View(s)
- to which we'd like to bind the columns (these should be in order, respective to
- the string array, but here we only have one for each).</li>
- <li>
- Next is the SimpleCursorAdapter instantiation.
- Like many classes in Android, the SimpleCursorAdapter needs a Context in order to do its
- work, so we pass in <code>this</code> for the context (since subclasses of Activity
- implement Context). We pass the <code>notes_row</code> View we created as the receptacle
- for the data, the Cursor we just created, and then our arrays.</li>
- </ol>
- <p>
- In the future, remember that the mapping between the <strong>from</strong> columns and <strong>to</strong> resources
- is done using the respective ordering of the two arrays. If we had more columns we wanted
- to bind, and more Views to bind them in to, we would specify them in order, for example we
- might use <code>{ NotesDbAdapter.KEY_TITLE, NotesDbAdapter.KEY_BODY }</code> and
- <code>{ R.id.text1, R.id.text2 }</code> to bind two fields into the row (and we would also need
- to define text2 in the notes_row.xml, for the body text). This is how you can bind multiple fields
- into a single row (and get a custom row layout as well).</p>
- <p>
- If you get compiler errors about classes not being found, ctrl-shift-O or
- (cmd-shift-O on the mac) to organize imports.
- </p>
-
-<h2 style="clear:right;">Step 13</h2>
- <p>Run it!
- <ol>
- <li>
- Right click on the <code>Notepadv1</code> project.</li>
- <li>
- From the popup menu, select <strong>Run As</strong> >
- <strong>Android Application</strong>.</li>
- <li>
- If you see a dialog come up, select Android Launcher as the way of running
- the application (you can also use the link near the top of the dialog to
- set this as your default for the workspace; this is recommended as it will
- stop the plugin from asking you this every time).</li>
- <li>Add new notes by hitting the menu button and selecting <em>Add
- Item</em> from the menu.</li>
- </ol>
-
-<h2 style="clear:right;">Solution and Next Steps</h2>
- <p>You can see the solution to this class in <code>Notepadv1Solution</code>
-from
-the zip file to compare with your own.</p>
-
-<p>Once you are ready, move on to <a href="notepad-ex2.html">Tutorial
-Exercise 2</a> to add the ability to create, edit and delete notes.</p>
-
diff --git a/docs/html/training/notepad/notepad-ex2.jd b/docs/html/training/notepad/notepad-ex2.jd
deleted file mode 100644
index 5ebd1aa..0000000
--- a/docs/html/training/notepad/notepad-ex2.jd
+++ /dev/null
@@ -1,645 +0,0 @@
-excludeFromSuggestions=true
-page.title=Notepad Exercise 2
-parent.title=Notepad Tutorial
-parent.link=index.html
-@jd:body
-
-
-<p><em>In this exercise, you will add a second Activity to your notepad application, to let the user
-create and edit notes. You will also allow the user to delete existing notes through a context menu.
-The new Activity assumes responsibility for creating new notes by
-collecting user input and packing it into a return Bundle provided by the intent. This exercise
-demonstrates:</em></p>
-<ul>
-<li><em>Constructing a new Activity and adding it to the Android manifest</em></li>
-<li><em>Invoking another Activity asynchronously using <code>startActivityForResult()</code></em></li>
-<li><em>Passing data between Activity in Bundle objects</em></li>
-<li><em>How to use a more advanced screen layout</em></li>
-<li><em>How to create a context menu</em></li>
-</ul>
-
-<div style="float:right;white-space:nowrap">
- [<a href="notepad-ex1.html">Exercise 1</a>]
- <span style="color:#BBB;">
- [<a href="notepad-ex2.html" style="color:#DDD;">Exercise 2</a>]
- </span>
- [<a href="notepad-ex3.html">Exercise 3</a>]
- [<a href="notepad-extra-credit.html">Extra Credit</a>]
-</div>
-
-<h2>Step 1</h2>
-
-<p>Create a new Android project using the sources from <code>Notepadv2</code> under the
-<code>NotepadCodeLab</code> folder, just like you did for the first exercise. If you see an error about
-<code>AndroidManifest.xml</code>, or some problems related to an
-<code>android.zip</code> file, right click on the project and select <strong>Android
-Tools</strong> > <strong>Fix Project Properties</strong>.</p>
-
-<p>Open the <code>Notepadv2</code> project and take a look around:</p>
-<ul>
- <li>
- Open and look at the <code>strings.xml</code> file under
- <code>res/values</code> — there are several new strings which we will use
- for our new functionality
- </li>
- <li>
- Also, open and take a look at the top of the <code>Notepadv2</code> class,
- you will notice several new constants have been defined along with a new <code>mNotesCursor</code>
- field used to hold the cursor we are using.
- </li>
- <li>
- Note also that the <code>fillData()</code> method has a few more comments and now uses
- the new field to store the notes Cursor. The <code>onCreate()</code> method is
- unchanged from the first exercise. Also notice that the member field used to store the
- notes Cursor is now called <code>mNotesCursor</code>. The <code>m</code> denotes a member
- field and is part of the Android coding style standards.
- </li>
- <li>
- There are also a couple of new overridden methods
- (<code>onCreateContextMenu()</code>, <code>onContextItemSelected()</code>,
- <code>onListItemClick()</code> and <code>onActivityResult()</code>)
- which we will be filling in below.
- </li>
-</ul>
-
-
-<h2>Step 2</h2>
-<div class="sidebox-wrapper">
-<div class="sidebox">
-<p>Context menus should always be used when performing actions upon specific elements in the UI.
-When you register a View to a context menu, the context menu is revealed by performing a "long-click"
-on the UI component (press and hold the touchscreen or highlight and hold down the selection key for about two seconds).</p>
-</div>
-</div>
-
-<p>First, let's create the context menu that will allow users to delete individual notes.
-Open the Notepadv2 class.</p>
-
-<ol>
- <li>In order for each list item in the ListView to register for the context menu, we call
- <code>registerForContextMenu()</code> and pass it our ListView. So, at the very end of
- the <code>onCreate()</code> method add this line:
- <pre>registerForContextMenu(getListView());</pre>
- <p>Because our Activity extends the ListActivity class, <code>getListView()</code> will return us
- the local ListView object for the Activity. Now, each list item in this ListView will activate the
- context menu.
- <li>
- Now fill in the <code>onCreateContextMenu()</code> method. This callback is similar to the other
- menu callback used for the options menu. Here, we add just one line, which will add a menu item
- to delete a note. Call <code>menu.add()</code> like so:
- <pre>
-public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
- super.onCreateContextMenu(menu, v, menuInfo);
- menu.add(0, DELETE_ID, 0, R.string.menu_delete);
-}</pre>
- <p>The <code>onCreateContextMenu()</code> callback passes some other information in addition to the Menu object,
- such as the View that has been triggered for the menu and
- an extra object that may contain additional information about the object selected. However, we don't care about
- these here, because we only have one kind of object in the Activity that uses context menus. In the next
- step, we'll handle the menu item selection.</p>
- </li>
-</ol>
-
-<h2>Step 3</h2>
- <p>Now that we've registered our ListView for a context menu and defined our context menu item, we need
- to handle the callback when it is selected. For this, we need to identify the list ID of the
- selected item, then delete it. So fill in the
- <code>onContextItemSelected()</code> method like this:</p>
-<pre>
-public boolean onContextItemSelected(MenuItem item) {
- switch(item.getItemId()) {
- case DELETE_ID:
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
- mDbHelper.deleteNote(info.id);
- fillData();
- return true;
- }
- return super.onContextItemSelected(item);
-}</pre>
-<p>Here, we retrieve the {@link android.widget.AdapterView.AdapterContextMenuInfo AdapterContextMenuInfo}
-with {@link android.view.MenuItem#getMenuInfo()}. The <var>id</var> field of this object tells us
-the position of the item in the ListView. We then pass this to the <code>deleteNote()</code>
-method of our NotesDbAdapter and the note is deleted. That's it for the context menu — notes
-can now be deleted.</p>
-
-<h2 style="clear:right;">Step 4</h2>
- <div class="sidebox-wrapper">
- <div class="sidebox">
- <h2>Starting Other Activities</h2>
- <p>In this example our Intent uses a class name specifically.
- As well as
- <a href="{@docRoot}resources/faq/commontasks.html#intentexamples">starting intents</a> in
- classes we already know about, be they in our own application or another
- application, we can also create Intents without knowing exactly which
- application will handle it.</p>
- <p>For example, we might want to open a page in a
- browser, and for this we still use
- an Intent. But instead of specifying a class to handle it, we use
- a predefined Intent constant, and a content URI that describes what we
- want to do. See {@link android.content.Intent
- android.content.Intent} for more information.</p>
- </div>
- </div>
-
- <p>Fill in the body of the <code>createNote()</code> method:
- <p>Create a new <code>Intent</code> to create a note
- (<code>ACTIVITY_CREATE</code>) using the <code>NoteEdit</code> class.
- Then fire the Intent using the <code>startActivityForResult()</code> method
- call:</p>
- <pre style="overflow:auto">
-Intent i = new Intent(this, NoteEdit.class);
-startActivityForResult(i, ACTIVITY_CREATE);</pre>
- <p>This form of the Intent call targets a specific class in our Activity, in this case
- <code>NoteEdit</code>. Since the Intent class will need to communicate with the Android
- operating system to route requests, we also have to provide a Context (<code>this</code>).</p>
- <p>The <code>startActivityForResult()</code> method fires the Intent in a way that causes a method
- in our Activity to be called when the new Activity is completed. The method in our Activity
- that receives the callback is called
- <code>onActivityResult()</code> and we will implement it in a later step. The other way
- to call an Activity is using <code>startActivity()</code> but this is a "fire-and-forget" way
- of calling it — in this manner, our Activity is not informed when the Activity is completed, and there is
- no way to return result information from the called Activity with <code>startActivity()</code>.
- <p>Don't worry about the fact that <code>NoteEdit</code> doesn't exist yet,
- we will fix that soon. </p>
- </li>
-
-
-<h2>Step 5</h2>
-
- <p>Fill in the body of the <code>onListItemClick()</code> override.</p>
- <p><code>onListItemClick()</code> is a callback method that we'll override. It is called when
- the user selects an item from the list. It is passed four parameters: the
- <code>ListView</code> object it was invoked from, the <code>View</code>
- inside the <code>ListView</code> that was clicked on, the
- <code>position</code> in the list that was clicked, and the
- <code>mRowId</code> of the item that was clicked. In this instance we can
- ignore the first two parameters (we only have one <code>ListView</code> it
- could be), and we ignore the <code>mRowId</code> as well. All we are
- interested in is the <code>position</code> that the user selected. We use
- this to get the data from the correct row, and bundle it up to send to
- the <code>NoteEdit</code> Activity.</p>
- <p>In our implementation of the callback, the method creates an
- <code>Intent</code> to edit the note using
- the <code>NoteEdit</code> class. It then adds data into the extras Bundle of
- the Intent, which will be passed to the called Activity. We use it
- to pass in the title and body text, and the <code>mRowId</code> for the note we are
- editing. Finally, it will fire the Intent using the
- <code>startActivityForResult()</code> method call. Here's the code that
- belongs in <code>onListItemClick()</code>:</p>
- <pre>
-super.onListItemClick(l, v, position, id);
-Cursor c = mNotesCursor;
-c.moveToPosition(position);
-Intent i = new Intent(this, NoteEdit.class);
-i.putExtra(NotesDbAdapter.KEY_ROWID, id);
-i.putExtra(NotesDbAdapter.KEY_TITLE, c.getString(
- c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
-i.putExtra(NotesDbAdapter.KEY_BODY, c.getString(
- c.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
-startActivityForResult(i, ACTIVITY_EDIT);</pre>
- <ul>
- <li>
- <code>putExtra()</code> is the method to add items into the extras Bundle
- to pass in to intent invocations. Here, we are
- using the Bundle to pass in the title, body and mRowId of the note we want to edit.
- </li>
- <li>
- The details of the note are pulled out from our query Cursor, which we move to the
- proper position for the element that was selected in the list, with
- the <code>moveToPosition()</code> method.</li>
- <li>With the extras added to the Intent, we invoke the Intent on the
- <code>NoteEdit</code> class by passing <code>startActivityForResult()</code>
- the Intent and the request code. (The request code will be
- returned to <code>onActivityResult</code> as the <code>requestCode</code> parameter.)</li>
- </ul>
- <p class="note"><b>Note:</b> We assign the mNotesCursor field to a local variable at the
- start of the method. This is done as an optimization of the Android code. Accessing a local
- variable is much more efficient than accessing a field in the Dalvik VM, so by doing this
- we make only one access to the field, and five accesses to the local variable, making the
- routine much more efficient. It is recommended that you use this optimization when possible.</p>
-
-
-<h2>Step 6</h2>
-
-<p>The above <code>createNote()</code> and <code>onListItemClick()</code>
- methods use an asynchronous Intent invocation. We need a handler for the callback, so here we fill
- in the body of the <code>onActivityResult()</code>. </p>
-<p><code>onActivityResult()</code> is the overridden method
- which will be called when an Activity returns with a result. (Remember, an Activity
- will only return a result if launched with <code>startActivityForResult</code>.) The parameters provided
- to the callback are: </p>
- <ul>
- <li><code>requestCode</code> — the original request code
- specified in the Intent invocation (either <code>ACTIVITY_CREATE</code> or
- <code>ACTIVITY_EDIT</code> for us).
- </li>
- <li><code>resultCode</code> — the result (or error code) of the call, this
- should be zero if everything was OK, but may have a non-zero code indicating
- that something failed. There are standard result codes available, and you
- can also create your own constants to indicate specific problems.
- </li>
- <li><code>intent</code> — this is an Intent created by the Activity returning
- results. It can be used to return data in the Intent "extras."
- </li>
- </ul>
- <p>The combination of <code>startActivityForResult()</code> and
- <code>onActivityResult()</code> can be thought of as an asynchronous RPC
- (remote procedure call) and forms the recommended way for an Activity to invoke
- another and share services.</p>
- <p>Here's the code that belongs in your <code>onActivityResult()</code>:</p>
- <pre>
-super.onActivityResult(requestCode, resultCode, intent);
-Bundle extras = intent.getExtras();
-
-switch(requestCode) {
-case ACTIVITY_CREATE:
- String title = extras.getString(NotesDbAdapter.KEY_TITLE);
- String body = extras.getString(NotesDbAdapter.KEY_BODY);
- mDbHelper.createNote(title, body);
- fillData();
- break;
-case ACTIVITY_EDIT:
- Long mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
- if (mRowId != null) {
- String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE);
- String editBody = extras.getString(NotesDbAdapter.KEY_BODY);
- mDbHelper.updateNote(mRowId, editTitle, editBody);
- }
- fillData();
- break;
-}</pre>
-
- <ul>
- <li>
- We are handling both the <code>ACTIVITY_CREATE</code> and
- <code>ACTIVITY_EDIT</code> activity results in this method.
- </li>
- <li>
- In the case of a create, we pull the title and body from the extras (retrieved from the
- returned Intent) and use them to create a new note.
- </li>
- <li>
- In the case of an edit, we pull the mRowId as well, and use that to update
- the note in the database.
- </li>
- <li>
- <code>fillData()</code> at the end ensures everything is up to date .
- </li>
- </ul>
-
-
-<h2>Step 7</h2>
-
- <div class="sidebox-wrapper">
- <div class="sidebox">
- <h2>The Art of Layout</h2>
- <p>The provided
- note_edit.xml layout file is the most sophisticated one in the application we will be building,
- but that doesn't mean it is even close to the kind of sophistication you will be likely to want
- in real Android applications.</p>
- <p>Creating a
- good UI is part art and part science, and the rest is work. Mastery of <a
- href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> is an essential part of
-creating
- a good looking Android application.</p>
- <p>The <a href="https://github.com/android/platform_development/tree/master/samples/ApiDemos"
- class="external-link">ApiDemos sample project</a> is a good resource for
- learning how to create different layouts.</p>
- </div>
- </div>
-
-<p>Open the file <code>note_edit.xml</code> that has been provided and take a
- look at it. This is the UI code for the Note Editor.</p>
- <p>This is the most
- sophisticated UI we have dealt with yet. The file is given to you to avoid
- problems that may sneak in when typing the code. (The XML is very strict
- about case sensitivity and structure, mistakes in these are the usual cause
- of problems with layout.)</p>
- <p>There is a new parameter used
- here that we haven't seen before: <code>android:layout_weight</code> (in
- this case set to use the value 1 in each case).</p>
- <p><code>layout_weight</code> is used in LinearLayouts
- to assign "importance" to Views within the layout. All Views have a default
- <code>layout_weight</code> of zero, meaning they take up only as much room
- on the screen as they need to be displayed. Assigning a value higher than
- zero will split up the rest of the available space in the parent View, according
- to the value of each View's <code>layout_weight</code> and its ratio to the
- overall <code>layout_weight</code> specified in the current layout for this
- and other View elements.</p>
- <p>To give an example: let's say we have a text label
- and two text edit elements in a horizontal row. The label has no
- <code>layout_weight</code> specified, so it takes up the minimum space
- required to render. If the <code>layout_weight</code> of each of the two
- text edit elements is set to 1, the remaining width in the parent layout will
- be split equally between them (because we claim they are equally important).
- If the first one has a <code>layout_weight</code> of 1
- and the second has a <code>layout_weight</code> of 2, then one third of the
- remaining space will be given to the first, and two thirds to the
- second (because we claim the second one is more important).</p>
- <p>This layout also demonstrates how to nest multiple layouts
- inside each other to achieve a more complex and pleasant layout. In this
- example, a horizontal linear layout is nested inside the vertical one to
- allow the title label and text field to be alongside each other,
- horizontally.</p>
-
-
-<h2 style="clear:right;">Step 8</h2>
-
- <p>Create a <code>NoteEdit</code> class that extends
- <code>android.app.Activity</code>.</p>
- <p>This is the first time we will have
- created an Activity without the Android Eclipse plugin doing it for us. When
- you do so, the <code>onCreate()</code> method is not automatically
- overridden for you. It is hard to imagine an Activity that doesn't override
- the <code>onCreate()</code> method, so this should be the first thing you do.</p>
- <ol>
- <li>Right click on the <code>com.android.demo.notepad2</code> package
- in the Package Explorer, and select <strong>New</strong> > <strong>Class</strong> from the popup
- menu.</li>
- <li>Fill in <code>NoteEdit</code> for the <code>Name:</code> field in the
- dialog.</li>
- <li>In the <code>Superclass:</code> field, enter
- <code>android.app.Activity</code> (you can also just type Activity and hit
- Ctrl-Space on Windows and Linux or Cmd-Space on the Mac, to invoke code
- assist and find the right package and class).</li>
- <li>Click <strong>Finish</strong>.</li>
- <li>In the resulting <code>NoteEdit</code> class, right click in the editor
- window and select <strong>Source</strong> > <strong>Override/Implement Methods...</strong></li>
- <li>Scroll down through the checklist in the dialog until you see
- <code>onCreate(Bundle)</code> — and check the box next to it.</li>
- <li>Click <strong>OK</strong>.<p>The method should now appear in your class.</p></li>
- </ol>
-
-<h2>Step 9</h2>
-
-<p>Fill in the body of the <code>onCreate()</code> method for <code>NoteEdit</code>.</p>
-
-<p>This will set the title of our new Activity to say "Edit Note" (one
- of the strings defined in <code>strings.xml</code>). It will also set the
- content view to use our <code>note_edit.xml</code> layout file. We can then
- grab handles to the title and body text edit views, and the confirm button,
- so that our class can use them to set and get the note title and body,
- and attach an event to the confirm button for when it is pressed by the
- user.</p>
- <p>We can then unbundle the values that were passed in to the Activity
- with the extras Bundle attached to the calling Intent. We'll use them to pre-populate
- the title and body text edit views so that the user can edit them.
- Then we will grab and store the <code>mRowId</code> so we can keep
- track of what note the user is editing.</p>
-
- <ol>
- <li>
- Inside <code>onCreate()</code>, set up the layout:<br>
- <pre>setContentView(R.layout.note_edit);</pre>
- </li>
- <li>
- 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,
- and <code>Button</code> for the confirm button):</p>
- <pre>
-mTitleText = (EditText) findViewById(R.id.title);
-mBodyText = (EditText) findViewById(R.id.body);
-Button confirmButton = (Button) findViewById(R.id.confirm);</pre>
- <p>Note that <code>mTitleText</code> and <code>mBodyText</code> are member
- fields (you need to declare them at the top of the class definition).</p>
- </li>
- <li>At the top of the class, declare a <code>Long mRowId</code> private field to store
- the current <code>mRowId</code> being edited (if any).
- </li>
- <li>Continuing inside <code>onCreate()</code>,
- add code to initialize the <code>title</code>, <code>body</code> and
- <code>mRowId</code> from the extras Bundle in
- the Intent (if it is present):<br>
- <pre>
-mRowId = null;
-Bundle extras = getIntent().getExtras();
-if (extras != null) {
- String title = extras.getString(NotesDbAdapter.KEY_TITLE);
- String body = extras.getString(NotesDbAdapter.KEY_BODY);
- mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
-
- if (title != null) {
- mTitleText.setText(title);
- }
- if (body != null) {
- mBodyText.setText(body);
- }
-}</pre>
- <ul>
- <li>
- We are pulling the <code>title</code> and
- <code>body</code> out of the
- <code>extras</code> Bundle that was set from the
- Intent invocation.
- </li><li>
- We also null-protect the text field setting (i.e., we don't want to set
- the text fields to null accidentally).</li>
- </ul>
- </li>
- <li>
- Create an <code>onClickListener()</code> for the button:
- <p>Listeners can be one of the more confusing aspects of UI
- implementation, but
- what we are trying to achieve in this case is simple. We want an
- <code>onClick()</code> method to be called when the user presses the
- confirm button, and use that to do some work and return the values
- of the edited note to the Intent caller. We do this using something called
- an anonymous inner class. This is a bit confusing to look at unless you
- have seen them before, but all you really need to take away from this is
- that you can refer to this code in the future to see how to create a
- listener and attach it to a button. (Listeners are a common idiom
- in Java development, particularly for user interfaces.) Here's the empty listener:<br>
- <pre>
-confirmButton.setOnClickListener(new View.OnClickListener() {
-
- public void onClick(View view) {
-
- }
-
-});</pre>
- </li>
- </ol>
-<h2>Step 10</h2>
-
-<p>Fill in the body of the <code>onClick()</code> method of the <code>OnClickListener</code> created in the last step.</p>
-
- <p>This is the code that will be run when the user clicks on the
- confirm button. We want this to grab the title and body text from the edit
- text fields, and put them into the return Bundle so that they can be passed
- back to the Activity that invoked this <code>NoteEdit</code> Activity. If the
- operation is an edit rather than a create, we also want to put the
- <code>mRowId</code> into the Bundle so that the
- <code>Notepadv2</code> class can save the changes back to the correct
- note.</p>
- <ol>
- <li>
- Create a <code>Bundle</code> and put the title and body text into it using the
- constants defined in Notepadv2 as keys:<br>
- <pre>
-Bundle bundle = new Bundle();
-
-bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
-bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
-if (mRowId != null) {
- bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
-}</pre>
- </li>
- <li>
- Set the result information (the Bundle) in a new Intent and finish the Activity:
- <pre>
-Intent mIntent = new Intent();
-mIntent.putExtras(bundle);
-setResult(RESULT_OK, mIntent);
-finish();</pre>
- <ul>
- <li>The Intent is simply our data carrier that carries our Bundle
- (with the title, body and mRowId).</li>
- <li>The <code>setResult()</code> method is used to set the result
- code and return Intent to be passed back to the
- Intent caller. In this case everything worked, so we return RESULT_OK for the
- result code.</li>
- <li>The <code>finish()</code> call is used to signal that the Activity
- is done (like a return call). Anything set in the Result will then be
- returned to the caller, along with execution control.</li>
- </ul>
- </li>
- </ol>
- <p>The full <code>onCreate()</code> method (plus supporting class fields) should
- now look like this:</p>
- <pre>
-private EditText mTitleText;
-private EditText mBodyText;
-private Long mRowId;
-
-@Override
-protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.note_edit);
-
- mTitleText = (EditText) findViewById(R.id.title);
- mBodyText = (EditText) findViewById(R.id.body);
-
- Button confirmButton = (Button) findViewById(R.id.confirm);
-
- mRowId = null;
- Bundle extras = getIntent().getExtras();
- if (extras != null) {
- String title = extras.getString(NotesDbAdapter.KEY_TITLE);
- String body = extras.getString(NotesDbAdapter.KEY_BODY);
- mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
-
- if (title != null) {
- mTitleText.setText(title);
- }
- if (body != null) {
- mBodyText.setText(body);
- }
- }
-
- confirmButton.setOnClickListener(new View.OnClickListener() {
-
- public void onClick(View view) {
- Bundle bundle = new Bundle();
-
- bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
- bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
- if (mRowId != null) {
- bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
- }
-
- Intent mIntent = new Intent();
- mIntent.putExtras(bundle);
- setResult(RESULT_OK, mIntent);
- finish();
- }
- });
-}</pre>
- </li>
- </ol>
-
-<h2>Step 11</h2>
-
- <div class="sidebox-wrapper">
- <div class="sidebox">
- <h2>The All-Important Android Manifest File</h2>
- <p>The AndroidManifest.xml file is the way in which Android sees your
- application. This file defines the category of the application, where
- it shows up (or even if it shows up) in the launcher or settings, what
- activities, services, and content providers it defines, what intents it can
- receive, and more. </p>
- <p>For more information, see the reference document
- <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml
-File</a></p>
- </div>
- </div>
-
-<p>Finally, the new Activity has to be defined in the manifest file:</p>
- <p>Before the new Activity can be seen by Android, it needs its own
- Activity entry in the <code>AndroidManifest.xml</code> file. This is to let
- the system know that it is there and can be called. We could also specify
- which IntentFilters the activity implements here, but we are going to skip
- this for now and just let Android know that the Activity is
- defined.</p>
- <p>There is a Manifest editor included in the Eclipse plugin that makes it much easier
- to edit the AndroidManifest file, and we will use this. If you prefer to edit the file directly
- or are not using the Eclipse plugin, see the box at the end for information on how to do this
- without using the new Manifest editor.<p>
- <ol>
- <li>Double click on the <code>AndroidManifest.xml</code> file in the package explorer to open it.
- </li>
- <li>Click the <strong>Application</strong> tab at the bottom of the Manifest editor.</li>
- <li>Click <strong>Add...</strong> in the Application Nodes section.
- <p>If you see a dialog with radiobuttons at the top, select the top radio button:
- "Create a new element at the top level, in Application".</p></li>
- <li>Make sure "(A) Activity" is selected in the selection pane of the dialog, and click <strong>OK</strong>.</li>
- <li>Click on the new "Activity" node, in the Application Nodes section, then
- type <code>.NoteEdit</code> into the <em>Name*</em>
- field to the right. Press Return/Enter.</li>
- </ol>
- <p>The Android Manifest editor helps you add more complex entries into the AndroidManifest.xml
- file, have a look around at some of the other options available (but be careful not to select
- them otherwise they will be added to your Manifest). This editor should help you understand
- and alter the AndroidManifest.xml file as you move on to more advanced Android applications.</p>
-
- <p class="note">If you prefer to edit this file directly, simply open the
- <code>AndroidManifest.xml</code> file and look at the source (use the
- <code>AndroidManifest.xml</code> tab in the eclipse editor to see the source code directly).
- Then edit the file as follows:<br>
- <code><activity android:name=".NoteEdit" /></code><br><br>
- This should be placed just below the line that reads:<br>
- <code></activity></code> for the <code>.Notepadv2</code> activity.</p>
-
-<h2 style="clear:right;">Step 12</h2>
-
-<p>Now Run it!</p>
-<p>You should now be able to add real notes from
-the menu, as well as delete an existing one. Notice that in order to delete, you must
-first use the directional controls on the device to highlight the note.
-Furthermore, selecting a note title from the list should bring up the note
-editor to let you edit it. Press confirm when finished to save the changes
-back to the database.
-
-<h2>Solution and Next Steps</h2>
-
-<p>You can see the solution to this exercise in <code>Notepadv2Solution</code>
-from the zip file to compare with your own.</p>
-<p>Now try editing a note, and then hitting the back button on the emulator
-instead of the confirm button (the back button is below the menu button). You
-will see an error come up. Clearly our application still has some problems.
-Worse still, if you did make some changes and hit the back button, when you go
-back into the notepad to look at the note you changed, you will find that all
-your changes have been lost. In the next exercise we will fix these
-problems.</p>
-
-<p>
-Once you are ready, move on to <a href="notepad-ex3.html">Tutorial
-Exercise 3</a> where you will fix the problems with the back button and lost
-edits by introducing a proper life cycle into the NoteEdit Activity.</p>
-
-
diff --git a/docs/html/training/notepad/notepad-ex3.jd b/docs/html/training/notepad/notepad-ex3.jd
deleted file mode 100644
index 648f9f2..0000000
--- a/docs/html/training/notepad/notepad-ex3.jd
+++ /dev/null
@@ -1,367 +0,0 @@
-excludeFromSuggestions=true
-page.title=Notepad Exercise 3
-parent.title=Notepad Tutorial
-parent.link=index.html
-@jd:body
-
-
-<p><em>In this exercise, you will use life-cycle event callbacks to store and
-retrieve application state data. This exercise demonstrates:</em></p>
-<ul>
-<li><em>Life-cycle events and how your application can use them</em></li>
-<li><em>Techniques for maintaining application state</em></li>
-</ul>
-
-<div style="float:right;white-space:nowrap">
- [<a href="notepad-ex1.html">Exercise 1</a>]
- [<a href="notepad-ex2.html">Exercise 2</a>]
- <span style="color:#BBB;">
- [<a href="notepad-ex3.html" style="color:#BBB;">Exercise 3</a>]
- </span>
- [<a href="notepad-extra-credit.html">Extra Credit</a>]
-</div>
-
-<h2>Step 1</h2>
-
-<p>Import <code>Notepadv3</code> into Eclipse. If you see an error about
-<code>AndroidManifest.xml,</code> or some problems related to an Android zip
-file, right click on the project and select <strong>Android Tools</strong> >
-<strong>Fix Project Properties</strong> from the popup menu. The starting point for this exercise is
-exactly where we left off at the end of the Notepadv2. </p>
-<p>The current application has some problems — hitting the back button when editing
-causes a crash, and anything else that happens during editing will cause the
-edits to be lost.</p>
-<p>To fix this, we will move most of the functionality for creating and editing
-the note into the NoteEdit class, and introduce a full life cycle for editing
-notes.</p>
-
- <ol>
- <li>Remove the code in <code>NoteEdit</code> that parses the title and body
- from the extras Bundle.
- <p>Instead, we are going to use the <code>DBHelper</code> class
- to access the notes from the database directly. All we need passed into the
- NoteEdit Activity is a <code>mRowId</code> (but only if we are editing, if creating we pass
- nothing). Remove these lines:</p>
- <pre>
-String title = extras.getString(NotesDbAdapter.KEY_TITLE);
-String body = extras.getString(NotesDbAdapter.KEY_BODY);</pre>
- </li>
- <li>We will also get rid of the properties that were being passed in
- the <code>extras</code> Bundle, which we were using to set the title
- and body text edit values in the UI. So delete:
- <pre>
-if (title != null) {
- mTitleText.setText(title);
-}
-if (body != null) {
- mBodyText.setText(body);
-}</pre>
- </li>
- </ol>
-
-<h2>Step 2</h2>
-
-<p>Create a class field for a <code>NotesDbAdapter</code> at the top of the NoteEdit class:</p>
- <pre> private NotesDbAdapter mDbHelper;</pre>
-<p>Also add an instance of <code>NotesDbAdapter</code> in the
- <code>onCreate()</code> method (right below the <code>super.onCreate()</code> call):</p>
- <pre>
- mDbHelper = new NotesDbAdapter(this);<br>
- mDbHelper.open();</pre>
-
-<h2>Step 3</h2>
-
-<p>In <code>NoteEdit</code>, we need to check the <var>savedInstanceState</var> for the
-<code>mRowId</code>, in case the note
- editing contains a saved state in the Bundle, which we should recover (this would happen
- if our Activity lost focus and then restarted).</p>
- <ol>
- <li>
- Replace the code that currently initializes the <code>mRowId</code>:<br>
- <pre>
- mRowId = null;
-
- Bundle extras = getIntent().getExtras();
- if (extras != null) {
- mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
- }
- </pre>
- with this:
- <pre>
- mRowId = (savedInstanceState == null) ? null :
- (Long) savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID);
- if (mRowId == null) {
- Bundle extras = getIntent().getExtras();
- mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID)
- : null;
- }
- </pre>
- </li>
- <li>
- Note the null check for <code>savedInstanceState</code>, and we still need to load up
- <code>mRowId</code> from the <code>extras</code> Bundle if it is not
- provided by the <code>savedInstanceState</code>. This is a ternary operator shorthand
- to safely either use the value or null if it is not present.
- </li>
- <li>
- Note the use of <code>Bundle.getSerializable()</code> instead of
- <code>Bundle.getLong()</code>. The latter encoding returns a <code>long</code> primitive and
- so can not be used to represent the case when <code>mRowId</code> is <code>null</code>.
- </li>
- </ol>
-
-<h2>Step 4</h2>
-
-<p>Next, we need to populate the fields based on the <code>mRowId</code> if we
- have it:</p>
- <pre>populateFields();</pre>
- <p>This goes before the <code>confirmButton.setOnClickListener()</code> line.
- We'll define this method in a moment.</p>
-
-<h2>Step 5</h2>
-
-<p>Get rid of the Bundle creation and Bundle value settings from the
- <code>onClick()</code> handler method. The Activity no longer needs to
- return any extra information to the caller. And because we no longer have
- an Intent to return, we'll use the shorter version
- of <code>setResult()</code>:</p>
- <pre>
-public void onClick(View view) {
- setResult(RESULT_OK);
- finish();
-}</pre>
- <p>We will take care of storing the updates or new notes in the database
- ourselves, using the life-cycle methods.</p>
-
- <p>The whole <code>onCreate()</code> method should now look like this:</p>
- <pre>
-super.onCreate(savedInstanceState);
-
-mDbHelper = new NotesDbAdapter(this);
-mDbHelper.open();
-
-setContentView(R.layout.note_edit);
-
-mTitleText = (EditText) findViewById(R.id.title);
-mBodyText = (EditText) findViewById(R.id.body);
-
-Button confirmButton = (Button) findViewById(R.id.confirm);
-
-mRowId = (savedInstanceState == null) ? null :
- (Long) savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID);
-if (mRowId == null) {
- Bundle extras = getIntent().getExtras();
- mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID)
- : null;
-}
-
-populateFields();
-
-confirmButton.setOnClickListener(new View.OnClickListener() {
-
- public void onClick(View view) {
- setResult(RESULT_OK);
- finish();
- }
-
-});</pre>
-
-<h2>Step 6</h2>
-
-<p>Define the <code>populateFields()</code> method.</p>
- <pre>
-private void populateFields() {
- if (mRowId != null) {
- Cursor note = mDbHelper.fetchNote(mRowId);
- startManagingCursor(note);
- mTitleText.setText(note.getString(
- note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
- mBodyText.setText(note.getString(
- note.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
- }
-}</pre>
-<p>This method uses the <code>NotesDbAdapter.fetchNote()</code> method to find the right note to
-edit, then it calls <code>startManagingCursor()</code> from the <code>Activity</code> class, which
-is an Android convenience method provided to take care of the Cursor life-cycle. This will release
-and re-create resources as dictated by the Activity life-cycle, so we don't need to worry about
-doing that ourselves. After that, we just look up the title and body values from the Cursor
-and populate the View elements with them.</p>
-
-
-<h2>Step 7</h2>
-
- <div class="sidebox-wrapper">
- <div class="sidebox">
- <h2>Why handling life-cycle events is important</h2>
- <p>If you are used to always having control in your applications, you
- might not understand why all this life-cycle work is necessary. The reason
- is that in Android, you are not in control of your Activity, the
- operating system is!</p>
- <p>As we have already seen, the Android model is based around activities
- calling each other. When one Activity calls another, the current Activity
- is paused at the very least, and may be killed altogether if the
- system starts to run low on resources. If this happens, your Activity will
- have to store enough state to come back up later, preferably in the same
- state it was in when it was killed.</p>
- <p>
- Activities have a <a
-href="{@docRoot}guide/components/activities.html#Lifecycle">well-defined life
-cycle</a>.
- Lifecycle events can happen even if you are not handing off control to
- another Activity explicitly. For example, perhaps a call comes in to the
- handset. If this happens, and your Activity is running, it will be swapped
- out while the call Activity takes over.</p>
- </div>
- </div>
-
-<p>Still in the <code>NoteEdit</code> class, we now override the methods
- <code>onSaveInstanceState()</code>, <code>onPause()</code> and
- <code>onResume()</code>. These are our life-cycle methods
- (along with <code>onCreate()</code> which we already have).</p>
-
-<p><code>onSaveInstanceState()</code> is called by Android if the
- Activity is being stopped and <strong>may be killed before it is
- resumed!</strong> This means it should store any state necessary to
- re-initialize to the same condition when the Activity is restarted. It is
- the counterpart to the <code>onCreate()</code> method, and in fact the
- <code>savedInstanceState</code> Bundle passed in to <code>onCreate()</code> is the same
- Bundle that you construct as <code>outState</code> in the
- <code>onSaveInstanceState()</code> method.</p>
-
-<p><code>onPause()</code> and <code>onResume()</code> are also
- complimentary methods. <code>onPause()</code> is always called when the
- Activity ends, even if we instigated that (with a <code>finish()</code> call for example).
- We will use this to save the current note back to the database. Good
- practice is to release any resources that can be released during an
- <code>onPause()</code> as well, to take up less resources when in the
- passive state. <code>onResume()</code> will call our <code>populateFields()</code> method
- to read the note out of the database again and populate the fields.</p>
-
-<p>So, add some space after the <code>populateFields()</code> method
- and add the following life-cycle methods:</p>
- <ol type="a">
- <li><code>
- onSaveInstanceState()</code>:
- <pre>
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- saveState();
- outState.putSerializable(NotesDbAdapter.KEY_ROWID, mRowId);
- }</pre>
- <p>We'll define <code>saveState()</code> next.</p>
- </li>
- <li><code>
- onPause()</code>:
- <pre>
- @Override
- protected void onPause() {
- super.onPause();
- saveState();
- }</pre>
- </li>
- <li><code>
- onResume()</code>:
- <pre>
- @Override
- protected void onResume() {
- super.onResume();
- populateFields();
- }</pre>
- </li>
- </ol>
-<p>Note that <code>saveState()</code> must be called in both <code>onSaveInstanceState()</code>
-and <code>onPause()</code> to ensure that the data is saved. This is because there is no
-guarantee that <code>onSaveInstanceState()</code> will be called and because when it <em>is</em>
-called, it is called before <code>onPause()</code>.</p>
-
-
-<h2 style="clear:right;">Step 8</h2>
-
-<p>Define the <code>saveState()</code> method to put the data out to the
-database.</p>
- <pre>
- private void saveState() {
- String title = mTitleText.getText().toString();
- String body = mBodyText.getText().toString();
-
- if (mRowId == null) {
- long id = mDbHelper.createNote(title, body);
- if (id > 0) {
- mRowId = id;
- }
- } else {
- mDbHelper.updateNote(mRowId, title, body);
- }
- }</pre>
- <p>Note that we capture the return value from <code>createNote()</code> and if a valid row ID is
- returned, we store it in the <code>mRowId</code> field so that we can update the note in future
- rather than create a new one (which otherwise might happen if the life-cycle events are
- triggered).</p>
-
-
-<h2 style="clear:right;">Step 9</h2>
-
-<p>Now pull out the previous handling code from the
- <code>onActivityResult()</code> method in the <code>Notepadv3</code>
- class.</p>
-<p>All of the note retrieval and updating now happens within the
- <code>NoteEdit</code> life cycle, so all the <code>onActivityResult()</code>
- method needs to do is update its view of the data, no other work is
- necessary. The resulting method should look like this:</p>
-<pre>
-@Override
-protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
- super.onActivityResult(requestCode, resultCode, intent);
- fillData();
-}</pre>
-
-<p>Because the other class now does the work, all this has to do is refresh
- the data.</p>
-
-<h2>Step 10</h2>
-
-<p>Also remove the lines which set the title and body from the
- <code>onListItemClick()</code> method (again they are no longer needed,
- only the <code>mRowId</code> is):</p>
-<pre>
- Cursor c = mNotesCursor;
- c.moveToPosition(position);</pre>
-<br>
-and also remove:
-<br>
-<pre>
- i.putExtra(NotesDbAdapter.KEY_TITLE, c.getString(
- c.getColumnIndex(NotesDbAdapter.KEY_TITLE)));
- i.putExtra(NotesDbAdapter.KEY_BODY, c.getString(
- c.getColumnIndex(NotesDbAdapter.KEY_BODY)));</pre>
-<br>
-so that all that should be left in that method is:
-<br>
-<pre>
- super.onListItemClick(l, v, position, id);
- Intent i = new Intent(this, NoteEdit.class);
- i.putExtra(NotesDbAdapter.KEY_ROWID, id);
- startActivityForResult(i, ACTIVITY_EDIT);</pre>
-
- <p>You can also now remove the mNotesCursor field from the class, and set it back to using
- a local variable in the <code>fillData()</code> method:
-<br><pre>
- Cursor notesCursor = mDbHelper.fetchAllNotes();</pre></p>
- <p>Note that the <code>m</code> in <code>mNotesCursor</code> denotes a member field, so when we
- make <code>notesCursor</code> a local variable, we drop the <code>m</code>. Remember to rename the
- other occurrences of <code>mNotesCursor</code> in your <code>fillData()</code> method.
-</ol>
-<p>
-Run it! (use <em>Run As -> Android Application</em> on the project right
-click menu again)</p>
-
-<h2>Solution and Next Steps</h2>
-
-<p>You can see the solution to this exercise in <code>Notepadv3Solution</code>
-from
-the zip file to compare with your own.</p>
-<p>
-When you are ready, move on to the <a href="notepad-extra-credit.html">Tutorial
-Extra Credit</a> exercise, where you can use the Eclipse debugger to
-examine the life-cycle events as they happen.</p>
diff --git a/docs/html/training/notepad/notepad-extra-credit.jd b/docs/html/training/notepad/notepad-extra-credit.jd
deleted file mode 100644
index 8ab2021..0000000
--- a/docs/html/training/notepad/notepad-extra-credit.jd
+++ /dev/null
@@ -1,71 +0,0 @@
-excludeFromSuggestions=true
-page.title=Notepad Extra Credit
-parent.title=Notepad Tutorial
-parent.link=index.html
-@jd:body
-
-
-<p><em>In this exercise, you will use the debugger to look at the work you did
-in Exercise 3. This exercise demonstrates:</em></p>
-<ul>
-<li><em>How to set breakpoints to observe execution</em> </li>
-<li><em>How to run your application in debug mode</code></em></li>
-</ul>
-
-<div style="float:right;white-space:nowrap">
-
- [<a href="notepad-ex1.html">Exercise 1</a>]
- [<a href="notepad-ex2.html">Exercise 2</a>]
- [<a href="notepad-ex3.html">Exercise 3</a>]
- <span style="color:#BBB;">
- [<a href="notepad-extra-credit.html" style="color:#BBB;">Extra Credit</a>]
- </span>
-</div>
-
-<h2>Step 1</h2>
-
-<p>Using the working <code>Notepadv3</code>, put breakpoints in the code at the
- beginning of the <code>onCreate()</code>, <code>onPause()</code>,
- <code>onSaveInstanceState()</code> and <code>onResume()</code> methods in the
- <code>NoteEdit</code> class (if you are not familiar with Eclipse, just
- right click in the narrow grey border on the left of the edit window at the
- line you want a breakpoint, and select <em>Toggle Breakpoint</em>, you
-should see a blue dot appear).</p>
-
-<h2>Step 2</h2>
-
-<p>Now start the notepad demo in debug mode:</p>
-
-<ol type="a">
- <li>
- Right click on the <code>Notepadv3</code> project and from the Debug menu
- select <em>Debug As -> Android Application.</em></li>
- <li>
- The Android emulator should say <em>"waiting for debugger to connect"</em>
- briefly and then run the application.</li>
- <li>
- If it gets stuck on the waiting... screen, quit the emulator and Eclipse,
- from the command line do an <code>adb kill-server</code>, and then restart
-Eclipse and try again.</li></ol>
-
- <h2>Step 3</h2>
-
-<p>When you edit or create a new note you should see the breakpoints getting
- hit and the execution stopping.</p>
-
- <h2>Step 4</h2>
-
-<p>Hit the Resume button to let execution continue (yellow rectangle with a
-green triangle to its right in the Eclipse toolbars near the top).</p>
-
-<h2>Step 5</h2>
-
-<p>Experiment a bit with the confirm and back buttons, and try pressing Home and
- making other mode changes. Watch what life-cycle events are generated and
-when.</p>
-
-<p>The Android Eclipse plugin not only offers excellent debugging support for
-your application development, but also superb profiling support. You can also
-try using <a href="{@docRoot}tools/help/traceview.html">Traceview</a> to profile your application. If your application is running too slow, this can help you
-find the bottlenecks and fix them.</p>
-
diff --git a/docs/html/training/notepad/notepad-index.jd b/docs/html/training/notepad/notepad-index.jd
deleted file mode 100644
index fde43fa..0000000
--- a/docs/html/training/notepad/notepad-index.jd
+++ /dev/null
@@ -1,144 +0,0 @@
-excludeFromSuggestions=true
-page.title=Notepad Tutorial
-@jd:body
-
-
-<p>The tutorial in this section gives you a "hands-on" introduction
-to the Android framework and the tools you use to build applications on it.
-Starting from a preconfigured project file, it guides you through the process of
-developing a simple notepad application and provides concrete examples of how to
-set up the project, develop the application logic and user interface, and then
-compile and run the application. </p>
-
-<p>The tutorial presents the notepad application development as a set of
-exercises (see below), each consisting of several steps. You can follow along
-with the steps in each exercise and gradually build up and refine your
-application. The exercises explain each step in detail and provide all the
-sample code you need to complete the application. </p>
-
-<p>When you are finished with the tutorial, you will have created a functioning
-Android application and learned in depth about many of the most important
-concepts in Android development. If you want to add more complex features to
-your application, you can examine the code in an alternative implementation
-of a notepad application, in the
-<a href="{@docRoot}samples/NotePad/index.html">Sample Code</a> documentation. </p>
-
-
-<a name="who"></a>
-<h2>Who Should Use this Tutorial</h2>
-
-<p>This tutorial is designed for experienced developers, especially those with
-knowledge of the Java programming language. If you haven't written Java
-applications before, you can still use the tutorial, but you might need to work
-at a slower pace. </p>
-
-<p>The tutorial assumes that you have some familiarity with the basic Android
-application concepts and terminology. If you aren't yet familiar with those, you
-should read <a href="{@docRoot}intro/anatomy.html">Overview of an Android
-Application</a> before continuing. </p>
-
-<p>Also note that this tutorial uses
-the Eclipse development environment, with the Android plugin installed. If you
-are not using Eclipse, you can follow the exercises and build the application,
-but you will need to determine how to accomplish the Eclipse-specific
-steps in your environment. </p>
-
-<a name="preparing"></a>
-<h2>Preparing for the Exercises</h2>
-
-<p>This tutorial builds on the information provided in the <a
-href="{@docRoot}intro/installing.html">Installing the SDK</a> and <a
-href="{@docRoot}intro/hello-android.html">Hello Android</a>
-documents, which explain in detail how to set up your development environment
-for building Android applications. Before you start this tutorial, you should
-read both these documents, have the SDK installed, and your work environment set up.</p>
-
-<p>To prepare for this lesson:</p>
-
-<ol>
- <li>Download the <a href="codelab/NotepadCodeLab.zip">project
- exercises archive (.zip)</a></li>
- <li>Unpack the archive file to a suitable location on your machine</li>
- <li>Open the <code>NotepadCodeLab</code> folder</li>
-</ol>
-
-<p>Inside the <code>NotepadCodeLab</code> folder, you should see six project
-files: <code>Notepadv1</code>,
- <code>Notepadv2</code>, <code>Notepadv3</code>,
- <code>Notepadv1Solution</code>, <code>Notepadv2Solution</code>
- and <code>Notepadv3Solution</code>. The <code>Notepadv#</code> projects are
-the starting points for each of the exercises, while the
-<code>Notepadv#Solution</code> projects are the exercise
- solutions. If you are having trouble with a particular exercise, you
- can compare your current work against the exercise solution.</p>
-
-<a name="exercises"></a>
-<h2> Exercises</h2>
-
- <p>The table below lists the tutorial exercises and describes the development
-areas that each covers. Each exercise assumes that you have completed any
-previous exercises.</p>
-
- <table border="0" style="padding:4px;spacing:2px;" summary="This
-table lists the
-tutorial examples and describes what each covers. ">
- <tr>
- <th width="120"><a href="{@docRoot}intro/tutorial-ex1.html">Exercise
-1</a></th>
- <td>Start here. Construct a simple notes list that lets the user add new notes but not
-edit them. Demonstrates the basics of <code>ListActivity</code> and creating
-and handling
- menu options. Uses a SQLite database to store the notes.</td>
- </tr>
- <tr>
- <th><a href="{@docRoot}intro/tutorial-ex2.html">Exercise 2</a></th>
- <td>Add a second Activity to the
-application. Demonstrates constructing a
-new Activity, adding it to the Android manifest, passing data between the
-activities, and using more advanced screen layout. Also shows how to
-invoke another Activity to return a result, using
-<code>startActivityForResult()</code>.</td>
- </tr>
- <tr>
- <th><a href="{@docRoot}intro/tutorial-ex3.html">Exercise 3</a></th>
- <td>Add handling of life-cycle events to
-the application, to let it
-maintain application state across the life cycle. </td>
- </tr>
- <tr>
- <th><a href="{@docRoot}intro/tutorial-extra-credit.html">Extra
-Credit</a></th>
- <td>Demonstrates how to use the Eclipse
-debugger and how you can use it to
-view life-cycle events as they are generated. This section is optional but
-highly recommended.</td>
- </tr>
-</table>
-
-
-<a name="other"></a>
-<h2>Other Resources and Further Learning</h2>
-<ul>
-<li>For a lighter but broader introduction to concepts not covered in the
-tutorial,
-take a look at <a href="{@docRoot}kb/commontasks.html">Common Android Tasks</a>.</li>
-<li>The Android SDK includes a variety of fully functioning sample applications
-that make excellent opportunities for further learning. You can find the sample
-applications in the <code>samples/</code> directory of your downloaded SDK.</li>
-<li>This tutorial draws from the full Notepad application included in the
-<code>samples/</code> directory of the SDK, though it does not match it exactly.
-When you are done with the tutorial,
-it is highly recommended that you take a closer look at this version of the Notepad
-application,
-as it demonstrates a variety of interesting additions for your application,
-such as:</li>
- <ul>
- <li>Setting up a custom striped list for the list of notes.</li>
- <li>Creating a custom text edit view that overrides the <code>draw()</code>
-method to
- make it look like a lined notepad.</li>
- <li>Implementing a full <code>ContentProvider</code> for notes.</li>
- <li>Reverting and discarding edits instead of just automatically saving
-them.</li>
-</ul>
-</ul>
diff --git a/docs/html/training/tv/playback/now-playing.jd b/docs/html/training/tv/playback/now-playing.jd
index a4c321e..0a50441 100644
--- a/docs/html/training/tv/playback/now-playing.jd
+++ b/docs/html/training/tv/playback/now-playing.jd
@@ -143,7 +143,7 @@
metadataBuilder.putString(MediaMetadata.METADATA_KEY_ARTIST,
myData.artist);
// A small bitmap for the artwork is also recommended
- metadataBuilder.putString(MediaMetadata.METADATA_KEY_ART,
+ metadataBuilder.putBitmap(MediaMetadata.METADATA_KEY_ART,
myData.artBitmap);
// Add any other fields you have for your data as well
mSession.setMetadata(metadataBuilder.build());
diff --git a/docs/html/training/volley/index.jd b/docs/html/training/volley/index.jd
index 97bddae..2cefc90 100644
--- a/docs/html/training/volley/index.jd
+++ b/docs/html/training/volley/index.jd
@@ -23,7 +23,7 @@
</div>
</div>
-<a class="notice-developers-video wide" href="https://developers.google.com/events/io/sessions/325304728">
+<a class="notice-developers-video wide" href="https://www.youtube.com/watch?v=yhv8l9F44qo">
<div>
<h3>Video</h3>
<p>Volley: Easy, Fast Networking for Android</p>
diff --git a/docs/html/training/volley/request-custom.jd b/docs/html/training/volley/request-custom.jd
index 7b669b9..bc0ef1c 100644
--- a/docs/html/training/volley/request-custom.jd
+++ b/docs/html/training/volley/request-custom.jd
@@ -16,7 +16,7 @@
</div>
</div>
-<a class="notice-developers-video wide" href="https://developers.google.com/events/io/sessions/325304728">
+<a class="notice-developers-video wide" href="https://www.youtube.com/watch?v=yhv8l9F44qo">
<div>
<h3>Video</h3>
<p>Volley: Easy, Fast Networking for Android</p>
diff --git a/docs/html/training/volley/request.jd b/docs/html/training/volley/request.jd
index 8a7dc62..a2b2ecd 100644
--- a/docs/html/training/volley/request.jd
+++ b/docs/html/training/volley/request.jd
@@ -17,7 +17,7 @@
</div>
</div>
-<a class="notice-developers-video wide" href="https://developers.google.com/events/io/sessions/325304728">
+<a class="notice-developers-video wide" href="https://www.youtube.com/watch?v=yhv8l9F44qo">
<div>
<h3>Video</h3>
<p>Volley: Easy, Fast Networking for Android</p>
diff --git a/docs/html/training/volley/requestqueue.jd b/docs/html/training/volley/requestqueue.jd
index 43b1e3f..f8c61aa 100644
--- a/docs/html/training/volley/requestqueue.jd
+++ b/docs/html/training/volley/requestqueue.jd
@@ -17,7 +17,7 @@
</div>
</div>
-<a class="notice-developers-video wide" href="https://developers.google.com/events/io/sessions/325304728">
+<a class="notice-developers-video wide" href="https://www.youtube.com/watch?v=yhv8l9F44qo">
<div>
<h3>Video</h3>
<p>Volley: Easy, Fast Networking for Android</p>
diff --git a/docs/html/training/volley/simple.jd b/docs/html/training/volley/simple.jd
index 4733958..ab61b9b 100644
--- a/docs/html/training/volley/simple.jd
+++ b/docs/html/training/volley/simple.jd
@@ -19,7 +19,7 @@
</div>
</div>
-<a class="notice-developers-video wide" href="https://developers.google.com/events/io/sessions/325304728">
+<a class="notice-developers-video wide" href="https://www.youtube.com/watch?v=yhv8l9F44qo">
<div>
<h3>Video</h3>
<p>Volley: Easy, Fast Networking for Android</p>
diff --git a/rs/java/android/renderscript/AllocationAdapter.java b/rs/java/android/renderscript/AllocationAdapter.java
index 9bfd6ec..6d7e97e 100644
--- a/rs/java/android/renderscript/AllocationAdapter.java
+++ b/rs/java/android/renderscript/AllocationAdapter.java
@@ -244,23 +244,23 @@
/**
*
*
- * Create an arbitrary window into the base allocation
+ * Create an arbitrary window into the base allocation.
* The type describes the shape of the window.
*
* Any dimensions present in the type must be equal or smaller
* to the dimensions in the source allocation. A dimension
* present in the allocation that is not present in the type
- * will be constrained away with the selectors
+ * will be constrained away with the selectors.
*
- * If a dimension is present in the type and allcation one of
- * two things will happen
+ * If a dimension is present in both the type and allocation, one of
+ * two things will happen.
*
- * If the type is smaller than the allocation a window will be
+ * If the type is smaller than the allocation, a window will be
* created, the selected value in the adapter for that dimension
- * will act as the base address and the type will describe the
+ * will act as the base address, and the type will describe the
* size of the view starting at that point.
*
- * If the type and allocation dimension are of the same size
+ * If the type and allocation dimension are of the same size,
* then setting the selector for the dimension will be an error.
*/
static public AllocationAdapter createTyped(RenderScript rs, Allocation a, Type t) {