Massive clobber of all HTML files in developer docs for new site design
Change-Id: Idc55a0b368c1d2c1e7d4999601b739dd57f08eb3
diff --git a/docs/html/training/advanced.jd b/docs/html/training/advanced.jd
new file mode 100644
index 0000000..7f9ddd4
--- /dev/null
+++ b/docs/html/training/advanced.jd
@@ -0,0 +1,11 @@
+page.title=Advanced Training
+
+@jd:body
+
+<p>Advanced Training contains a variety of classes that teach you best practices in Android
+development. These classes simplify the steps required to enhance your app with powerful
+platform features or effectively optimize your app performance.</p>
+
+<p>What you see now is still the beginning. We plan to add many more classes, expand and refine
+existing classes, re-organize, and build courses that help you enhance your apps using
+objective-oriented collections of classes.</p>
\ No newline at end of file
diff --git a/docs/html/training/backward-compatible-ui/index.jd b/docs/html/training/backward-compatible-ui/index.jd
index 7e27e68..f81b5a7 100644
--- a/docs/html/training/backward-compatible-ui/index.jd
+++ b/docs/html/training/backward-compatible-ui/index.jd
@@ -14,7 +14,7 @@
<ul>
<li>API level 5</li>
- <li><a href="{@docRoot}sdk/compatibility-library.html">The Android Support Package</a></li>
+ <li><a href="{@docRoot}tools/extras/support-library.html">The Android Support Package</a></li>
</ul>
<h2>You should also read</h2>
diff --git a/docs/html/training/basics/activity-lifecycle/index.jd b/docs/html/training/basics/activity-lifecycle/index.jd
index d278f04..127c1c2 100644
--- a/docs/html/training/basics/activity-lifecycle/index.jd
+++ b/docs/html/training/basics/activity-lifecycle/index.jd
@@ -21,7 +21,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a></li>
+ <li><a href="{@docRoot}guide/components/activities.html">Activities</a></li>
</ul>
diff --git a/docs/html/training/basics/activity-lifecycle/pausing.jd b/docs/html/training/basics/activity-lifecycle/pausing.jd
index 216d55e1..fa88beb 100644
--- a/docs/html/training/basics/activity-lifecycle/pausing.jd
+++ b/docs/html/training/basics/activity-lifecycle/pausing.jd
@@ -21,7 +21,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>
+ <li><a href="{@docRoot}guide/components/activities.html">Activities</a>
</li>
</ul>
diff --git a/docs/html/training/basics/activity-lifecycle/recreating.jd b/docs/html/training/basics/activity-lifecycle/recreating.jd
index 941f1fd11..005a95b 100644
--- a/docs/html/training/basics/activity-lifecycle/recreating.jd
+++ b/docs/html/training/basics/activity-lifecycle/recreating.jd
@@ -23,7 +23,7 @@
Different Screens</a></li>
<li><a
href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a></li>
- <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>
+ <li><a href="{@docRoot}guide/components/activities.html">Activities</a>
</li>
</ul>
diff --git a/docs/html/training/basics/activity-lifecycle/starting.jd b/docs/html/training/basics/activity-lifecycle/starting.jd
index 1d328c7..c32968b 100644
--- a/docs/html/training/basics/activity-lifecycle/starting.jd
+++ b/docs/html/training/basics/activity-lifecycle/starting.jd
@@ -22,7 +22,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a></li>
+ <li><a href="{@docRoot}guide/components/activities.html">Activities</a></li>
</ul>
<h2>Try it out</h2>
diff --git a/docs/html/training/basics/activity-lifecycle/stopping.jd b/docs/html/training/basics/activity-lifecycle/stopping.jd
index 7dfc6d3..d56c921 100644
--- a/docs/html/training/basics/activity-lifecycle/stopping.jd
+++ b/docs/html/training/basics/activity-lifecycle/stopping.jd
@@ -21,7 +21,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>
+ <li><a href="{@docRoot}guide/components/activities.html">Activities</a>
</li>
</ul>
@@ -37,7 +37,7 @@
</div>
<p>Properly stopping and restarting your activity is an important process in the activity lifecycle
-that ensures your users perceive that your app is always alive and doesn't loose their progress.
+that ensures your users perceive that your app is always alive and doesn't lose their progress.
There are a few of key scenarios in which your activity is stopped and restarted:</p>
<ul>
diff --git a/docs/html/training/basics/firstapp/building-ui.jd b/docs/html/training/basics/firstapp/building-ui.jd
index dae70a2..df8089f 100644
--- a/docs/html/training/basics/firstapp/building-ui.jd
+++ b/docs/html/training/basics/firstapp/building-ui.jd
@@ -19,7 +19,7 @@
<ol>
<li><a href="#LinearLayout">Use a Linear Layout</a></li>
- <li><a href="#TextInput">Add a Text Input Box</a></li>
+ <li><a href="#TextInput">Add a Text Field</a></li>
<li><a href="#Strings">Add String Resources</a></li>
<li><a href="#Button">Add a Button</a></li>
<li><a href="#Weight">Make the Input Box Fill in the Screen Width</a></li>
@@ -61,7 +61,7 @@
</div>
</div>
-<img src="{@docRoot}images/viewgroup.png" alt="" />
+<img src="{@docRoot}images/viewgroup.png" alt="" width="440" />
<p class="img-caption"><strong>Figure 1.</strong> Illustration of how {@link
android.view.ViewGroup} objects form branches in the layout and contain {@link
android.view.View} objects.</p>
@@ -130,12 +130,12 @@
-<h2 id="TextInput">Add a Text Input Box</h2>
+<h2 id="TextInput">Add a Text Field</h2>
-<p>To create a user-editable text box, add an {@link android.widget.EditText
+<p>To create a user-editable text field, add an {@link android.widget.EditText
<EditText>} element inside the {@link android.widget.LinearLayout <LinearLayout>}. The {@link
android.widget.EditText} class is a subclass of {@link android.view.View} that displays an editable
-text box.</p>
+text field.</p>
<p>Like every {@link android.view.View} object, you must define certain XML attributes to specify
the {@link android.widget.EditText} object's properties. Here’s how you should declare it
@@ -185,7 +185,8 @@
compiled, the SDK tools use the ID value, <code>edit_message</code>, to create a new identifier in
your project's {@code gen/R.java} file that is now assiciated with the {@link
android.widget.EditText} element. Once the resource ID is created, other references to the ID do not
-need the plus symbol. See the sidebox for more information about resource objects.</p></dd>
+need the plus symbol. This is the only attribute that may need the plus-symbol. See the sidebox for
+more information about resource objects.</p></dd>
<dt><a
href="{@docRoot}reference/android/view/View.html#attr_android:layout_width">{@code
@@ -202,12 +203,12 @@
<dt><a
href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">{@code
android:hint}</a></dt>
-<dd>This is a default string to display when the text box is empty. Instead of using a hard-coded
-string as the value, the value given in this example refers to a string resource. When you add the
-{@code
-"@string/edit_message"} value, you’ll see a compiler error because there’s no matching string
-resource by that name. You'll fix this in the next section by defining the string
-resource.</dd>
+<dd>This is a default string to display when the text field is empty. Instead of using a hard-coded
+string as the value, the {@code "@string/edit_message"} value refers to a string resource defined
+in a separate file. Because this value refers to an existing resource, it does not need the
+plus-symbol. However, because you haven't defined the string resource yet, you’ll see a compiler
+error when you add the {@code "@string/edit_message"} value. You'll fix this in the next section by
+defining the string resource.</dd>
</dl>
@@ -276,9 +277,9 @@
android.widget.Button} widgets have their widths set to
<code>"wrap_content"</code>.</p>
-<p>This works fine for the button, but not as well for the text box, because the user might type
+<p>This works fine for the button, but not as well for the text field, because the user might type
something longer and there's extra space left on the screen. So, it'd be nice to fill that width
-using the text box.
+using the text field.
{@link android.widget.LinearLayout} enables such a design with the <em>weight</em> property, which
you can specify using the <a
href="{@docRoot}reference/android/widget/LinearLayout.LayoutParams.html#weight">{@code
diff --git a/docs/html/training/basics/firstapp/creating-project.jd b/docs/html/training/basics/firstapp/creating-project.jd
index 5a89f2e..4fbfe34 100644
--- a/docs/html/training/basics/firstapp/creating-project.jd
+++ b/docs/html/training/basics/firstapp/creating-project.jd
@@ -23,9 +23,9 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}sdk/installing.html">Installing the
+ <li><a href="{@docRoot}sdk/installing/index.html">Installing the
SDK</a></li>
- <li><a href="{@docRoot}guide/developing/projects/index.html">Managing Projects</a></li>
+ <li><a href="{@docRoot}tools/projects/index.html">Managing Projects</a></li>
</ul>
@@ -42,8 +42,8 @@
<p class="note"><strong>Note:</strong> You should already have the Android SDK installed, and if
you're using Eclipse, you should have installed the <a
-href="{@docRoot}sdk/eclipse-adt.html">ADT plugin</a> as well. If you have not installed
-these, see <a href="{@docRoot}sdk/installing.html">Installing the Android SDK</a> and return here
+href="{@docRoot}tools/sdk/eclipse-adt.html">ADT plugin</a> as well. If you have not installed
+these, see <a href="{@docRoot}sdk/installing/index.html">Installing the Android SDK</a> and return here
when you've completed the installation.</p>
@@ -59,7 +59,7 @@
The resulting dialog should have a folder labeled <em>Android</em>. (If you don’t see the
<em>Android</em> folder,
then you have not installed the ADT plugin—see <a
-href="{@docRoot}sdk/eclipse-adt.html#installing">Installing the ADT Plugin</a>).</li>
+href="{@docRoot}tools/sdk/eclipse-adt.html#installing">Installing the ADT Plugin</a>).</li>
<li>Open the <em>Android</em> folder, select <em>Android Project</em> and click
<strong>Next</strong>.</li>
<li>Enter a project name (such as "MyFirstApp") and click <strong>Next</strong>.</li>
@@ -68,7 +68,7 @@
support older versions, but setting the build target to the latest version allows you to
easily optimize your app for a great user experience on the latest Android-powered devices.</p>
<p>If you don't see any built targets listed, you need to install some using the Android SDK
-Manager tool. See <a href="{@docRoot}sdk/installing.html#AddingComponents">step 4 in the
+Manager tool. See <a href="{@docRoot}sdk/installing/index.html#AddingComponents">step 4 in the
installing guide</a>.</p>
<p>Click <strong>Next</strong>.</p></li>
<li>Specify other app details, such as the:
@@ -87,7 +87,7 @@
<li><em>Minimum SDK</em>: Select <em>4 (Android 1.6)</em>.
<p>Because this version is lower than the build target selected for the app, a warning
appears, but that's alright. You simply need to be sure that you don't use any APIs that require an
-<a href="{@docRoot}guide/appendix/api-levels.html">API level</a> greater than the minimum SDK
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API level</a> greater than the minimum SDK
version without first using some code to verify the device's system version (you'll see this in some
other classes).</p>
</li>
@@ -117,7 +117,7 @@
your app for the latest devices.</p>
<p>If you don't see any targets listed, you need to
install some using the Android SDK
-Manager tool. See <a href="{@docRoot}sdk/installing.html#AddingComponents">step 4 in the
+Manager tool. See <a href="{@docRoot}sdk/installing/index.html#AddingComponents">step 4 in the
installing guide</a>.</p></li>
<li>Execute:
<pre class="no-pretty-print">
diff --git a/docs/html/training/basics/firstapp/index.jd b/docs/html/training/basics/firstapp/index.jd
index 9ff5b18..43b289b 100644
--- a/docs/html/training/basics/firstapp/index.jd
+++ b/docs/html/training/basics/firstapp/index.jd
@@ -35,7 +35,7 @@
<li>Download the latest SDK tools and platforms using the SDK Manager.</li>
</ol>
-<p>If you haven't already done this setup, read <a href="{@docRoot}sdk/installing.html">Installing
+<p>If you haven't already done this setup, read <a href="{@docRoot}sdk/installing/index.html">Installing
the SDK</a>. Once you've finished the setup, you're ready to begin this class.</p>
<p>This class uses a tutorial format that incrementally builds a small Android app in order to teach
diff --git a/docs/html/training/basics/firstapp/running-app.jd b/docs/html/training/basics/firstapp/running-app.jd
index 43b8983..5105a3b 100644
--- a/docs/html/training/basics/firstapp/running-app.jd
+++ b/docs/html/training/basics/firstapp/running-app.jd
@@ -25,9 +25,9 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/developing/device.html">Using Hardware Devices</a></li>
- <li><a href="{@docRoot}guide/developing/devices/index.html">Managing Virtual Devices</a></li>
- <li><a href="{@docRoot}guide/developing/projects/index.html">Managing Projects</a></li>
+ <li><a href="{@docRoot}tools/device.html">Using Hardware Devices</a></li>
+ <li><a href="{@docRoot}tools/devices/index.html">Managing Virtual Devices</a></li>
+ <li><a href="{@docRoot}tools/projects/index.html">Managing Projects</a></li>
</ul>
@@ -85,7 +85,7 @@
<ol>
<li>Plug in your Android-powered device to your machine with a USB cable.
If you’re developing on Windows, you might need to install the appropriate USB driver for your
-device. For help installing drivers, see the <a href=”{@docRoot}sdk/oem-usb.html”>OEM USB
+device. For help installing drivers, see the <a href="{@docRoot}tools/extras/oem-usb.html">OEM USB
Drivers</a> document.</li>
<li>Ensure that <strong>USB debugging</strong> is enabled in the device Settings (open Settings
and navitage to <strong>Applications > Development</strong> on most devices, or select
@@ -116,7 +116,7 @@
<h2 id="Emulator">Run on the Emulator</h2>
<p>Whether you’re using Eclipse or the command line, you need to first create an <a
-href="{@docRoot}guide/developing/devices/index.html">Android Virtual
+href="{@docRoot}tools/devices/index.html">Android Virtual
Device</a> (AVD). An AVD is a
device configuration for the Android emulator that allows you to model
different device configurations.</p>
diff --git a/docs/html/training/basics/firstapp/starting-activity.jd b/docs/html/training/basics/firstapp/starting-activity.jd
index c548c1d..a8d32b6 100644
--- a/docs/html/training/basics/firstapp/starting-activity.jd
+++ b/docs/html/training/basics/firstapp/starting-activity.jd
@@ -31,7 +31,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}sdk/installing.html">Installing the
+ <li><a href="{@docRoot}sdk/installing/index.html">Installing the
SDK</a></li>
</ul>
@@ -42,7 +42,7 @@
<p>After completing the <a href="building-ui.html">previous lesson</a>, you have an app that
-shows an activity (a single screen) with a text box and a button. In this lesson, you’ll add some
+shows an activity (a single screen) with a text field and a button. In this lesson, you’ll add some
code to <code>MyFirstActivity</code> that
starts a new activity when the user selects the Send button.</p>
@@ -90,7 +90,7 @@
android.view.View} that was clicked)</li>
</ul>
-<p>Next, you’ll fill in this method to read the contents of the text box and deliver that text to
+<p>Next, you’ll fill in this method to read the contents of the text field and deliver that text to
another activity.</p>
@@ -290,8 +290,8 @@
}
</pre>
-<p>You can now run the app, type a message in the text box, press Send, and view the message on the
-second activity.</p>
+<p>You can now run the app, type a message in the text field, press Send, and view the message on
+the second activity.</p>
<img src="{@docRoot}images/training/firstapp/firstapp.png" />
<p class="img-caption"><strong>Figure 1.</strong> Both activities in the final app, running
diff --git a/docs/html/training/basics/fragments/communicating.jd b/docs/html/training/basics/fragments/communicating.jd
index e3e308f..3ac9873 100644
--- a/docs/html/training/basics/fragments/communicating.jd
+++ b/docs/html/training/basics/fragments/communicating.jd
@@ -19,7 +19,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a></li>
+ <li><a href="{@docRoot}guide/components/fragments.html">Fragments</a></li>
</ul>
<h2>Try it out</h2>
diff --git a/docs/html/training/basics/fragments/creating.jd b/docs/html/training/basics/fragments/creating.jd
index c4a9b46..0646230 100644
--- a/docs/html/training/basics/fragments/creating.jd
+++ b/docs/html/training/basics/fragments/creating.jd
@@ -21,7 +21,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a></li>
+ <li><a href="{@docRoot}guide/components/fragments.html">Fragments</a></li>
</ul>
<h2>Try it out</h2>
@@ -84,7 +84,7 @@
to {@link android.support.v4.app.Fragment#onPause()}.</p>
<p>More information about the fragment lifecycle and callback methods is available in the <a
-href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+href="{@docRoot}guide/components/fragments.html">Fragments</a> developer guide.</p>
diff --git a/docs/html/training/basics/fragments/fragment-ui.jd b/docs/html/training/basics/fragments/fragment-ui.jd
index f906f46..4ec4de5 100644
--- a/docs/html/training/basics/fragments/fragment-ui.jd
+++ b/docs/html/training/basics/fragments/fragment-ui.jd
@@ -20,7 +20,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a></li>
+ <li><a href="{@docRoot}guide/components/fragments.html">Fragments</a></li>
<li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">Supporting Tablets and
Handsets</a></li>
</ul>
diff --git a/docs/html/training/basics/fragments/index.jd b/docs/html/training/basics/fragments/index.jd
index dcdcd31..bc93f43 100644
--- a/docs/html/training/basics/fragments/index.jd
+++ b/docs/html/training/basics/fragments/index.jd
@@ -23,7 +23,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a></li>
+ <li><a href="{@docRoot}guide/components/fragments.html">Fragments</a></li>
<li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">Supporting Tablets and
Handsets</a></li>
</ul>
diff --git a/docs/html/training/basics/fragments/support-lib.jd b/docs/html/training/basics/fragments/support-lib.jd
index e2166f5..ba10b78 100644
--- a/docs/html/training/basics/fragments/support-lib.jd
+++ b/docs/html/training/basics/fragments/support-lib.jd
@@ -17,12 +17,12 @@
</ol>
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}sdk/compatibility-library.html">Support Library</a></li>
+ <li><a href="{@docRoot}tools/extras/support-library.html">Support Library</a></li>
</ul>
</div>
</div>
-<p>The Android <a href="{@docRoot}sdk/compatibility-library.html">Support Library</a> provides a JAR
+<p>The Android <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> provides a JAR
file with an API library that allow you to use some of the more recent Android APIs in your app
while running on earlier versions of Android. For instance, the Support Library provides a version
of the {@link android.app.Fragment} APIs that you can use on Android 1.6 (API level 4) and
diff --git a/docs/html/training/basics/intents/index.jd b/docs/html/training/basics/intents/index.jd
index c661d98..d94ff015 100644
--- a/docs/html/training/basics/intents/index.jd
+++ b/docs/html/training/basics/intents/index.jd
@@ -24,7 +24,7 @@
<li><a
href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html">
Integrating Application with Intents (blog post)</a></li>
- <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent
Filters</a></li>
</ul>
@@ -32,7 +32,7 @@
</div>
<p>An Android app typically has several <a
-href="{@docRoot}guide/topics/fundamentals/activities.html">activities</a>. Each activity displays a
+href="{@docRoot}guide/components/activities.html">activities</a>. Each activity displays a
user interface that allows the user to perform a specific task (such as view a map or take a photo).
To take the user from one activity to another, your app must use an {@link
android.content.Intent} to define your app's "intent" to do something. When you pass an
diff --git a/docs/html/training/basics/intents/sending.jd b/docs/html/training/basics/intents/sending.jd
index bfd8f9b..f2a2cc3 100644
--- a/docs/html/training/basics/intents/sending.jd
+++ b/docs/html/training/basics/intents/sending.jd
@@ -166,7 +166,7 @@
starts in case you need to disable the feature that uses the intent before the user attempts to use
it. If you know of a specific app that can handle the intent, you can also provide a link for the
user to download the app (see how to <a
-href="{@docRoot}guide/publishing/publishing.html#marketintent">link to an app on Google
+href="{@docRoot}distribute/googleplay/promote/linking.html">link to your product on Google
Play</a>).</p>
diff --git a/docs/html/training/basics/network-ops/connecting.jd b/docs/html/training/basics/network-ops/connecting.jd
new file mode 100644
index 0000000..f70cf58
--- /dev/null
+++ b/docs/html/training/basics/network-ops/connecting.jd
@@ -0,0 +1,284 @@
+page.title=Connecting to the Network
+parent.title=Performing Network Operations
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Managing Network Usage
+next.link=managing.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#http-client">Choose an HTTP Client</a></li>
+ <li><a href="#connection">Check the Network Connection</a></li>
+ <li><a href="#AsyncTask">Perform Network Operations on a Separate Thread</a></li>
+ <li><a href="#download">Connect and Download Data</a></li>
+ <li><a href="#stream">Convert the InputStream to a String</a></li>
+
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}training/monitoring-device-state/index.html">Optimizing Battery Life</a></li>
+ <li><a href="{@docRoot}training/efficient-downloads/index.html">Transferring Data Without Draining the Battery</a></li>
+ <li><a href="{@docRoot}guide/webapps/index.html">Web Apps Overview</a></li>
+ <li><a href="{@docRoot}guide/components/fundamentals.html">Application Fundamentals</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>This lesson shows you how to implement a simple application that connects to
+the network. It explains some of the best practices you should follow in
+creating even the simplest network-connected app.</p>
+
+<p>Note that to perform the network operations described in this lesson, your
+application manifest must include the following permissions:</p>
+
+<pre><uses-permission android:name="android.permission.INTERNET" />
+<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /></pre>
+
+
+
+<h2 id="http-client">Choose an HTTP Client</h2>
+
+<p>Most network-connected Android apps use HTTP to send and receive data.
+Android includes two HTTP clients: {@link java.net.HttpURLConnection} and Apache
+ {@link org.apache.http.client.HttpClient}. Both support HTTPS, streaming uploads and downloads, configurable
+timeouts, IPv6, and connection pooling. We recommend using {@link
+java.net.HttpURLConnection} for applications targeted at Gingerbread and higher. For
+more discussion of this topic, see the blog post <a
+href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html"
+>Android's HTTP Clients</a>.</p>
+
+<h2 id="connection">Check the Network Connection</h2>
+
+<p>Before your app attempts to connect to the network, it should check to see whether a
+network connection is available using
+{@link android.net.ConnectivityManager#getActiveNetworkInfo getActiveNetworkInfo()}
+and {@link android.net.NetworkInfo#isConnected isConnected()}.
+Remember, the device may be out of range of a
+network, or the user may have disabled both Wi-Fi and mobile data access.
+For more discussion of this topic, see the lesson <a
+href="{@docRoot}training/network-ops/managing.html">Managing Network
+Usage</a>.</p>
+
+<pre>
+public void myClickHandler(View view) {
+ ...
+ ConnectivityManager connMgr = (ConnectivityManager)
+ getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
+ if (networkInfo != null && networkInfo.isConnected()) {
+ // fetch data
+ } else {
+ // display error
+ }
+ ...
+}</pre>
+
+<h2 id="AsyncTask">Perform Network Operations on a Separate Thread</h2>
+
+<p>Network operations can involve unpredictable delays. To prevent this from
+causing a poor user experience, always perform network operations on a separate
+thread from the UI. The {@link android.os.AsyncTask} class provides one of the
+simplest ways to fire off a new task from the UI thread. For more discussion of
+this topic, see the blog post <a
+href="http://android-developers.blogspot.com/2010/07/multithreading-for-
+performance.html">Multithreading For Performance</a>.</p>
+
+
+<p>In the following snippet, the <code>myClickHandler()</code> method invokes <code>new
+DownloadWebpageTask().execute(stringUrl)</code>. The
+<code>DownloadWebpageTask</code> class is a subclass of {@link
+android.os.AsyncTask}. <code>DownloadWebpageTask</code> implements the following
+{@link android.os.AsyncTask} methods:</p>
+
+ <ul>
+
+ <li>{@link android.os.AsyncTask#doInBackground doInBackground()} executes
+the method <code>downloadUrl()</code>. It passes the web page URL as a
+parameter. The method <code>downloadUrl()</code> fetches and processes the web
+page content. When it finishes, it passes back a result string.</li>
+
+ <li>{@link android.os.AsyncTask#onPostExecute onPostExecute()} takes the
+returned string and displays it in the UI.</li>
+
+
+ </ul>
+
+<pre>
+public class HttpExampleActivity extends Activity {
+ private static final String DEBUG_TAG = "HttpExample";
+ private EditText urlText;
+ private TextView textView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ urlText = (EditText) findViewById(R.id.myUrl);
+ textView = (TextView) findViewById(R.id.myText);
+ }
+
+ // When user clicks button, calls AsyncTask.
+ // Before attempting to fetch the URL, makes sure that there is a network connection.
+ public void myClickHandler(View view) {
+ // Gets the URL from the UI's text field.
+ String stringUrl = urlText.getText().toString();
+ ConnectivityManager connMgr = (ConnectivityManager)
+ getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
+ if (networkInfo != null && networkInfo.isConnected()) {
+ new DownloadWebpageText().execute(stringUrl);
+ } else {
+ textView.setText("No network connection available.");
+ }
+ }
+
+ // Uses AsyncTask to create a task away from the main UI thread. This task takes a
+ // URL string and uses it to create an HttpUrlConnection. Once the connection
+ // has been established, the AsyncTask downloads the contents of the webpage as
+ // an InputStream. Finally, the InputStream is converted into a string, which is
+ // displayed in the UI by the AsyncTask's onPostExecute method.
+ private class DownloadWebpageText extends AsyncTask<String, Void, String> {
+ @Override
+ protected String doInBackground(String... urls) {
+
+ // params comes from the execute() call: params[0] is the url.
+ try {
+ return downloadUrl(urls[0]);
+ } catch (IOException e) {
+ return "Unable to retrieve web page. URL may be invalid.";
+ }
+ }
+ // onPostExecute displays the results of the AsyncTask.
+ @Override
+ protected void onPostExecute(String result) {
+ textView.setText(result);
+ }
+ }
+ ...
+}</pre>
+
+<p>The sequence of events in this snippet is as follows:</p>
+<ol>
+
+ <li>When users click the button that invokes {@code myClickHandler()},
+ the app passes
+the specified URL to the {@link android.os.AsyncTask} subclass
+<code>DownloadWebpageTask</code>.</li>
+
+ <li>The {@link android.os.AsyncTask} method {@link
+android.os.AsyncTask#doInBackground doInBackground()} calls the
+<code>downloadUrl()</code> method. </li>
+
+ <li>The <code>downloadUrl()</code> method takes a URL string as a parameter
+and uses it to create a {@link java.net.URL} object.</li>
+
+ <li>The {@link java.net.URL} object is used to establish an {@link
+java.net.HttpURLConnection}.</li>
+
+ <li>Once the connection has been established, the {@link
+java.net.HttpURLConnection} object fetches the web page content as an {@link
+java.io.InputStream}.</li>
+
+ <li>The {@link java.io.InputStream} is passed to the <code>readIt()</code>
+method, which converts the stream to a string.</li>
+
+ <li>Finally, the {@link android.os.AsyncTask}'s {@link
+android.os.AsyncTask#onPostExecute onPostExecute()} method displays the string
+in the main activity's UI.</li>
+
+</ol>
+
+ <h2 id="download">Connect and Download Data</h2>
+
+ <p>In your thread that performs your network transactions, you can use
+ {@link java.net.HttpURLConnection} to perform a {@code GET} and download your data.
+ After you call {@code connect()}, you can get an {@link java.io.InputStream} of the data
+ by calling {@code getInputStream()}.
+
+ <p>In the following snippet, the {@link android.os.AsyncTask#doInBackground
+doInBackground()} method calls the method <code>downloadUrl()</code>. The
+<code>downloadUrl()</code> method takes the given URL and uses it to connect to
+the network via {@link java.net.HttpURLConnection}. Once a connection has been
+established, the app uses the method <code>getInputStream()</code> to retrieve
+the data as an {@link java.io.InputStream}.</p>
+
+<pre>
+// Given a URL, establishes an HttpUrlConnection and retrieves
+// the web page content as a InputStream, which it returns as
+// a string.
+private String downloadUrl(String myurl) throws IOException {
+ InputStream is = null;
+ // Only display the first 500 characters of the retrieved
+ // web page content.
+ int len = 500;
+
+ try {
+ URL url = new URL(myurl);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setReadTimeout(10000 /* milliseconds */);
+ conn.setConnectTimeout(15000 /* milliseconds */);
+ conn.setRequestMethod("GET");
+ conn.setDoInput(true);
+ // Starts the query
+ conn.connect();
+ int response = conn.getResponseCode();
+ Log.d(DEBUG_TAG, "The response is: " + response);
+ is = conn.getInputStream();
+
+ // Convert the InputStream into a string
+ String contentAsString = readIt(is, len);
+ return contentAsString;
+
+ // Makes sure that the InputStream is closed after the app is
+ // finished using it.
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+}</pre>
+
+<p>Note that the method <code>getResponseCode()</code> returns the connection's
+<a href="http://www.w3.org/Protocols/HTTP/HTRESP.html">status code</a>. This is
+a useful way of getting additional information about the connection. A status
+code of 200 indicates success.</p>
+
+<h2 id="stream">Convert the InputStream to a String</h2>
+
+<p>An {@link java.io.InputStream} is a readable source of bytes. Once you get an {@link java.io.InputStream},
+it's common to decode or convert it into a
+target data type. For example, if you were downloading image data, you might
+decode and display it like this:</p>
+
+<pre>InputStream is = null;
+...
+Bitmap bitmap = BitmapFactory.decodeStream(is);
+ImageView imageView = (ImageView) findViewById(R.id.image_view);
+imageView.setImageBitmap(bitmap);
+</pre>
+
+<p>In the example shown above, the {@link java.io.InputStream} represents the text of a
+web page. This is how the example converts the {@link java.io.InputStream} to
+a string so that the activity can display it in the UI:</p>
+
+<pre>// Reads an InputStream and converts it to a String.
+public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
+ Reader reader = null;
+ reader = new InputStreamReader(stream, "UTF-8");
+ char[] buffer = new char[len];
+ reader.read(buffer);
+ return new String(buffer);
+}</pre>
+
+
+
diff --git a/docs/html/training/basics/network-ops/index.jd b/docs/html/training/basics/network-ops/index.jd
new file mode 100644
index 0000000..b213c03
--- /dev/null
+++ b/docs/html/training/basics/network-ops/index.jd
@@ -0,0 +1,73 @@
+page.title=Performing Network Operations
+
+trainingnavtop=true
+startpage=true
+next.title=Connecting to the Network
+next.link=connecting.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+<h2>Dependencies and prerequisites</h2>
+<ul>
+ <li>Android 1.6 (API level 4) or higher</li>
+ <li>A device that is able to connect to mobile and Wi-Fi networks</li>
+</ul>
+
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}training/monitoring-device-state/index.html">Optimizing Battery Life</a></li>
+ <li><a href="{@docRoot}training/efficient-downloads/index.html">Transferring Data Without Draining the Battery</a></li>
+ <li><a href="{@docRoot}guide/webapps/index.html">Web Apps Overview</a></li>
+</ul>
+
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/NetworkUsage.zip"
+class="button">Download the sample</a>
+ <p class="filename">NetworkUsage.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>This class explains the basic tasks involved in connecting to the network,
+monitoring the network connection (including connection changes), and giving
+users control over an app's network usage. It also describes how to parse and
+consume XML data.</p>
+
+<p>This class includes a sample application that illustrates how to perform
+common network operations. You can download the sample (to the right) and use it
+as a source of reusable code for your own application.</p>
+
+<p>By going through these lessons, you'll have the
+fundamental building blocks for creating Android applications that download
+content and parse data efficiently, while minimizing network traffic.</p>
+
+
+
+<h2>Lessons</h2>
+
+<dl>
+ <dt><b><a href="connecting.html">Connecting to the Network</a></b></dt>
+
+ <dd>Learn how to connect to the network, choose an HTTP client, and perform
+network operations outside of the UI thread.</dd>
+
+ <dt><b><a href="managing.html">Managing Network Usage</a></b></dt>
+
+ <dd>Learn how to check a
+device's network connection, create a preferences UI for controlling network
+usage, and respond to connection changes.</dd>
+
+ <dt><b><a href="xml.html">Parsing XML Data</a></b></dt>
+ <dd>Learn how to parse and consume XML data.</dd>
+
+</dl>
+
diff --git a/docs/html/training/basics/network-ops/managing.jd b/docs/html/training/basics/network-ops/managing.jd
new file mode 100644
index 0000000..33cb195
--- /dev/null
+++ b/docs/html/training/basics/network-ops/managing.jd
@@ -0,0 +1,445 @@
+page.title=Managing Network Usage
+parent.title=Performing Network Operations
+parent.link=index.html
+
+trainingnavtop=true
+
+previous.title=Connecting to the Network
+previous.link=connecting.html
+next.title=Parsing XML Data
+next.link=xml.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#check-connection">Check a Device's Network Connection</a></li>
+ <li><a href="#manage-usage">Manage Network Usage</a></li>
+ <li><a href="#prefs">Implement a Preferences Activity</a></li>
+ <li><a href="#pref-change">Respond to Preference Changes</a></li>
+ <li><a href="#detect-changes">Detect Connection Changes</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}training/monitoring-device-state/index.html">Optimizing Battery Life</a></li>
+ <li><a href="{@docRoot}training/efficient-downloads/index.html">Transferring Data Without Draining the Battery</a></li>
+ <li><a href="{@docRoot}guide/webapps/index.html">Web Apps Overview</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/NetworkUsage.zip"
+class="button">Download the sample</a>
+ <p class="filename">NetworkUsage.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>This lesson describes how to write applications that have fine-grained
+control over their usage of network resources. If your application performs a
+lot of network operations, you should provide user settings that allow users
+to control your app’s data habits, such as how often your app syncs data,
+whether to perform uploads/downloads only when on Wi-Fi, whether to use data
+while roaming, and so on. With these controls available to them, users are much
+less likely to disable your app’s access to background data when they approach their
+limits, because they can instead precisely control how much data your app
+uses.</p>
+
+<p>For general guidelines on how to write apps that minimize the battery life
+impact of downloads and network connections, see
+<a href="{@docRoot}training/monitoring-device-state/index.html">Optimizing Battery Life</a>
+and <a href="{@docRoot}training/efficient-downloads/index.html">Transferring Data Without Draining the Battery</a>.
+
+<h2 id="check-connection">Check a Device's Network Connection</h2>
+
+<p>A device can have various types of network connections. This lesson
+focuses on using either a Wi-Fi or a mobile network connection. For the full
+list of possible network types, see {@link android.net.ConnectivityManager}.<p>
+
+<p>Wi-Fi is typically faster. Also, mobile data is often metered, which can get
+expensive.
+A common strategy for apps is to only fetch large data
+if a Wi-Fi network is available.</p>
+
+<p>Before you perform network operations, it's good practice to check the state of
+network connectivity. Among other things, this could prevent your app from inadvertently using
+the wrong radio. If a network connection is unavailable, your application
+should respond gracefully. To check the network connection, you typically use
+the following classes:</p>
+
+<ul>
+
+ <li>{@link android.net.ConnectivityManager}: Answers queries about the state
+of network connectivity. It also notifies applications when network
+connectivity changes. </li>
+
+ <li>{@link android.net.NetworkInfo}: Describes the status of a network
+interface of a given type (currently either Mobile or Wi-Fi).
+ </li>
+
+</ul>
+
+
+
+<p>This code snippet tests network connectivity for Wi-Fi and mobile. It
+determines whether these network interfaces are available (that is, whether
+network connectivity is possible) and/or connected (that is, whether network
+connectivity exists and if it is possible to establish sockets and pass
+data): </p>
+
+<pre>
+private static final String DEBUG_TAG = "NetworkStatusExample";
+...
+ConnectivityManager connMgr = (ConnectivityManager)
+ getSystemService(Context.CONNECTIVITY_SERVICE);
+NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+boolean isWifiConn = networkInfo.isConnected();
+networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+boolean isMobileConn = networkInfo.isConnected();
+Log.d(DEBUG_TAG, "Wifi connected: " + isWifiConn);
+Log.d(DEBUG_TAG, "Mobile connected: " + isMobileConn);
+</pre>
+
+<p>Note that you should not base decisions on whether a network is
+"available." You should always check {@link
+android.net.NetworkInfo#isConnected isConnected()} before performing network
+operations, since {@link android.net.NetworkInfo#isConnected isConnected()}
+handles cases like flaky mobile networks, airplane mode, and restricted
+background data.</p>
+
+<p>A more concise way of checking whether a network interface is available is as
+follows. The method {@link
+android.net.ConnectivityManager#getActiveNetworkInfo() getActiveNetworkInfo()}
+returns a {@link android.net.NetworkInfo} instance representing the first
+connected network interface it can find, or <code>null</code> if none if the
+interfaces is connected (meaning that an
+internet connection is not available):</p>
+
+<pre>
+public boolean isOnline() {
+ ConnectivityManager connMgr = (ConnectivityManager)
+ getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
+ return (networkInfo != null && networkInfo.isConnected());
+} </pre>
+
+<p>To query more fine-grained state you can use {@link
+android.net.NetworkInfo.DetailedState}, but this should seldom be necessary.</p>
+
+
+<h2 id="manage-usage">Manage Network Usage</h2>
+
+<p>You can implement a preferences activity that gives users explicit control
+over your app's usage of network resources. For
+example:</p>
+
+<ul>
+
+<li>You might allow users to upload videos only when the device is connected to a
+Wi-Fi network.</li>
+
+<li>You might sync (or not) depending on specific criteria such as network
+availability, time interval, and so on.</li>
+
+</ul>
+
+<p>To write an app that supports network access and managing
+network usage, your manifest must have the right permissions and
+intent filters.
+</p>
+
+<ul>
+ <li>The manifest excerpted below includes the following permissions:
+ <ul>
+
+ <li>{@link android.Manifest.permission#INTERNET
+android.permission.INTERNET}—Allows applications to open network
+sockets.</li>
+
+ <li>{@link android.Manifest.permission#ACCESS_NETWORK_STATE
+android.permission.ACCESS_NETWORK_STATE}—Allows applications to access
+information about networks.</li>
+
+ </ul>
+ </li>
+
+ <li>You can declare the intent filter for the
+{@link android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} action (introduced in
+Android 4.0) to indicate that your application defines an activity that offers
+options to control data usage. {@link
+android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} shows settings for managing
+the network data usage of a specific application. When your app has a settings activity
+that allows users to control network usage, you should declare this intent filter for that activity.
+In the sample application, this action is handled by the class
+<code>SettingsActivity</code>, which displays a preferences UI to let users
+decide when to download a feed.</li>
+
+</ul>
+
+
+<pre>
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.networkusage"
+ ...>
+
+ <uses-sdk android:minSdkVersion="4"
+ android:targetSdkVersion="14" />
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+
+ <application
+ ...>
+ ...
+ <activity android:label="SettingsActivity" android:name=".SettingsActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
+</pre>
+
+<h2 id="prefs">Implement a Preferences Activity</h2>
+
+<p>As you can see in the manifest excerpt above, the sample app's activity
+<code>SettingsActivity</code> has an intent filter for the {@link
+android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} action.
+<code>SettingsActivity</code> is a subclass of {@link
+android.preference.PreferenceActivity}. It displays a preferences screen
+(shown in figure 1) that
+lets users specify the following:</p>
+
+<ul>
+
+ <li>Whether to display summaries for each XML feed entry, or just a link for
+each entry.</li>
+
+ <li>Whether to download the XML feed if any network connection is available,
+or only if Wi-Fi is available.</li>
+
+</ul>
+
+<img src="{@docRoot}images/training/basics/network-settings1.png" alt="Preferences panel" />
+
+<img src="{@docRoot}images/training/basics/network-settings2.png" alt="Setting a network preference" />
+<p class="img-caption"><strong>Figure 1.</strong> Preferences activity.</p>
+
+<p>Here is <code>SettingsActivity</code>. Note that it implements
+{@link android.content.SharedPreferences.OnSharedPreferenceChangeListener OnSharedPreferenceChangeListener}.
+When a user changes a preference, it fires
+{@link android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged onSharedPreferenceChanged()},
+which sets {@code refreshDisplay} to true. This causes the display to refresh when the user
+returns to the main activity:</p>
+
+<pre>public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Loads the XML preferences file
+ addPreferencesFromResource(R.xml.preferences);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ // Registers a listener whenever a key changes
+ getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ // Unregisters the listener set in onResume().
+ // It's best practice to unregister listeners when your app isn't using them to cut down on
+ // unnecessary system overhead. You do this in onPause().
+ getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
+ }
+
+ // When the user changes the preferences selection,
+ // onSharedPreferenceChanged() restarts the main activity as a new
+ // task. Sets the the refreshDisplay flag to "true" to indicate that
+ // the main activity should update its display.
+ // The main activity queries the PreferenceManager to get the latest settings.
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ // Sets refreshDisplay to true so that when the user returns to the main
+ // activity, the display refreshes to reflect the new settings.
+ NetworkActivity.refreshDisplay = true;
+ }
+}</pre>
+
+<h2 id="pref-change">Respond to Preference Changes</h2>
+
+<p>When the user changes preferences in the settings screen, it typically has
+consequences for the app's behavior. In this snippet, the app checks the
+preferences settings in {@code onStart()}. if there is a match between the setting and
+the device's network connection (for example, if the setting is {@code "Wi-Fi"} and the
+device has a Wi-Fi connection), the app downloads the feed and refreshes the
+display.</p>
+
+<pre>
+public class NetworkActivity extends Activity {
+ public static final String WIFI = "Wi-Fi";
+ public static final String ANY = "Any";
+ private static final String URL = "http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest";
+
+ // Whether there is a Wi-Fi connection.
+ private static boolean wifiConnected = false;
+ // Whether there is a mobile connection.
+ private static boolean mobileConnected = false;
+ // Whether the display should be refreshed.
+ public static boolean refreshDisplay = true;
+
+ // The user's current network preference setting.
+ public static String sPref = null;
+
+ // The BroadcastReceiver that tracks network connectivity changes.
+ private NetworkReceiver receiver = new NetworkReceiver();
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Registers BroadcastReceiver to track network connection changes.
+ IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
+ receiver = new NetworkReceiver();
+ this.registerReceiver(receiver, filter);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ // Unregisters BroadcastReceiver when app is destroyed.
+ if (receiver != null) {
+ this.unregisterReceiver(receiver);
+ }
+ }
+
+ // Refreshes the display if the network connection and the
+ // pref settings allow it.
+
+ @Override
+ public void onStart () {
+ super.onStart();
+
+ // Gets the user's network preference settings
+ SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+ // Retrieves a string value for the preferences. The second parameter
+ // is the default value to use if a preference value is not found.
+ sPref = sharedPrefs.getString("listPref", "Wi-Fi");
+
+ updateConnectedFlags();
+
+ if(refreshDisplay){
+ loadPage();
+ }
+ }
+
+ // Checks the network connection and sets the wifiConnected and mobileConnected
+ // variables accordingly.
+ public void updateConnectedFlags() {
+ ConnectivityManager connMgr = (ConnectivityManager)
+ getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ NetworkInfo activeInfo = connMgr.getActiveNetworkInfo();
+ if (activeInfo != null && activeInfo.isConnected()) {
+ wifiConnected = activeInfo.getType() == ConnectivityManager.TYPE_WIFI;
+ mobileConnected = activeInfo.getType() == ConnectivityManager.TYPE_MOBILE;
+ } else {
+ wifiConnected = false;
+ mobileConnected = false;
+ }
+ }
+
+ // Uses AsyncTask subclass to download the XML feed from stackoverflow.com.
+ public void loadPage() {
+ if (((sPref.equals(ANY)) && (wifiConnected || mobileConnected))
+ || ((sPref.equals(WIFI)) && (wifiConnected))) {
+ // AsyncTask subclass
+ new DownloadXmlTask().execute(URL);
+ } else {
+ showErrorPage();
+ }
+ }
+...
+
+}</pre>
+
+<h2 id="detect-changes">Detect Connection Changes</h2>
+
+<p>The final piece of the puzzle is the {@link
+android.content.BroadcastReceiver} subclass, <code>NetworkReceiver</code>. When
+the device's network connection changes, <code>NetworkReceiver</code> intercepts
+the action {@link android.net.ConnectivityManager#CONNECTIVITY_ACTION},
+determines what the network connection status is, and sets the flags
+<code>wifiConnected</code> and <code>mobileConnected</code> to true/false
+accordingly. The upshot is that the next time the user returns to the app, the
+app will only download the latest feed and update the display if
+<code>NetworkActivity.refreshDisplay</code> is set to <code>true</code>.</p>
+
+<p>Setting up a BroadcastReceiver that gets called unnecessarily can be a
+drain on system resources.
+The sample application registers the
+{@link android.content.BroadcastReceiver} {@code NetworkReceiver} in
+{@link android.app.Activity#onCreate(android.os.Bundle) onCreate()},
+and it unregisters it in
+{@link android.app.Activity#onDestroy onDestroy()}. This is more lightweight
+than declaring a {@code <receiver>} in the manifest. When you declare a
+{@code <receiver>} in the manifest, it can wake up your app at any time,
+even if you haven't run it for weeks. By registering and unregistering
+{@code NetworkReceiver} within the main activity, you ensure that the app won't
+be woken up after the user leaves the app.
+If you do declare a {@code <receiver>} in the manifest and you know exactly
+where you need it, you can use
+{@link android.content.pm.PackageManager#setComponentEnabledSetting setComponentEnabledSetting()}
+to enable and disable it as appropriate.</p>
+
+<p>Here is <code>NetworkReceiver</code>:</p>
+
+<pre>public class NetworkReceiver extends BroadcastReceiver {
+
+@Override
+public void onReceive(Context context, Intent intent) {
+ ConnectivityManager conn = (ConnectivityManager)
+ context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = conn.getActiveNetworkInfo();
+
+ // Checks the user prefs and the network connection. Based on the result, decides whether
+ // to refresh the display or keep the current display.
+ // If the userpref is Wi-Fi only, checks to see if the device has a Wi-Fi connection.
+ if (WIFI.equals(sPref) && networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
+ // If device has its Wi-Fi connection, sets refreshDisplay
+ // to true. This causes the display to be refreshed when the user
+ // returns to the app.
+ refreshDisplay = true;
+ Toast.makeText(context, R.string.wifi_connected, Toast.LENGTH_SHORT).show();
+
+ // If the setting is ANY network and there is a network connection
+ // (which by process of elimination would be mobile), sets refreshDisplay to true.
+ } else if (ANY.equals(sPref) && networkInfo != null) {
+ refreshDisplay = true;
+
+ // Otherwise, the app can't download content--either because there is no network
+ // connection (mobile or Wi-Fi), or because the pref setting is WIFI, and there
+ // is no Wi-Fi connection.
+ // Sets refreshDisplay to false.
+ } else {
+ refreshDisplay = false;
+ Toast.makeText(context, R.string.lost_connection, Toast.LENGTH_SHORT).show();
+ }
+}</pre>
+
diff --git a/docs/html/training/basics/network-ops/xml.jd b/docs/html/training/basics/network-ops/xml.jd
new file mode 100644
index 0000000..b148257
--- /dev/null
+++ b/docs/html/training/basics/network-ops/xml.jd
@@ -0,0 +1,555 @@
+page.title=Parsing XML Data
+parent.title=Performing Network Operations
+parent.link=index.html
+
+trainingnavtop=true
+
+previous.title=Managing Network Usage
+previous.link=managing.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#choose">Choose a Parser</a></li>
+ <li><a href="#analyze">Analyze the Feed</a></li>
+ <li><a href="#instantiate">Instantiate the Parser</a></li>
+ <li><a href="#read">Read the Feed</a></li>
+ <li><a href="#parse">Parse XML</a></li>
+ <li><a href="#skip">Skip Tags You Don't Care About</a></li>
+ <li><a href="#consume">Consume XML Data</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/webapps/index.html">Web Apps Overview</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/NetworkUsage.zip"
+class="button">Download the sample</a>
+ <p class="filename">NetworkUsage.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Extensible Markup Language (XML) is a set of rules for encoding documents in
+machine-readable form. XML is a popular format for sharing data on the internet.
+Websites that frequently update their content, such as news sites or blogs,
+often provide an XML feed so that external programs can keep abreast of content
+changes. Uploading and parsing XML data is a common task for network-connected
+apps. This lesson explains how to parse XML documents and use their data.</p>
+
+<h2 id="choose">Choose a Parser</h2>
+
+<p>We recommend {@link org.xmlpull.v1.XmlPullParser}, which is an efficient and
+maintainable way to parse XML on Android. Historically Android has had two
+implementations of this interface:</p>
+
+<ul>
+ <li><a href="http://kxml.sourceforge.net/"><code>KXmlParser</code></a>
+ via {@link org.xmlpull.v1.XmlPullParserFactory#newPullParser XmlPullParserFactory.newPullParser()}.
+ </li>
+ <li><code>ExpatPullParser</code>, via
+ {@link android.util.Xml#newPullParser Xml.newPullParser()}.
+ </li>
+</ul>
+
+<p>Either choice is fine. The
+example in this section uses <code>ExpatPullParser</code>, via
+{@link android.util.Xml#newPullParser Xml.newPullParser()}. </p>
+
+<h2 id="analyze">Analyze the Feed</h2>
+
+<p>The first step in parsing a feed is to decide which fields you're interested in.
+The parser extracts data for those fields and ignores the rest.</p>
+
+<p>Here is an excerpt from the feed that's being parsed in the sample app. Each
+post to <a href="http://stackoverflow.com">StackOverflow.com</a> appears in the
+feed as an <code>entry</code> tag that contains several nested tags:</p>
+
+<pre><?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" ...">
+<title type="text">newest questions tagged android - Stack Overflow</title>
+...
+ <entry>
+ ...
+ </entry>
+ <entry>
+ <id>http://stackoverflow.com/q/9439999</id>
+ <re:rank scheme="http://stackoverflow.com">0</re:rank>
+ <title type="text">Where is my data file?</title>
+ <category scheme="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest/tags" term="android"/>
+ <category scheme="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest/tags" term="file"/>
+ <author>
+ <name>cliff2310</name>
+ <uri>http://stackoverflow.com/users/1128925</uri>
+ </author>
+ <link rel="alternate" href="http://stackoverflow.com/questions/9439999/where-is-my-data-file" />
+ <published>2012-02-25T00:30:54Z</published>
+ <updated>2012-02-25T00:30:54Z</updated>
+ <summary type="html">
+ <p>I have an Application that requires a data file...</p>
+
+ </summary>
+ </entry>
+ <entry>
+ ...
+ </entry>
+...
+</feed></pre>
+
+<p>The sample app
+extracts data for the <code>entry</code> tag and its nested tags
+<code>title</code>, <code>link</code>, and <code>summary</code>.</p>
+
+
+<h2 id="instantiate">Instantiate the Parser</h2>
+
+<p>The next step is to
+instantiate a parser and kick off the parsing process. In this snippet, a parser
+is initialized to not process namespaces, and to use the provided {@link
+java.io.InputStream} as its input. It starts the parsing process with a call to
+{@link org.xmlpull.v1.XmlPullParser#nextTag() nextTag()} and invokes the
+<code>readFeed()</code> method, which extracts and processes the data the app is
+interested in:</p>
+
+<pre>public class StackOverflowXmlParser {
+ // We don't use namespaces
+ private static final String ns = null;
+
+ public List<Entry> parse(InputStream in) throws XmlPullParserException, IOException {
+ try {
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
+ parser.setInput(in, null);
+ parser.nextTag();
+ return readFeed(parser);
+ } finally {
+ in.close();
+ }
+ }
+ ...
+}</pre>
+
+<h2 id="read">Read the Feed</h2>
+
+<p>The <code>readFeed()</code> method does the actual work of processing the
+feed. It looks for elements tagged "entry" as a starting point for recursively
+processing the feed. If a tag isn't an {@code entry} tag, it skips it. Once the whole
+feed has been recursively processed, <code>readFeed()</code> returns a {@link
+java.util.List} containing the entries (including nested data members) it
+extracted from the feed. This {@link java.util.List} is then returned by the
+parser.</p>
+
+<pre>
+private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
+ List<Entry> entries = new ArrayList<Entry>();
+
+ parser.require(XmlPullParser.START_TAG, ns, "feed");
+ while (parser.next() != XmlPullParser.END_TAG) {
+ if (parser.getEventType() != XmlPullParser.START_TAG) {
+ continue;
+ }
+ String name = parser.getName();
+ // Starts by looking for the entry tag
+ if (name.equals("entry")) {
+ entries.add(readEntry(parser));
+ } else {
+ skip(parser);
+ }
+ }
+ return entries;
+}</pre>
+
+
+<h2 id="parse">Parse XML</h2>
+
+
+<p>The steps for parsing an XML feed are as follows:</p>
+<ol>
+
+ <li>As described in <a href="#analyze">Analyze the Feed</a>, identify the tags you want to include in your app. This
+example extracts data for the <code>entry</code> tag and its nested tags
+<code>title</code>, <code>link</code>, and <code>summary</code>.</li>
+
+<li>Create the following methods:</p>
+
+<ul>
+
+<li>A "read" method for each tag you're interested in. For example,
+<code>readEntry()</code>, <code>readTitle()</code>, and so on. The parser reads
+tags from the input stream. When it encounters a tag named <code>entry</code>,
+<code>title</code>,
+<code>link</code> or <code>summary</code>, it calls the appropriate method
+for that tag. Otherwise, it skips the tag.
+</li>
+
+<li>Methods to extract data for each different type of tag and to advance the
+parser to the next tag. For example:
+<ul>
+
+<li>For the <code>title</code> and <code>summary</code> tags, the parser calls
+<code>readText()</code>. This method extracts data for these tags by calling
+<code>parser.getText()</code>.</li>
+
+<li>For the <code>link</code> tag, the parser extracts data for links by first
+determining if the link is the kind
+it's interested in. Then it uses <code>parser.getAttributeValue()</code> to
+extract the link's value.</li>
+
+<li>For the <code>entry</code> tag, the parser calls <code>readEntry()</code>.
+This method parses the entry's nested tags and returns an <code>Entry</code>
+object with the data members <code>title</code>, <code>link</code>, and
+<code>summary</code>.</li>
+
+</ul>
+</li>
+<li>A helper <code>skip()</code> method that's recursive. For more discussion of this topic, see <a href="#skip">Skip Tags You Don't Care About</a>.</li>
+</ul>
+
+ </li>
+</ol>
+
+<p>This snippet shows how the parser parses entries, titles, links, and summaries.</p>
+<pre>public static class Entry {
+ public final String title;
+ public final String link;
+ public final String summary;
+
+ private Entry(String title, String summary, String link) {
+ this.title = title;
+ this.summary = summary;
+ this.link = link;
+ }
+}
+
+// Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them off
+// to their respective "read" methods for processing. Otherwise, skips the tag.
+private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
+ parser.require(XmlPullParser.START_TAG, ns, "entry");
+ String title = null;
+ String summary = null;
+ String link = null;
+ while (parser.next() != XmlPullParser.END_TAG) {
+ if (parser.getEventType() != XmlPullParser.START_TAG) {
+ continue;
+ }
+ String name = parser.getName();
+ if (name.equals("title")) {
+ title = readTitle(parser);
+ } else if (name.equals("summary")) {
+ summary = readSummary(parser);
+ } else if (name.equals("link")) {
+ link = readLink(parser);
+ } else {
+ skip(parser);
+ }
+ }
+ return new Entry(title, summary, link);
+}
+
+// Processes title tags in the feed.
+private String readTitle(XmlPullParser parser) throws IOException, XmlPullParserException {
+ parser.require(XmlPullParser.START_TAG, ns, "title");
+ String title = readText(parser);
+ parser.require(XmlPullParser.END_TAG, ns, "title");
+ return title;
+}
+
+// Processes link tags in the feed.
+private String readLink(XmlPullParser parser) throws IOException, XmlPullParserException {
+ String link = "";
+ parser.require(XmlPullParser.START_TAG, ns, "link");
+ String tag = parser.getName();
+ String relType = parser.getAttributeValue(null, "rel");
+ if (tag.equals("link")) {
+ if (relType.equals("alternate")){
+ link = parser.getAttributeValue(null, "href");
+ parser.nextTag();
+ }
+ }
+ parser.require(XmlPullParser.END_TAG, ns, "link");
+ return link;
+}
+
+// Processes summary tags in the feed.
+private String readSummary(XmlPullParser parser) throws IOException, XmlPullParserException {
+ parser.require(XmlPullParser.START_TAG, ns, "summary");
+ String summary = readText(parser);
+ parser.require(XmlPullParser.END_TAG, ns, "summary");
+ return summary;
+}
+
+// For the tags title and summary, extracts their text values.
+private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
+ String result = "";
+ if (parser.next() == XmlPullParser.TEXT) {
+ result = parser.getText();
+ parser.nextTag();
+ }
+ return result;
+}
+ ...
+}</pre>
+
+<h2 id="skip">Skip Tags You Don't Care About</h2>
+
+<p>One of the steps in the XML parsing described above is for the parser to skip tags it's not interested in. Here is the parser's <code>skip()</code> method:</p>
+
+<pre>
+private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
+ if (parser.getEventType() != XmlPullParser.START_TAG) {
+ throw new IllegalStateException();
+ }
+ int depth = 1;
+ while (depth != 0) {
+ switch (parser.next()) {
+ case XmlPullParser.END_TAG:
+ depth--;
+ break;
+ case XmlPullParser.START_TAG:
+ depth++;
+ break;
+ }
+ }
+ }
+</pre>
+
+<p>This is how it works:</p>
+
+<ul>
+
+<li>It throws an exception if the current event isn't a
+<code>START_TAG</code>.</li>
+
+<li>It consumes the <code>START_TAG</code>, and all events up to and including
+the matching <code>END_TAG</code>.</li>
+
+<li>To make sure that it stops at the correct <code>END_TAG</code> and not at
+the first tag it encounters after the original <code>START_TAG</code>, it keeps
+track of the nesting depth.</li>
+
+</ul>
+
+<p>Thus if the current element has nested elements, the value of
+<code>depth</code> won't be 0 until the parser has consumed all events between
+the original <code>START_TAG</code> and its matching <code>END_TAG</code>. For
+example, consider how the parser skips the <code><author></code> element,
+which has 2 nested elements, <code><name></code> and
+<code><uri></code>:</p>
+
+<ul>
+
+<li>The first time through the <code>while</code> loop, the next tag the parser
+encounters after <code><author></code> is the <code>START_TAG</code> for
+<code><name></code>. The value for <code>depth</code> is incremented to
+2.</li>
+
+<li>The second time through the <code>while</code> loop, the next tag the parser
+encounters is the <code>END_TAG</code> <code></name></code>. The value
+for <code>depth</code> is decremented to 1.</li>
+
+<li>The third time through the <code>while</code> loop, the next tag the parser
+encounters is the <code>START_TAG</code> <code><uri></code>. The value
+for <code>depth</code> is incremented to 2.</li>
+
+<li>The fourth time through the <code>while</code> loop, the next tag the parser
+encounters is the <code>END_TAG</code> <code></uri></code>. The value for
+<code>depth</code> is decremented to 1.</li>
+
+<li>The fifth time and final time through the <code>while</code> loop, the next
+tag the parser encounters is the <code>END_TAG</code>
+<code></author></code>. The value for <code>depth</code> is decremented to
+0, indicating that the <code><author></code> element has been successfully
+skipped.</li>
+
+</ul>
+
+<h2 id="consume">Consume XML Data</h2>
+
+<p>The example application fetches and parses the XML feed within an {@link
+android.os.AsyncTask}. This takes the processing off the main UI thread. When
+processing is complete, the app updates the UI in the main activity
+(<code>NetworkActivity</code>).</p>
+<p>In the excerpt shown below, the <code>loadPage()</code> method does the
+following:</p>
+
+<ul>
+
+ <li>Initializes a string variable with the URL for the XML feed.</li>
+
+ <li>If the user's settings and the network connection allow it, invokes
+<code>new DownloadXmlTask().execute(url)</code>. This instantiates a new
+<code>DownloadXmlTask</code> object ({@link android.os.AsyncTask} subclass) and
+runs its {@link android.os.AsyncTask#execute execute()} method, which downloads
+and parses the feed and returns a string result to be displayed in the UI.</li>
+
+</ul>
+<pre>
+public class NetworkActivity extends Activity {
+ public static final String WIFI = "Wi-Fi";
+ public static final String ANY = "Any";
+ private static final String URL = "http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest";
+
+ // Whether there is a Wi-Fi connection.
+ private static boolean wifiConnected = false;
+ // Whether there is a mobile connection.
+ private static boolean mobileConnected = false;
+ // Whether the display should be refreshed.
+ public static boolean refreshDisplay = true;
+ public static String sPref = null;
+
+ ...
+
+ // Uses AsyncTask to download the XML feed from stackoverflow.com.
+ public void loadPage() {
+
+ if((sPref.equals(ANY)) && (wifiConnected || mobileConnected)) {
+ new DownloadXmlTask().execute(URL);
+ }
+ else if ((sPref.equals(WIFI)) && (wifiConnected)) {
+ new DownloadXmlTask().execute(URL);
+ } else {
+ // show error
+ }
+ }</pre>
+
+<p>The {@link android.os.AsyncTask} subclass shown below,
+<code>DownloadXmlTask</code>, implements the following {@link
+android.os.AsyncTask} methods:</p>
+
+ <ul>
+
+ <li>{@link android.os.AsyncTask#doInBackground doInBackground()} executes
+the method <code>loadXmlFromNetwork()</code>. It passes the feed URL as a
+parameter. The method <code>loadXmlFromNetwork()</code> fetches and processes
+the feed. When it finishes, it passes back a result string.</li>
+
+ <li>{@link android.os.AsyncTask#onPostExecute onPostExecute()} takes the
+returned string and displays it in the UI.</li>
+
+ </ul>
+
+<pre>
+// Implementation of AsyncTask used to download XML feed from stackoverflow.com.
+private class DownloadXmlTask extends AsyncTask<String, Void, String> {
+ @Override
+ protected String doInBackground(String... urls) {
+ try {
+ return loadXmlFromNetwork(urls[0]);
+ } catch (IOException e) {
+ return getResources().getString(R.string.connection_error);
+ } catch (XmlPullParserException e) {
+ return getResources().getString(R.string.xml_error);
+ }
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ setContentView(R.layout.main);
+ // Displays the HTML string in the UI via a WebView
+ WebView myWebView = (WebView) findViewById(R.id.webview);
+ myWebView.loadData(result, "text/html", null);
+ }
+}</pre>
+
+ <p>Below is the method <code>loadXmlFromNetwork()</code> that is invoked from
+<code>DownloadXmlTask</code>. It does the following:</p>
+
+ <ol>
+
+ <li>Instantiates a <code>StackOverflowXmlParser</code>. It also creates variables for
+a {@link java.util.List} of <code>Entry</code> objects (<code>entries</code>), and
+<code>title</code>, <code>url</code>, and <code>summary</code>, to hold the
+values extracted from the XML feed for those fields.</li>
+
+ <li>Calls <code>downloadUrl()</code>, which fetches the feed and returns it as
+ an {@link java.io.InputStream}.</li>
+
+ <li>Uses <code>StackOverflowXmlParser</code> to parse the {@link java.io.InputStream}.
+ <code>StackOverflowXmlParser</code> populates a
+ {@link java.util.List} of <code>entries</code> with data from the feed.</li>
+
+ <li>Processes the <code>entries</code> {@link java.util.List},
+ and combines the feed data with HTML markup.</li>
+
+ <li>Returns an HTML string that is displayed in the main activity
+UI by the {@link android.os.AsyncTask} method {@link
+android.os.AsyncTask#onPostExecute onPostExecute()}.</li>
+
+</ol>
+
+<pre>
+// Uploads XML from stackoverflow.com, parses it, and combines it with
+// HTML markup. Returns HTML string.
+private String loadXmlFromNetwork(String urlString) throws XmlPullParserException, IOException {
+ InputStream stream = null;
+ // Instantiate the parser
+ StackOverflowXmlParser stackOverflowXmlParser = new StackOverflowXmlParser();
+ List<Entry> entries = null;
+ String title = null;
+ String url = null;
+ String summary = null;
+ Calendar rightNow = Calendar.getInstance();
+ DateFormat formatter = new SimpleDateFormat("MMM dd h:mmaa");
+
+ // Checks whether the user set the preference to include summary text
+ SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+ boolean pref = sharedPrefs.getBoolean("summaryPref", false);
+
+ StringBuilder htmlString = new StringBuilder();
+ htmlString.append("<h3>" + getResources().getString(R.string.page_title) + "</h3>");
+ htmlString.append("<em>" + getResources().getString(R.string.updated) + " " +
+ formatter.format(rightNow.getTime()) + "</em>");
+
+ try {
+ stream = downloadUrl(urlString);
+ entries = stackOverflowXmlParser.parse(stream);
+ // Makes sure that the InputStream is closed after the app is
+ // finished using it.
+ } finally {
+ if (stream != null) {
+ stream.close();
+ }
+ }
+
+ // StackOverflowXmlParser returns a List (called "entries") of Entry objects.
+ // Each Entry object represents a single post in the XML feed.
+ // This section processes the entries list to combine each entry with HTML markup.
+ // Each entry is displayed in the UI as a link that optionally includes
+ // a text summary.
+ for (Entry entry : entries) {
+ htmlString.append("<p><a href='");
+ htmlString.append(entry.link);
+ htmlString.append("'>" + entry.title + "</a></p>");
+ // If the user set the preference to include summary text,
+ // adds it to the display.
+ if (pref) {
+ htmlString.append(entry.summary);
+ }
+ }
+ return htmlString.toString();
+}
+
+// Given a string representation of a URL, sets up a connection and gets
+// an input stream.
+private InputStream downloadUrl(String urlString) throws IOException {
+ URL url = new URL(urlString);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setReadTimeout(10000 /* milliseconds */);
+ conn.setConnectTimeout(15000 /* milliseconds */);
+ conn.setRequestMethod("GET");
+ conn.setDoInput(true);
+ // Starts the query
+ conn.connect();
+ InputStream stream = conn.getInputStream();
+}</pre>
diff --git a/docs/html/training/basics/supporting-devices/languages.jd b/docs/html/training/basics/supporting-devices/languages.jd
index fcc95c2..d83fbca 100644
--- a/docs/html/training/basics/supporting-devices/languages.jd
+++ b/docs/html/training/basics/supporting-devices/languages.jd
@@ -97,6 +97,10 @@
</resources>
</pre>
+<p class="note"><strong>Note:</strong> You can use the locale qualifier (or any
+configuration qualifer) on any resource type, such as if you want to provide
+localized versions of your bitmap drawable. For more information, see <a
+href="{@docRoot}guide/topics/resources/localization.html">Localization</a>.
<h2 id="UseString">Use the String Resources</h2>
diff --git a/docs/html/training/basics/supporting-devices/platforms.jd b/docs/html/training/basics/supporting-devices/platforms.jd
index 0d4e7d9..04872a3 100644
--- a/docs/html/training/basics/supporting-devices/platforms.jd
+++ b/docs/html/training/basics/supporting-devices/platforms.jd
@@ -21,9 +21,9 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">Android API Levels</a></li>
<li><a
-href="{@docRoot}sdk/compatibility-library.html">Android Support Library</a></li>
+href="{@docRoot}tools/extras/support-library.html">Android Support Library</a></li>
</ul>
</div>
</div>
@@ -34,7 +34,7 @@
versions as well.</p>
<p>The dashboard for <a
-href="http://developer.android.com/resources/dashboard/platform-versions.html">Platform Versions</a>
+href="http://developer.android.com/about/dashboards/index.html">Platform Versions</a>
is updated regularly to show the distribution of active
devices running each version of Android, based on the number of devices that visit the Google Play
Store. Generally, it’s a good practice to support about 90% of the active devices, while
@@ -42,7 +42,7 @@
<p class="note"><strong>Tip:</strong> In order to provide the best features and
functionality across several Android versions, you should use the <a
-href="{@docRoot}sdk/compatibility-library.html">Android Support Library</a> in your app,
+href="{@docRoot}tools/extras/support-library.html">Android Support Library</a> in your app,
which allows you to use several recent platform APIs on older versions.</p>
diff --git a/docs/html/training/camera/index.jd b/docs/html/training/camera/index.jd
index d209c7e..282bed8 100644
--- a/docs/html/training/camera/index.jd
+++ b/docs/html/training/camera/index.jd
@@ -21,7 +21,7 @@
<h2>You should also read</h2>
<ul>
<li><a href="{@docRoot}guide/topics/media/camera.html">Camera</a></li>
- <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a></li>
+ <li><a href="{@docRoot}guide/components/activities.html">Activities</a></li>
</ul>
diff --git a/docs/html/training/camera/photobasics.jd b/docs/html/training/camera/photobasics.jd
index 3420918..8fa6d67b 100644
--- a/docs/html/training/camera/photobasics.jd
+++ b/docs/html/training/camera/photobasics.jd
@@ -25,7 +25,7 @@
<h2>You should also read</h2>
<ul>
<li><a href="{@docRoot}guide/topics/media/camera.html">Camera</a></li>
- <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent
Filters</a></li>
</ul>
diff --git a/docs/html/training/camera/videobasics.jd b/docs/html/training/camera/videobasics.jd
index 5fe1a3a..d011d09 100644
--- a/docs/html/training/camera/videobasics.jd
+++ b/docs/html/training/camera/videobasics.jd
@@ -24,7 +24,7 @@
<h2>You should also read</h2>
<ul>
<li><a href="{@docRoot}guide/topics/media/camera.html">Camera</a></li>
- <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent
Filters</a></li>
</ul>
diff --git a/docs/html/training/custom-views/create-view.jd b/docs/html/training/custom-views/create-view.jd
new file mode 100644
index 0000000..b0bc8b4
--- /dev/null
+++ b/docs/html/training/custom-views/create-view.jd
@@ -0,0 +1,281 @@
+page.title=Creating a View Class
+parent.title=Creating Custom Views
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Custom Drawing
+next.link=custom-drawing.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#subclassview">Subclass a View</a></li>
+ <li><a href="#customattr">Define Custom Attributes</a></li>
+ <li><a href="#applyattr">Apply Custom Attributes to a View</a></li>
+ <li><a href="#addprop">Add Properties and Events</a></li>
+ <li><a href="#accessibility">Design For Accessibility</a></li>
+ </ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}/guide/topics/ui/custom-components.html">Custom Components</a>
+ </li>
+ </ul>
+<h2>Try it out</h2>
+<div class="download-box">
+<a href="{@docRoot}shareables/training/CustomView.zip"
+class="button">Download the sample</a>
+<p class="filename">CustomView.zip</p>
+</div>
+ </div>
+</div>
+
+<p>A well-designed custom view is much like any other well-designed class. It encapsulates a
+specific set of
+functionality with an easy to use interface, it uses CPU and memory efficiently, and so forth. In
+addition to being a
+well-designed class, though, a custom view should:
+
+<ul>
+ <li>Conform to Android standards</li>
+ <li>Provide custom styleable attributes that work with Android XML layouts</li>
+ <li>Send accessibility events</li>
+ <li>Be compatible with multiple Android platforms.</li>
+</ul>
+
+<p>The Android framework provides a set of base classes and XML tags to help you create a view that
+ meets all of these
+ requirements. This lesson discusses how to use the Android framework to create the core
+ functionality of a view
+ class.</p>
+
+<h2 id="subclassview">Subclass a View</h2>
+
+<p>All of the view classes defined in the Android framework extend {@link android.view.View}. Your
+ custom view can also
+ extend {@link android.view.View View} directly, or you can save time by extending one of the
+ existing view
+ subclasses, such as {@link android.widget.Button}.</p>
+
+<p>To allow the <a href=”{@docRoot}guide/developing/tools/adt.html”>Android Developer Tools
+</a> to interact with your view, at a minimum you must provide a constructor that takes a
+{@link android.content.Context} and an {@link android.util.AttributeSet} object as parameters.
+This constructor allows the layout editor to create and edit an instance of your view.</p>
+
+<pre class="prettyprint">
+class PieChart extends View {
+ public PieChart(Context ctx, AttributeSet attrs) {
+ super(ctx, attrs);
+ }
+}
+</pre>
+
+<h2 id="customattr">Define Custom Attributes</h2>
+
+<p>To add a built-in {@link android.view.View View} to your user interface, you specify it in an XML element and
+control its
+appearance and behavior with element attributes. Well-written custom views can also be added and
+styled via XML. To
+enable this behavior in your custom view, you must:
+
+<ul>
+ <li>Define custom attributes for your view in a {@code
+ <declare-styleable>
+ } resource element
+ </li>
+ <li>Specify values for the attributes in your XML layout</li>
+ <li>Retrieve attribute values at runtime</li>
+ <li>Apply the retrieved attribute values to your view</li>
+</ul>
+
+<p>This section discusses how to define custom attributes and specify their values.
+ The next section deals with
+ retrieving and applying the values at runtime.</p>
+
+<p>To define custom attributes, add {@code
+ <declare-styleable>
+ } resources to your project. It's customary to put these resources into a {@code
+ res/values/attrs.xml} file. Here's
+ an example of an {@code attrs.xml} file:
+</p>
+
+<pre>
+<resources>;
+ <declare-styleable name="PieChart">
+ <attr name="showText" format="boolean" />
+ <attr name="labelPosition" format="enum">
+ <enum name="left" value="0"/>
+ <enum name="right" value="1"/>
+ </attr>
+ </declare-styleable>
+</resources>
+</pre>
+
+<p>This code declares two custom attributes, {@code showText} and {@code labelPosition}, that belong
+ to a styleable
+ entity named {@code PieChart}. The name of the styleable entity is, by convention, the same name as the
+ name of the class
+ that defines the custom view. Although it's not strictly necessary to follow this convention,
+ many popular code
+ editors depend on this naming convention to provide statement completion.</p>
+
+<p>Once you define the custom attributes, you can use them in layout XML files just like built-in
+ attributes. The only
+ difference is that your custom attributes belong to a different namespace. Instead of belonging
+ to the {@code
+ http://schemas.android.com/apk/res/android} namespace, they belong to {@code
+ http://schemas.android.com/apk/res/[your package name]}. For example, here's how to use the
+ attributes defined for
+ {@code PieChart}:
+ <p>
+
+<pre>
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:custom="http://schemas.android.com/apk/res/com.example.customviews">
+ <com.example.customviews.charting.PieChart
+ custom:showText="true"
+ custom:labelPosition="left" />
+</LinearLayout>
+</pre>
+
+ <p>In order to avoid having to repeat the long namespace URI, the sample uses an {@code
+ xmlns} directive. This
+ directive assigns the alias {@code custom} to the namespace {@code
+ http://schemas.android.com/apk/res/com.example.customviews}. You can choose any alias
+ you want for your
+ namespace.</p>
+
+ <p>Notice the name of the XML tag that adds the custom view to the layout. It is the fully
+ qualified name of the
+ custom view class. If your view class is an inner class, you must further qualify it with the name of the view's outer class.
+ further. For instance, the
+ {@code PieChart} class has an inner class called {@code PieView}. To use the custom attributes from this class, you would
+ use the tag {@code com.example.customviews.charting.PieChart$PieView}.</p>
+
+ <h2 id="applyattr">Apply Custom Attributes</h2>
+
+ <p>When a view is created from an XML layout, all of the attributes in the XML tag are read
+ from the resource
+ bundle and passed into the view's constructor as an {@link android.util.AttributeSet}.
+ Although it's
+ possible to read values from the {@link android.util.AttributeSet} directly, doing so
+ has some disadvantages:</p>
+
+ <ul>
+ <li>Resource references within attribute values are not resolved</li>
+ <li>Styles are not applied</li>
+ </ul>
+
+ <p>Instead, pass the {@link android.util.AttributeSet} to {@link
+ android.content.res.Resources.Theme#obtainStyledAttributes obtainStyledAttributes()}.
+ This method passes back a {@link android.content.res.TypedArray TypedArray} array of
+ values that have
+ already been dereferenced and styled.</p>
+
+ <p>The Android resource compiler does a lot of work for you to make calling {@link
+ android.content.res.Resources.Theme#obtainStyledAttributes obtainStyledAttributes()}
+ easier. For each {@code <declare-styleable>}
+ resource in the res directory, the generated R.java defines both an array of attribute
+ ids and a set of
+ constants that define the index for each attribute in the array. You use the predefined
+ constants to read
+ the attributes from the {@link android.content.res.TypedArray TypedArray}. Here's how
+ the {@code PieChart} class
+ reads its attributes:</p>
+
+<pre>
+public PieChart(Context ctx, AttributeSet attrs) {
+ super(ctx, attrs);
+ TypedArray a = context.getTheme().obtainStyledAttributes(
+ attrs,
+ R.styleable.PieChart,
+ 0, 0);
+
+ try {
+ mShowText = a.getBoolean(R.styleable.PieChart_showText, false);
+ mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
+ } finally {
+ a.recycle();
+ }
+}
+</pre>
+
+ <p>Note that {@link android.content.res.TypedArray TypedArray} objects
+ are a shared resource
+ and must be recycled after use.</p>
+
+ <h2 id="addprop">Add Properties and Events</h2>
+
+ <p>Attributes are a powerful way of controlling the behavior and appearance of views, but
+ they can only be read
+ when the view is initialized. To provide dynamic behavior, expose a property getter and
+ setter pair for each
+ custom attribute. The following snippet shows how {@code PieChart} exposes a property
+ called {@code
+ showText}:</p>
+
+<pre>
+public boolean isShowText() {
+ return mShowText;
+}
+
+public void setShowText(boolean showText) {
+ mShowText = showText;
+ invalidate();
+ requestLayout();
+}
+</pre>
+
+ <p>Notice that {@code setShowText} calls {@link android.view.View#invalidate invalidate()}
+ and {@link android.view.View#requestLayout requestLayout()}. These calls are crucial
+ to ensure that the view behaves reliably. You have
+ to invalidate the view after any change to its properties that might change its
+ appearance, so that the
+ system knows that it needs to be redrawn. Likewise, you need to request a new layout if
+ a property changes
+ that might affect the size or shape of the view. Forgetting these method calls can cause
+ hard-to-find
+ bugs.</p>
+
+ <p>Custom views should also support event listeners to communicate important events. For
+ instance, {@code PieChart}
+ exposes a custom event called {@code OnCurrentItemChanged} to notify listeners that the
+ user has rotated the
+ pie chart to focus on a new pie slice.</p>
+
+ <p>It's easy to forget to expose properties and events, especially when you're the only user
+ of the custom view.
+ Taking some time to carefully define your view's interface reduces future maintenance
+ costs.
+ A good rule to follow is to always expose any property that affects the visible
+ appearance or behavior of
+ your custom view.
+
+ <h2 id="accessibility">Design For Accessibility</h2>
+
+ <p>Your custom view should support the widest range of users. This includes users with
+ disabilities that
+ prevent them from seeing or using a touchscreen. To support users with disabilities,
+ you should:</p>
+
+ <ul>
+ <li>Label your input fields using the {@code android:contentDescription} attribute
+ </li>
+ <li>Send accessibility events by calling {@link
+ android.view.accessibility.AccessibilityEventSource#sendAccessibilityEvent
+ sendAccessibilityEvent()} when
+ appropriate.
+ </li>
+ <li>
+ Support alternate controllers, such as D-pad and trackball</li>
+ </ul>
+
+ <p>For more information on creating accessible views, see
+ <a href=”{@docRoot}guide/topics/ui/accessibility/apps.html#custom-views”>
+ Making Applications Accessible</a> in the Android Developers Guide.
+ </p>
diff --git a/docs/html/training/custom-views/custom-drawing.jd b/docs/html/training/custom-views/custom-drawing.jd
new file mode 100644
index 0000000..8280237
--- /dev/null
+++ b/docs/html/training/custom-views/custom-drawing.jd
@@ -0,0 +1,284 @@
+page.title=Custom Drawing
+parent.title=Creating Custom Views
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Creating a View Class
+previous.link=create-view.html
+next.title=Making the View Interactive
+next.link=making-interactive.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#ondraw">Override onDraw()</a></li>
+ <li><a href="#createobject">Create Drawing Objects</a></li>
+ <li><a href="#layoutevent">Handle Layout Events</a></li>
+ <li><a href="#draw">Draw!</a></li>
+ </ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/topics/graphics/2d-graphics.html">
+ Canvas and Drawables</a></li>
+ </ul>
+<h2>Try it out</h2>
+<div class="download-box">
+<a href="{@docRoot}shareables/training/CustomView.zip"
+class="button">Download the sample</a>
+<p class="filename">CustomView.zip</p>
+</div>
+ </div>
+</div>
+
+<p>The most important part of a custom view is its appearance. Custom drawing can be easy or complex
+according to your
+application's needs. This lesson covers some of the most common operations.</p>
+
+<h2 id="overrideondraw">Override onDraw()</h2>
+
+<p>The most important step in drawing a custom view is to override the {@link
+android.view.View#onDraw(android.graphics.Canvas) onDraw()} method. The parameter to {@link
+android.view.View#onDraw(android.graphics.Canvas) onDraw()} is a {@link
+android.graphics.Canvas Canvas} object that the view can use to draw itself. The {@link
+android.graphics.Canvas Canvas}
+class defines methods for drawing text, lines, bitmaps, and many other graphics primitives. You can
+use these methods in
+{@link
+android.view.View#onDraw(android.graphics.Canvas) onDraw()} to create your custom user interface (UI).</p>
+
+<p>Before you can call any drawing methods, though, it's necessary to create a {@link
+android.graphics.Paint Paint}
+object. The next section discusses {@link android.graphics.Paint Paint} in more detail.</p>
+
+<h2 id="createobject">Create Drawing Objects</h2>
+
+<p>The {@link android.graphics} framework divides drawing into two areas:</p>
+
+<ul>
+<li><i>What</i> to draw, handled by {@link android.graphics.Canvas Canvas}</li>
+<li><i>How</i> to draw, handled by {@link android.graphics.Paint}.</li>
+</ul>
+
+<p>For instance, {@link android.graphics.Canvas Canvas} provides a method to draw a line, while
+{@link
+android.graphics.Paint Paint} provides methods to define that line's color. {@link
+android.graphics.Canvas Canvas} has a
+method to draw a rectangle, while {@link android.graphics.Paint Paint} defines whether to fill that
+rectangle with a
+color or leave it empty. Simply put, {@link android.graphics.Canvas Canvas} defines shapes that you
+can draw on the
+screen, while {@link android.graphics.Paint Paint} defines the color, style, font, and so forth of
+each shape you
+draw.</p>
+
+<p>So, before you draw anything, you need to create one or more {@link android.graphics.Paint Paint}
+objects. The {@code PieChart} example does this in a method called {@code init}, which is
+called from the
+constructor:</p>
+
+<pre>
+private void init() {
+ mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint.setColor(mTextColor);
+ if (mTextHeight == 0) {
+ mTextHeight = mTextPaint.getTextSize();
+ } else {
+ mTextPaint.setTextSize(mTextHeight);
+ }
+
+ mPiePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mPiePaint.setStyle(Paint.Style.FILL);
+ mPiePaint.setTextSize(mTextHeight);
+
+ mShadowPaint = new Paint(0);
+ mShadowPaint.setColor(0xff101010);
+ mShadowPaint.setMaskFilter(new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL));
+
+ ...
+</pre>
+
+
+<p>Creating objects ahead of time is an important optimization. Views are redrawn very frequently,
+and many drawing
+objects require expensive initialization. Creating drawing objects within your {@link
+android.view.View#onDraw(android.graphics.Canvas) onDraw()}
+method significantly
+reduces performance and can make your UI appear sluggish.</p>
+
+<h2 id="layouteevent">Handle Layout Events</h2>
+
+<p>In order to properly draw your custom view, you need to know what size it is. Complex custom
+views often need to
+perform multiple layout calculations depending on the size and shape of their area on screen. You
+should never make
+assumptions about the size of your view on the screen. Even if only one app uses your view, that app
+needs to handle
+different screen sizes, multiple screen densities, and various aspect ratios in both portrait and
+landscape mode.</p>
+
+<p>Although {@link android.view.View} has many methods for handling measurement, most of them do not
+need to be
+overridden. If your view doesn't need special control over its size, you only need to override one
+method: {@link
+android.view.View#onSizeChanged onSizeChanged()}.</p>
+
+<p>{@link
+android.view.View#onSizeChanged onSizeChanged()} is called when your view is first assigned a size,
+and again if the size of your view changes
+for any reason. Calculate positions, dimensions, and any other values related to your view's size in
+{@link
+android.view.View#onSizeChanged onSizeChanged()}, instead of recalculating them every time you draw.
+In the {@code PieChart} example, {@link
+android.view.View#onSizeChanged onSizeChanged()} is
+where the {@code PieChart} view calculates the bounding rectangle of the pie chart and the relative position
+of the text label
+and other visual elements.</p>
+
+<p>When your view is assigned a size, the layout manager assumes that the size includes all of the
+view's padding. You
+must handle the padding values when you calculate your view's size. Here's a snippet from {@code
+PieChart.onSizeChanged()}
+that shows how to do this:</p>
+
+<pre>
+ // Account for padding
+ float xpad = (float)(getPaddingLeft() + getPaddingRight());
+ float ypad = (float)(getPaddingTop() + getPaddingBottom());
+
+ // Account for the label
+ if (mShowText) xpad += mTextWidth;
+
+ float ww = (float)w - xpad;
+ float hh = (float)h - ypad;
+
+ // Figure out how big we can make the pie.
+ float diameter = Math.min(ww, hh);
+</pre>
+
+<p>If you need finer control over your view's layout parameters, implement {@link
+android.view.View#onMeasure onMeasure()}. This method's parameters are
+{@link android.view.View.MeasureSpec} values that tell you how big your view's
+parent wants your view to be, and whether that size is a hard maximum or just a suggestion. As an
+optimization, these
+values are stored as packed integers, and you use the static methods of
+{@link android.view.View.MeasureSpec} to
+unpack the information
+stored in each integer.
+
+<p>Here's an example implementation of {@link android.view.View#onMeasure onMeasure()}.
+ In this implementation, {@code PieChart}
+ attempts to make its area
+ big enough to make the pie as big as its label:</p>
+
+<pre>
+@Override
+protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // Try for a width based on our minimum
+ int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
+ int w = resolveSizeAndState(minw, widthMeasureSpec, 1);
+
+ // Whatever the width ends up being, ask for a height that would let the pie
+ // get as big as it can
+ int minh = MeasureSpec.getSize(w) - (int)mTextWidth + getPaddingBottom() + getPaddingTop();
+ int h = resolveSizeAndState(MeasureSpec.getSize(w) - (int)mTextWidth, heightMeasureSpec, 0);
+
+ setMeasuredDimension(w, h);
+}
+</pre>
+
+<p>There are three important things to note in this code:</p>
+
+<ul>
+ <li>The calculations take into account the view's padding. As mentioned earlier, this is the
+ view's
+ responsibility.
+ </li>
+ <li>The helper method {@link android.view.View#resolveSizeAndState resolveSizeAndState()} is
+ used to create the
+ final width and height values. This helper returns an appropriate
+ {@link android.view.View.MeasureSpec} value
+ by comparing the view's desired size to the spec passed into
+ {@link android.view.View#onMeasure onMeasure()}.
+ </li>
+ <li>{@link android.view.View#onMeasure onMeasure()} has no return value.
+ Instead, the method communicates its results by
+ calling {@link
+ android.view.View#setMeasuredDimension setMeasuredDimension()}. Calling this method is
+ mandatory. If you omit
+ this call, the {@link android.view.View} class throws a runtime exception.
+ </li>
+</ul>
+
+<h2 id="draw">Draw!</h2>
+
+<p>Once you have your object creation and measuring code defined, you can implement {@link
+ android.view.View#onDraw(android.graphics.Canvas) onDraw()}. Every view
+ implements {@link
+ android.view.View#onDraw(android.graphics.Canvas) onDraw()}
+ differently, but there are some common operations that most views
+ share:</p>
+
+<ul>
+ <li>Draw text using {@link android.graphics.Canvas#drawText drawText()}. Specify the typeface by
+ calling {@link
+ android.graphics.Paint#setTypeface setTypeface()}, and the text color by calling {@link
+ android.graphics.Paint#setColor setColor()}.
+ </li>
+ <li>Draw primitive shapes using {@link android.graphics.Canvas#drawRect drawRect()}, {@link
+ android.graphics.Canvas#drawOval drawOval()}, and {@link android.graphics.Canvas#drawArc
+ drawArc()}. Change
+ whether the shapes are filled, outlined, or both by calling {@link
+ android.graphics.Paint#setStyle(android.graphics.Paint.Style) setStyle()}.
+ </li>
+ <li>Draw more complex shapes using the {@link android.graphics.Path} class.
+ Define a shape by adding lines and curves to a
+ {@link
+ android.graphics.Path} object, then draw the shape using {@link
+ android.graphics.Canvas#drawPath drawPath()}.
+ Just as with primitive shapes, paths can be outlined, filled, or both, depending on the
+ {@link android.graphics.Paint#setStyle
+ setStyle()}.
+ </li>
+ <li>
+ Define gradient fills by creating {@link android.graphics.LinearGradient} objects. Call {@link
+ android.graphics.Paint#setShader setShader()} to use your
+ {@link android.graphics.LinearGradient} on filled
+ shapes.
+ <li>Draw bitmaps using {@link android.graphics.Canvas#drawBitmap drawBitmap()}.</li>
+</ul>
+
+<p>For example, here's the code that draws {@code PieChart}. It uses a mix of text, lines, and shapes.</p>
+
+<pre>
+protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ // Draw the shadow
+ canvas.drawOval(
+ mShadowBounds,
+ mShadowPaint
+ );
+
+ // Draw the label text
+ canvas.drawText(mData.get(mCurrentItem).mLabel, mTextX, mTextY, mTextPaint);
+
+ // Draw the pie slices
+ for (int i = 0; i < mData.size(); ++i) {
+ Item it = mData.get(i);
+ mPiePaint.setShader(it.mShader);
+ canvas.drawArc(mBounds,
+ 360 - it.mEndAngle,
+ it.mEndAngle - it.mStartAngle,
+ true, mPiePaint);
+ }
+
+ // Draw the pointer
+ canvas.drawLine(mTextX, mPointerY, mPointerX, mPointerY, mTextPaint);
+ canvas.drawCircle(mPointerX, mPointerY, mPointerSize, mTextPaint);
+}
+</pre>
diff --git a/docs/html/training/custom-views/index.jd b/docs/html/training/custom-views/index.jd
new file mode 100644
index 0000000..0661c05
--- /dev/null
+++ b/docs/html/training/custom-views/index.jd
@@ -0,0 +1,79 @@
+page.title=Creating Custom Views
+
+trainingnavtop=true
+startpage=true
+next.title=Creating a View Class
+next.link=create-view.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>Dependencies and prerequisites</h2>
+ <ul>
+ <li>Android 2.1 (API level 7) or higher</li>
+ </ul>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}/guide/topics/ui/custom-components.html">Custom Components</a>
+ </li>
+ <li><a href="{@docRoot}/guide/topics/ui/ui-events.html">Input Events</a></li>
+ <li><a href="{@docRoot}/guide/topics/graphics/prop-animation.html">Property
+ Animation</a></li>
+ <li><a href="{@docRoot}/guide/topics/graphics/hardware-accel.html">Hardware
+ Acceleration</a></li>
+ <li><a href="{@docRoot}guide/topics/ui/accessibility/index.html">
+ Accessibility</a> developer guide</li>
+ </ul>
+<h2>Try it out</h2>
+<div class="download-box">
+<a href="{@docRoot}shareables/training/CustomView.zip"
+class="button">Download the sample</a>
+<p class="filename">CustomView.zip</p>
+</div>
+ </div>
+</div>
+
+<p>
+The Android framework has a large set of {@link android.view.View} classes for
+interacting with the user and displaying various
+types of data. But
+sometimes your app has unique needs that aren’t covered by the built-in views. This class shows you
+how to create your
+own views that are robust and reusable.</p>
+
+<h2>Lessons</h2>
+
+<dl>
+<dt><b><a href="create-view.html">Creating a View Class</a></b></dt>
+<dd>Create a class that acts like a built-in view, with custom
+ attributes and support from the <a href="http://developer.android.com/sdk/eclipse-adt.html">ADT</a> layout editor.
+</dd>
+
+<dt><b><a href="custom-drawing.html">Custom Drawing</a></b></dt>
+<dd>Make your view visually distinctive using the Android graphics system.</dd>
+
+<dt><b><a href="making-interactive.html">Making the View Interactive</a></b></dt>
+<dd>Users expect a view to react smoothly and naturally to input gestures.
+ This lesson discusses how to use gesture detection, physics, and animation
+ to give your user interface a professional feel.
+</dd>
+
+<dt><b><a href="optimizing-view.html">Optimizing the View</a></b></dt>
+<dd>No matter how beautiful your UI is, users won't love it if it
+ doesn't run at a consistently high frame rate. Learn how to avoid common
+ performance problems, and how to use hardware acceleration to make your
+ custom drawings run faster.
+</dd>
+
+</dl>
+
+
+
+
+
+
+
+
diff --git a/docs/html/training/custom-views/making-interactive.jd b/docs/html/training/custom-views/making-interactive.jd
new file mode 100644
index 0000000..4e9d53a
--- /dev/null
+++ b/docs/html/training/custom-views/making-interactive.jd
@@ -0,0 +1,292 @@
+page.title=Making the View Interactive
+parent.title=Creating Custom Views
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Custom Drawing
+previous.link=custom-drawing.html
+next.title=Optmizing the View
+next.link=optimizing-view.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#inputgesture">Handle Input Gestures</a></li>
+ <li><a href="#motion">Create Physically Plausible Motion</a></li>
+ <li><a href="#makesmooth">Make Your Transitions Smooth</a></li>
+ </ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/topics/ui/ui-events.html">Input Events</a></li>
+ <li><a href="{@docRoot}guide/topics/graphics/prop-animation.html">Property Animation</a>
+ </li>
+ </ul>
+<h2>Try it out</h2>
+<div class="download-box">
+<a href="{@docRoot}shareables/training/CustomView.zip"
+class="button">Download the sample</a>
+<p class="filename">CustomView.zip</p>
+</div>
+ </div>
+</div>
+
+<p>Drawing a UI is only one part of creating a custom view. You also need to make your view respond
+to user input in a
+way that closely resembles the real-world action you're mimicking. Objects should always act in the
+same way that real
+objects do. For example, images should not immediately pop out of existence and reappear somewhere
+else, because objects
+in the real world don't do that. Instead, images should move from one place to another.</p>
+
+<p>Users also sense subtle behavior or feel in an interface, and react best to subtleties that
+mimic the real world.
+For example, when users fling a UI object, they should sense friction at the beginning that delays
+the motion, and then
+at the end sense momentum that carries the motion beyond the fling.</p>
+
+<p>This lesson demonstrates how to use features of the Android framework to add these real-world
+behaviors to your
+custom view.
+
+<h2 id="inputgesture">Handle Input Gestures</h2>
+
+<p>Like many other UI frameworks, Android supports an input event model. User actions are turned
+ into events that
+ trigger callbacks, and you can override the callbacks to customize how your application responds
+ to the user. The
+ most common input event in the Android system is <em>touch</em>, which triggers {@link
+ android.view.View#onTouchEvent(android.view.MotionEvent)}. Override this method to handle the
+ event:</p>
+
+<pre>
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return super.onTouchEvent(event);
+ }
+</pre>
+
+<p>Touch events by themselves are not particularly useful. Modern touch UIs define interactions in
+ terms of gestures
+ such as tapping, pulling, pushing, flinging, and zooming. To convert raw touch events into
+ gestures, Android
+ provides {@link android.view.GestureDetector}.</p>
+
+<p>Construct a {@link android.view.GestureDetector} by passing in an instance of a class that
+ implements {@link
+ android.view.GestureDetector.OnGestureListener}. If you only want to process a few gestures, you
+ can extend {@link
+ android.view.GestureDetector.SimpleOnGestureListener} instead of implementing the {@link
+ android.view.GestureDetector.OnGestureListener}
+ interface. For instance, this code creates a class that extends {@link
+ android.view.GestureDetector.SimpleOnGestureListener} and overrides {@link
+ android.view.GestureDetector.SimpleOnGestureListener#onDown}.</p>
+
+<pre>
+class mListener extends GestureDetector.SimpleOnGestureListener {
+ @Override
+ public boolean onDown(MotionEvent e) {
+ return true;
+ }
+}
+mDetector = new GestureDetector(PieChart.this.getContext(), new mListener());
+</pre>
+
+<p>Whether or not you use {@link
+ android.view.GestureDetector.SimpleOnGestureListener}, you must always implement an
+ {@link android.view.GestureDetector.OnGestureListener#onDown onDown()} method that
+ returns {@code true}. This step is necessary because all gestures begin with an
+ {@link android.view.GestureDetector.OnGestureListener#onDown onDown()} message. If
+ you return {@code
+ false} from {@link android.view.GestureDetector.OnGestureListener#onDown onDown()}, as
+ {@link android.view.GestureDetector.SimpleOnGestureListener} does, the system assumes that
+ you want to ignore the
+ rest of the gesture, and the other methods of
+ {@link android.view.GestureDetector.OnGestureListener} never get called. The
+ only time you should
+ return {@code false} from {@link android.view.GestureDetector.OnGestureListener#onDown onDown()}
+ is if you truly want to ignore an entire gesture.
+
+ Once you've implemented {@link android.view.GestureDetector.OnGestureListener}
+ and created an instance of {@link android.view.GestureDetector}, you can use
+ your {@link android.view.GestureDetector} to interpret the touch events you receive in {@link
+ android.view.GestureDetector#onTouchEvent onTouchEvent()}.</p>
+
+<pre>
+@Override
+public boolean onTouchEvent(MotionEvent event) {
+ boolean result = mDetector.onTouchEvent(event);
+ if (!result) {
+ if (event.getAction() == MotionEvent.ACTION_UP) {
+ stopScrolling();
+ result = true;
+ }
+ }
+ return result;
+}
+</pre>
+
+<p>When you pass {@link android.view.GestureDetector#onTouchEvent onTouchEvent()} a touch event that
+ it doesn't
+ recognize as part of a gesture, it returns {@code false}. You can then run your own custom
+ gesture-detection
+ code.</p>
+
+<h2 id="motion">Create Physically Plausible Motion</h2>
+
+<p>Gestures are a powerful way to control touchscreen devices, but they can be counterintuitive and
+ difficult to
+ remember unless they produce physically plausible results. A good example of this is the <em>fling</em>
+ gesture, where the
+ user quickly moves a finger across the screen and then lifts it. This gesture makes sense if the UI
+ responds by moving
+ quickly in the direction of the fling, then slowing down, as if the user had pushed on a
+ flywheel and set it
+ spinning.</p>
+
+<p>However, simulating the feel of a flywheel isn't trivial. A lot of physics and math are required
+ to get a flywheel
+ model working correctly. Fortunately, Android provides helper classes to simulate this and other
+ behaviors. The
+ {@link android.widget.Scroller} class is the basis for handling flywheel-style <em>fling</em>
+ gestures.</p>
+
+<p>To start a fling, call {@link android.widget.Scroller#fling fling()} with the starting velocity
+ and the minimum and
+ maximum x and y values of the fling. For the velocity value, you can use the value computed for
+ you by {@link android.view.GestureDetector}.</p>
+
+<pre>
+@Override
+public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+ mScroller.fling(currentX, currentY, velocityX / SCALE, velocityY / SCALE, minX, minY, maxX, maxY);
+ postInvalidate();
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> Although the velocity calculated by
+ {@link android.view.GestureDetector} is physically accurate,
+ many developers feel
+ that using this value makes the fling animation too fast. It's common to divide the x and y
+ velocity by a factor of
+ 4 to 8.</p>
+
+<p>The call to {@link android.widget.Scroller#fling fling()} sets up the physics model for the fling
+ gesture.
+ Afterwards, you need to update the {@link android.widget.Scroller Scroller} by calling {@link
+ android.widget.Scroller#computeScrollOffset Scroller.computeScrollOffset()} at regular
+ intervals. {@link
+ android.widget.Scroller#computeScrollOffset computeScrollOffset()} updates the {@link
+ android.widget.Scroller
+ Scroller} object's internal state by reading the current time and using the physics model to calculate
+ the x and y position
+ at that time. Call {@link android.widget.Scroller#getCurrX} and {@link
+ android.widget.Scroller#getCurrY} to
+ retrieve these values.</p>
+
+<p>Most views pass the {@link android.widget.Scroller Scroller} object's x and y position directly to
+ {@link
+ android.view.View#scrollTo scrollTo()}. The PieChart example is a little different: it
+ uses the current scroll
+ y position to set the rotational angle of the chart.</p>
+
+<pre>
+if (!mScroller.isFinished()) {
+ mScroller.computeScrollOffset();
+ setPieRotation(mScroller.getCurrY());
+}
+</pre>
+
+<p>The {@link android.widget.Scroller Scroller} class computes scroll positions for you, but it does
+ not automatically
+ apply those positions to your view. It's your responsibility to make sure you get and apply new
+ coordinates often
+ enough to make the scrolling animation look smooth. There are two ways to do this:</p>
+
+<ul>
+ <li>Call {@link android.view.View#postInvalidate() postInvalidate()} after calling
+ {@link android.widget.Scroller#fling(int, int, int, int, int, int, int, int) fling()},
+ in order to
+ force a redraw. This
+ technique requires that you compute scroll offsets in {@link android.view.View#onDraw onDraw()}
+ and call {@link android.view.View#postInvalidate() postInvalidate()} every
+ time the scroll offset changes.
+ </li>
+ <li>Set up a {@link android.animation.ValueAnimator} to animate for the duration of the fling,
+ and add a listener to process animation updates
+ by calling {@link android.animation.ValueAnimator#addUpdateListener addUpdateListener()}.
+ </li>
+</ul>
+
+<p>The PieChart example uses the second approach. This technique is slightly more complex to set up, but
+ it works more
+ closely with the animation system and doesn't require potentially unnecessary view
+ invalidation. The drawback is that {@link android.animation.ValueAnimator}
+ is not available prior to API level 11, so this technique cannot be used
+on devices running Android versions lower than 3.0.</p>
+
+<p class="note"><strong>Note:</strong> {@link android.animation.ValueAnimator} isn't available
+ prior to API level 11, but you can still use it in applications that
+target lower API levels. You just need to make sure to check the current API level
+at runtime, and omit the calls to the view animation system if the current level is less than 11.</p>
+
+<pre>
+ mScroller = new Scroller(getContext(), null, true);
+ mScrollAnimator = ValueAnimator.ofFloat(0,1);
+ mScrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ if (!mScroller.isFinished()) {
+ mScroller.computeScrollOffset();
+ setPieRotation(mScroller.getCurrY());
+ } else {
+ mScrollAnimator.cancel();
+ onScrollFinished();
+ }
+ }
+ });
+</pre>
+
+<h2 id="makesmooth">Make Your Transitions Smooth</h2>
+
+<p>Users expect a modern UI to transition smoothly between states. UI elements fade in and out
+ instead of appearing and
+ disappearing. Motions begin and end smoothly instead of starting and stopping abruptly. The
+ Android <a
+ href="{@docRoot}guide/topics/graphics/prop-animation.html">property animation
+ framework</a>, introduced in
+ Android 3.0, makes smooth transitions easy.</p>
+
+<p>To use the animation system, whenever a property changes that will affect your view's appearance,
+ do not change the
+ property directly. Instead, use {@link android.animation.ValueAnimator} to make the change. In
+ the following
+ example, modifying the
+ currently selected pie slice in PieChart causes the entire chart to rotate so that the selection
+ pointer is centered
+ in the selected slice. {@link android.animation.ValueAnimator} changes the rotation over a
+ period of several
+ hundred milliseconds,
+ rather than immediately setting the new rotation value.</p>
+
+<pre>
+mAutoCenterAnimator = ObjectAnimator.ofInt(PieChart.this, "PieRotation", 0);
+mAutoCenterAnimator.setIntValues(targetAngle);
+mAutoCenterAnimator.setDuration(AUTOCENTER_ANIM_DURATION);
+mAutoCenterAnimator.start();
+</pre>
+
+<p>If the value you want to change is one of the base {@link android.view.View} properties, doing
+ the animation
+ is even easier,
+ because Views have a built-in {@link android.view.ViewPropertyAnimator} that is optimized for
+ simultaneous animation
+ of multiple properties. For example:</p>
+
+<pre>
+animate().rotation(targetAngle).setDuration(ANIM_DURATION).start();
+</pre>
diff --git a/docs/html/training/custom-views/optimizing-view.jd b/docs/html/training/custom-views/optimizing-view.jd
new file mode 100644
index 0000000..1f489dd
--- /dev/null
+++ b/docs/html/training/custom-views/optimizing-view.jd
@@ -0,0 +1,176 @@
+page.title=Optimizing the View
+parent.title=Creating Custom Views
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Making the View Interactive
+previous.link=making-interactive.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#less">Do Less, Less Frequently</a></li>
+ <li><a href="#accelerate">Use Hardware Acceleration</a></li>
+ </ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href=”{@docRoot}guide/topics/graphics/hardware-accel.html”>
+ Hardware Acceleration
+ </a>
+ </li>
+ </ul>
+<h2>Try it out</h2>
+<div class="download-box">
+<a href="{@docRoot}shareables/training/CustomView.zip"
+class="button">Download the sample</a>
+<p class="filename">CustomView.zip</p>
+</div>
+</div>
+ </div>
+
+
+<p>Now that you have a well-designed view that responds to gestures and transitions between states,
+you need to ensure
+that the view runs fast. To avoid a UI that feels sluggish or stutters during playback, you must
+ensure that your
+animations consistently run at 60 frames per second.</p>
+
+<h2 id="less">Do Less, Less Frequently</h2>
+
+<p>To speed up your view, eliminate unnecessary code from routines that are called frequently. Start
+by working on
+{@link android.view.View#onDraw onDraw()}, which will give you the biggest payback. In particular
+you should eliminate
+allocations in {@link android.view.View#onDraw onDraw()}, because allocations may lead to a garbage
+collection that
+would cause a stutter. Allocate objects during initialization, or between animations. Never make an
+allocation while an
+animation is running.</p>
+
+<p>In addition to making {@link android.view.View#onDraw onDraw()} leaner, you should also make sure
+it's called as
+infrequently as possible. Most calls to {@link android.view.View#onDraw onDraw()} are the result of
+a call to {@link
+android.view.View#invalidate() invalidate()}, so eliminate unnecessary calls to {@link
+android.view.View#invalidate()
+invalidate()}. When possible, call the four-parameter variant of {@link
+android.view.View#invalidate() invalidate()}
+rather than the version that takes no parameters. The no-parameter variant invalidates the entire
+view, while the
+four-parameter variant invalidates only a specified portion of the view. This approach allows draw calls to
+be more efficient and
+can eliminate unnecessary invalidation of views that fall outside the invalid rectangle.</p>
+
+<p>Another very expensive operation is traversing layouts. Any time a view calls {@link
+android.view.View#requestLayout()
+requestLayout()}, the Android UI system needs to traverse the entire view hierarchy to find out how
+big each view needs
+to be. If it finds conflicting measurements, it may need to traverse the hierarchy multiple times.
+UI designers
+sometimes create deep hierarchies of nested {@link android.view.ViewGroup ViewGroup} objects in
+order to get the UI to
+behave properly. These deep view hierarchies cause performance problems. Make your view hierarchies
+as shallow as
+possible.</p>
+
+<p>If you have a complex UI, you should consider writing a custom {@link android.view.ViewGroup
+ViewGroup} to perform
+its layout. Unlike the built-in views, your custom view can make application-specific assumptions
+about the size and
+shape of its children, and thus avoid traversing its children to calculate measurements. The
+PieChart example shows how
+to extend {@link android.view.ViewGroup ViewGroup} as part of a custom view. PieChart has child
+views, but it never
+measures them. Instead, it sets their sizes directly according to its own custom layout
+algorithm.</p>
+
+<h2 id="accelerate">Use Hardware Acceleration</h2>
+
+<p>As of Android 3.0, the Android 2D graphics system can be accelerated by the GPU (Graphics
+Processing Unit) hardware
+found in most newer Android devices. GPU hardware acceleration can result in a tremendous
+performance increase for many
+applications, but it isn't the right choice for every application. The Android framework
+gives you the ability to finely control which parts of your application are or are not
+hardware accelerated.</p>
+
+<p>See <a href="{@docRoot}guide/topics/graphics/hardware-accel.html">Hardware Acceleration</a>
+ in the Android Developers Guide for directions on how to enable acceleration at the
+ application, activity, or window level. Notice that in addition to the directions in
+ the developer guide, you must also set your application's target API to 11 or higher by
+ specifying {@code <uses-sdk
+ android:targetSdkVersion="11"/>} in your {@code AndroidManifest.xml} file.</p>
+
+<p>Once you've enabled hardware acceleration, you may or may not see a performance increase.
+Mobile GPUs are very good at certain tasks, such as scaling, rotating, and translating
+bitmapped images. They are not particularly good at other tasks, such as drawing lines or curves. To
+get the most out of GPU acceleration, you should maximize the number of operations that the GPU is
+good at, and minimize the number of operations that the GPU isn't good at.</p>
+
+<p>In the PieChart example, for instance, drawing the pie is relatively expensive. Redrawing the pie
+each time it's
+rotated causes the UI to feel sluggish. The solution is to place the pie chart into a child
+{@link android.view.View} and set that
+{@link android.view.View}'s
+<a href="{@docRoot}reference/android/view/View.html#setLayerType(int, android.graphics.Paint)">
+ layer type</a> to {@link android.view.View#LAYER_TYPE_HARDWARE}, so that the GPU can cache it as
+a static
+image. The sample
+defines the child view as an inner class of {@code PieChart}, which minimizes the amount of code
+changes that are needed
+to implement this solution.</p>
+
+<pre>
+ private class PieView extends View {
+
+ public PieView(Context context) {
+ super(context);
+ if (!isInEditMode()) {
+ setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ for (Item it : mData) {
+ mPiePaint.setShader(it.mShader);
+ canvas.drawArc(mBounds,
+ 360 - it.mEndAngle,
+ it.mEndAngle - it.mStartAngle,
+ true, mPiePaint);
+ }
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mBounds = new RectF(0, 0, w, h);
+ }
+
+ RectF mBounds;
+ }
+</pre>
+
+<p>After this code change, {@code PieChart.PieView.onDraw()} is called only when the view is first
+shown. During the rest
+of the application's lifetime, the pie chart is cached as an image, and redrawn at different
+rotation angles by the GPU.
+GPU hardware is particularly good at this sort of thing, and the performance difference is
+immediately noticeable.</p>
+
+<p>There is a tradeoff, though. Caching images as hardware layers consumes video memory, which is a
+limited resource.
+For this reason, the final version of {@code PieChart.PieView} only sets its layer type to
+{@link android.view.View#LAYER_TYPE_HARDWARE}
+while the user is actively scrolling. At all other times, it sets its layer type to
+{@link android.view.View#LAYER_TYPE_NONE}, which
+allows the GPU to stop caching the image.</p>
+
+<p>Finally, don't forget to profile your code. Techniques that improve performance on one view
+might negatively affect performance on another.</p>
diff --git a/docs/html/training/design-navigation/ancestral-temporal.jd b/docs/html/training/design-navigation/ancestral-temporal.jd
index ab6a64d..33a75b2 100644
--- a/docs/html/training/design-navigation/ancestral-temporal.jd
+++ b/docs/html/training/design-navigation/ancestral-temporal.jd
@@ -22,7 +22,7 @@
<h2>You should also read</h2>
<ul>
<li><a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a></li>
- <li><a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
+ <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
</ul>
</div>
@@ -58,7 +58,7 @@
<p>Applications generally don't have to worry about managing the <em>Back</em> button themselves;
-the system handles <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">tasks and
+the system handles <a href="{@docRoot}guide/components/tasks-and-back-stack.html">tasks and
the <em>back stack</em></a>, or the list of previous screens, automatically. The <em>Back</em>
button by default simply traverses this list of screens, removing the current screen from the list
upon being pressed.</p>
diff --git a/docs/html/training/design-navigation/wireframing.jd b/docs/html/training/design-navigation/wireframing.jd
index 6deceb1..42f892d 100644
--- a/docs/html/training/design-navigation/wireframing.jd
+++ b/docs/html/training/design-navigation/wireframing.jd
@@ -78,7 +78,7 @@
<li>What's the learning curve? Professional vector illustration tools may have a steep learning curve, while tools designed for wireframing may offer a smaller set of features that are more relevant to the task.</li>
</ul>
-<p>Lastly, the XML Layout Editor that comes with the <a href="{@docRoot}guide/developing/tools/adt.html">Android Development Tools (ADT)</a> plugin for Eclipse can often be used for prototyping. However, you should be careful to focus more on the high-level layout and less on visual design details at this point.</p>
+<p>Lastly, the XML Layout Editor that comes with the <a href="{@docRoot}tools/help/adt.html">Android Development Tools (ADT)</a> plugin for Eclipse can often be used for prototyping. However, you should be careful to focus more on the high-level layout and less on visual design details at this point.</p>
<h2 id="wireframe-digital">Create Digital Wireframes</h2>
@@ -120,6 +120,6 @@
<ul>
<li><a href="{@docRoot}guide/topics/ui/index.html">Developer's Guide: User Interface</a>: learn how to implement your user interface designs using the Android SDK.</li>
<li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>: implement tabs, up navigation, on-screen actions, etc.
- <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a>: implement re-usable, multi-pane layouts
- <li><a href="{@docRoot}sdk/compatibility-library.html">Support Library</a>: implement horizontal paging (swipe views) using <code>ViewPager</code></li>
+ <li><a href="{@docRoot}guide/components/fragments.html">Fragments</a>: implement re-usable, multi-pane layouts
+ <li><a href="{@docRoot}tools/extras/support-library.html">Support Library</a>: implement horizontal paging (swipe views) using <code>ViewPager</code></li>
</ul>
diff --git a/docs/html/training/displaying-bitmaps/index.jd b/docs/html/training/displaying-bitmaps/index.jd
index 6755c24..78371ad 100644
--- a/docs/html/training/displaying-bitmaps/index.jd
+++ b/docs/html/training/displaying-bitmaps/index.jd
@@ -13,7 +13,7 @@
<h2>Dependencies and prerequisites</h2>
<ul>
<li>Android 2.1 (API Level 7) or higher</li>
- <li><a href="{@docRoot}sdk/compatibility-library.html">Support Library</a></li>
+ <li><a href="{@docRoot}tools/extras/support-library.html">Support Library</a></li>
</ul>
<h2>Try it out</h2>
diff --git a/docs/html/training/displaying-bitmaps/process-bitmap.jd b/docs/html/training/displaying-bitmaps/process-bitmap.jd
index c1450b4..d1e346c 100644
--- a/docs/html/training/displaying-bitmaps/process-bitmap.jd
+++ b/docs/html/training/displaying-bitmaps/process-bitmap.jd
@@ -21,7 +21,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/practices/design/responsiveness.html">Designing for Responsiveness</a></li>
+ <li><a href="{@docRoot}guide/practices/responsiveness.html">Designing for Responsiveness</a></li>
<li><a
href="http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html">Multithreading
for Performance</a></li>
@@ -45,7 +45,7 @@
load is unpredictable and depends on a variety of factors (speed of reading from disk or network,
size of image, power of CPU, etc.). If one of these tasks blocks the UI thread, the system flags
your application as non-responsive and the user has the option of closing it (see <a
-href="{@docRoot}guide/practices/design/responsiveness.html">Designing for Responsiveness</a> for
+href="{@docRoot}guide/practices/responsiveness.html">Designing for Responsiveness</a> for
more information).</p>
<p>This lesson walks you through processing bitmaps in a background thread using
diff --git a/docs/html/training/efficient-downloads/efficient-network-access.jd b/docs/html/training/efficient-downloads/efficient-network-access.jd
index 0efad7d..1d3a8a5 100644
--- a/docs/html/training/efficient-downloads/efficient-network-access.jd
+++ b/docs/html/training/efficient-downloads/efficient-network-access.jd
@@ -142,7 +142,7 @@
<h2 id="DDMSNetworkTraffic">Use the DDMS Network Traffic Tool to Identify Areas of Concern</h2>
-<p>The Android <a href="{@docRoot}guide/developing/debugging/ddms.html">DDMS (Dalvik Debug Monitor Server)</a> includes a Detailed Network Usage tab that makes it possible to track when your application is making network requests. Using this tool, you can monitor how and when your app transfers data and optimize the underlying code appropriately.</p>
+<p>The Android <a href="{@docRoot}tools/debugging/ddms.html">DDMS (Dalvik Debug Monitor Server)</a> includes a Detailed Network Usage tab that makes it possible to track when your application is making network requests. Using this tool, you can monitor how and when your app transfers data and optimize the underlying code appropriately.</p>
<p>Figure 3 shows a pattern of transferring small amounts of data roughly 15 seconds apart, suggesting that efficiency could be dramatically improved by prefetching each request or bundling the uploads.</p>
diff --git a/docs/html/training/graphics/opengl/draw.jd b/docs/html/training/graphics/opengl/draw.jd
new file mode 100644
index 0000000..156ff70
--- /dev/null
+++ b/docs/html/training/graphics/opengl/draw.jd
@@ -0,0 +1,195 @@
+page.title=Drawing Shapes
+parent.title=Displaying Graphics with OpenGL ES
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Defining Shapes
+previous.link=environment.html
+next.title=Applying Projection and Camera Views
+next.link=projection.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#initialize">Initialize Shapes</a></li>
+ <li><a href="#draw">Draw a Shape</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li>
+</ul>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/OpenGLES.zip"
+class="button">Download the sample</a>
+ <p class="filename">OpenGLES.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>After you define shapes to be drawn with OpenGL, you probably want to draw them. Drawing shapes
+with the OpenGL ES 2.0 takes a bit more code than you might imagine, because the API provides a
+great deal of control over the graphics rendering pipeline.</p>
+
+<p>This lesson explains how to draw the shapes you defined in the previous lesson using the OpenGL
+ES 2.0 API.</p>
+
+
+<h2 id="initialize">Initialize Shapes</h2>
+
+<p>Before you do any drawing, you must initialize and load the shapes you plan to draw. Unless the
+structure (the original coordinates) of the shapes you use in your program change during the course
+of execution, you should initialize them in the {@link
+android.opengl.GLSurfaceView.Renderer#onSurfaceCreated onSurfaceCreated()} method of your renderer
+for memory and processing efficiency.</p>
+
+<pre>
+public void onSurfaceCreated(GL10 unused, EGLConfig config) {
+ ...
+
+ // initialize a triangle
+ mTriangle = new Triangle();
+ // initialize a square
+ mSquare = new Square();
+}
+</pre>
+
+
+<h2 id="draw">Draw a Shape</h2>
+
+<p>Drawing a defined shape using OpenGL ES 2.0 requires a significant amount of code, because you
+must provide a lot of details to the graphics rendering pipeline. Specifically, you must define the
+following:</p>
+
+<ul>
+ <li><em>Vertex Shader</em> - OpenGL ES graphics code for rendering the vertices of a shape.</li>
+ <li><em>Fragment Shader</em> - OpenGL ES code for rendering the face of a shape with colors or
+textures.</li>
+ <li><em>Program</em> - An OpenGL ES object that contains the shaders you want to use for drawing
+one or more shapes.</li>
+</ul>
+
+<p>You need at least one vertex shader to draw a shape and one fragment shader to color that shape.
+These shaders must be complied and then added to an OpenGL ES program, which is then used to draw
+the shape. Here is an example of how to define basic shaders you can use to draw a shape:</p>
+
+<pre>
+private final String vertexShaderCode =
+ "attribute vec4 vPosition;" +
+ "void main() {" +
+ " gl_Position = vPosition;" +
+ "}";
+
+private final String fragmentShaderCode =
+ "precision mediump float;" +
+ "uniform vec4 vColor;" +
+ "void main() {" +
+ " gl_FragColor = vColor;" +
+ "}";
+</pre>
+
+<p>Shaders contain OpenGL Shading Language (GLSL) code that must be compiled prior to using it in
+the OpenGL ES environment. To compile this code, create a utility method in your renderer class:</p>
+
+<pre>
+public static int loadShader(int type, String shaderCode){
+
+ // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
+ // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
+ int shader = GLES20.glCreateShader(type);
+
+ // add the source code to the shader and compile it
+ GLES20.glShaderSource(shader, shaderCode);
+ GLES20.glCompileShader(shader);
+
+ return shader;
+}
+</pre>
+
+<p>In order to draw your shape, you must compile the shader code, add them to a OpenGL ES program
+object and then link the program. Do this in your drawn object’s constructor, so it is only done
+once.</p>
+
+<p class="note"><strong>Note:</strong> Compiling OpenGL ES shaders and linking programs is expensive
+in terms of CPU cycles and processing time, so you should avoid doing this more than once. If you do
+not know the content of your shaders at runtime, you should build your code such that they only
+get created once and then cached for later use.</p>
+
+<pre>
+public Triangle() {
+ ...
+
+ int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
+ int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+
+ mProgram = GLES20.glCreateProgram(); // create empty OpenGL ES Program
+ GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
+ GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
+ GLES20.glLinkProgram(mProgram); // creates OpenGL ES program executables
+}
+</pre>
+
+<p>At this point, you are ready to add the actual calls that draw your shape. Drawing shapes with
+OpenGL ES requires that you specify several parameters to tell the rendering pipeline what you want
+to draw and how to draw it. Since drawing options can vary by shape, it's a good idea to have your
+shape classes contain their own drawing logic.</p>
+
+<p>Create a {@code draw()} method for drawing the shape. This code sets the position and
+color values to the shape’s vertex shader and fragment shader, and then executes the drawing
+function.</p>
+
+<pre>
+public void draw() {
+ // Add program to OpenGL ES environment
+ GLES20.glUseProgram(mProgram);
+
+ // get handle to vertex shader's vPosition member
+ mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
+
+ // Enable a handle to the triangle vertices
+ GLES20.glEnableVertexAttribArray(mPositionHandle);
+
+ // Prepare the triangle coordinate data
+ GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
+ GLES20.GL_FLOAT, false,
+ vertexStride, vertexBuffer);
+
+ // get handle to fragment shader's vColor member
+ mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
+
+ // Set color for drawing the triangle
+ GLES20.glUniform4fv(mColorHandle, 1, color, 0);
+
+ // Draw the triangle
+ GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
+
+ // Disable vertex array
+ GLES20.glDisableVertexAttribArray(mPositionHandle);
+}
+</pre>
+
+<p>Once you have all this code in place, drawing this object just requires a call to the
+{@code draw()} method from within your renderer’s {@link
+android.opengl.GLSurfaceView.Renderer#onDrawFrame onDrawFrame()} method. When you run the
+application, it should look something like this:</p>
+
+<img src="{@docRoot}images/opengl/ogl-triangle.png">
+<p class="img-caption">
+<strong>Figure 1.</strong> Triangle drawn without a projection or camera view.</p>
+
+<p>There are a few problems with this code example. First of all, it is not going to impress your
+friends. Secondly, the triangle is a bit squashed and changes shape when you change the screen
+orientation of the device. The reason the shape is skewed is due to the fact that the object’s
+vertices have not been corrected for the proportions of the screen area where the {@link
+android.opengl.GLSurfaceView} is displayed. You can fix that problem using a projection and camera
+view in the next lesson.</p>
+
+<p>Lastly, the triangle is stationary, which is a bit boring. In the <a href="motion.html">Adding
+Motion</a> lesson, you make this shape rotate and make more interesting use of the OpenGL ES
+graphics pipeline.</p>
\ No newline at end of file
diff --git a/docs/html/training/graphics/opengl/environment.jd b/docs/html/training/graphics/opengl/environment.jd
new file mode 100644
index 0000000..e1e2c8a
--- /dev/null
+++ b/docs/html/training/graphics/opengl/environment.jd
@@ -0,0 +1,223 @@
+page.title=Building an OpenGL ES Environment
+parent.title=Displaying Graphics with OpenGL ES
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Displaying Graphics with OpenGL ES
+previous.link=index.html
+next.title=Defining Shapes
+next.link=shapes.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#manifest">Declare OpenGL ES Use in the Manifest</a></li>
+ <li><a href="#activity">Create an Activity for OpenGL ES Graphics</a></li>
+ <li><a href="#glsurfaceview">Build a GLSurfaceView Object</a></li>
+ <li><a href="#renderer">Build a Renderer Class</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/OpenGLES.zip"
+class="button">Download the sample</a>
+ <p class="filename">OpenGLES.zip</p>
+</div>
+
+</div>
+</div>
+
+
+<p>In order to draw graphics with OpenGL ES in your Android application, you must create a
+view container for them. One of the more straight-forward ways to do this is to implement both a
+{@link android.opengl.GLSurfaceView} and a {@link android.opengl.GLSurfaceView.Renderer}. A {@link
+android.opengl.GLSurfaceView} is a view container for graphics drawn with OpenGL and {@link
+android.opengl.GLSurfaceView.Renderer} controls what is drawn within that view. For more information
+about these classes, see the <a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL ES</a>
+developer guide.</p>
+
+<p>{@link android.opengl.GLSurfaceView} is just one way to incorporate OpenGL ES graphics into your
+application. For a full-screen or near-full screen graphics view, it is a reasonable choice.
+Developers who want to incorporate OpenGL ES graphics in a small portion of their layouts should
+take a look at {@link android.view.TextureView}. For real, do-it-yourself developers, it is also
+possible to build up an OpenGL ES view using {@link android.view.SurfaceView}, but this requires
+writing quite a bit of additional code.</p>
+
+<p>This lesson explains how to complete a minimal implementation of {@link
+android.opengl.GLSurfaceView} and {@link android.opengl.GLSurfaceView.Renderer} in a simple
+application activity.</p>
+
+
+<h2 id="manifest">Declare OpenGL ES Use in the Manifest</h2>
+
+<p>In order for your application to use the OpenGL ES 2.0 API, you must add the following
+declaration to your manifest:</p>
+
+<pre>
+<uses-feature android:glEsVersion="0x00020000" android:required="true" />
+</pre>
+
+<p>If your application uses texture compression, you must also declare which compression formats
+you support so that devices that do not support theses formats do not try to run your
+application:</p>
+
+<pre>
+<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
+<supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />
+</pre>
+
+<p>For more information about texture compression formats, see the
+<a href="{@docRoot}guide/topics/graphics/opengl.html#textures">OpenGL</a> developer guide.</p>
+
+
+<h2 id="activity">Create an Activity for OpenGL ES Graphics</h2>
+
+<p>Android applications that use OpenGL ES have activities just like any other application that has
+a user interface. The main difference from other applications is what you put in the layout for your
+activity. While in many applications you might use {@link android.widget.TextView}, {@link
+android.widget.Button} and {@link android.widget.ListView}, in an app that uses OpenGL ES, you can
+also add a {@link android.opengl.GLSurfaceView}.</p>
+
+<p>The following code example shows a minimal implementation of an activity that uses a
+{@link android.opengl.GLSurfaceView} as its primary view:</p>
+
+<pre>
+public class OpenGLES20 extends Activity {
+
+ private GLSurfaceView mGLView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Create a GLSurfaceView instance and set it
+ // as the ContentView for this Activity.
+ mGLView = new MyGLSurfaceView(this);
+ setContentView(mGLView);
+ }
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> OpenGL ES 2.0 requires Android 2.2 (API Level 8) or higher,
+so make sure your Android project targets that API or higher.</p>
+
+
+<h2 id="glsurfaceview">Build a GLSurfaceView Object</h2>
+
+<p>A {@link android.opengl.GLSurfaceView} is a specialized view where you can draw OpenGL ES
+graphics.
+It does not do much by itself. The actual drawing of objects is controlled in the {@link
+android.opengl.GLSurfaceView.Renderer} that you set on this view. In fact, the code for this object
+is so thin, you may be tempted to skip extending it and just create an unmodified {@link
+android.opengl.GLSurfaceView} instance, but don’t do that. You need to extend this class in
+order to capture touch events, which is covered in the <a href="#touch.html">Responding to Touch
+Events</a> lesson.</p>
+
+<p>The essential code for a {@link android.opengl.GLSurfaceView} is minimal, so for a quick
+implementation, it is common to
+just create an inner class in the activity that uses it:</p>
+
+<pre>
+class MyGLSurfaceView extends GLSurfaceView {
+
+ public MyGLSurfaceView(Context context){
+ super(context);
+
+ // Set the Renderer for drawing on the GLSurfaceView
+ setRenderer(new MyRenderer());
+ }
+}
+</pre>
+
+<p>When using OpenGL ES 2.0, you must add another call to your {@link android.opengl.GLSurfaceView}
+constructor, specifying that you want to use the 2.0 API:</p>
+
+<pre>
+// Create an OpenGL ES 2.0 context
+setEGLContextClientVersion(2);
+</pre>
+
+<p class="note"><strong>Note:</strong> If you are using the OpenGL ES 2.0 API, make sure you declare
+this in your application manifest. For more information, see <a href="#manifest">Declare OpenGL ES
+Use
+in the Manifest</a>.</p>
+
+<p>One other optional addition to your {@link android.opengl.GLSurfaceView} implementation is to set
+the render mode to only draw the view when there is a change to your drawing data using the
+{@link android.opengl.GLSurfaceView#RENDERMODE_WHEN_DIRTY GLSurfaceView.RENDERMODE_WHEN_DIRTY}
+setting:</p>
+
+<pre>
+// Render the view only when there is a change in the drawing data
+setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+</pre>
+
+<p>This setting prevents the {@link android.opengl.GLSurfaceView} frame from being redrawn until you
+call {@link android.opengl.GLSurfaceView#requestRender requestRender()}, which is more
+efficient for this sample app.</p>
+
+
+<h2 id="renderer">Build a Renderer Class</h2>
+
+<p>The implementation of the {@link android.opengl.GLSurfaceView.Renderer} class, or renderer,
+within an application that uses OpenGL ES is where things start to get interesting. This class
+controls
+what gets drawn on the {@link android.opengl.GLSurfaceView} with which it is associated. There are
+three methods in a renderer that are called by the Android system in order to figure out what and
+how to draw on a {@link android.opengl.GLSurfaceView}:</p>
+
+<ul>
+ <li>{@link android.opengl.GLSurfaceView.Renderer#onSurfaceCreated onSurfaceCreated()} -
+Called once to set up the view's OpenGL ES environment.</li>
+ <li>{@link android.opengl.GLSurfaceView.Renderer#onDrawFrame onDrawFrame()} - Called for each
+redraw of the view.</li>
+ <li>{@link android.opengl.GLSurfaceView.Renderer#onSurfaceChanged onSurfaceChanged()} - Called if
+the geometry of the view changes, for example when the device's screen orientation changes.
+ </li>
+</ul>
+
+<p>Here is a very basic implementation of an OpenGL ES renderer, that does nothing more than draw a
+gray background in the {@link android.opengl.GLSurfaceView}:</p>
+
+<pre>
+public class MyGL20Renderer implements GLSurfaceView.Renderer {
+
+ public void onSurfaceCreated(GL10 unused, EGLConfig config) {
+ // Set the background frame color
+ GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+ }
+
+ public void onDrawFrame(GL10 unused) {
+ // Redraw background color
+ GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+ }
+
+ public void onSurfaceChanged(GL10 unused, int width, int height) {
+ GLES20.glViewport(0, 0, width, height);
+ }
+}
+</pre>
+
+<p>That’s all there is to it! The code examples above create a simple Android application that
+displays a gray screen using OpenGL. While this code does not do anything very interesting, by
+creating these classes, you have laid the foundation you need to start drawing graphic elements with
+OpenGL.</p>
+
+<p class="note"><strong>Note:</strong> You may wonder why these methods have a {@link
+javax.microedition.khronos.opengles.GL10} parameter, when you are using the OpengGL ES 2.0 APIs.
+These method signatures are simply reused for the 2.0 APIs to keep the Android framework code
+simpler.</p>
+
+<p>If you are familiar with the OpenGL ES APIs, you should now be able to set up a OpenGL ES
+environment in your app and start drawing graphics. However, if you need a bit more help getting
+started with OpenGL, head on to the next lessons for a few more hints.</p>
diff --git a/docs/html/training/graphics/opengl/index.jd b/docs/html/training/graphics/opengl/index.jd
new file mode 100644
index 0000000..23a734a
--- /dev/null
+++ b/docs/html/training/graphics/opengl/index.jd
@@ -0,0 +1,75 @@
+page.title=Displaying Graphics with OpenGL ES
+trainingnavtop=true
+next.title=Building an OpenGL ES Environment
+next.link=environment.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Dependencies and prerequisites</h2>
+<ul>
+ <li>Android 2.2 (API Level 8) or higher</li>
+ <li>Experience building an <a href="{@docRoot}training/basics/firstapp/index.html">Android
+app</a></li>
+</ul>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/OpenGLES.zip"
+class="button">Download the sample</a>
+ <p class="filename">OpenGLES.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>The Android framework provides plenty of standard tools for creating attractive, functional
+graphical user interfaces. However, if you want more control of what your application draws on
+screen, or are venturing into three dimensional graphics, you need to use a different tool. The
+OpenGL ES APIs provided by the Android framework offers a set of tools for displaying high-end,
+animated graphics that are limited only by your imagination and can also benefit from the
+acceleration of graphics processing units (GPUs) provided on many Android devices.</p>
+
+<p>This class walks you through the basics of developing applications that use OpenGL, including
+setup, drawing objects, moving drawn elements and responding to touch input.</p>
+
+<p>The example code in this class uses the OpenGL ES 2.0 APIs, which is the recommended API version
+to use with current Android devices. For more information about versions of OpenGL ES, see the <a
+href="{@docRoot}guide/topics/graphics/opengl.html#choosing-version">OpenGL</a>
+developer guide.</p>
+
+<p class="note"><strong>Note:</strong> Be careful not to mix OpenGL ES 1.x API calls with OpenGL
+ES 2.0 methods! The two APIs are not interchangeable and trying to use them together only results in
+frustration and sadness.</p>
+
+
+<h2>Lessons</h2>
+
+<dl>
+ <dt><b><a href="environment.html">Building an OpenGL ES Environment</a></b></dt>
+ <dd>Learn how to set up an Android application to be able to draw OpenGL graphics.</dd>
+
+ <dt><b><a href="shapes.html">Defining Shapes</a></b></dt>
+ <dd>Learn how to define shapes and why you need to know about faces and winding.</dd>
+
+ <dt><b><a href="draw.html">Drawing Shapes</a></b></dt>
+ <dd>Learn how to draw OpenGL shapes in your application.</dd>
+
+ <dt><b><a href="projection.html">Applying Projection and Camera Views</a></b></dt>
+ <dd>Learn how to use projection and camera views to get a new perspective on your drawn
+objects.</dd>
+
+ <dt><b><a href="motion.html">Adding Motion</a></b></dt>
+ <dd>Learn how to do basic movement and animation of drawn objects with OpenGL.</dd>
+
+ <dt><b><a href="touch.html">Responding to Touch Events</a></b></dt>
+ <dd>Learn how to do basic interaction with OpenGL graphics.</dd>
+</dl>
diff --git a/docs/html/training/graphics/opengl/motion.jd b/docs/html/training/graphics/opengl/motion.jd
new file mode 100644
index 0000000..6888235
--- /dev/null
+++ b/docs/html/training/graphics/opengl/motion.jd
@@ -0,0 +1,92 @@
+page.title=Adding Motion
+parent.title=Displaying Graphics with OpenGL ES
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Applying Projection and Camera Views
+previous.link=projection.html
+next.title=Responding to Touch Events
+next.link=touch.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#rotate-gl1">Rotate a Shape</a></li>
+ <li><a href="#cont-render">Enable Continuous Rendering</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li>
+</ul>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/OpenGLES.zip"
+class="button">Download the sample</a>
+ <p class="filename">OpenGLES.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Drawing objects on screen is a pretty basic feature of OpenGL, but you can do this with other
+Android graphics framwork classes, including {@link android.graphics.Canvas} and
+{@link android.graphics.drawable.Drawable} objects. OpenGL ES provides additional capabilities for
+moving and transforming drawn objects in three dimensions or in other unique ways to create
+compelling user experiences.</p>
+
+<p>In this lesson, you take another step forward into using OpenGL ES by learning how to add motion
+to a shape with rotation.</p>
+
+
+<h2 id="rotate">Rotate a Shape</h2>
+
+<p>Rotating a drawing object with OpenGL ES 2.0 is relatively simple. You create another
+transformation matrix (a rotation matrix) and then combine it with your projection and
+camera view tranformation matrices:</p>
+
+<pre>
+private float[] mRotationMatrix = new float[16];
+public void onDrawFrame(GL10 gl) {
+ ...
+ // Create a rotation transformation for the triangle
+ long time = SystemClock.uptimeMillis() % 4000L;
+ float angle = 0.090f * ((int) time);
+ Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);
+
+ // Combine the rotation matrix with the projection and camera view
+ Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);
+
+ // Draw triangle
+ mTriangle.draw(mMVPMatrix);
+}
+</pre>
+
+<p>If your triangle does not rotate after making these changes, make sure you have commented out the
+{@link android.opengl.GLSurfaceView#RENDERMODE_WHEN_DIRTY GLSurfaceView.RENDERMODE_WHEN_DIRTY}
+setting, as described in the next section.</p>
+
+
+<h2 id="cont-render">Enable Continuous Rendering</h2>
+
+<p>If you have diligently followed along with the example code in this class to this point, make
+sure you comment out the line that sets the render mode only draw when dirty, otherwise OpenGL
+rotates the shape only one increment and then waits for a call to {@link
+android.opengl.GLSurfaceView#requestRender requestRender()} from the {@link
+android.opengl.GLSurfaceView} container:</p>
+
+<pre>
+public MyGLSurfaceView(Context context) {
+ ...
+ // Render the view only when there is a change in the drawing data
+ //setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); // comment out for auto-rotation
+}
+</pre>
+
+<p>Unless you have objects changing without any user interaction, it’s usually a good idea have this
+flag turned on. Be ready to uncomment this code, because the next lesson makes this call applicable
+once again.</p>
diff --git a/docs/html/training/graphics/opengl/projection.jd b/docs/html/training/graphics/opengl/projection.jd
new file mode 100644
index 0000000..2a91093
--- /dev/null
+++ b/docs/html/training/graphics/opengl/projection.jd
@@ -0,0 +1,152 @@
+page.title=Applying Projection and Camera Views
+parent.title=Displaying Graphics with OpenGL ES
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Drawing Shapes
+previous.link=draw.html
+next.title=Applying Projection and Camera Views
+next.link=projection.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#projection">Define a Projection</a></li>
+ <li><a href="#camera-view">Define a Camera View</a></li>
+ <li><a href="#transform">Apply Projection and Camera Transformations</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li>
+</ul>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/OpenGLES.zip"
+class="button">Download the sample</a>
+ <p class="filename">OpenGLES.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>In the OpenGL ES environment, projection and camera views allow you to display drawn objects in a
+way that more closely resembles how you see physical objects with your eyes. This simulation of
+physical viewing is done with mathematical transformations of drawn object coordinates:</p>
+
+<ul>
+ <li><em>Projection</em> - This transformation adjusts the coordinates of drawn objects based on
+the width and height of the {@link android.opengl.GLSurfaceView} where they are displayed. Without
+this calculation, objects drawn by OpenGL ES are skewed by the unequal proportions of the view
+window. A projection transformation typically only has to be calculated when the proportions of the
+OpenGL view are established or changed in the {@link
+android.opengl.GLSurfaceView.Renderer#onSurfaceChanged
+onSurfaceChanged()} method of your renderer. For more information about OpenGL ES projections and
+coordinate mapping, see <a
+href="{@docRoot}guide/topics/graphics/opengl.html#coordinate-mapping">Mapping Coordinates for Drawn
+Objects</a>.</li>
+ <li><em>Camera View</em> - This transformation adjusts the coordinates of drawn objects based on a
+virtual camera position. It’s important to note that OpenGL ES does not define an actual camera
+object, but instead provides utility methods that simulate a camera by transforming the display of
+drawn objects. A camera view transformation might be calculated only once when you establish your
+{@link android.opengl.GLSurfaceView}, or might change dynamically based on user actions or your
+application’s function.</li>
+</ul>
+
+<p>This lesson describes how to create a projection and camera view and apply it to shapes drawn in
+your {@link android.opengl.GLSurfaceView}.</p>
+
+
+<h2 id="projection">Define a Projection</h2>
+
+<p>The data for a projection transformation is calculated in the {@link
+android.opengl.GLSurfaceView.Renderer#onSurfaceChanged onSurfaceChanged()}
+method of your {@link android.opengl.GLSurfaceView.Renderer} class. The following example code
+takes the height and width of the {@link android.opengl.GLSurfaceView} and uses it to populate a
+projection transformation {@link android.opengl.Matrix} using the {@link
+android.opengl.Matrix#frustumM Matrix.frustumM()} method:</p>
+
+<pre>
+@Override
+public void onSurfaceChanged(GL10 unused, int width, int height) {
+ GLES20.glViewport(0, 0, width, height);
+
+ float ratio = (float) width / height;
+
+ // this projection matrix is applied to object coordinates
+ // in the onDrawFrame() method
+ Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
+}
+</pre>
+
+<p>This code populates a projection matrix, {@code mProjMatrix} which you can then combine with a
+camera view transformation in the {@link android.opengl.GLSurfaceView.Renderer#onDrawFrame
+onDrawFrame()} method, which is shown in the next section.</p>
+
+<p class="note"><strong>Note:</strong> Just applying a projection transformation to your
+drawing objects typically results in a very empty display. In general, you must also apply a camera
+view transformation in order for anything to show up on screen.</p>
+
+
+<h2 id="camera-view">Define a Camera View</h2>
+
+<p>Complete the process of transforming your drawn objects by adding a camera view transformation as
+part of the drawing process. In the following example code, the camera view transformation is
+calculated using the {@link android.opengl.Matrix#setLookAtM Matrix.setLookAtM()} method and then
+combined with the previously calculated projection matrix. The combined transformation matrices
+are then passed to the drawn shape.</p>
+
+<pre>
+@Override
+public void onDrawFrame(GL10 unused) {
+ ...
+
+ // Set the camera position (View matrix)
+ Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+ // Calculate the projection and view transformation
+ Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
+
+ // Draw shape
+ mTriangle.draw(mMVPMatrix);
+}
+</pre>
+
+
+<h2 id="#transform">Apply Projection and Camera Transformations</h2>
+
+<p>In order to use the combined projection and camera view transformation matrix shown in the
+previews sections, modify the {@code draw()} method of your graphic objects to accept the combined
+transformation matrix and apply it to the shape:</p>
+
+<pre>
+public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
+ ...
+
+ // get handle to shape's transformation matrix
+ mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
+
+ // Apply the projection and view transformation
+ GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
+
+ // Draw the triangle
+ GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
+ ...
+}
+</pre>
+
+<p>Once you have correctly calulated and applied the projection and camera view transformations,
+your graphic objects are drawn in correct proportions and should look like this:</p>
+
+
+<img src="{@docRoot}images/opengl/ogl-triangle-projected.png">
+<p class="img-caption">
+<strong>Figure 1.</strong> Triangle drawn with a projection and camera view applied.</p>
+
+
+<p>Now that you have an application that displays your shapes in correct proportions, it's time to
+add motion to your shapes.</p>
diff --git a/docs/html/training/graphics/opengl/shapes.jd b/docs/html/training/graphics/opengl/shapes.jd
new file mode 100644
index 0000000..98381cc
--- /dev/null
+++ b/docs/html/training/graphics/opengl/shapes.jd
@@ -0,0 +1,153 @@
+page.title=Defining Shapes
+parent.title=Displaying Graphics with OpenGL ES
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Building an OpenGL ES Environment
+previous.link=environment.html
+next.title=Drawing Shapes
+next.link=draw.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#triangle">Define a Triangle</a></li>
+ <li><a href="#square">Define a Square</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li>
+</ul>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/OpenGLES.zip"
+class="button">Download the sample</a>
+ <p class="filename">OpenGLES.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Being able to define shapes to be drawn in the context of an OpenGL ES view is the first step in
+creating your high-end graphics masterpiece. Drawing with OpenGL ES can be a little tricky without
+knowing a few basic things about how OpenGL ES expects you to define graphic objects.</p>
+
+<p>This lesson explains the OpenGL ES coordinate system relative to an Android device screen, the
+basics of defining a shape, shape faces, as well as defining a triangle and a square.</p>
+
+
+<h2 id="triangle">Define a Triangle</h2>
+
+<p>OpenGL ES allows you to define drawn objects using coordinates in three-dimensional space. So,
+before you can draw a triangle, you must define its coordinates. In OpenGL, the typical way to do
+this is to define a vertex array of floating point numbers for the coordinates. For maximum
+efficiency, you write these coordinates into a {@link java.nio.ByteBuffer}, that is passed into the
+OpenGL ES graphics pipeline for processing.</p>
+
+<pre>
+class Triangle {
+
+ private FloatBuffer vertexBuffer;
+
+ // number of coordinates per vertex in this array
+ static final int COORDS_PER_VERTEX = 3;
+ static float triangleCoords[] = { // in counterclockwise order:
+ 0.0f, 0.622008459f, 0.0f, // top
+ -0.5f, -0.311004243f, 0.0f, // bottom left
+ 0.5f, -0.311004243f, 0.0f // bottom right
+ };
+
+ // Set color with red, green, blue and alpha (opacity) values
+ float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
+
+ public Triangle() {
+ // initialize vertex byte buffer for shape coordinates
+ ByteBuffer bb = ByteBuffer.allocateDirect(
+ // (number of coordinate values * 4 bytes per float)
+ triangleCoords.length * 4);
+ // use the device hardware's native byte order
+ bb.order(ByteOrder.nativeOrder());
+
+ // create a floating point buffer from the ByteBuffer
+ vertexBuffer = bb.asFloatBuffer();
+ // add the coordinates to the FloatBuffer
+ vertexBuffer.put(triangleCoords);
+ // set the buffer to read the first coordinate
+ vertexBuffer.position(0);
+ }
+}
+</pre>
+
+<p>By default, OpenGL ES assumes a coordinate system where [0,0,0] (X,Y,Z) specifies the center of
+the {@link android.opengl.GLSurfaceView} frame, [1,1,0] is the top right corner of the frame and
+[-1,-1,0] is bottom left corner of the frame. For an illustration of this coordinate system, see the
+<a href="{@docRoot}guide/topics/graphics/opengl.html#coordinate-mapping">OpenGL ES</a> developer
+guide.</p>
+
+<p>Note that the coordinates of this shape are defined in a counterclockwise order. The drawing
+order is important because it defines which side is the front face of the shape, which you typically
+want to have drawn, and the back face, which you can choose to not draw using the OpenGL ES cull
+face feature. For more information about faces and culling, see the <a
+href="{@docRoot}guide/topics/graphics/opengl.html#faces-winding">OpenGL ES</a> developer guide.</p>
+
+
+<h2 id="square">Define a Square</h2>
+
+<p>Defining triangles is pretty easy in OpenGL, but what if you want to get a just a little more
+complex? Say, a square? There are a number of ways to do this, but a typical path to drawing such a
+shape in OpenGL ES is to use two triangles drawn together:</p>
+
+<img src="{@docRoot}images/opengl/ccw-square.png">
+<p class="img-caption">
+ <strong>Figure 1.</strong> Drawing a square using two triangles.</p>
+
+<p>Again, you should define the vertices in a counterclockwise order for both triangles that
+represent this shape, and put the values in a {@link java.nio.ByteBuffer}. In order to avoid
+defining the two coordinates shared by each triangle twice, use a drawing list to tell the
+OpenGL ES graphics pipeline how to draw these vertices. Here’s the code for this shape:</p>
+
+<pre>
+class Square {
+
+ private FloatBuffer vertexBuffer;
+ private ShortBuffer drawListBuffer;
+
+ // number of coordinates per vertex in this array
+ static final int COORDS_PER_VERTEX = 3;
+ static float squareCoords[] = { -0.5f, 0.5f, 0.0f, // top left
+ -0.5f, -0.5f, 0.0f, // bottom left
+ 0.5f, -0.5f, 0.0f, // bottom right
+ 0.5f, 0.5f, 0.0f }; // top right
+
+ private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
+
+ public Square() {
+ // initialize vertex byte buffer for shape coordinates
+ ByteBuffer bb = ByteBuffer.allocateDirect(
+ // (# of coordinate values * 4 bytes per float)
+ squareCoords.length * 4);
+ bb.order(ByteOrder.nativeOrder());
+ vertexBuffer = bb.asFloatBuffer();
+ vertexBuffer.put(squareCoords);
+ vertexBuffer.position(0);
+
+ // initialize byte buffer for the draw list
+ ByteBuffer dlb = ByteBuffer.allocateDirect(
+ // (# of coordinate values * 2 bytes per short)
+ drawOrder.length * 2);
+ dlb.order(ByteOrder.nativeOrder());
+ drawListBuffer = dlb.asShortBuffer();
+ drawListBuffer.put(drawOrder);
+ drawListBuffer.position(0);
+ }
+}
+</pre>
+
+<p>This example gives you a peek at what it takes to create more complex shapes with OpenGL. In
+general, you use collections of triangles to draw objects. In the next lesson, you learn how to draw
+these shapes on screen.</p>
diff --git a/docs/html/training/graphics/opengl/touch.jd b/docs/html/training/graphics/opengl/touch.jd
new file mode 100644
index 0000000..c058a59
--- /dev/null
+++ b/docs/html/training/graphics/opengl/touch.jd
@@ -0,0 +1,145 @@
+page.title= Responding to Touch Events
+parent.title=Displaying Graphics with OpenGL ES
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Adding Motion
+previous.link=motion.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#listener">Setup a Touch Listener</a></li>
+ <li><a href="#angle">Expose the Rotation Angle</a></li>
+ <li><a href="#rotate">Apply Rotation</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li>
+</ul>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/OpenGLES.zip"
+class="button">Download the sample</a>
+ <p class="filename">OpenGLES.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Making objects move according to a preset program like the rotating triangle is useful for
+getting some attention, but what if you want to have users interact with your OpenGL ES graphics?
+The key to making your OpenGL ES application touch interactive is expanding your implementation of
+{@link android.opengl.GLSurfaceView} to override the {@link
+android.opengl.GLSurfaceView#onTouchEvent onTouchEvent()} to listen for touch events.</p>
+
+<p>This lesson shows you how to listen for touch events to let users rotate an OpenGL ES object.</p>
+
+
+<h2 id="listener">Setup a Touch Listener</h2>
+
+<p>In order to make your OpenGL ES application respond to touch events, you must implement the
+{@link android.opengl.GLSurfaceView#onTouchEvent onTouchEvent()} method in your
+{@link android.opengl.GLSurfaceView} class. The example implementation below shows how to listen for
+{@link android.view.MotionEvent#ACTION_MOVE MotionEvent.ACTION_MOVE} events and translate them to
+an angle of rotation for a shape.</p>
+
+<pre>
+@Override
+public boolean onTouchEvent(MotionEvent e) {
+ // MotionEvent reports input details from the touch screen
+ // and other input controls. In this case, you are only
+ // interested in events where the touch position changed.
+
+ float x = e.getX();
+ float y = e.getY();
+
+ switch (e.getAction()) {
+ case MotionEvent.ACTION_MOVE:
+
+ float dx = x - mPreviousX;
+ float dy = y - mPreviousY;
+
+ // reverse direction of rotation above the mid-line
+ if (y > getHeight() / 2) {
+ dx = dx * -1 ;
+ }
+
+ // reverse direction of rotation to left of the mid-line
+ if (x < getWidth() / 2) {
+ dy = dy * -1 ;
+ }
+
+ mRenderer.mAngle += (dx + dy) * TOUCH_SCALE_FACTOR; // = 180.0f / 320
+ requestRender();
+ }
+
+ mPreviousX = x;
+ mPreviousY = y;
+ return true;
+}
+</pre>
+
+<p>Notice that after calculating the rotation angle, this method calls {@link
+android.opengl.GLSurfaceView#requestRender requestRender()} to tell the
+renderer that it is time to render the frame. This approach is the most efficient in this example
+because the frame does not need to be redrawn unless there is a change in the rotation. However, it
+does not have any impact on efficiency unless you also request that the renderer only redraw when
+the data changes using the {@link android.opengl.GLSurfaceView#setRenderMode setRenderMode()}
+method, so make sure this line is uncommented in the renderer:</p>
+
+<pre>
+public MyGLSurfaceView(Context context) {
+ ...
+ // Render the view only when there is a change in the drawing data
+ <strong>setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);</strong>
+}
+</pre>
+
+<h2 id="angle">Expose the Rotation Angle</h2>
+
+<p>The example code above requires that you expose the rotation angle through your renderer by
+adding a public member. Since the renderer code is running on a separate thread from the main user
+interface thread of your application, you must declare this public variable as {@code volatile}.
+Here is the code to do that:</p>
+
+<pre>
+public class MyGLRenderer implements GLSurfaceView.Renderer {
+ ...
+ public volatile float mAngle;
+</pre>
+
+
+<h2 id="rotate">Apply Rotation</h2>
+
+<p>To apply the rotation generated by touch input, comment out the code that generates an angle and
+add {@code mAngle}, which contains the touch input generated angle:</p>
+
+<pre>
+public void onDrawFrame(GL10 gl) {
+ ...
+ // Create a rotation for the triangle
+ // long time = SystemClock.uptimeMillis() % 4000L;
+ // float angle = 0.090f * ((int) time);
+ <strong>Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);</strong>
+
+ // Combine the rotation matrix with the projection and camera view
+ Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);
+
+ // Draw triangle
+ mTriangle.draw(mMVPMatrix);
+}
+</pre>
+
+<p>When you have completed the steps described above, run the program and drag your finger over the
+screen to rotate the triangle:</p>
+
+<img src="{@docRoot}images/opengl/ogl-triangle-touch.png">
+<p class="img-caption">
+<strong>Figure 1.</strong> Triangle being rotated with touch input (circle shows touch
+location).</p>
diff --git a/docs/html/training/id-auth/index.jd b/docs/html/training/id-auth/index.jd
index 361e6cf..140545c 100644
--- a/docs/html/training/id-auth/index.jd
+++ b/docs/html/training/id-auth/index.jd
@@ -14,7 +14,7 @@
<h2>Requirements and prerequisites</h2>
<ul>
<li>Android 2.0 (API level 5) or higher</li>
- <li>Experience with <a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a></li>
+ <li>Experience with <a href="{@docRoot}guide/components/services.html">Services</a></li>
<li>Experience with <a href="http://oauth.net/2/">OAuth 2.0</a></li>
</ul>
diff --git a/docs/html/training/implementing-navigation/ancestral.jd b/docs/html/training/implementing-navigation/ancestral.jd
index 495b45d..ac35e64 100644
--- a/docs/html/training/implementing-navigation/ancestral.jd
+++ b/docs/html/training/implementing-navigation/ancestral.jd
@@ -22,7 +22,7 @@
<h2>You should also read</h2>
<ul>
<li><a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Providing Ancestral and Temporal Navigation</a></li>
- <li><a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
+ <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
<li><a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a></li>
</ul>
@@ -87,7 +87,7 @@
<p>When the current activity belongs to a task from a different application—for example if it was reached via an intent from another application—pressing <em>Up</em> should create a new task for the application with a synthesized back stack. This approach is described in <a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a> and the {@link android.support.v4.app.TaskStackBuilder} class reference.</p>
-<p>The {@link android.support.v4.app.NavUtils} and {@link android.support.v4.app.TaskStackBuilder} classes in the <a href="{@docRoot}sdk/compatibility-library.html">Android Support Package</a> provide helpers for implementing this behavior correctly. An example usage of these two helper classes is below:</p>
+<p>The {@link android.support.v4.app.NavUtils} and {@link android.support.v4.app.TaskStackBuilder} classes in the <a href="{@docRoot}tools/extras/support-library.html">Android Support Package</a> provide helpers for implementing this behavior correctly. An example usage of these two helper classes is below:</p>
<pre>
{@literal @}Override
diff --git a/docs/html/training/implementing-navigation/index.jd b/docs/html/training/implementing-navigation/index.jd
index da61c81..ebb4995 100644
--- a/docs/html/training/implementing-navigation/index.jd
+++ b/docs/html/training/implementing-navigation/index.jd
@@ -15,7 +15,7 @@
<ul>
<li>API level 14</li>
<li>Understanding of fragments and Android layouts</li>
- <li><a href="{@docRoot}sdk/compatibility-library.html">The Android Support Package</a></li>
+ <li><a href="{@docRoot}tools/extras/support-library.html">The Android Support Package</a></li>
<li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a></li>
</ul>
@@ -23,7 +23,7 @@
<ul>
<li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a></li>
- <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a></li>
+ <li><a href="{@docRoot}guide/components/fragments.html">Fragments</a></li>
<li><a href="{@docRoot}training/multiscreen/index.html">Designing for Multiple Screens</a></li>
</ul>
diff --git a/docs/html/training/implementing-navigation/lateral.jd b/docs/html/training/implementing-navigation/lateral.jd
index d9ba5c9..76acf03 100644
--- a/docs/html/training/implementing-navigation/lateral.jd
+++ b/docs/html/training/implementing-navigation/lateral.jd
@@ -119,7 +119,7 @@
<h2 id="horizontal-paging">Implement Horizontal Paging (Swipe Views)</h2>
-<p>Horizontal paging, or swipe views, allow users to <a href="{@docRoot}design/patterns/swipe-views">swipe</a> horizontally on the current screen to navigate to adjacent screens. This pattern can be implemented using the {@link android.support.v4.view.ViewPager} widget, currently available as part of the <a href="{@docRoot}sdk/compatibility-library.html">Android Support Package</a>. For navigating between sibling screens representing a fixed number of sections, it's best to provide the {@link android.support.v4.view.ViewPager} with a {@link android.support.v4.app.FragmentPagerAdapter}. For horizontal paging across collections of objects, it's best to use a {@link android.support.v4.app.FragmentStatePagerAdapter}, which destroys fragments as the user navigates to other pages, minimizing memory usage.</p>
+<p>Horizontal paging, or swipe views, allow users to <a href="{@docRoot}design/patterns/swipe-views">swipe</a> horizontally on the current screen to navigate to adjacent screens. This pattern can be implemented using the {@link android.support.v4.view.ViewPager} widget, currently available as part of the <a href="{@docRoot}tools/extras/support-library.html">Android Support Package</a>. For navigating between sibling screens representing a fixed number of sections, it's best to provide the {@link android.support.v4.view.ViewPager} with a {@link android.support.v4.app.FragmentPagerAdapter}. For horizontal paging across collections of objects, it's best to use a {@link android.support.v4.app.FragmentStatePagerAdapter}, which destroys fragments as the user navigates to other pages, minimizing memory usage.</p>
<p>Below is an example of using a {@link android.support.v4.view.ViewPager} to swipe across a collection of objects.</p>
diff --git a/docs/html/training/implementing-navigation/temporal.jd b/docs/html/training/implementing-navigation/temporal.jd
index f36991f..1c41732 100644
--- a/docs/html/training/implementing-navigation/temporal.jd
+++ b/docs/html/training/implementing-navigation/temporal.jd
@@ -22,7 +22,7 @@
<h2>You should also read</h2>
<ul>
<li><a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Providing Ancestral and Temporal Navigation</a></li>
- <li><a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
+ <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
<li><a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a></li>
</ul>
@@ -32,7 +32,7 @@
<p><em>Temporal navigation</em> is navigation to previously visited screens. Users can visit previous screens by pressing the device <em>Back</em> button. This user interface pattern is described further in <a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Providing Ancestral and Temporal Navigation</a> in <em>Designing Effective Navigation</em> and in <a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a>.</p>
-<p>Android handles basic <em>Back</em> navigation for you (see <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a> for details on this behavior). This lesson discusses a number of cases where applications should provide specialized logic for the <em>Back</em> button.</p>
+<p>Android handles basic <em>Back</em> navigation for you (see <a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back Stack</a> for details on this behavior). This lesson discusses a number of cases where applications should provide specialized logic for the <em>Back</em> button.</p>
<h2 id="back-fragments">Implement <em>Back</em> Navigation with Fragments</h2>
diff --git a/docs/html/training/improving-layouts/optimizing-layout.jd b/docs/html/training/improving-layouts/optimizing-layout.jd
index 0eaf199..520ce56 100644
--- a/docs/html/training/improving-layouts/optimizing-layout.jd
+++ b/docs/html/training/improving-layouts/optimizing-layout.jd
@@ -44,8 +44,8 @@
android.widget.GridView}.</p>
<p>In this lesson you'll learn to use <a
-href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">Hierarchy Viewer</a> and <a
-href="{@docRoot}guide/developing/tools/layoutopt.html">Layoutopt</a> to examine and optimize your
+href="{@docRoot}tools/help/hierarchy-viewer.html">Hierarchy Viewer</a> and <a
+href="{@docRoot}tools/help/layoutopt.html">Layoutopt</a> to examine and optimize your
layout.</p>
@@ -53,7 +53,7 @@
<h2 id="Inspect">Inspect Your Layout</h2>
<p>The Android SDK tools include a tool called <a
-href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">Hierarchy Viewer</a> that allows
+href="{@docRoot}tools/help/hierarchy-viewer.html">Hierarchy Viewer</a> that allows
you to analyze your layout while your application is running. Using this tool helps you discover
bottlenecks in the layout performance.</p>
diff --git a/docs/html/training/index.jd b/docs/html/training/index.jd
index 8bf32bb..3c67af9 100644
--- a/docs/html/training/index.jd
+++ b/docs/html/training/index.jd
@@ -1,18 +1,14 @@
-page.title=Orientation to Android Training
+page.title=Android Training
page.metaDescription=Android Training provides a collection of classes that aim to help you build great apps for Android. Each class explains the steps required to solve a problem or implement a feature using code snippets and sample code for you to use in your apps.
@jd:body
-<div class="figure" style="width:450px;margin-top:-30px">
- <img src="{@docRoot}images/training/training-prof.png" alt="" />
-</div>
-
<p>Welcome to Android Training. Here you'll find a collection of classes that aim to help you
build great apps for Android, using best practices in a variety of framework topics.</p>
<p>Each class explains the steps required to solve a problem or implement a feature using code
snippets and sample code for you to use in your apps.</p>
-<p>What you see now is just the beginning. We plan to add many more classes, expand and refine
-existing classes, and build Training Courses that help you enhance your apps using
-objective-oriented collections of classes.</p>
+<p>This first section is focused on teaching you the bare essentials. If you're a new developer
+on Android, you should walk through each of these classes, beginning with
+<a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a>.</p></a>
diff --git a/docs/html/training/managing-audio/index.jd b/docs/html/training/managing-audio/index.jd
index 3aa2d88..0f7bbfd 100644
--- a/docs/html/training/managing-audio/index.jd
+++ b/docs/html/training/managing-audio/index.jd
@@ -19,7 +19,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a></li>
+ <li><a href="{@docRoot}guide/components/services.html">Services</a></li>
</ul>
</div>
diff --git a/docs/html/training/monitoring-device-state/battery-monitoring.jd b/docs/html/training/monitoring-device-state/battery-monitoring.jd
index 6e25df8..c963a18 100644
--- a/docs/html/training/monitoring-device-state/battery-monitoring.jd
+++ b/docs/html/training/monitoring-device-state/battery-monitoring.jd
@@ -21,7 +21,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
</ul>
</div>
diff --git a/docs/html/training/monitoring-device-state/connectivity-monitoring.jd b/docs/html/training/monitoring-device-state/connectivity-monitoring.jd
index 98ba63c..11a05e1 100644
--- a/docs/html/training/monitoring-device-state/connectivity-monitoring.jd
+++ b/docs/html/training/monitoring-device-state/connectivity-monitoring.jd
@@ -24,7 +24,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
</ul>
</div>
diff --git a/docs/html/training/monitoring-device-state/docking-monitoring.jd b/docs/html/training/monitoring-device-state/docking-monitoring.jd
index 82d655e..3787a55 100644
--- a/docs/html/training/monitoring-device-state/docking-monitoring.jd
+++ b/docs/html/training/monitoring-device-state/docking-monitoring.jd
@@ -23,7 +23,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
</ul>
</div>
diff --git a/docs/html/training/monitoring-device-state/index.jd b/docs/html/training/monitoring-device-state/index.jd
index 61f7176..585b669 100644
--- a/docs/html/training/monitoring-device-state/index.jd
+++ b/docs/html/training/monitoring-device-state/index.jd
@@ -13,12 +13,12 @@
<h2>Dependencies and prerequisites</h2>
<ul>
<li>Android 2.0 (API level 5) or higher</li>
- <li>Experience with <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a></li>
+ <li>Experience with <a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a></li>
</ul>
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a>
+ <li><a href="{@docRoot}guide/components/services.html">Services</a>
</ul>
</div>
diff --git a/docs/html/training/monitoring-device-state/manifest-receivers.jd b/docs/html/training/monitoring-device-state/manifest-receivers.jd
index 0b79ce6..d4aeed3 100644
--- a/docs/html/training/monitoring-device-state/manifest-receivers.jd
+++ b/docs/html/training/monitoring-device-state/manifest-receivers.jd
@@ -21,7 +21,7 @@
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
</ul>
</div>
diff --git a/docs/html/training/multiple-apks/api.jd b/docs/html/training/multiple-apks/api.jd
index 3492245..1a2593a 100644
--- a/docs/html/training/multiple-apks/api.jd
+++ b/docs/html/training/multiple-apks/api.jd
@@ -33,7 +33,7 @@
<!-- other docs (NOT javadocs) -->
<h2>You should also read</h2>
<ul>
- <li><a href="http://developer.android.com/guide/market/publishing/multiple-apks.html">Multiple APK
+ <li><a href="http://developer.android.com/guide/google/play/publishing/multiple-apks.html">Multiple APK
Support</a></li>
<li><a
href="http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html">
@@ -57,7 +57,7 @@
platform, naturally you want your application to take advantage of new features on new devices,
without sacrificing backwards compatibility. It may seem at the outset as though multiple APK
support is the best solution, but this often isn’t the case. The <a
-href="{@docRoot}guide/market/publishing/multiple-apks.html#ApiLevelOptions">Using Single APK
+href="{@docRoot}guide/google/play/publishing/multiple-apks.html#ApiLevelOptions">Using Single APK
Instead</a> section of the multiple APK developer guide includes some useful information on how to
accomplish this with a single APK, including use of our support library. You can also learn how to
write code that runs only at certain API levels in a single APK, without resorting to
@@ -85,7 +85,7 @@
<p>Start off by creating a simple chart to quickly determine how many APKs you need, and what API
range each APK covers. For handy reference, the <a
-href="{@docRoot}resources/dashboard/platform-versions.html">Platform Versions</a> page of the
+href="{@docRoot}about/dashboards/index.html">Platform Versions</a> page of the
Android Developer website provides data about the relative number of active devices running a given
version of the Android platform. Also, although it sounds easy at first, keeping track of which set
of API levels each APK is going to target gets difficult rather quickly, especially if there’s going
@@ -153,10 +153,10 @@
their creation at the following links:</p>
<ul>
<li><a
-href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
+href="{@docRoot}tools/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
a library project (Eclipse)</a></li>
<li><a
-href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
+href="{@docRoot}tools/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
a library project (Command line)</a></li>
</ul>
@@ -279,7 +279,7 @@
<p>
Now, let’s further assume that the Red APK has some requirement on it that the other two don’t.
-<a href="{@docRoot}guide/appendix/market-filters.html">Filters on Google Play</a> page of
+<a href="{@docRoot}guide/google/play/filters.html">Filters on Google Play</a> page of
the Android Developer guide has a whole list of possible culprits. For the
sake of example, let’s assume that red requires a front-facing camera. In fact, the entire point of
the red APK is to combine the front-facing camera with sweet new functionality that was added in API
@@ -296,7 +296,7 @@
<p> In order to keep all your APKs on separate "tracks", it’s important to have a good version code
scheme. The recommended one can be found on the <a
-href="{@docRoot}guide/market/publishing/multiple-apks.html#VersionCodes">Version Codes</a> area of
+href="{@docRoot}guide/google/play/publishing/multiple-apks.html#VersionCodes">Version Codes</a> area of
our developer guide. Since the example set of APKs is only dealing with one of 3 possible
dimensions, it would be sufficient to separate each APK by 1000, set the first couple digits to the
minSdkVersion for that particular APK, and increment from there. This might look like:</p>
diff --git a/docs/html/training/multiple-apks/index.jd b/docs/html/training/multiple-apks/index.jd
index d92c106..1f2fee8 100644
--- a/docs/html/training/multiple-apks/index.jd
+++ b/docs/html/training/multiple-apks/index.jd
@@ -23,7 +23,7 @@
<!-- related docs (NOT javadocs) -->
<h2>You should also read</h2>
<ul>
- <li><a href="http://developer.android.com/guide/market/publishing/multiple-apks.html">Multiple APK
+ <li><a href="http://developer.android.com/guide/google/play/publishing/multiple-apks.html">Multiple APK
Support</a></li>
</ul>
diff --git a/docs/html/training/multiple-apks/multiple.jd b/docs/html/training/multiple-apks/multiple.jd
index b30068f..25938da 100644
--- a/docs/html/training/multiple-apks/multiple.jd
+++ b/docs/html/training/multiple-apks/multiple.jd
@@ -33,7 +33,7 @@
<!-- other docs (NOT javadocs) -->
<h2>You should also read</h2>
<ul>
- <li><a href="http://developer.android.com/guide/market/publishing/multiple-apks.html">Multiple APK
+ <li><a href="http://developer.android.com/guide/google/play/publishing/multiple-apks.html">Multiple APK
Support</a></li>
</ul>
@@ -54,7 +54,7 @@
take advantage of the space of large screens but still work on small ones, to use new Android API
features or visual textures available on cutting edge devices but not abandon older ones. It may
seem at the outset as though multiple APK support is the best solution, but this often isn’t the
-case. The <a href="{@docRoot}guide/market/publishing/multiple-apks.html#ApiLevelOptions">Using
+case. The <a href="{@docRoot}guide/google/play/publishing/multiple-apks.html#ApiLevelOptions">Using
Single APK Instead</a> section of the multiple APK guide includes some useful information on how to
accomplish all of this with a single APK, including use of our <a
href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html">support library</a>,
@@ -182,10 +182,10 @@
their creation at the following links:</p>
<ul>
<li><a
-href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
+href="{@docRoot}tools/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
a library project (Eclipse)</a></li>
<li><a
-href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
+href="{@docRoot}tools/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
a library project (Command line)</a></li>
</ul>
@@ -329,7 +329,7 @@
Purple ≥ Red ≥ Green ≥ Blue
</p><p>
Why allow all the overlap? Let’s pretend that the Purple APK has some requirement on it that the
-other two don’t. The <a href="{@docRoot}guide/appendix/market-filters.html">Filters on Google Play</a> page
+other two don’t. The <a href="{@docRoot}guide/google/play/filters.html">Filters on Google Play</a> page
of the Android Developer guide has a whole list of possible culprits. For the sake of example,
let’s assume that Purple requires a front-facing camera. In fact, the entire point of Purple is to
use entertaining things with the front-facing camera! But, it turns out, not all API 11+ devices
@@ -345,7 +345,7 @@
<p> In order to keep all your APKs on separate "tracks", it’s important to have a good version code
scheme. The recommended one can be found on the <a
-href="{@docRoot}guide/market/publishing/multiple-apks.html#VersionCodes">Version Codes</a> area of
+href="{@docRoot}guide/google/play/publishing/multiple-apks.html#VersionCodes">Version Codes</a> area of
our developer guide. It’s worth reading the whole section, but the basic gist is for this set of
APKs, we’d use two digits to represent the minSDK, two to represent the min/max screen size, and 3
to represent the build number. That way, when the device upgraded to a new version of Android,
diff --git a/docs/html/training/multiple-apks/screensize.jd b/docs/html/training/multiple-apks/screensize.jd
index ac679a7..ea793db 100644
--- a/docs/html/training/multiple-apks/screensize.jd
+++ b/docs/html/training/multiple-apks/screensize.jd
@@ -34,7 +34,7 @@
<!-- other docs (NOT javadocs) -->
<h2>You should also read</h2>
<ul>
- <li><a href="http://developer.android.com/guide/market/publishing/multiple-apks.html">Multiple APK
+ <li><a href="http://developer.android.com/guide/google/play/publishing/multiple-apks.html">Multiple APK
Support</a></li>
<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
</ul>
@@ -56,7 +56,7 @@
naturally you want your application to take advantage of all the available space on larger devices,
without sacrificing compatibility or usability on the smaller screens. It may seem at the outset as
though multiple APK support is the best solution, but this often isn’t the case. The <a
-href="{@docRoot}guide/market/publishing/multiple-apks.html#ApiLevelOptions">Using Single APK
+href="{@docRoot}guide/google/play/publishing/multiple-apks.html#ApiLevelOptions">Using Single APK
Instead</a> section of the multiple APK developer guide includes some useful information on how to
accomplish this with a single APK, including use of our support library. You should also read the
guide to <a href="{@docRoot}guide/practices/screens_support.html">supporting multiple screens</a>,
@@ -130,10 +130,10 @@
their creation at the following links:</p>
<ul>
<li><a
-href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
+href="{@docRoot}tools/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
a library project (Eclipse)</a></li>
<li><a
-href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
+href="{@docRoot}tools/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
a library project (Command line)</a></li>
</ul>
@@ -227,7 +227,7 @@
</table>
<p>
Now, let’s further assume that the Red APK has some requirement on it that the other two don’t. The
-<a href="{@docRoot}guide/appendix/market-filters.html">Filters on Google Play</a> page of the Android
+<a href="{@docRoot}guide/google/play/filters.html">Filters on Google Play</a> page of the Android
Developer guide has a whole list of possible culprits. For the sake of example, let’s assume that
red requires a front-facing camera. In fact, the entire point of the red APK is to use the extra
available screen space to do entertaining things with that front-facing camera. But, it turns out,
@@ -243,7 +243,7 @@
<p> In order to keep all your APKs on separate "tracks", it’s important to have a good version code
scheme. The recommended one can be found on the <a
-href="{@docRoot}guide/market/publishing/multiple-apks.html#VersionCodes">Version Codes</a> area of
+href="{@docRoot}guide/google/play/publishing/multiple-apks.html#VersionCodes">Version Codes</a> area of
our developer guide. Since the example set of APKs is only dealing with one of 3 possible
dimensions, it would be sufficient to separate each APK by 1000 and increment from there. This
might look like:</p>
diff --git a/docs/html/training/multiple-apks/texture.jd b/docs/html/training/multiple-apks/texture.jd
index 497d6b8..70ad1e0 100644
--- a/docs/html/training/multiple-apks/texture.jd
+++ b/docs/html/training/multiple-apks/texture.jd
@@ -33,7 +33,7 @@
<!-- other docs (NOT javadocs) -->
<h2>You should also read</h2>
<ul>
- <li><a href="http://developer.android.com/guide/market/publishing/multiple-apks.html">Multiple APK
+ <li><a href="http://developer.android.com/guide/google/play/publishing/multiple-apks.html">Multiple APK
Support</a></li>
</ul>
@@ -49,10 +49,10 @@
devices, naturally you want your application look its best on each individual device, regardless of
the fact they don’t all support the same set of GL textures. It may seem at the outset as though
multiple APK support is the best solution, but this often isn’t the case. The <a
-href="{@docRoot}guide/market/publishing/multiple-apks.html#ApiLevelOptions">Using Single APK
+href="{@docRoot}guide/google/play/publishing/multiple-apks.html#ApiLevelOptions">Using Single APK
Instead</a> section of the multiple APK developer guide includes some useful information on how to
accomplish this with a single APK, including how to <a
-href="{@docRoot}guide/market/publishing/multiple-apks.html#TextureOptions">detect supported texture
+href="{@docRoot}guide/google/play/publishing/multiple-apks.html#TextureOptions">detect supported texture
formats at runtime</a>. Depending on your situation, it might be easier to bundle all formats with
your application, and simply pick which one to use at runtime.</p>
@@ -113,10 +113,10 @@
their creation at the following links:</p>
<ul>
<li><a
-href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
+href="{@docRoot}tools/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
a library project (Eclipse)</a></li>
<li><a
-href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
+href="{@docRoot}tools/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
a library project (Command line)</a></li>
</ul>
diff --git a/docs/html/training/multiscreen/index.jd b/docs/html/training/multiscreen/index.jd
index a986cef..23f6564 100644
--- a/docs/html/training/multiscreen/index.jd
+++ b/docs/html/training/multiscreen/index.jd
@@ -15,12 +15,12 @@
<ul>
<li>Android 1.6 or higher (2.1+ for the sample app)</li>
<li>Basic knowledge of <a
-href="http://developer.android.com/guide/topics/fundamentals/activities.html">Activities</a> and
-<a href="http://developer.android.com/guide/topics/fundamentals/fragments.html">Fragments</a></li>
+href="http://developer.android.com/guide/components/activities.html">Activities</a> and
+<a href="http://developer.android.com/guide/components/fragments.html">Fragments</a></li>
<li>Experience building an Android <a
href="http://developer.android.com/guide/topics/ui/index.html"> User Interface</a></li>
<li>Several features require the use of the <a
-href="{@docRoot}sdk/compatibility-library.html">support library</a></li>
+href="{@docRoot}tools/extras/support-library.html">support library</a></li>
</ul>
<h2>You should also read</h2>
@@ -59,7 +59,7 @@
of reusable code for your own application.</p>
<p class="note"><strong>Note:</strong> This class and the associated sample use the <a
-href="{@docRoot}sdk/compatibility-library.html">support library</a> in order to use the {@link
+href="{@docRoot}tools/extras/support-library.html">support library</a> in order to use the {@link
android.app.Fragment} APIs on versions lower than Android 3.0. You must download and add the
library to your application in order to use all APIs in this class.</p>
diff --git a/docs/html/training/multiscreen/screensizes.jd b/docs/html/training/multiscreen/screensizes.jd
index bf19b08..a34c3d5 100644
--- a/docs/html/training/multiscreen/screensizes.jd
+++ b/docs/html/training/multiscreen/screensizes.jd
@@ -348,7 +348,7 @@
<p class="img-caption"><strong>Figure 4.</strong> <code>button.png</code></p>
<p>And then run it through the <ode
-href="{@docRoot}guide/developing/tools/draw9patch.html"><code>draw9patch</code></a> utility of the
+href="{@docRoot}tools/help/draw9patch.html"><code>draw9patch</code></a> utility of the
SDK (which is located in the <code>tools/</code> directory), in which you can mark the areas that
should be stretched by drawing pixels along the left and top borders. You can also mark the area
that should hold the content by drawing pixels along the right and bottom borders, resulting in
diff --git a/docs/html/training/sharing/index.jd b/docs/html/training/sharing/index.jd
index 9ee5e29..c2e8dbc 100644
--- a/docs/html/training/sharing/index.jd
+++ b/docs/html/training/sharing/index.jd
@@ -14,7 +14,7 @@
<h2>Dependencies and prerequisites</h2>
<ul>
<li>Android 1.0 or higher (greater requirements where noted)</li>
- <li>Experience with <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
+ <li>Experience with <a href="{@docRoot}guide/components/intents-filters.html">Intents and
Intent Filters</a></li>
</ul>
diff --git a/docs/html/training/sharing/receive.jd b/docs/html/training/sharing/receive.jd
index 9c932b1..7ec3def 100644
--- a/docs/html/training/sharing/receive.jd
+++ b/docs/html/training/sharing/receive.jd
@@ -23,7 +23,7 @@
<!-- other docs (NOT javadocs) -->
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and
Intent Filters</a></li>
</ul>
@@ -48,7 +48,7 @@
lesson, you create intent filters in order to be able to receive intents with this action. You
define an intent filter in your manifest, using the
<code><a
-href="{@docRoot}guide/topics/intents/intents-filters.html#ifs"><intent-filter></a></code>
+href="{@docRoot}guide/components/intents-filters.html#ifs"><intent-filter></a></code>
element. For example, if your application handles receiving text content, a single image of any
type, or multiple images of any type, your manifest would look like:</p>
@@ -73,7 +73,7 @@
</pre>
<p class="note"><strong>Note:</strong> For more information on intent filters and intent resolution
-please read <a href="{@docRoot}guide/topics/intents/intents-filters.html#ifs">Intents and Intent
+please read <a href="{@docRoot}guide/components/intents-filters.html#ifs">Intents and Intent
Filters</a></p>
<p>When another application tries to share any of these things by constructing an intent and passing
diff --git a/docs/html/training/sharing/send.jd b/docs/html/training/sharing/send.jd
index afb0e34..741c017 100644
--- a/docs/html/training/sharing/send.jd
+++ b/docs/html/training/sharing/send.jd
@@ -22,7 +22,7 @@
<!-- other docs (NOT javadocs) -->
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
+ <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and
Intent Filters</a></li>
</ul>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
new file mode 100644
index 0000000..77a6837
--- /dev/null
+++ b/docs/html/training/training_toc.cs
@@ -0,0 +1,685 @@
+<ul id="nav">
+
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/index.html">
+ <span class="en">Get Started</span>
+ </a>
+ </div>
+
+ <ul>
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/basics/firstapp/index.html">
+ <span class="en">Building Your First App</span>
+ </a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/firstapp/creating-project.html">
+ <span class="en">Creating an Android Project</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/firstapp/running-app.html">
+ <span class="en">Running Your Application</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/firstapp/building-ui.html">
+ <span class="en">Building a Simple User Interface</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/firstapp/starting-activity.html">
+ <span class="en">Starting Another Activity</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/index.html">
+ <span class="en">Managing the Activity Lifecycle</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/starting.html">
+ <span class="en">Starting an Activity</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/pausing.html">
+ <span class="en">Pausing and Resuming an Activity</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/stopping.html">
+ <span class="en">Stopping and Restarting an Activity</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/recreating.html">
+ <span class="en">Recreating an Activity</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/basics/supporting-devices/index.html">
+ <span class="en">Supporting Different Devices</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/supporting-devices/languages.html">
+ <span class="en">Supporting Different Languages</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/supporting-devices/screens.html">
+ <span class="en">Supporting Different Screens</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/supporting-devices/platforms.html">
+ <span class="en">Supporting Different Platform Versions</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/basics/fragments/index.html">
+ <span class="en">Building a Dynamic UI with Fragments</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/fragments/support-lib.html">
+ <span class="en">Using the Support Library</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/fragments/creating.html">
+ <span class="en">Creating a Fragment</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/fragments/fragment-ui.html">
+ <span class="en">Building a Flexible UI</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/fragments/communicating.html">
+ <span class="en">Communicating with Other Fragments</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/basics/intents/index.html">
+ <span class="en">Interacting with Other Apps</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/intents/sending.html">
+ <span class="en">Sending the User to Another App</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/intents/result.html">
+ <span class="en">Getting a Result from the Activity</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/intents/filters.html">
+ <span class="en">Allowing Other Apps to Start Your Activity</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+
+ </ul>
+ </li><!-- end basic training -->
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/advanced.html">
+ <span class="en">Advanced Training</span>
+ </a>
+ </div>
+ <ul>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/basics/location/index.html">
+ <span class="en">Making Your App Location Aware</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/location/locationmanager.html">
+ <span class="en">Using the Location Manager</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/location/currentlocation.html">
+ <span class="en">Obtaining the Current Location</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/location/geocoding.html">
+ <span class="en">Displaying a Location Address</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/basics/network-ops/index.html">
+ <span class="en">Performing Network Operations</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/network-ops/connecting.html">
+ <span class="en">Connecting to the Network</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/network-ops/managing.html">
+ <span class="en">Managing Network Usage</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/network-ops/xml.html">
+ <span class="en">Parsing XML Data</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/efficient-downloads/index.html">
+ <span class="en">Transferring Data Without Draining the Battery</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/efficient-downloads/efficient-network-access.html">
+ <span class="en">Optimizing Downloads for Efficient Network Access</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/efficient-downloads/regular_updates.html">
+ <span class="en">Minimizing the Effect of Regular Updates</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/efficient-downloads/redundant_redundant.html">
+ <span class="en">Redundant Downloads are Redundant</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/efficient-downloads/connectivity_patterns.html">
+ <span class="en">Modifying Patterns Based on the Connectivity Type</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/cloudsync/index.html">
+ <span class="en">Syncing to the Cloud</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/cloudsync/aesync.html">
+ <span class="en">Syncing with App Engine</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/cloudsync/backupapi.html">
+ <span class="en">Using the Backup API</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/multiscreen/index.html">
+ <span class="en">Designing for Multiple Screens</span>
+ <span class="es">Cómo diseñar aplicaciones para varias pantallas</span>
+ <span class="ja">複数画面のデザイン</span>
+ <span class="ko">Designing for Multiple Screens</span>
+ <span class="ru">Designing for Multiple Screens</span>
+ <span class="zh-CN">针对多种屏幕进行设计</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/multiscreen/screensizes.html">
+ <span class="en">Supporting Different Screen Sizes</span>
+ <span class="es">Cómo admitir varios tamaños de pantalla</span>
+ <span class="ja">さまざまな画面サイズのサポート</span>
+ <span class="ko">다양한 화면 크기 지원</span>
+ <span class="ru">Supporting Different Screen Sizes</span>
+ <span class="zh-CN">支持各种屏幕尺寸</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/multiscreen/screendensities.html">
+ <span class="en">Supporting Different Screen Densities</span>
+ <span class="es">Cómo admitir varias densidades de pantalla</span>
+ <span class="ja">さまざまな画面密度のサポート</span>
+ <span class="ko">Supporting Different Screen Densities</span>
+ <span class="ru">Supporting Different Screen Densities</span>
+ <span class="zh-CN">支持各种屏幕密度</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/multiscreen/adaptui.html">
+ <span class="en">Implementing Adaptive UI Flows</span>
+ <span class="es">Cómo implementar interfaces de usuario adaptables</span>
+ <span class="ja">順応性のある UI フローの実装</span>
+ <span class="ko">Implementing Adaptive UI Flows</span>
+ <span class="ru">Implementing Adaptive UI Flows</span>
+ <span class="zh-CN">实施自适应用户界面流程</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/improving-layouts/index.html">
+ <span class="en">Improving Layout Performance</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/improving-layouts/optimizing-layout.html">
+ <span class="en">Optimizing Layout Hierarchies</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/improving-layouts/reusing-layouts.html">
+ <span class="en">Re-using Layouts with <include/></span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/improving-layouts/loading-ondemand.html">
+ <span class="en">Loading Views On Demand</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/improving-layouts/smooth-scrolling.html">
+ <span class="en">Making ListView Scrolling Smooth</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/managing-audio/index.html">
+ <span class="en">Managing Audio Playback</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/managing-audio/volume-playback.html">
+ <span class="en">Controlling Your App?s Volume and Playback</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/managing-audio/audio-focus.html">
+ <span class="en">Managing Audio Focus</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/managing-audio/audio-output.html">
+ <span class="en">Dealing with Audio Output Hardware</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/monitoring-device-state/index.html">
+ <span class="en">Optimizing Battery Life</span>
+ <span class="es">Cómo optimizar la duración de la batería</span>
+ <span class="ja">電池消費量の最適化</span>
+ <span class="ko">Optimizing Battery Life</span>
+ <span class="ru">Optimizing Battery Life</span>
+ <span class="zh-CN">优化电池使用时间</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/monitoring-device-state/battery-monitoring.html">
+ <span class="en">Monitoring the Battery Level and Charging State</span>
+ <span class="es">Cómo controlar el nivel de batería y el estado de carga</span>
+ <span class="ja">電池残量と充電状態の監視</span>
+ <span class="ko">Monitoring the Battery Level and Charging State</span>
+ <span class="ru">Monitoring the Battery Level and Charging State</span>
+ <span class="zh-CN">监控电池电量和充电状态</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/monitoring-device-state/docking-monitoring.html">
+ <span class="en">Determining and Monitoring the Docking State and Type</span>
+ <span class="es">Cómo determinar y controlar el tipo de conector y el estado de la conexión</span>
+ <span class="ja">ホルダーの装着状態とタイプの特定と監視</span>
+ <span class="ko">Determining and Monitoring the Docking State and Type</span>
+ <span class="ru">Determining and Monitoring the Docking State and Type</span>
+ <span class="zh-CN">确定和监控基座对接状态和类型</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/monitoring-device-state/connectivity-monitoring.html">
+ <span class="en">Determining and Monitoring the Connectivity Status</span>
+ <span class="es">Cómo determinar y controlar el estado de la conectividad</span>
+ <span class="ja">接続状態の特定と監視</span>
+ <span class="ko">Determining and Monitoring the Connectivity Status</span>
+ <span class="ru">Determining and Monitoring the Connectivity Status</span>
+ <span class="zh-CN">确定和监控网络连接状态</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/monitoring-device-state/manifest-receivers.html">
+ <span class="en">Manipulating Broadcast Receivers On Demand</span>
+ <span class="es">Cómo manipular los receptores de emisión bajo demanda</span>
+ <span class="ja">オンデマンドでのブロードキャスト レシーバ操作</span>
+ <span class="ko">Manipulating Broadcast Receivers On Demand</span>
+ <span class="ru">Manipulating Broadcast Receivers On Demand</span>
+ <span class="zh-CN">根据需要操作广播接收器</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/custom-views/index.html">
+ <span class="en">Creating Custom Views</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/custom-views/create-view.html">
+ <span class="en">Creating a Custom View Class</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/custom-views/custom-drawing.html">
+ <span class="en">Implementing Custom Drawing</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/custom-views/making-interactive.html">
+ <span class="en">Making the View Interactive</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/custom-views/optimizing-view.html">
+ <span class="en">Optimizing the View</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/search/index.html">
+ <span class="en">Adding Search Functionality</span>
+ </a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/search/setup.html">
+ <span class="en">Setting up the Search Interface</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/search/search.html">
+ <span class="en">Storing and Searching for Data</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/search/backward-compat.html">
+ <span class="en">Remaining Backward Compatible</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/id-auth/index.html">
+ <span class="en">Remembering Users</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/id-auth/identify.html">
+ <span class="en">Remembering Your User</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/id-auth/authenticate.html">
+ <span class="en">Authenticating to OAuth2 Services</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/id-auth/custom_auth.html">
+ <span class="en">Creating a Custom Account Type</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/sharing/index.html">
+ <span class="en">Sharing Content</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/sharing/send.html">
+ <span class="en">Sending Content to Other Apps</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/sharing/receive.html">
+ <span class="en">Receiving Content from Other Apps</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/sharing/shareaction.html">
+ <span class="en">Adding an Easy Share Action</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/camera/index.html">
+ <span class="en">Capturing Photos</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/camera/photobasics.html">
+ <span class="en">Taking Photos Simply</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/camera/videobasics.html">
+ <span class="en">Recording Videos Simply</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/camera/cameradirect.html">
+ <span class="en">Controlling the Camera</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/multiple-apks/index.html">
+ <span class="en">Maintaining Multiple APKs</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/multiple-apks/api.html">
+ <span class="en">Creating Multiple APKs for Different API Levels</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/multiple-apks/screensize.html">
+ <span class="en">Creating Multiple APKs for Different Screen Sizes</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/multiple-apks/texture.html">
+ <span class="en">Creating Multiple APKs for Different GL Textures</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/multiple-apks/multiple.html">
+ <span class="en">Creating Multiple APKs with 2+ Dimensions</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/backward-compatible-ui/index.html">
+ <span class="en">Creating Backward-Compatible UIs</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/backward-compatible-ui/abstracting.html">
+ <span class="en">Abstracting the New APIs</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/backward-compatible-ui/new-implementation.html">
+ <span class="en">Proxying to the New APIs</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/backward-compatible-ui/older-implementation.html">
+ <span class="en">Creating an Implementation with Older APIs</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/backward-compatible-ui/using-component.html">
+ <span class="en">Using the Version-Aware Component</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/enterprise/index.html">
+ <span class="en">Developing for Enterprise</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/enterprise/device-management-policy.html">
+ <span class="en">Enhancing Security with Device Management Policies</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/monetization/index.html">
+ <span class="en">Monetizing Your App</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/monetization/ads-and-ux.html">
+ <span class="en">Advertising without Compromising User Experience</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/design-navigation/index.html">
+ <span class="en">Designing Effective Navigation</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/design-navigation/screen-planning.html">
+ <span class="en">Planning Screens and Their Relationships</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/design-navigation/multiple-sizes.html">
+ <span class="en">Planning for Multiple Touchscreen Sizes</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/design-navigation/descendant-lateral.html">
+ <span class="en">Providing Descendant and Lateral Navigation</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/design-navigation/ancestral-temporal.html">
+ <span class="en">Providing Ancestral and Temporal Navigation</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/design-navigation/wireframing.html">
+ <span class="en">Putting it All Together: Wireframing the Example App</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/implementing-navigation/index.html">
+ <span class="en">Implementing Effective Navigation</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/implementing-navigation/lateral.html">
+ <span class="en">Implementing Lateral Navigation</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/implementing-navigation/ancestral.html">
+ <span class="en">Implementing Ancestral Navigation</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/implementing-navigation/temporal.html">
+ <span class="en">Implementing Temporal Navigation</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/implementing-navigation/descendant.html">
+ <span class="en">Implementing Descendant Navigation</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/tv/index.html">
+ <span class="en">Designing for TV</span>
+ </a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/tv/optimizing-layouts-tv.html">
+ <span class="en">Optimizing Layouts for TV</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/tv/optimizing-navigation-tv.html">
+ <span class="en">Optimizing Navigation for TV</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/tv/unsupported-features-tv.html">
+ <span class="en">Handling Features Not Supported on TV</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/displaying-bitmaps/index.html">
+ <span class="en">Displaying Bitmaps Efficiently</span>
+ </a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/load-bitmap.html">
+ <span class="en">Loading Large Bitmaps Efficiently</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/process-bitmap.html">
+ <span class="en">Processing Bitmaps Off the UI Thread</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/cache-bitmap.html">
+ <span class="en">Caching Bitmaps</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/display-bitmap.html">
+ <span class="en">Displaying Bitmaps in Your UI</span>
+ </a></li>
+ </ul>
+ </li>
+
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/accessibility/index.html">
+ <span class="en">Implementing Accessibility</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/accessibility/accessible-app.html">
+ <span class="en">Developing Accessible Applications</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/accessibility/service.html">
+ <span class="en">Developing Accessibility Services</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot
+?>training/graphics/opengl/index.html">
+ <span class="en">Displaying Graphics with OpenGL ES</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/graphics/opengl/environment.html">
+ <span class="en">Building an OpenGL ES Environment</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/graphics/opengl/shapes.html">
+ <span class="en">Defining Shapes</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/graphics/opengl/draw.html">
+ <span class="en">Drawing Shapes</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/graphics/opengl/projection.html">
+ <span class="en">Applying Projection and Camera Views</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/graphics/opengl/motion.html">
+ <span class="en">Adding Motion</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/graphics/opengl/touch.html">
+ <span class="en">Responding to Touch Events</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+
+ </ul>
+ </li>
+</ul><!-- nav -->
+
+<script type="text/javascript">
+<!--
+ buildToggleLists();
+ changeNavLang(getLangPref());
+//-->
+</script>
diff --git a/docs/html/training/tv/optimizing-layouts-tv.jd b/docs/html/training/tv/optimizing-layouts-tv.jd
index 49c278c..a6db052 100644
--- a/docs/html/training/tv/optimizing-layouts-tv.jd
+++ b/docs/html/training/tv/optimizing-layouts-tv.jd
@@ -50,7 +50,7 @@
<ul>
<li>Put on-screen navigational controls on the left or right side of the screen and save the
vertical space for content.</li>
- <li>Create UIs that are divided into sections, by using <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a>
+ <li>Create UIs that are divided into sections, by using <a href="{@docRoot}guide/components/fragments.html">Fragments</a>
and use view groups like {@link android.widget.GridView} instead
of {@link android.widget.ListView} to make better use of the
horizontal screen space.</li>
@@ -157,7 +157,7 @@
</p>
<p>
-To get the best scaling results for images, provide them as <a href="{@docRoot}guide/developing/tools/draw9patch.html">
+To get the best scaling results for images, provide them as <a href="{@docRoot}tools/help/draw9patch.html">
9-patch image</a> elements if possible.
If you provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or grainy. This
is not a good experience for the user. Instead, use high-quality images.