| 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 >= Build.VERSION_CODES.GINGERBREAD && 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<Location, Void, Void> { |
| Context mContext; |
| |
| public ReverseGeocodingTask(Context context) { |
| super(); |
| mContext = context; |
| } |
| |
| @Override |
| protected Void doInBackground(Location... params) { |
| Geocoder geocoder = new Geocoder(mContext, Locale.getDefault()); |
| |
| Location loc = params[0]; |
| List<Address> 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 && addresses.size() > 0) { |
| Address address = addresses.get(0); |
| // Format the first line of address (if available), city, and country name. |
| String addressText = String.format("%s, %s, %s", |
| address.getMaxAddressLineIndex() > 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> |