Showing posts with label Android Reverse Geocoding. Show all posts
Showing posts with label Android Reverse Geocoding. Show all posts

Monday, April 5, 2010

Reverse Geocoding in android 2.2 Froyo(or api level greater than 8)

I have faced problem in android 2.2 Froyo(or api level greater than 8) and found solution myself.
getFromLocationName() returns null or get java.io.IOException: Service not Available
exception so i have find alternate solution to solve this issue.

Google provide service for reverse Geocoding just use this service for reverse geocoding in api level 8 or greater.
below is sample code:
Firstly add kxml.jar into your project using project->Build Path
For download kxml.jar click here.

now create below class into your project.
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Hashtable;
import org.kxml.*;
import org.kxml.io.*;
import org.kxml.kdom.*;
import org.kxml.parser.*;
import android.util.Log;

public class Geocoding
{
      Hashtable ht=null;
      private boolean time=true;
      private int count=0;
      private String citystreetvalue=null;
      public Geocoding()
      {
           System.out.println("Constructor call...");
           ht=new Hashtable();
      }
//***************************** Find Address of the latitude Longitude ***********

      public String parseXml(String address)
      {
         try
         {
            System.out.println("Address is:" + address);
            //URL mUrl = new URL("http://maps.google.com/maps/api/geocode/xml?address=tagore%20road%20rajkot&sensor=false");

            URL mUrl = new URL("http://maps.google.com/maps/api/geocode/xml?address=" + address + "&sensor=false");

             Log.e("Url",mUrl.toString());
             HttpURLConnection mConn = (HttpURLConnection) mUrl.openConnection();
             System.out.println("After address add...");
             InputStream is = mConn.getInputStream();
             Reader reader = new InputStreamReader(is);
             XmlParser parser = new XmlParser(reader);
             traverse(parser,"");
             mConn.disconnect();
             is.close();
             System.out.println("Close all connection...");
             if(ht.get("status").toString().equals("OK"))
             {
                System.out.println("result is Ok..." + ht.get("locality").toString() + ht.get("street").toString());
                 citystreetvalue=ht.get("latitude").toString() + ","+ ht.get("longitude").toString() +","+ht.get("street").toString()+","+ht.get("locality").toString();
             }else
             {
                  System.out.println("result is not Ok...");
                  citystreetvalue="InvalidLocation";
             }
           }
           catch(Exception e)
           {
               System.out.println(e.toString());
           }
           System.out.println("before returen statement...");
        return citystreetvalue;
    }
    public void traverse(XmlParser parser, String indent ) throws Exception
    {
        System.out.println("in Traverse method....");
        boolean leave = false;
        String title = new String();
        String desc = new String();
        do
        {
           ParseEvent event = parser.read ();
           ParseEvent pe;
           switch (event.getType())
           {
               // For example,
               case Xml.START_TAG:
               // see API doc of StartTag for more access methods
               // Pick up Title for display
                     if ("status".equals(event.getName()))
                     {
                           pe = parser.read();
                           title = pe.getText();
                           ht.put("status",title);
                     }
                     if(count<2 br="br">
                     {
                         if ("lat".equals(event.getName()))
                         {
                             pe = parser.read();
                             title = pe.getText();
                             ht.put("latitude",title);
                             count=count+1;
                         }
                         if ("lng".equals(event.getName()))
                         {
                             pe = parser.read();
                             desc = pe.getText();
                             ht.put("longitude",desc);
                             count=count+1;
                         }
                     }
                     if ("long_name".equals(event.getName()))
                     {
                        pe = parser.read();
                        title = pe.getText();
                     }
                     if ("type".equals(event.getName()))
                     {
                        pe = parser.read();
                        desc = pe.getText();
                        if(desc.equals("route"))
                        {
                            System.out.println("street is:" + title);
                            ht.put("street",title);
                        }
                     }
                     if("formatted_address".equals(event.getName()))
                     {
                        if(time)
                        {
                            pe = parser.read();
                            title = pe.getText();
                            ht.put("address",title);
                            time=false;
                        }
                     }
                     ht.put(desc,title);
                     traverse(parser,"") ; // recursion call for each
                     break;
                    // For example 
               case Xml.END_TAG:
                    leave = true;
                    break;
               // For example
               case Xml.END_DOCUMENT:
                    leave = true;
                    break;

              // For example, the text between tags
               case Xml.TEXT:
                    break;
     
               case Xml.WHITESPACE:
                    break; 
    
              default:
          }
       } while( !leave );
   }
}


And now your activity class is as below.


import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Vector;
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 android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;

public class GeocoderAppActivity extends MapActivity {
 /** Called when the activity is first created. */
 MapView mapview;
 MapController mpcontroller;
 LocationManager locationmngr;
 LinearLayout googlemap_panel; 
 EditText addresstxt;  
 Geocoding geocoding=null;
  
 
 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        addresstxt=(EditText)findViewById(R.id.editText1);
        addresstxt.setText("");
        addresstxt.setOnKeyListener(SearchListner);
        
        googlemap_panel=(LinearLayout)findViewById(R.id.googlemap_panel);
               
        mapview = new MapView(this, "0b2ibhsKaC5aNXBVdm-c6uJZVPbiypSmaMppgUg");
        mapview.setVisibility(View.VISIBLE);
        mapview.setClickable(true);
        mapview.setEnabled(true);
        
