Merge "docs: Adds new geocoding sample to Location API training. Uses GoogleApiClient to connect to Play services. Uses the latest Fused Location Provider API." into lmp-docs
diff --git a/docs/html/training/location/display-address.jd b/docs/html/training/location/display-address.jd
index 621b082..516f14f 100644
--- a/docs/html/training/location/display-address.jd
+++ b/docs/html/training/location/display-address.jd
@@ -1,280 +1,468 @@
 page.title=Displaying a Location Address
-
 trainingnavtop=true
-
 @jd:body
 
-
-
 <div id="tb-wrapper">
-<div id="tb">
+  <div id="tb">
 
-<h2>This lesson teaches you to</h2>
-<ol>
-  <li><a href="#DefineTask">Define the Address Lookup Task</a></li>
-  <li><a href="#DisplayResults">Define a Method to Display the Results</a></li>
-  <li><a href="#RunTask">Run the Lookup Task</a></li>
-</ol>
+    <h2>This lesson teaches you how to</h2>
+    <ol>
+      <li><a href="#connect">Get a Geographic Location</a></li>
+      <li><a href="#fetch-address">Define an Intent Service to Fetch the
+        Address</a></li>
+      <li><a href="#start-intent">Start the Intent Service</a></li>
+      <li><a href="#result-receiver">Receive the Geocoding Results</a></li>
+    </ol>
 
-<h2>You should also read</h2>
-<ul>
-    <li>
-        <a href="{@docRoot}google/play-services/setup.html">Setup Google Play Services SDK</a>
-    </li>
-    <li>
-        <a href="retrieve-current.html">Retrieving the Current Location</a>
-    </li>
-    <li>
-        <a href="receive-location-updates.html">Receiving Location Updates</a>
-    </li>
-</ul>
-<h2>Try it out</h2>
+    <h2>You should also read</h2>
+      <ul>
+        <li>
+          <a href="{@docRoot}google/play-services/setup.html">Setting up Google
+          Play Services</a>
+        </li>
+        <li>
+          <a href="retrieve-current.html">Getting the Last Known Location</a>
+        </li>
+        <li>
+          <a href="receive-location-updates.html">Receiving Location Updates</a>
+        </li>
+      </ul>
+    <h2>Try it out</h2>
 
-<div class="download-box">
-<a href="http://developer.android.com/shareables/training/LocationUpdates.zip" class="button">Download
-  the sample app</a>
-<p class="filename">LocationUpdates.zip</p>
+    <ul>
+      <li>
+        <a href="https://github.com/googlesamples/android-play-location/tree/master/LocationAddress" class="external-link">LocationAddress</a>
+      </li>
+    </ul>
+  </div>
 </div>
 
-</div>
-</div>
+<p>The lessons <a href="retrieve-current.html">Getting the Last Known
+  Location</a> and <a href="receive-location-updates.html">Receiving Location
+  Updates</a> describe how to get the user's location in the form of a
+  {@link android.location.Location} object that contains latitude and longitude
+  coordinates. Although latitude and longitude are useful for calculating
+  distance or displaying a map position, in many cases the address of the
+  location is more useful. For example, if you want to let your users know where
+  they are or what is close by, a street address is more meaningful than the
+  geographic coordinates (latitude/longitude) of the location.</p>
 
