page.title=Displaying the Location Address
parent.title=Making Your App Location Aware
parent.link=index.html

trainingnavtop=true
previous.title=Obtaining the Current Location
previous.link=currentlocation.html

@jd:body


<!-- This is the training bar -->
<div id="tb-wrapper">
<div id="tb">

<h2>This lesson teaches you to</h2>
<ol>
  <li><a href="geocoding.html#TaskReverseGeocoding">Perform Reverse Geocoding</a></li>
</ol>

<h2>You should also read</h2>

<ul>
  <li><a href="{@docRoot}guide/topics/location/index.html">Location and Maps</a></li>
</ul>

<h2>Try it out</h2>

<div class="download-box">
<a href="http://developer.android.com/shareables/training/LocationAware.zip" class="button">Download
  the sample app</a>
<p class="filename">LocationAware.zip</p>
</div>

</div>
</div>

<p>As shown in previous lessons, location updates are received in the form of latitude and longitude coordinates.  While this format is useful for calculating distance or displaying a pushpin on a map, the decimal numbers make no sense to most end users.  If you need to display a location to user, it is much more preferable to display the address instead.</p>

<h2 id="TaskReverseGeocoding">Perform Reverse Geocoding</h2>

<p>Reverse-geocoding is the process of translating latitude longitude coordinates to a human-readable address.  The {@link android.location.Geocoder} API is available for this purpose.  Note that behind the scene, the API is dependent on a web service.  If such service is unavailable on the device, the API will throw a "Service not Available exception" or return an empty list of addresses.  A helper method called {@link android.location.Geocoder#isPresent()} was added in Android 2.3 (API level 9) to check for the existence of the service.</p>

<p>The following code snippet demonstrates the use of the {@link android.location.Geocoder} API to perform reverse-geocoding.  Since the {@link android.location.Geocoder#getFromLocation(double, double, int) getFromLocation()} method is synchronous, you should not invoke it from the UI thread, hence an {@link android.os.AsyncTask} is used in the snippet.</p>

<pre>
private final LocationListener listener = new LocationListener() {

    public void onLocationChanged(Location location) {
        // Bypass reverse-geocoding if the Geocoder service is not available on the
        // device. The isPresent() convenient method is only available on Gingerbread or above.
        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.GINGERBREAD &amp;&amp; Geocoder.isPresent()) {
            // Since the geocoding API is synchronous and may take a while.  You don't want to lock
            // up the UI thread.  Invoking reverse geocoding in an AsyncTask.
            (new ReverseGeocodingTask(this)).execute(new Location[] {location});
        }
    }
    ...
};

// AsyncTask encapsulating the reverse-geocoding API.  Since the geocoder API is blocked,
// we do not want to invoke it from the UI thread.
private class ReverseGeocodingTask extends AsyncTask&lt;Location, Void, Void&gt; {
    Context mContext;

    public ReverseGeocodingTask(Context context) {
        super();
        mContext = context;
    }

    &#064;Override
    protected Void doInBackground(Location... params) {
        Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());

        Location loc = params[0];
        List&lt;Address&gt; addresses = null;
        try {
            // Call the synchronous getFromLocation() method by passing in the lat/long values.
            addresses = geocoder.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
        } catch (IOException e) {
            e.printStackTrace();
            // Update UI field with the exception.
            Message.obtain(mHandler, UPDATE_ADDRESS, e.toString()).sendToTarget();
        }
        if (addresses != null &amp;&amp; addresses.size() &gt; 0) {
            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",
                    address.getMaxAddressLineIndex() &gt; 0 ? address.getAddressLine(0) : "",
                    address.getLocality(),
                    address.getCountryName());
            // Update the UI via a message handler.
            Message.obtain(mHandler, UPDATE_ADDRESS, addressText).sendToTarget();
        }
        return null;
    }
}
</pre>