        mapview.setSatellite(true);
  View zoomControll=mapview.getZoomControls();
  mapview.addView(zoomControll);
  mapview.displayZoomControls(true);
  
  
  String loccontax=Context.LOCATION_SERVICE;
  locationmngr=(LocationManager)getSystemService(loccontax);
              
  mpcontroller=mapview.getController();
  
  Double latitude=22.287535*1E6;
  Double longitude=70.791226*1E6;      
  
  GeoPoint gp=new GeoPoint(latitude.intValue(),longitude.intValue());
  mpcontroller.setCenter(gp);
  mpcontroller.setZoom(18);
  mpcontroller.animateTo(gp);        
        
    }
 @Override
 protected boolean isRouteDisplayed() {
  // TODO Auto-generated method stub
  return false;
 }
 private android.view.View.OnKeyListener SearchListner = new View.OnKeyListener() {
  
  @Override
  public boolean onKey(View v, int keyCode, KeyEvent event) {
   
   if ((event.getAction()==KeyEvent.ACTION_DOWN)&&(keyCode == KeyEvent.KEYCODE_ENTER)){
    
    String txtvalue=addresstxt.getText().toString().trim();
    
    googlemap_panel.removeView(mapview);
    googlemap_panel.addView(mapview, new LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.FILL_PARENT));
          
    rgeocoding(txtvalue);     
    
      }
   return false;
  }
 };
 
 public void rgeocoding(String addres)
 {
  geocoding=new Geocoding();

  Log.e("girish", addres);
  StringBuilder sb=new StringBuilder("Address:");
  
  
  addres=addres.replace(" ","%20");
  
  String citystreetvalue=geocoding.parseXml(addres);    
  System.out.println("string is:" + citystreetvalue);
  
  
  if(citystreetvalue.equals("InvalidLocation"))
  {
   showDialog("Invalide Location...");
   
  }else
  {                 
   String citystreetval[]=Split(citystreetvalue, ",");  
         String latcity=citystreetval[3];
         String latstreet=citystreetval[2];
         String nlatitude=citystreetval[0];
         String nlongitude=citystreetval[1];
         
        
         Log.e("lat is:", nlatitude);
         Log.e("long is:", nlongitude);
            
         sb.append(latstreet);
         sb.append(latcity);
   sb.append(nlatitude);
   sb.append(nlongitude);
   
   Log.e("String is:" , sb.toString());
   
   Double latitude=Double.parseDouble(nlatitude);
   Double longitude=Double.parseDouble(nlongitude);
   
   
     GeoPoint gp=new GeoPoint(latitude.intValue(),longitude.intValue());
     mpcontroller.setCenter(gp);
     mpcontroller.setZoom(18);
     mpcontroller.animateTo(gp);
         
     Log.e("String is:", sb.toString());
     showDialog(sb.toString());      
  }           
      
  List providers=locationmngr.getProviders(true);
      
  for(String provider:providers)
  {
   locationmngr.requestLocationUpdates(provider,1000, 0,new LocationListener() 
   {    
    public void onStatusChanged(String provider, int status, Bundle extras) {
     // TODO Auto-generated method stub     
    }    
    public void onProviderEnabled(String provider) {
     // TODO Auto-generated method stub     
    }    
    public void onProviderDisabled(String provider) {
     // TODO Auto-generated method stub     
    }    
    public void onLocationChanged(Location location) {
     // TODO Auto-generated method stub     
    }
   });
   sb.append("\n").append(provider).append(":");
   Location loc=locationmngr.getLastKnownLocation(provider);
   
   if(loc!=null)
   {
    double lat=loc.getLatitude();
    double lon=loc.getLongitude();
    sb.append(lat).append(",").append(lon);        
   }
   else
   {
    sb.append("No Location found");
   }
  } 
 }
   public String[] Split(String splitStr, String delimiter)
     {
             StringBuffer token = new StringBuffer();
             Vector tokens = new Vector();
             // split
             char[] chars = splitStr.toCharArray();
             for (int i=0; i < chars.length; i++)
             {
                 if (delimiter.indexOf(chars[i]) != -1)
                 {
                     // we bumbed into a delimiter
                     if (token.length() > 0)
                     {
                         tokens.addElement(token.toString());
                         token.setLength(0);
                     }
                 }
                 else
                 {
                     token.append(chars[i]);
                 }
             }
             // don't forget the "tail"...
             if (token.length() > 0)
             {
                 tokens.addElement(token.toString());
             }
             // convert the vector into an array
             String[] splitArray = new String[tokens.size()];
             for (int i=0; i < splitArray.length; i++)
             {
                 splitArray[i] = (String)tokens.elementAt(i);
             }
             return splitArray;
     }
   
  public void showDialog(String msg)
  {      
        AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
      alt_bld.setMessage(msg)
      .setCancelable(false)
      .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int id) {
      // Action for 'Yes' Button
      }
      })
      .setNegativeButton("No", new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int id) {
      //  Action for 'NO' Button
      dialog.cancel();
      }
      });
      AlertDialog alert = alt_bld.create();
      // Title for AlertDialog
      alert.setTitle("Massege");
      // Icon for AlertDialog
      
      alert.show();
         // Perform action on click      
  }      
}
Download complete source code click here.