-<p>
-    The lessons <a href="retrieve-current.html">Retrieving the Current Location</a> and
-    <a href="receive-location-updates.html">Receiving Location Updates</a> describe how to get the
-    user's current location in the form of a {@link android.location.Location} object that
-    contains latitude and longitude coordinates. Although latitude and longitude are useful for
-    calculating distance or displaying a map position, in many cases the address of the location is
-    more useful.
-</p>
-<p>
-    The Android platform API provides a feature that returns an estimated street addresses for
-    latitude and longitude values. This lesson shows you how to use this address lookup feature.
-</p>
-<p class="note">
-    <strong>Note:</strong> Address lookup requires a backend service that is not included in the
-    core Android framework. If this backend service is not available,
-    {@link android.location.Geocoder#getFromLocation Geocoder.getFromLocation()} returns an empty
-    list. The helper method {@link android.location.Geocoder#isPresent isPresent()}, available
-    in API level 9 and later, checks to see if the backend service is available.
-</p>
-<p>
-    The snippets in the following sections assume that your app has already retrieved the
-    current location and stored it as a {@link android.location.Location} object in the global
-    variable {@code mLocation}.
-</p>
-<!--
-    Define the address lookup task
--->
-<h2 id="DefineTask">Define the Address Lookup Task</h2>
-<p>
-To get an address for a given latitude and longitude, call
-{@link android.location.Geocoder#getFromLocation Geocoder.getFromLocation()}, which returns a
-list of addresses. The method is synchronous, and may take a long time to do its work, so you
-should call the method from the {@link android.os.AsyncTask#doInBackground
-doInBackground()} method of an {@link android.os.AsyncTask}.
-</p>
-<p>
-While your app is getting the address, display an indeterminate activity
-indicator to show that your app is working in the background. Set the indicator's initial state
-to {@code android:visibility="gone"}, to make it invisible and remove it from the layout
-hierarchy. When you start the address lookup, you set its visibility to "visible".
-</p>
-<p>
-The following snippet shows how to add an indeterminate {@link android.widget.ProgressBar} to
-your layout file:
-</p>
+<p>Using the {@link android.location.Geocoder} class in the Android framework
+  location APIs, you can convert an address to the corresponding geographic
+  coordinates. This process is called <em>geocoding</em>. Alternatively, you can
+  convert a geographic location to an address. The address lookup feature is
+  also known as <em>reverse geocoding</em>.</p>
+
+<p>This lesson shows you how to use the
+  {@link android.location.Geocoder#getFromLocation getFromLocation()} method to
+  convert a geographic location to an address. The method returns an estimated
+  street address corresponding to a given latitude and longitude.</p>
+
+<h2 id="connect">Get a Geographic Location</h2>
+
+<p>The last known location of the device is a useful starting point for the
+  address lookup feature. The lesson on
+  <a href="retrieve-current.html">Getting the Last Known Location</a> shows you
+  how to use the
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)">{@code getLastLocation()}</a>
+  method provided by the
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html">fused
+  location provider</a> to find the latest location of the device.</p>
+
+<p>To access the fused location provider, you need to create an instance of the
+  Google Play services API client. To learn how to connect your client, see
+  <a href="{@docRoot}training/location/retrieve-current.html#play-services">Connect
+  to Google Play Services</a>.</p>
+
+<p>In order for the fused location provider to retrieve a precise street
+  address, set the location permission in your app manifest to
+  {@code ACCESS_FINE_LOCATION}, as shown in the following example:</p>
+
 <pre>
-&lt;ProgressBar
-android:id="&#64;+id/address_progress"
-android:layout_width="wrap_content"
-android:layout_height="wrap_content"
-android:layout_centerHorizontal="true"
-android:indeterminate="true"
-android:visibility="gone" /&gt;
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.gms.location.sample.locationupdates" &gt;
+
+  &lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/&gt;
+&lt;/manifest&gt;
 </pre>
-<p>
-To create the background task, define a subclass of {@link android.os.AsyncTask} that calls
-{@link android.location.Geocoder#getFromLocation getFromLocation()} and returns an address.
-Define a {@link android.widget.TextView} object {@code mAddress} to contain the returned
-address, and a {@link android.widget.ProgressBar} object that allows you to control the
-indeterminate activity indicator. For example:
-</p>
+
+<h2 id="fetch-address">Define an Intent Service to Fetch the Address</h2>
+
+<p>The {@link android.location.Geocoder#getFromLocation getFromLocation()}
+  method provided by the {@link android.location.Geocoder} class accepts a
+  latitude and longitude, and returns a list of addresses. The method is
+  synchronous, and may take a long time to do its work, so you should not call
+  it from the main, user interface (UI) thread of your app.</p>
+
+<p>The {@link android.app.IntentService IntentService} class provides a
+  structure for running a task on a background thread. Using this class, you can
+  handle a long-running operation without affecting your UI's responsiveness.
+  Note that the {@link android.os.AsyncTask AsyncTask} class also allows you to
+  perform background operations, but it's designed for short operations. An
+  {@link android.os.AsyncTask AsyncTask} shouldn't keep a reference to the UI if
+  the activity is recreated, for example when the device is rotated. In
+  contrast, an {@link android.app.IntentService IntentService} doesn't need to
+  be cancelled when the activity is rebuilt.</p>
+
+<p>Define a {@code FetchAddressIntentService} class that extends
+  {@link android.app.IntentService}. This class is your address lookup service.
+  The intent service handles an intent asynchronously on a worker thread, and
+  stops itself when it runs out of work. The intent extras provide the data
+  needed by the service, including a {@link android.location.Location} object
+  for conversion to an address, and a {@link android.os.ResultReceiver} object
+  to handle the results of the address lookup. The service uses a {@link
+  android.location.Geocoder} to fetch the address for the location, and sends
+  the results to the {@link android.os.ResultReceiver}.</p>
+
+<h3>Define the Intent Service in your App Manifest</h3>
+
+<p>Add an entry to your app manifest defining the intent service:</p>
+
 <pre>
-public class MainActivity extends FragmentActivity {
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.gms.location.sample.locationaddress" &gt;
+    &lt;application
+        ...
+        &lt;service
+            android:name=".FetchAddressIntentService"
+            android:exported="false"/&gt;
+    &lt;/application&gt;
     ...
-    private TextView mAddress;
-    private ProgressBar mActivityIndicator;
+&lt;/manifest&gt;
+</pre>
+
+<p class="note"><strong>Note:</strong> The {@code &lt;service&gt;} element in
+  the manifest doesn't need to include an intent filter, because your main
+  activity creates an explicit intent by specifying the name of the class to use
+  for the intent.</p>
+
+<h3>Create a Geocoder</h3>
+
+<p>The process of converting a geographic location to an address is called
+  <em>reverse geocoding</em>. To perform the main work of the intent service,
+  that is, your reverse geocoding request, implement
+  {@link android.app.IntentService#onHandleIntent onHandleIntent()} within the
+  {@code FetchAddressIntentService} class. Create a
+  {@link android.location.Geocoder} object to handle the reverse geocoding.</p>
+
+<p>A locale represents a specific geographical or linguistic region. Locale
+  objects are used to adjust the presentation of information, such as numbers or
+  dates, to suit the conventions in the region represented by the locale. Pass a
+  <a href="{@docRoot}reference/java/util/Locale.html">{@code Locale}</a> object
+  to the {@link android.location.Geocoder} object, to ensure that the resulting
+  address is localized to the user's geographic region.</p>
+
+<pre>
+&#64;Override
+protected void onHandleIntent(Intent intent) {
+    Geocoder geocoder = new Geocoder(this, Locale.getDefault());
+    ...
+}
+</pre>
+
+<h3 id="retrieve-street-address">Retrieve the street address data</h3>
+
+<p>The next step is to retrieve the street address from the geocoder, handle
+  any errors that may occur, and send the results back to the activity that
+  requested the address. To report the results of the geocoding
+  process, you need two numeric constants that indicate success or failure.
+  Define a {@code Constants} class to contain the values, as shown in this code
+  snippet:</p>
+
+<pre>
+public final class Constants {
+    public static final int SUCCESS_RESULT = 0;
+    public static final int FAILURE_RESULT = 1;
+    public static final String PACKAGE_NAME =
+        "com.google.android.gms.location.sample.locationaddress";
+    public static final String RECEIVER = PACKAGE_NAME + ".RECEIVER";
+    public static final String RESULT_DATA_KEY = PACKAGE_NAME +
+        ".RESULT_DATA_KEY";
+    public static final String LOCATION_DATA_EXTRA = PACKAGE_NAME +
+        ".LOCATION_DATA_EXTRA";
+}
+</pre>
+
+<p>To get a street address corresponding to a geographical location, call
+  {@link android.location.Geocoder#getFromLocation getFromLocation()},
+  passing it the latitude and longitude from the location object, and the
+  maximum number of addresses you want returned. In this case, you want just one
+  address. The geocoder returns an array of addresses. If no addresses were
+  found to match the given location, it returns an empty list. If there is no
+  backend geocoding service available, the geocoder returns null.</p>
+
+<p>Check for the following errors as shown in the code sample below. If an error
+  occurs, place the corresponding error message in the {@code errorMessage}
+  variable, so you can send it back to the requesting activity:</p>
+
+<ul>
+  <li><strong>No location data provided</strong> - The intent extras do not
+    include the {@link android.location.Location} object required for reverse
+    geocoding.</li>
+  <li><strong>Invalid latitude or longitude used</strong> - The latitude
+    and/or longitude values provided in the {@link android.location.Location}
+    object are invalid.</li>
+  <li><strong>No geocoder available</strong> - The background geocoding service
+    is not available, due to a network error or IO exception.</li>
+  <li><strong>Sorry, no address found</strong> - The geocoder could not find an
+    address for the given latitude/longitude.</li>
+</ul>
+
+<p>To get the individual lines of an address object, use the
+  {@link android.location.Address#getAddressLine getAddressLine()}
+  method provided by the {@link android.location.Address} class. Then join the
+  lines into a list of address fragments ready to return to the activity that
+  requested the address.</p>
+
+<p>To send the results back to the requesting activity, call the
+  {@code deliverResultToReceiver()} method (defined in
+  <a href="#return-address">Return the address to the requestor</a>). The
+  results consist of the previously-mentioned numeric success/failure code and
+  a string. In the case of a successful reverse geocoding, the string contains
+  the address. In the case of a failure, the string contains the error message,
+  as shown in the code sample below:</p>
+
+<pre>
+&#64;Override
+protected void onHandleIntent(Intent intent) {
+    String errorMessage = "";
+
+    // Get the location passed to this service through an extra.
+    Location location = intent.getParcelableExtra(
+            Constants.LOCATION_DATA_EXTRA);
+
+    ...
+
+    List&lt;Address&gt; addresses = null;
+
+    try {
+        addresses = geocoder.getFromLocation(
+                location.getLatitude(),
+                location.getLongitude(),
+                // In this sample, get just a single address.
+                1);
+    } catch (IOException ioException) {
+        // Catch network or other I/O problems.
+        errorMessage = getString(R.string.service_not_available);
+        Log.e(TAG, errorMessage, ioException);
+    } catch (IllegalArgumentException illegalArgumentException) {
+        // Catch invalid latitude or longitude values.
+        errorMessage = getString(R.string.invalid_lat_long_used);
+        Log.e(TAG, errorMessage + ". " +
+                "Latitude = " + location.getLatitude() +
+                ", Longitude = " +
+                location.getLongitude(), illegalArgumentException);
+    }
+
+    // Handle case where no address was found.
+    if (addresses == null || addresses.size()  == 0) {
+        if (errorMessage.isEmpty()) {
+            errorMessage = getString(R.string.no_address_found);
+            Log.e(TAG, errorMessage);
+        }
+        deliverResultToReceiver(Constants.FAILURE_RESULT, errorMessage);
+    } else {
+        Address address = addresses.get(0);
+        ArrayList&lt;String&gt; addressFragments = new ArrayList&lt;String&gt;();
+
+        // Fetch the address lines using {@code getAddressLine},
+        // join them, and send them to the thread.
+        for(int i = 0; i < address.getMaxAddressLineIndex(); i++) {
+            addressFragments.add(address.getAddressLine(i));
+        }
+        Log.i(TAG, getString(R.string.address_found));
+        deliverResultToReceiver(Constants.SUCCESS_RESULT,
+                TextUtils.join(System.getProperty("line.separator"),
+                        addressFragments));
+    }
+}
+</pre>
+
+<h3 id="return-address">Return the address to the requestor</h3>
+
+<p>The final thing the intent service must do is send the address back to a
+  {@link android.os.ResultReceiver} in the activity that started the service.
+  The {@link android.os.ResultReceiver} class allows you to send a
+  numeric result code as well as a message containing the result data. The
+  numeric code is useful for reporting the success or failure of the geocoding
+  request. In the case of a successful reverse geocoding, the message contains
+  the address. In the case of a failure, the message contains some text
+  describing the reason for failure.</p>
+
+<p>You have already retrieved the address from the geocoder, trapped any errors
+  that may occur, and called the {@code deliverResultToReceiver()} method. Now
+  you need to define the {@code deliverResultToReceiver()} method that sends
+  a result code and message bundle to the result receiver.</p>
+
+<p>For the result code, use the value that you've passed to the
+  {@code deliverResultToReceiver()} method in the {@code resultCode} parameter.
+  To construct the message bundle, concatenate the {@code RESULT_DATA_KEY}
+  constant from your {@code Constants} class (defined in
+  <a href="#retrieve-street-address">Retrieve the street address data</a>) and
+  the value in the {@code message} parameter passed to the
+  {@code deliverResultToReceiver()} method, as shown in the following sample:
+</p>
+
+<pre>
+public class FetchAddressIntentService extends IntentService {
+    protected ResultReceiver mReceiver;
+    ...
+    private void deliverResultToReceiver(int resultCode, String message) {
+        Bundle bundle = new Bundle();
+        bundle.putString(Constants.RESULT_DATA_KEY, message);
+        mReceiver.send(resultCode, bundle);
+    }
+}
+</pre>
+
+<h2 id="start-intent">Start the Intent Service</h2>
+
+<p>The intent service, as defined in the previous section, runs in the
+  background and is responsible for fetching the address corresponding to a
+  given geographic location. When you start the service, the Android framework
+  instantiates and starts the service if it isn't already running, and creates a
+  process if needed. If the service is already running then it remains running.
+  Because the service extends {@link android.app.IntentService IntentService},
+  it shuts down automatically when all intents have been processed.</p>
+  
+<p>Start the service from your app's main activity,
+  and create an {@link android.content.Intent} to pass data to the service. You
+  need an <em>explicit</em> intent, because you want only your service
+  to respond to the intent. For more information, see
+  <a href="{@docRoot}guide/components/intents-filters.html#Types">Intent
+  Types</a>.</p>
+
+<p>To create an explicit intent, specify the name of the
+  class to use for the service: {@code FetchAddressIntentService.class}.
+  Pass two pieces of information in the intent extras:</p>
+
+<ul>
+  <li>A {@link android.os.ResultReceiver} to handle the results of the address
+    lookup.</li>
+  <li>A {@link android.location.Location} object containing the latitude and
+    longitude that you want to convert to an address.</li>
+</ul>
+
+<p>The following code sample shows you how to start the intent service:</p>
+
+<pre>
+public class MainActivity extends ActionBarActivity implements
+        ConnectionCallbacks, OnConnectionFailedListener {
+
+    protected Location mLastLocation;
+    private AddressResultReceiver mResultReceiver;
+    ...
+
+    protected void startIntentService() {
+        Intent intent = new Intent(this, FetchAddressIntentService.class);
+        intent.putExtra(Constants.RECEIVER, mResultReceiver);
+        intent.putExtra(Constants.LOCATION_DATA_EXTRA, mLastLocation);
+        startService(intent);
+    }
+}
+</pre>
+
+<p>Call the above {@code startIntentService()} method when the
+  user takes an action that requires a geocoding address lookup. For example,
+  the user may press a <em>Fetch address</em> button on your app's UI. Before
+  starting the intent service, you need to check that the connection to Google
+  Play services is present. The following code snippet shows the call to the
+  {@code startIntentService()} method in the button handler:</p>
+
+<pre>
+public void fetchAddressButtonHandler(View view) {
+    // Only start the service to fetch the address if GoogleApiClient is
+    // connected.
+    if (mGoogleApiClient.isConnected() && mLastLocation != null) {
+        startIntentService();
+    }
+    // If GoogleApiClient isn't connected, process the user's request by
+    // setting mAddressRequested to true. Later, when GoogleApiClient connects,
+    // launch the service to fetch the address. As far as the user is
+    // concerned, pressing the Fetch Address button
+    // immediately kicks off the process of getting the address.
+    mAddressRequested = true;
+    updateUIWidgets();
+}
+</pre>
+
+<p>You must also start the intent service when the connection to Google Play
+  services is established, if the user has already clicked the button on your
+  app's UI. The following code snippet shows the call to the
+  {@code startIntentService()} method in the
+  <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">{@code onConnected()}</a>
+  callback provided by the Google API Client:</p>
+
+<pre>
+public class MainActivity extends ActionBarActivity implements
+        ConnectionCallbacks, OnConnectionFailedListener {
     ...
     &#64;Override
-    protected void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    ...
-    mAddress = (TextView) findViewById(R.id.address);
-    mActivityIndicator =
-            (ProgressBar) findViewById(R.id.address_progress);
-    }
-    ...
-    /**
-    * A subclass of AsyncTask that calls getFromLocation() in the
-    * background. The class definition has these generic types:
-    * Location - A {@link android.location.Location} object containing
-    * the current location.
-    * Void     - indicates that progress units are not used
-    * String   - An address passed to onPostExecute()
-    */
-    private class GetAddressTask extends
-            AsyncTask&lt;Location, Void, String&gt; {
-        Context mContext;
-        public GetAddressTask(Context context) {
-            super();
-            mContext = context;
-        }
-        ...
-        /**
-         * Get a Geocoder instance, get the latitude and longitude
-         * look up the address, and return it
-         *
-         * &#64;params params One or more Location objects
-         * &#64;return A string containing the address of the current
-         * location, or an empty string if no address can be found,
-         * or an error message
-         */
-        &#64;Override
-        protected String doInBackground(Location... params) {
-            Geocoder geocoder =
-                    new Geocoder(mContext, Locale.getDefault());
-            // Get the current location from the input parameter list
-            Location loc = params[0];
-            // Create a list to contain the result address
-            List&lt;Address&gt; addresses = null;
-            try {
-                /*
-                 * Return 1 address.
-                 */
-                addresses = geocoder.getFromLocation(loc.getLatitude(),
-                        loc.getLongitude(), 1);
-            } catch (IOException e1) {
-            Log.e("LocationSampleActivity",
-                    "IO Exception in getFromLocation()");
-            e1.printStackTrace();
-            return ("IO Exception trying to get address");
-            } catch (IllegalArgumentException e2) {
-            // Error message to post in the log
-            String errorString = "Illegal arguments " +
-                    Double.toString(loc.getLatitude()) +
-                    " , " +
-                    Double.toString(loc.getLongitude()) +
-                    " passed to address service";
-            Log.e("LocationSampleActivity", errorString);
-            e2.printStackTrace();
-            return errorString;
+    public void onConnected(Bundle connectionHint) {
+        // Gets the best and most recent location currently available,
+        // which may be null in rare cases when a location is not available.
+        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
+                mGoogleApiClient);
+
+        if (mLastLocation != null) {
+            // Determine whether a Geocoder is available.
+            if (!Geocoder.isPresent()) {
+                Toast.makeText(this, R.string.no_geocoder_available,
+                        Toast.LENGTH_LONG).show();
+                return;
             }
-            // If the reverse geocode returned an address
-            if (addresses != null &amp;&amp; addresses.size() &gt; 0) {
-                // Get the first address
-                Address address = addresses.get(0);
-                /*
-                 * Format the first line of address (if available),
-                 * city, and country name.
-                 */
-                String addressText = String.format(
-                        "&#037;s, &#037;s, &#037;s",
-                        // If there's a street address, add it
-                        address.getMaxAddressLineIndex() &gt; 0 ?
-                                address.getAddressLine(0) : "",
-                        // Locality is usually a city
-                        address.getLocality(),
-                        // The country of the address
-                        address.getCountryName());
-                // Return the text
-                return addressText;
-            } else {
-                return "No address found";
+
+            if (mAddressRequested) {
+                startIntentService();
             }
         }
-        ...
     }
-    ...
 }
 </pre>
-<p>
-The next section shows you how to display the address in the user interface.
-</p>
-<!-- Define a method to display the address -->
-<h2 id="DisplayResults">Define a Method to Display the Results</h2>
-<p>
-    {@link android.os.AsyncTask#doInBackground doInBackground()} returns the result of the address
-    lookup as a {@link java.lang.String}. This value is passed to
-    {@link android.os.AsyncTask#onPostExecute onPostExecute()}, where you do further processing
-    on the results. Since {@link android.os.AsyncTask#onPostExecute onPostExecute()}
-    runs on the UI thread, it can update the user interface; for example, it can turn off the
-    activity indicator and display the results to the user:
-</p>
+
+<h2 id="result-receiver">Receive the Geocoding Results</h2>
+
+<p>The intent service has handled the geocoding request, and uses a
+  {@link android.os.ResultReceiver} to return the results to the activity that
+  made the request. In the activity that makes the request, define an
+  {@code AddressResultReceiver} that extends {@link android.os.ResultReceiver}
+  to handle the response from {@code FetchAddressIntentService}.</p>
+
+<p>The result includes a numeric result code (<code>resultCode</code>) as well
+  as a message containing the result data (<code>resultData</code>). If the
+  reverse geocoding process was successful, the <code>resultData</code> contains
+  the address. In the case of a failure, the <code>resultData</code> contains
+  text describing the reason for failure. For details of the possible errors,
+  see <a href="#return-address">Return the address to the requestor</a>.</p>
+
+<p>Override the
+  {@link android.os.ResultReceiver#onReceiveResult onReceiveResult()} method
+  to handle the results delivered to the result receiver, as shown in the
+  following code sample:</p>
+
 <pre>
-    private class GetAddressTask extends
-            AsyncTask&lt;Location, Void, String&gt; {
-        ...
-        /**
-         * A method that's called once doInBackground() completes. Turn
-         * off the indeterminate activity indicator and set
-         * the text of the UI element that shows the address. If the
-         * lookup failed, display the error message.
-         */
+public class MainActivity extends ActionBarActivity implements
+        ConnectionCallbacks, OnConnectionFailedListener {
+    ...
+    class AddressResultReceiver extends ResultReceiver {
+        public AddressResultReceiver(Handler handler) {
+            super(handler);
+        }
+
         &#64;Override
-        protected void onPostExecute(String address) {
-            // Set activity indicator visibility to "gone"
-            mActivityIndicator.setVisibility(View.GONE);
-            // Display the results of the lookup.
-            mAddress.setText(address);
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+
+            // Display the address string
+            // or an error message sent from the intent service.
+            mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
+            displayAddressOutput();
+
+            // Show a toast message if an address was found.
+            if (resultCode == Constants.SUCCESS_RESULT) {
+                showToast(getString(R.string.address_found));
+            }
+
         }
-        ...
     }
-</pre>
-<p>
-    The final step is to run the address lookup.
-</p>
-<!-- Get and display the address -->
-<h2 id="RunTask">Run the Lookup Task</h2>
-<p>
-    To get the address, call {@link android.os.AsyncTask#execute execute()}. For example, the
-    following snippet starts the address lookup when the user clicks the "Get Address" button:
-</p>
-<pre>
-public class MainActivity extends FragmentActivity {
-    ...
-    /**
-     * The "Get Address" button in the UI is defined with
-     * android:onClick="getAddress". The method is invoked whenever the
-     * user clicks the button.
-     *
-     * &#64;param v The view object associated with this method,
-     * in this case a Button.
-     */
-    public void getAddress(View v) {
-        // Ensure that a Geocoder services is available
-        if (Build.VERSION.SDK_INT &gt;=
-                Build.VERSION_CODES.GINGERBREAD
-                            &amp;&amp;
-                Geocoder.isPresent()) {
-            // Show the activity indicator
-            mActivityIndicator.setVisibility(View.VISIBLE);
-            /*
-             * Reverse geocoding is long-running and synchronous.
-             * Run it on a background thread.
-             * Pass the current location to the background task.
-             * When the task finishes,
-             * onPostExecute() displays the address.
-             */
-            (new GetAddressTask(this)).execute(mLocation);
-        }
-        ...
-    }
-    ...
 }
 </pre>
-<p>
-    The next lesson, <a href="geofencing.html">Creating and Monitoring Geofences</a>, demonstrates
-    how to define locations of interest called <b>geofences</b> and how to use geofence monitoring
-    to detect the user's proximity to a location of interest.
-</p>