Merge "Multiple design styleguide fixes -Changing extras to videos -new bullet item in swipeviews -new in 4.0 removal -Ui overview notification info -reppling typo fixed" into jb-dev
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index c40504a7..f64ef87 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -257,7 +257,7 @@
      * data using {@link android.hardware.usb.UsbRequest}.
      *
      * @param device the device to open
-     * @return true if we successfully opened the device
+     * @return a {@link UsbDeviceConnection}, or {@code null} if open failed
      */
     public UsbDeviceConnection openDevice(UsbDevice device) {
         try {
diff --git a/docs/downloads/design/Android_Design_Downloads_20120229.zip b/docs/downloads/design/Android_Design_Downloads_20120229.zip
deleted file mode 100644
index 7bbd85f..0000000
--- a/docs/downloads/design/Android_Design_Downloads_20120229.zip
+++ /dev/null
Binary files differ
diff --git a/docs/downloads/design/Android_Design_Downloads_20120814.zip b/docs/downloads/design/Android_Design_Downloads_20120814.zip
new file mode 100755
index 0000000..102b011
--- /dev/null
+++ b/docs/downloads/design/Android_Design_Downloads_20120814.zip
Binary files differ
diff --git a/docs/downloads/design/Android_Design_Fireworks_Stencil_20120229.png b/docs/downloads/design/Android_Design_Fireworks_Stencil_20120229.png
deleted file mode 100644
index 5136379..0000000
--- a/docs/downloads/design/Android_Design_Fireworks_Stencil_20120229.png
+++ /dev/null
Binary files differ
diff --git a/docs/downloads/design/Android_Design_Fireworks_Stencil_20120814.png b/docs/downloads/design/Android_Design_Fireworks_Stencil_20120814.png
new file mode 100755
index 0000000..9a55143
--- /dev/null
+++ b/docs/downloads/design/Android_Design_Fireworks_Stencil_20120814.png
Binary files differ
diff --git a/docs/downloads/design/Android_Design_Holo_Widgets_20120302.zip b/docs/downloads/design/Android_Design_Holo_Widgets_20120302.zip
deleted file mode 100644
index 90c45c6..0000000
--- a/docs/downloads/design/Android_Design_Holo_Widgets_20120302.zip
+++ /dev/null
Binary files differ
diff --git a/docs/downloads/design/Android_Design_Holo_Widgets_20120814.zip b/docs/downloads/design/Android_Design_Holo_Widgets_20120814.zip
new file mode 100755
index 0000000..295affd
--- /dev/null
+++ b/docs/downloads/design/Android_Design_Holo_Widgets_20120814.zip
Binary files differ
diff --git a/docs/downloads/design/Android_Design_Icons_20120229.zip b/docs/downloads/design/Android_Design_Icons_20120229.zip
deleted file mode 100644
index c2728f3..0000000
--- a/docs/downloads/design/Android_Design_Icons_20120229.zip
+++ /dev/null
Binary files differ
diff --git a/docs/downloads/design/Android_Design_Icons_20120814.zip b/docs/downloads/design/Android_Design_Icons_20120814.zip
new file mode 100755
index 0000000..3471438
--- /dev/null
+++ b/docs/downloads/design/Android_Design_Icons_20120814.zip
Binary files differ
diff --git a/docs/downloads/design/Android_Design_Illustrator_Vectors_20120814.ai b/docs/downloads/design/Android_Design_Illustrator_Vectors_20120814.ai
new file mode 100644
index 0000000..928ecfa
--- /dev/null
+++ b/docs/downloads/design/Android_Design_Illustrator_Vectors_20120814.ai
Binary files differ
diff --git a/docs/downloads/design/Android_Design_OmniGraffle_Stencil_20120229.graffle b/docs/downloads/design/Android_Design_OmniGraffle_Stencil_20120229.graffle
deleted file mode 100644
index 9e418d3..0000000
--- a/docs/downloads/design/Android_Design_OmniGraffle_Stencil_20120229.graffle
+++ /dev/null
Binary files differ
diff --git a/docs/downloads/design/Android_Design_OmniGraffle_Stencil_20120814.graffle b/docs/downloads/design/Android_Design_OmniGraffle_Stencil_20120814.graffle
new file mode 100755
index 0000000..d575008
--- /dev/null
+++ b/docs/downloads/design/Android_Design_OmniGraffle_Stencil_20120814.graffle
Binary files differ
diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd
index 67dfd79..be75800 100644
--- a/docs/html/design/downloads/index.jd
+++ b/docs/html/design/downloads/index.jd
@@ -12,7 +12,7 @@
   <div class="layout-content-col span-4">
 
 <p>
-  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_Downloads_20120229.zip">Download All</a>
+  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_Downloads_20120814.zip">Download All</a>
 </p>
 
   </div>
@@ -37,9 +37,10 @@
   <div class="layout-content-col span-4">
 
 <p>
-  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_Fireworks_Stencil_20120229.png">Adobe&reg; Fireworks&reg; PNG Stencil</a>
-  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_OmniGraffle_Stencil_20120229.graffle">Omni&reg; OmniGraffle&reg; Stencil</a>
-  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_Holo_Widgets_20120302.zip">Adobe&reg; Photoshop&reg; Sources</a>
+  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_Fireworks_Stencil_20120814.png">Adobe&reg; Fireworks&reg; PNG Stencil</a>
+  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_Illustrator_Vectors_20120814.ai">Adobe&reg; Illustrator&reg; Stencil</a>
+  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_OmniGraffle_Stencil_20120814.graffle">Omni&reg; OmniGraffle&reg; Stencil</a>
+  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_Holo_Widgets_20120814.zip">Adobe&reg; Photoshop&reg; Sources</a>
 </p>
 
   </div>
@@ -65,7 +66,7 @@
   <div class="layout-content-col span-4">
 
 <p>
-  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_Icons_20120229.zip">Action Bar Icon Pack</a>
+  <a class="download-button" href="https://dl-ssl.google.com/android/design/Android_Design_Icons_20120814.zip">Action Bar Icon Pack</a>
 </p>
 
   </div>
diff --git a/docs/html/guide/components/bound-services.jd b/docs/html/guide/components/bound-services.jd
index 43e6e5e..8d2bba5 100644
--- a/docs/html/guide/components/bound-services.jd
+++ b/docs/html/guide/components/bound-services.jd
@@ -640,12 +640,6 @@
 
 <h2 id="Lifecycle">Managing the Lifecycle of a Bound Service</h2>
 
-<div class="figure" style="width:588px">
-<img src="{@docRoot}images/fundamentals/service_binding_tree_lifecycle.png" alt="" />
-<p class="img-caption"><strong>Figure 1.</strong> The lifecycle for a service that is started
-and also allows binding.</p>
-</div>
-
 <p>When a service is unbound from all clients, the Android system destroys it (unless it was also
 started with {@link android.app.Service#onStartCommand onStartCommand()}). As such, you don't have
 to manage the lifecycle of your service if it's purely a bound
@@ -667,6 +661,12 @@
 {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback.
 Below, figure 1 illustrates the logic for this kind of lifecycle.</p>
 
+
+<img src="{@docRoot}images/fundamentals/service_binding_tree_lifecycle.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> The lifecycle for a service that is started
+and also allows binding.</p>
+
+
 <p>For more information about the lifecycle of an started service, see the <a
 href="{@docRoot}guide/components/services.html#Lifecycle">Services</a> document.</p>
 
diff --git a/docs/html/guide/components/services.jd b/docs/html/guide/components/services.jd
index b89914a..6e5dfd2 100644
--- a/docs/html/guide/components/services.jd
+++ b/docs/html/guide/components/services.jd
@@ -755,15 +755,6 @@
 changes in the service's state and perform work at the appropriate times. The following skeleton
 service demonstrates each of the lifecycle methods:</p>
 
-
-<div class="figure" style="width:432px">
-<img src="{@docRoot}images/service_lifecycle.png" alt="" />
-<p class="img-caption"><strong>Figure 2.</strong> The service lifecycle. The diagram on the left
-shows the lifecycle when the service is created with {@link android.content.Context#startService
-startService()} and the diagram on the right shows the lifecycle when the service is created
-with {@link android.content.Context#bindService bindService()}.</p>
-</div>
-
 <pre>
 public class ExampleService extends Service {
     int mStartMode;       // indicates how to behave if the service is killed
@@ -804,6 +795,12 @@
 <p class="note"><strong>Note:</strong> Unlike the activity lifecycle callback methods, you are
 <em>not</em> required to call the superclass implementation of these callback methods.</p>
 
+<img src="{@docRoot}images/service_lifecycle.png" alt="" />
+<p class="img-caption"><strong>Figure 2.</strong> The service lifecycle. The diagram on the left
+shows the lifecycle when the service is created with {@link android.content.Context#startService
+startService()} and the diagram on the right shows the lifecycle when the service is created
+with {@link android.content.Context#bindService bindService()}.</p>
+
 <p>By implementing these methods, you can monitor two nested loops of the service's lifecycle: </p>
 
 <ul>
diff --git a/docs/html/guide/webapps/targeting.jd b/docs/html/guide/webapps/targeting.jd
index 46f769c..7410202 100644
--- a/docs/html/guide/webapps/targeting.jd
+++ b/docs/html/guide/webapps/targeting.jd
@@ -270,7 +270,7 @@
 
 <p>The density of a device's screen is based on the screen resolution, as defined by the number of
 dots per inch (dpi). There are three screen
-density categories supported by Android: low (ldpi), medium (mdpi), and high (mdpi). A screen
+density categories supported by Android: low (ldpi), medium (mdpi), and high (hdpi). A screen
 with low density has fewer available pixels per inch, whereas a screen with high density has more
 pixels per inch (compared to a medium density screen). The Android Browser and {@link
 android.webkit.WebView} target a medium density screen by default.</p>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index df97855..cf85a34 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -2,21 +2,21 @@
 header.hide=1
 page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
 
-sdk.win_installer=installer_r20.0.1-windows.exe
-sdk.win_installer_bytes=70486979
-sdk.win_installer_checksum=a8df28a29c7b8598e4c50f363692256d
+sdk.win_installer=installer_r20.0.3-windows.exe
+sdk.win_installer_bytes=70495456
+sdk.win_installer_checksum=cf23b95d0c9cd57fac3c3be253171af4
 
-sdk.win_download=android-sdk_r20.0.1-windows.zip
-sdk.win_bytes=90370975
-sdk.win_checksum=5774f536892036f87d3bf6502862cea5
+sdk.win_download=android-sdk_r20.0.3-windows.zip
+sdk.win_bytes=90379469
+sdk.win_checksum=cd895c79201f7f02507eb3c3868a1c5e
 
-sdk.mac_download=android-sdk_r20.0.1-macosx.zip
-sdk.mac_bytes=58217336
-sdk.mac_checksum=cc132d04bc551b23b0c507cf5943df57
+sdk.mac_download=android-sdk_r20.0.3-macosx.zip
+sdk.mac_bytes=58218455
+sdk.mac_checksum=07dc88ba2c0817ef178a665d002831bf
 
-sdk.linux_download=android-sdk_r20.0.1-linux.tgz
-sdk.linux_bytes=82607616
-sdk.linux_checksum=cd7176831087f53e46123dd91551be32
+sdk.linux_download=android-sdk_r20.0.3-linux.tgz
+sdk.linux_bytes=82616305
+sdk.linux_checksum=0d53c2c31d6b5d0cf7385bccd0b06c27
 
 @jd:body
 
@@ -141,3 +141,4 @@
     $('.reqs').show();
   }
 </script>
+
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 414b97b..4fc2ca6 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -1,9 +1,9 @@
 page.title=Installing the Eclipse Plugin
 walkthru=1
-adt.zip.version=20.0.2
-adt.zip.download=ADT-20.0.2.zip
-adt.zip.bytes=12388464
-adt.zip.checksum=8e727bcdc9789c900784a82e6330ec22
+adt.zip.version=20.0.3
+adt.zip.download=ADT-20.0.3.zip
+adt.zip.bytes=12390954
+adt.zip.checksum=869a536b1c56d0cd920ed9ae259ae619
 
 @jd:body
 
@@ -11,7 +11,7 @@
 
 <p>Android offers a custom plugin for the Eclipse IDE, called Android
 Development Tools (ADT). This plugin is designed to give you a powerful, integrated
-environment in which to develop Android apps. It extends the capabilites
+environment in which to develop Android apps. It extends the capabilities
 of Eclipse to let you quickly set up new Android projects, build an app
 UI, debug your app, and export signed (or unsigned) app packages (APKs) for distribution.
 </p>
@@ -39,21 +39,21 @@
 
 <ol>
     <li>Start Eclipse, then select <strong>Help</strong> &gt; <strong>Install New
-Software...</strong>.</li>
+Software</strong>.</li>
     <li>Click <strong>Add</strong>, in the top-right corner.</li>
     <li>In the Add Repository dialog that appears, enter "ADT Plugin" for the <em>Name</em> and the
 following URL for the <em>Location</em>:
       <pre>https://dl-ssl.google.com/android/eclipse/</pre>
     </li>
-    <li>Click <strong>OK</strong>
-      <p>Note: If you have trouble acquiring the plugin, try using "http" in the Location URL,
+    <li>Click <strong>OK</strong>.
+      <p>If you have trouble acquiring the plugin, try using "http" in the Location URL,
 instead of "https" (https is preferred for security reasons).</p></li>
     <li>In the Available Software dialog, select the checkbox next to Developer Tools and click
 <strong>Next</strong>.</li>
     <li>In the next window, you'll see a list of the tools to be downloaded. Click
 <strong>Next</strong>. </li>
     <li>Read and accept the license agreements, then click <strong>Finish</strong>.
-      <p>Note: If you get a security warning saying that the authenticity or validity of
+      <p>If you get a security warning saying that the authenticity or validity of
 the software can't be established, click <strong>OK</strong>.</p></li>
     <li>When the installation completes, restart Eclipse. </li>
 </ol>
@@ -148,17 +148,15 @@
 manually install it:</p>
 
 <ol>
-  <li>Download the current ADT Plugin zip file from the table below (do not unpack it).
+  <li>Download the ADT Plugin zip file (do not unpack it):
 
   <table class="download">
     <tr>
-      <th>Name</th>
       <th>Package</th>
       <th>Size</th>
       <th>MD5 Checksum</th>
   </tr>
   <tr>
-    <td>ADT {@adtZipVersion}</td>
     <td>
       <a href="http://dl.google.com/android/{@adtZipDownload}">{@adtZipDownload}</a>
     </td>
@@ -169,16 +167,20 @@
 </li>
 
 </li>
-  <li>Follow steps 1 and 2 in the <a href="#installing">default install
-      instructions</a> (above).</li>
-  <li>In the Add Site dialog, click <strong>Archive</strong>.</li>
-  <li>Browse and select the downloaded zip file.</li>
-  <li>Enter a name for the local update site (e.g.,
-      "Android Plugin") in the "Name" field.</li>
-  <li>Click <strong>OK</strong>.
-  <li>Follow the remaining procedures as listed for
-      <a href="#installing">default installation</a> above,
-      starting from step 4.</li>
+  <li>Start Eclipse, then select <strong>Help</strong> &gt; <strong>Install New
+Software</strong>.</li>
+  <li>Click <strong>Add</strong>, in the top-right corner.</li>
+  <li>In the Add Repository dialog, click <strong>Archive</strong>.</li>
+  <li>Select the downloaded {@adtZipDownload} file and click <strong>OK</strong>.</li>
+  <li>Enter "ADT Plugin" for the name and click <strong>OK</strong>.
+  <li>In the Available Software dialog, select the checkbox next to Developer Tools and click
+<strong>Next</strong>.</li>
+  <li>In the next window, you'll see a list of the tools to be downloaded. Click
+<strong>Next</strong>. </li>
+  <li>Read and accept the license agreements, then click <strong>Finish</strong>.
+    <p>If you get a security warning saying that the authenticity or validity of
+the software can't be established, click <strong>OK</strong>.</p></li>
+  <li>When the installation completes, restart Eclipse. </li>
 </ol>
 
 <p>To update your plugin once you've installed using the zip file, you will have
@@ -204,3 +206,4 @@
 ...then your development machine lacks a suitable Java VM. Installing Sun
 Java 6 will resolve this issue and you can then reinstall the ADT
 Plugin.</p>
+
diff --git a/docs/html/tools/extras/support-library.jd b/docs/html/tools/extras/support-library.jd
index 869a15b..b1e2ea0 100644
--- a/docs/html/tools/extras/support-library.jd
+++ b/docs/html/tools/extras/support-library.jd
@@ -90,6 +90,24 @@
 <div class="toggleable opened">
   <a href="#" onclick="return toggleDiv(this)">
   <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px"
+/>Support Package, revision 10</a> <em>(August 2012)</em>
+  <div class="toggleme">
+    <dl>
+      <dt>Changes for v4 support library:</dt>
+      <dd>
+        <ul>
+          <li>Added support for notification features introduced in Android 4.1 (API Level 16) with
+          additions to {@link android.support.v4.app.NotificationCompat}.</li>
+        </ul>
+      </dd>
+    </dl>
+  </div>
+</div>
+
+
+<div class="toggleable closed">
+  <a href="#" onclick="return toggleDiv(this)">
+  <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px"
 />Support Package, revision 9</a> <em>(June 2012)</em>
   <div class="toggleme">
     <dl>
@@ -589,3 +607,4 @@
 <p>Additionally, the <a href="http://code.google.com/p/iosched/">Google I/O App</a> is a complete
 application that uses the v4 support library to provide a single APK for both handsets and tablets
 and also demonstrates some of Android's best practices in Android UI design.</p>
+
diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd
index 4e75f2e..d44d54b 100644
--- a/docs/html/tools/help/adb.jd
+++ b/docs/html/tools/help/adb.jd
@@ -88,13 +88,14 @@
 	<li>Serial number &mdash; A string created by adb to uniquely identify an emulator/device instance by its 
         console port number. The format of the serial number is <code>&lt;type&gt;-&lt;consolePort&gt;</code>. 
         Here's an example serial number: <code>emulator-5554</code></li>
-	<li>State &mdash; The connection state of the instance. Three states are supported: 
+	<li>State &mdash; The connection state of the instance may be one of the following:
 		<ul>
 		<li><code>offline</code> &mdash; the instance is not connected to adb or is not responding.</li>
 		<li><code>device</code> &mdash; the instance is now connected to the adb server. Note that this state does not 
                     imply that the Android system is fully booted and operational, since the instance connects to adb 
                     while the system is still booting. However, after boot-up, this is the normal operational state of 
                     an emulator/device instance.</li>
+                <li><code>no device</code> &mdash; there is no emulator/device connected.
 		</ul>
 	</li>
 </ul>
@@ -111,7 +112,6 @@
 emulator-5556&nbsp;&nbsp;device
 emulator-5558&nbsp;&nbsp;device</pre>
 
-<p>If there is no emulator/device running, adb returns <code>no device</code>.</p>
 
 
 <a name="directingcommands"></a>
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index bdb4a9e..10c622b 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -97,6 +97,39 @@
   <a href="#" onclick="return toggleDiv(this)">
   <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
     width="9px"/>
+ADT 20.0.3</a> <em>(August 2012)</em>
+  <div class="toggleme">
+<dl>
+  <dt>Dependencies:</dt>
+
+  <dd>
+    <ul>
+      <li>Java 1.6 or higher is required for ADT 20.0.3.</li>
+      <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 20.0.3.</li>
+      <li>ADT 20.0.3 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
+      Tools r20.0.3</a>. If you haven't already installed SDK Tools r20.0.3 into your SDK, use the
+      Android SDK Manager to do so.</li>
+    </ul>
+  </dd>
+
+  <dt>Bug fixes:</dt>
+  <dd>
+    <ul>
+      <li>Fixed issue with keyboard shortcuts for editors in Eclipse Juno (Version 4.x).</li>
+      <li>Fixed problem with cached download lists in SDK Manager.</li>
+    </ul>
+  </dd>
+
+</dl>
+
+</div>
+</div>
+
+
+<div class="toggleable closed">
+  <a href="#" onclick="return toggleDiv(this)">
+  <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+    width="9px"/>
 ADT 20.0.2</a> <em>(July 2012)</em>
   <div class="toggleme">
 <dl>
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index 039c4b5..f8b5d25 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -28,6 +28,37 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>SDK Tools, Revision 20.0.3</a> <em>(August 2012)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+    <dd>
+      <ul>
+        <li>Android SDK Platform-tools revision 12 or later.</li>
+        <li>If you are developing in Eclipse with ADT, note that the SDK Tools r20.0.3 is designed
+        for use with ADT 20.0.3 and later. If you haven't already, update your
+        <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 20.0.3.</li>
+        <li>If you are developing outside Eclipse, you must have
+          <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+    </ul>
+    </dd>
+    <dt>Bug fixes:</dt>
+    <dd>
+      <ul>
+        <li>Fixed problem with cached download lists in SDK Manager.</li>
+      </ul>
+    </dd>
+    </dl>
+  </div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>SDK Tools, Revision 20.0.1</a> <em>(July 2012)</em>
   </p>
 
@@ -942,3 +973,4 @@
 </dl>
  </div>
 </div>
+
diff --git a/docs/html/training/accessibility/service.jd b/docs/html/training/accessibility/service.jd
index 80ecbc7..373ddbb 100644
--- a/docs/html/training/accessibility/service.jd
+++ b/docs/html/training/accessibility/service.jd
@@ -175,7 +175,7 @@
 android.view.accessibility.AccessibilityEvent#getEventType} to determine the
 type of event, and {@link
 android.view.accessibility.AccessibilityEvent#getContentDescription} to extract
-any label text associated with the fiew that fired the event.</pre>
+any label text associated with the view that fired the event.</pre>
 
 <pre>
 &#64;Override
diff --git a/docs/html/training/basics/firstapp/starting-activity.jd b/docs/html/training/basics/firstapp/starting-activity.jd
index cbd063a..4d0a84a 100644
--- a/docs/html/training/basics/firstapp/starting-activity.jd
+++ b/docs/html/training/basics/firstapp/starting-activity.jd
@@ -226,7 +226,7 @@
 
 <p>Open the {@code DisplayMessageActivity.java} file. If you used Eclipse to create it, the class
 already includes an implementation of the required {@link android.app.Activity#onCreate onCreate()}
-method. There's also an implemtation of the {@link android.app.Activity#onCreateOptionsMenu
+method. There's also an implementation of the {@link android.app.Activity#onCreateOptionsMenu
 onCreateOptionsMenu()} method, but
 you won't need it for this app so you can remove it. The class should look like this:</p>
 
diff --git a/docs/html/training/basics/intents/sending.jd b/docs/html/training/basics/intents/sending.jd
index 77f0e1a..37a06f1 100644
--- a/docs/html/training/basics/intents/sending.jd
+++ b/docs/html/training/basics/intents/sending.jd
@@ -31,11 +31,11 @@
 <p>One of Android's most important features is an app's ability to send the user to another app
 based on an "action" it would like to perform. For example, if
 your app has the address of a business that you'd like to show on a map, you don't have to build
-an activity in your app that shows a map. Instead, you can send a out a request to view the address
-using an {@link android.content.Intent}. The Android system then starts an app that's able to view
+an activity in your app that shows a map. Instead, you can create a request to view the address
+using an {@link android.content.Intent}. The Android system then starts an app that's able to show
 the address on a map.</p>
 
-<p>As shown in the first class, <a href="{@docRoot}training/basics/firstapp/index.html">Building
+<p>As explained in the first class, <a href="{@docRoot}training/basics/firstapp/index.html">Building
 Your First App</a>, you must use intents to navigate between activities in your own app. You
 generally do so with an <em>explicit intent</em>, which defines the exact class name of the
 component you want to start. However, when you want to have a separate app perform an action, such
diff --git a/docs/html/training/basics/network-ops/managing.jd b/docs/html/training/basics/network-ops/managing.jd
index 33cb195..0f3d495 100644
--- a/docs/html/training/basics/network-ops/managing.jd
+++ b/docs/html/training/basics/network-ops/managing.jd
@@ -116,7 +116,7 @@
 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
+connected network interface it can find, or <code>null</code> if none of the
 interfaces is connected (meaning that an
 internet connection is not available):</p>
 
diff --git a/docs/html/training/cloudsync/gcm.jd b/docs/html/training/cloudsync/gcm.jd
index dcc1b6b..df26d34 100644
--- a/docs/html/training/cloudsync/gcm.jd
+++ b/docs/html/training/cloudsync/gcm.jd
@@ -37,8 +37,7 @@
 <p>This lesson covers some of the best practices
 for integrating GCM into your application, and assumes you are already familiar
 with basic implementation of this service.  If this is not the case, you can read the <a
-  href="http://developer.google.com/android/gcm/demo">GCM
-  Tutorial</a>.</p>
+  href="{@docRoot}guide/google/gcm/demo.html">GCM demo app tutorial</a>.</p>
 
 <h2 id="multicast">Send Multicast Messages Efficiently</h2>
 <p>One of the most useful features in GCM is support for up to 1,000 recipients for
diff --git a/docs/html/training/managing-audio/audio-focus.jd b/docs/html/training/managing-audio/audio-focus.jd
index 66649e8..33f04e9 100644
--- a/docs/html/training/managing-audio/audio-focus.jd
+++ b/docs/html/training/managing-audio/audio-focus.jd
@@ -135,7 +135,7 @@
 (pressing play in your app) to be required before you resume playing audio.</p>
 
 <p>In the following code snippet, we pause the playback or our media player object if the audio
-loss is transien and resume it when we have regained the focus. If the loss is permanent, it
+loss is transient and resume it when we have regained the focus. If the loss is permanent, it
 unregisters our media button event receiver and stops monitoring audio focus changes.<p>
 
 <pre>
@@ -169,7 +169,7 @@
 <pre>
 OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
     public void onAudioFocusChange(int focusChange) {
-        if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
+        if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
             // Lower the volume
         } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
             // Raise it back to normal
diff --git a/samples/training/network-usage/AndroidManifest.xml b/samples/training/network-usage/AndroidManifest.xml
new file mode 100644
index 0000000..4b96d14
--- /dev/null
+++ b/samples/training/network-usage/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<!--
+  Copyright (C) 2012 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.networkusage"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <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
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name" >
+
+        <activity
+            android:name="com.example.networkusage.NetworkActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <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>
diff --git a/samples/training/network-usage/README.txt b/samples/training/network-usage/README.txt
new file mode 100644
index 0000000..cc9a7a0
--- /dev/null
+++ b/samples/training/network-usage/README.txt
@@ -0,0 +1,14 @@
+README
+======
+
+This Network Usage sample app does the following:
+
+-- Downloads an XML feed from StackOverflow.com for the most recent posts tagged "android".
+
+-- Parses the XML feed, combines feed elements with HTML markup, and displays the resulting HTML in the UI.
+
+-- Lets users control their network data usage through a settings UI. Users can choose to fetch the feed
+   when any network connection is available, or only when a Wi-Fi connection is available.
+
+-- Detects when there is a change in the device's connection status and responds accordingly. For example, if
+   the device loses its network connection, the app will not attempt to download the feed.
diff --git a/samples/training/network-usage/res/drawable-hdpi/ic_launcher.png b/samples/training/network-usage/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/samples/training/network-usage/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/training/network-usage/res/drawable-ldpi/ic_launcher.png b/samples/training/network-usage/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000..1095584
--- /dev/null
+++ b/samples/training/network-usage/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/samples/training/network-usage/res/drawable-mdpi/ic_launcher.png b/samples/training/network-usage/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/samples/training/network-usage/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/training/network-usage/res/layout/main.xml b/samples/training/network-usage/res/layout/main.xml
new file mode 100644
index 0000000..8498934
--- /dev/null
+++ b/samples/training/network-usage/res/layout/main.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+<WebView  xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/webview"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+/>
+</LinearLayout>
diff --git a/samples/training/network-usage/res/menu/mainmenu.xml b/samples/training/network-usage/res/menu/mainmenu.xml
new file mode 100644
index 0000000..17d44db
--- /dev/null
+++ b/samples/training/network-usage/res/menu/mainmenu.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright (C) 2012 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+     <item android:id="@+id/settings"
+          android:title="@string/settings" />
+    <item android:id="@+id/refresh"
+          android:title="@string/refresh" />
+</menu>
diff --git a/samples/training/network-usage/res/values/arrays.xml b/samples/training/network-usage/res/values/arrays.xml
new file mode 100644
index 0000000..2e8b8a7
--- /dev/null
+++ b/samples/training/network-usage/res/values/arrays.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright (C) 2012 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <string-array name="listArray">
+        <item>Only when on Wi-Fi</item>
+        <item>On any network</item>
+    </string-array>
+    <string-array name="listValues">
+        <item>Wi-Fi</item>
+        <item>Any</item>
+    </string-array>
+</resources>
diff --git a/samples/training/network-usage/res/values/strings.xml b/samples/training/network-usage/res/values/strings.xml
new file mode 100644
index 0000000..d7c702f
--- /dev/null
+++ b/samples/training/network-usage/res/values/strings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright (C) 2012 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <string name="app_name">NetworkUsage</string>
+
+    <!--  Menu items -->
+    <string name="settings">Settings</string>
+    <string name="refresh">Refresh</string>
+
+    <!--  NetworkActivity -->
+    <string name="page_title">Newest StackOverflow questions tagged \'android\'</string>
+    <string name="updated">Last updated:</string>
+    <string name="lost_connection">Lost connection.</string>
+    <string name="wifi_connected">Wi-Fi reconnected.</string>
+    <string name="connection_error">Unable to load content. Check your network connection.</string>
+    <string name="xml_error">Error parsing XML.</string>
+
+</resources>
diff --git a/samples/training/network-usage/res/xml/preferences.xml b/samples/training/network-usage/res/xml/preferences.xml
new file mode 100644
index 0000000..801ba79
--- /dev/null
+++ b/samples/training/network-usage/res/xml/preferences.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright (C) 2012 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+    <ListPreference
+        android:title="Download Feed"
+        android:summary="Network connectivity required to download the feed."
+        android:key="listPref"
+        android:defaultValue="Wi-Fi"
+        android:entries="@array/listArray"
+        android:entryValues="@array/listValues"
+     />
+    <CheckBoxPreference
+        android:title="Show Summaries"
+        android:defaultValue="false"
+        android:summary="Show a summary for each link."
+        android:key="summaryPref" />
+</PreferenceScreen>
diff --git a/samples/training/network-usage/src/com/example/android/networkusage/NetworkActivity.java b/samples/training/network-usage/src/com/example/android/networkusage/NetworkActivity.java
new file mode 100644
index 0000000..b7ed331
--- /dev/null
+++ b/samples/training/network-usage/src/com/example/android/networkusage/NetworkActivity.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.example.android.networkusage;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.webkit.WebView;
+import android.widget.Toast;
+
+import com.example.android.networkusage.R;
+import com.example.android.networkusage.StackOverflowXmlParser.Entry;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.List;
+
+
+/**
+ * Main Activity for the sample application.
+ *
+ * This activity does the following:
+ *
+ * o Presents a WebView screen to users. This WebView has a list of HTML links to the latest
+ *   questions tagged 'android' on stackoverflow.com.
+ *
+ * o Parses the StackOverflow XML feed using XMLPullParser.
+ *
+ * o Uses AsyncTask to download and process the XML feed.
+ *
+ * o Monitors preferences and the device's network connection to determine whether
+ *   to refresh the WebView content.
+ */
+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);
+
+        // Register BroadcastReceiver to track connection changes.
+        IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
+        receiver = new NetworkReceiver();
+        this.registerReceiver(receiver, filter);
+    }
+
+    // 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();
+
+        // Only loads the page if refreshDisplay is true. Otherwise, keeps previous
+        // display. For example, if the user has set "Wi-Fi only" in prefs and the
+        // device loses its Wi-Fi connection midway through the user using the app,
+        // you don't want to refresh the display--this would force the display of
+        // an error page instead of stackoverflow.com content.
+        if (refreshDisplay) {
+            loadPage();
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (receiver != null) {
+            this.unregisterReceiver(receiver);
+        }
+    }
+
+    // Checks the network connection and sets the wifiConnected and mobileConnected
+    // variables accordingly.
+    private 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.
+    // This avoids UI lock up. To prevent network operations from
+    // causing a delay that results in a poor user experience, always perform
+    // network operations on a separate thread from the UI.
+    private void loadPage() {
+        if (((sPref.equals(ANY)) && (wifiConnected || mobileConnected))
+                || ((sPref.equals(WIFI)) && (wifiConnected))) {
+            // AsyncTask subclass
+            new DownloadXmlTask().execute(URL);
+        } else {
+            showErrorPage();
+        }
+    }
+
+    // Displays an error if the app is unable to load content.
+    private void showErrorPage() {
+        setContentView(R.layout.main);
+
+        // The specified network connection is not available. Displays error message.
+        WebView myWebView = (WebView) findViewById(R.id.webview);
+        myWebView.loadData(getResources().getString(R.string.connection_error),
+                "text/html", null);
+    }
+
+    // Populates the activity's options menu.
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.mainmenu, menu);
+        return true;
+    }
+
+    // Handles the user's menu selection.
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case R.id.settings:
+                Intent settingsActivity = new Intent(getBaseContext(), SettingsActivity.class);
+                startActivity(settingsActivity);
+                return true;
+        case R.id.refresh:
+                loadPage();
+                return true;
+        default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+    // 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);
+        }
+    }
+
+    // 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;
+        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();
+        return stream;
+    }
+
+    /**
+     *
+     * This BroadcastReceiver intercepts the android.net.ConnectivityManager.CONNECTIVITY_ACTION,
+     * which indicates a connection change. It checks whether the type is TYPE_WIFI.
+     * If it is, it checks whether Wi-Fi is connected and sets the wifiConnected flag in the
+     * main activity accordingly.
+     *
+     */
+    public class NetworkReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            ConnectivityManager connMgr =
+                    (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+            NetworkInfo networkInfo = connMgr.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();
+            }
+        }
+    }
+}
diff --git a/samples/training/network-usage/src/com/example/android/networkusage/SettingsActivity.java b/samples/training/network-usage/src/com/example/android/networkusage/SettingsActivity.java
new file mode 100644
index 0000000..73b72d2
--- /dev/null
+++ b/samples/training/network-usage/src/com/example/android/networkusage/SettingsActivity.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.example.android.networkusage;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import com.example.android.networkusage.R;
+
+/**
+ * This preference activity has in its manifest declaration an intent filter for
+ * the ACTION_MANAGE_NETWORK_USAGE action. This activity provides a settings UI
+ * for users to specify network settings to control data usage.
+ */
+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 callback to be invoked whenever a user changes a preference.
+        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);
+    }
+
+    // Fires when the user changes a preference.
+    @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;
+    }
+}
diff --git a/samples/training/network-usage/src/com/example/android/networkusage/StackOverflowXmlParser.java b/samples/training/network-usage/src/com/example/android/networkusage/StackOverflowXmlParser.java
new file mode 100644
index 0000000..6a01098
--- /dev/null
+++ b/samples/training/network-usage/src/com/example/android/networkusage/StackOverflowXmlParser.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.example.android.networkusage;
+
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class parses XML feeds from stackoverflow.com.
+ * Given an InputStream representation of a feed, it returns a List of entries,
+ * where each list element represents a single entry (post) in the XML feed.
+ */
+public class StackOverflowXmlParser {
+    private static final String ns = null;
+
+    // We don't use namespaces
+
+    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();
+        }
+    }
+
+    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;
+    }
+
+    // This class represents a single entry (post) in the XML feed.
+    // It includes the data members "title," "link," and "summary."
+    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 &quot;read&quot; 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;
+    }
+
+    // Skips tags the parser isn't interested in. Uses depth to handle nested tags. i.e.,
+    // if the next tag after a START_TAG isn't a matching END_TAG, it keeps going until it
+    // finds the matching END_TAG (as indicated by the value of "depth" being 0).
+    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;
+            }
+        }
+    }
+}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 3501e47..75b3f04 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -8833,7 +8833,7 @@
         // little while.
         mHandler.post(new Runnable() {
             public void run() {
-                updateExternalMediaStatusInner(mediaStatus, reportStatus);
+                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
             }
         });
     }
@@ -8843,7 +8843,7 @@
      * Should block until all the ASEC containers are finished being scanned.
      */
     public void scanAvailableAsecs() {
-        updateExternalMediaStatusInner(true, false);
+        updateExternalMediaStatusInner(true, false, false);
     }
 
     /*
@@ -8852,7 +8852,8 @@
      * Please note that we always have to report status if reportStatus has been
      * set to true especially when unloading packages.
      */
-    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus) {
+    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
+            boolean externalStorage) {
         // Collection of uids
         int uidArr[] = null;
         // Collection of stale containers
@@ -8890,6 +8891,14 @@
                         continue;
                     }
 
+                    /*
+                     * Skip packages that are not external if we're unmounting
+                     * external storage.
+                     */
+                    if (externalStorage && !isMounted && !isExternal(ps)) {
+                        continue;
+                    }
+
                     final AsecInstallArgs args = new AsecInstallArgs(cid, isForwardLocked(ps));
                     // The package status is changed only if the code path
                     // matches between settings and the container id.