Google

Tuesday, July 13, 2010

Android Multi-Threaded Geocoding


This version uses multi-threading to run the geocoder.getFromLocationName() method in a separate thread for improved performance.


 <?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/layout/geocode.xml -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<LinearLayout android:layout_width="fill_parent"
android:layout_alignParentBottom="true" android:layout_height="wrap_content"
android:orientation="vertical">
<EditText android:layout_width="fill_parent" android:id="@+id/location"
android:layout_height="wrap_content" android:text="Enter location" />
<Button android:id="@+id/geocodeBtn" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Find Location" />
</LinearLayout>
<com.google.android.maps.MapView
android:id="@+id/geoMap" android:clickable="true"
android:layout_width="fill_parent" android:layout_height="320px"
android:apiKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
</RelativeLayout>




 package com.gta;
import java.io.IOException;
import java.util.List;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
public class GeocodingThreadActivity extends MapActivity
{
Geocoder geocoder = null;
MapView mapView = null;
ProgressDialog progDialog=null;
List<Address> addressList=null;
@Override
protected boolean isLocationDisplayed() {
return false;
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.geocode);
mapView = (MapView)findViewById(R.id.geoMap);
mapView.setBuiltInZoomControls(true);
// lat/long of IICP
GeoPoint pt = new GeoPoint((int)(5.34079*1000000),(int)(100.28241*1000000));
mapView.getController().setZoom(10);
mapView.getController().setCenter(pt);
Button geoBtn =(Button)findViewById(R.id.geocodeBtn);
geocoder = new Geocoder(this);
geoBtn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View view) {
EditText loc = (EditText)findViewById(R.id.location);
String locationName = loc.getText().toString();
progDialog = ProgressDialog.show(GeocodingThreadActivity.this, "Processing...", "Finding Location...", true, false);
findLocation(locationName);
}});
}
private void findLocation(final String locationName)
{
Thread thrd = new Thread()
{
public void run()
{
try {
// do backgrond work
addressList = geocoder.getFromLocationName(locationName, 5);
//send message to handler to process results
uiCallback.sendEmptyMessage(0);
} catch (IOException e) {
e.printStackTrace();
}
}
};
thrd.start();
}
// ui thread callback handler
private Handler uiCallback = new Handler()
{
@Override
public void handleMessage(Message msg)
{
progDialog.dismiss();
if(addressList!=null && addressList.size()>0)
{
int lat = (int)(addressList.get(0).getLatitude()*1000000);
int lng = (int)(addressList.get(0).getLongitude()*1000000);
GeoPoint pt = new GeoPoint(lat,lng);
mapView.getController().setZoom(15);
mapView.getController().setCenter(pt);
}
else
{
Dialog foundNothingDlg = new AlertDialog.Builder(GeocodingThreadActivity.this)
.setIcon(0)
.setTitle("Failed to Find Location")
.setPositiveButton("Ok", null)
.setMessage("Location Not Found...")
.create();
foundNothingDlg.show();
}
}
};
}