Reverse geocoding is the process of transforming a (latitude, longitude) coordinate into a (partial) address.
In this article, we will create an Android application which adds a marker on the touched location of the Google Map. It also displays the address of the touched location in a TextView using reverse Geocoding.
For reverse Geocoding, this application make use Android’s Geocoder API.
This application is developed in Eclipse ( 4.2.0 ) with ADT plugin (20.0.3 ) and Android SDK ( R20.0.3 ).
Update : An upgraded version of this application ( using Google Map Android API V2 ) is available in the article titled “Android Reverse Geocoding at touched location in Google Map Android API V2”
1. Create a new Android application project namely “LocationReverseGeocoding”
2. Design application launcher icon for this application
3. Create a blank activity to define the class MainActivity
4. Enter MainActivity details
5. Delete Android’s Support Library from this project
By default Eclipse ( 4.2.0) adds Android Support Library to Android application project. For this application, we don’t need to use this support library. So the library file libs/android-support-v4.jar may be removed manually via ProjectExplorer by simply right click on the file and then clicking the menu item “delete”.
6. Obtain Google Map Key
Google’s Map Key for the Android application will be available here.
The map key obtained has to be entered as the value of the attribute android:apiKey in the layout file res/layout/activity_main.
7. Create a new folder namely drawable under the folder “res”
8. Download the given below image file namely “marker.png” to the folder “res/drawable”
9. Update the file res/values/strings.xml
<resources>
<string name="app_name">LocationReverseGeocoding</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_main">ReverseGeocoding</string>
</resources>
10. Update the file res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/tv_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
tools:context=".MainActivity" />
<com.google.android.maps.MapView
android:id="@+id/map_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:apiKey="0u7AJChI1NV8vCpj21C0Cq8YnNMrB6YMgigu0GA"
android:clickable="true"
android:layout_below="@id/tv_location" />
</RelativeLayout>
Note : Replace the value of android:apiKey (Line 17) with the Google Map Key obtained in Step 6
11. Create a class namely TouchedLocationOverlay in the file src/in/wptrafficanalyzer/locationreversegeocoding/TouchedLocationOverlay.java
package in.wptrafficanalyzer.locationreversegeocoding;
import java.util.ArrayList;
import java.util.List;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
public class TouchedLocationOverlay extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
private Handler handler;
public TouchedLocationOverlay(Drawable defaultMarker,Handler h) {
super(boundCenterBottom(defaultMarker));
// Handler object instantiated in the class MainActivity
this.handler = h;
}
// Executed, when populate() method is called
@Override
protected OverlayItem createItem(int arg0) {
return mOverlays.get(arg0);
}
@Override
public int size() {
return mOverlays.size();
}
public void addOverlay(OverlayItem overlay){
mOverlays.add(overlay);
populate(); // Invokes the method createItem()
}
// This method is invoked, when user tap on the map
@Override
public boolean onTap(GeoPoint p, MapView map) {
List<Overlay> overlays = map.getOverlays();
// Creating a Message object to send to Handler
Message message = new Message();
// Creating a Bundle object ot set in Message object
Bundle data = new Bundle();
// Setting latitude in Bundle object
data.putInt("latitude", p.getLatitudeE6());
// Setting longitude in the Bundle object
data.putInt("longitude", p.getLongitudeE6());
// Setting the Bundle object in the Message object
message.setData(data);
// Sending Message object to handler
handler.sendMessage(message);
return super.onTap(p, map);
}
}
12. Update the class MainActivity in the file src/in/wptrafficanalyzer/locationreversegeocoding/MainActivity.java
package in.wptrafficanalyzer.locationreversegeocoding;
import java.io.IOException;
import java.util.List;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.widget.TextView;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
public class MainActivity extends MapActivity {
private MapView mapView;
private TextView tvLocation;
// Handles Taps on the Google Map
Handler h = new Handler(){
// Invoked by the method onTap()
// in the class CurrentLocationOverlay
@Override
public void handleMessage(Message msg) {
Bundle data = msg.getData();
// Getting the Latitude of the location
int latitude = data.getInt("latitude");
// Getting the Longitude of the location
int longitude = data.getInt("longitude");
// Show the location in the Google Map
showLocation(latitude,longitude);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Getting reference to map_view available in activity_main.xml
mapView = (MapView) findViewById(R.id.map_view);
// Getting reference to tv_location available in activity_main.xml
tvLocation = (TextView) findViewById(R.id.tv_location);
// Default Latitude
int latitude = 28426365;
// Default Longitude
int longitude = 77320393;
// Show the location in the Google Map
showLocation(latitude,longitude);
}
private void showLocation(int latitude, int longitude){
// Setting Zoom Controls
mapView.setBuiltInZoomControls(true);
// Getting the MapController
MapController mapController = mapView.getController();
// Getting Overlays of the map
List<Overlay> overlays = mapView.getOverlays();
// Getting Drawable object corresponding to a resource image
Drawable drawable = getResources().getDrawable(R.drawable.marker);
// Creating an ItemizedOverlay
TouchedLocationOverlay locationOverlay = new TouchedLocationOverlay(drawable,h);
// Getting the MapController
MapController mc = mapView.getController();
// Creating an instance of GeoPoint, to display in Google Map
GeoPoint p = new GeoPoint(
latitude,
longitude
);
// Locating the point in the Google Map
mc.animateTo(p);
// Creating an OverlayItem to mark the point
OverlayItem overlayItem = new OverlayItem(p, "Item", "Item");
// Adding the OverlayItem in the LocationOverlay
locationOverlay.addOverlay(overlayItem);
// Clearing the overlays
overlays.clear();
// Adding locationOverlay to the overlay
overlays.add(locationOverlay);
// Redraws the map
mapView.invalidate();
Double[] lat_long = new Double[] { latitude/1E6, longitude/1E6 };
// Executing ReverseGeocodingTask to get Address
new ReverseGeocodingTask(getBaseContext()).execute(lat_long);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return false;
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
private class ReverseGeocodingTask extends AsyncTask<Double, Void, String>{
Context mContext;
public ReverseGeocodingTask(Context context){
super();
mContext = context;
}
@Override
protected String doInBackground(Double... params) {
Geocoder geocoder = new Geocoder(mContext);
double latitude = params[0].doubleValue();
double longitude = params[1].doubleValue();
List<Address> addresses = null;
String addressText="";
try {
addresses = geocoder.getFromLocation(latitude, longitude,1);
} catch (IOException e) {
e.printStackTrace();
}
if(addresses != null && addresses.size() > 0 ){
Address address = addresses.get(0);
addressText = String.format("%s, %s, %s",
address.getMaxAddressLineIndex() > 0 ? address.getAddressLine(0) : "",
address.getLocality(),
address.getCountryName());
}
return addressText;
}
@Override
protected void onPostExecute(String addressText) {
// Setting address of the touched Position
tvLocation.setText(addressText);
}
}
}
13. Update the file AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="in.wptrafficanalyzer.locationreversegeocoding"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="4"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<uses-library android:name="com.google.android.maps"/>
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
14. Screenshot of the application

Figure 5 : Showing address of the touched location by Reverse Geocoding in Google APIs Emulator ( API Level 4 )
15. Download
16. Reference
http://developer.android.com/guide/index.html




Superb …………………george..
Thanks a lot for program,
how can be displayed name of state inside that area for the address.?