Google Places API Code Example in Android

Note: Full Source code can be downloaded at the end of this page

Place Search Using Google Places API

The Google Places API allows you to query for place information on a variety of categories, such as: establishments, prominent points of interest, geographic locations, and much more. You can search for places either by proximity or a text string. A Place Search returns a list of Places along with summary information about each Place; If you want to view additional information it is extracted using Place Details query.

An HTTP URL is used for search query specifying the type of Place you are searching, latitude and longitude of your location and radius.

The HTTP URL should look like:

https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=YourAPIKey



Mandatory parameters

key — Your application's API key. This key identifies your application for purposes of quota management and so that Places added from your application are made immediately available to your app. Visit the APIs Console to create an API Project and obtain your key.

location — The latitude/longitude around which to retrieve Place information. This must be specified as latitude,longitude.

radius — Defines the distance (in meters) within which to return Place results. The maximum allowed radius is 50 000 meters. Note that radius must not be included if rankby=distance (described under Optional parameters below) is specified.

 sensor — Indicates whether or not the Place request came from a device using a location sensor (e.g. a GPS) to determine the location sent in this request. This value must be either true or false.
 

A JSON response contains up to four root elements:

status: contains metadata on the request. See Status Codes below.

results: contains an array of Places, with information about each. See Nearby Search Results for information about these results. The Places API returns up to 20 establishment results per query. Additionally, political results may be returned which serve to identify the area of the request.
  
html_attributions: contain a set of attributions about this listing which must be displayed to the user.
  
next_page_token: contains a token that can be used to return up to 20 additional results. A next_page_token will not be returned if there are no additional results to display. The maximum number of results that can be returned is 60. There is a short delay between when a next_page_token is issued, and when it will become valid.

Status Codes

The status field within the search response object contains the status of the request, and may contain debugging information to help you track down why the request failed. The status field may contain the following values:
   
OK indicates that no errors occurred; the place was successfully detected and at least one result was returned.   

ZERO_RESULTS indicates that the search was successful but returned no results. This may occur if the search was passed a latlng in a remote location. 
  
OVER_QUERY_LIMIT indicates that you are over your quota.    

REQUEST_DENIED indicates that your request was denied, generally because of lack of a sensor parameter.   

INVALID_REQUEST generally indicates that a required query parameter (location or radius) is missing.


Place Detail Search

Once you have a reference from a Place Search, you can request more details about a particular establishment or point of interest by initiating a Place Details request. A Place Details request returns more comprehensive information about the indicated place such as its complete address, phone number, user rating and reviews.

A Place Details request is an HTTP URL of the following form:
 
https://maps.googleapis.com/maps/api/place/details/json?reference=ReferenceToPlace&
sensor=true&key=AddYourOwnKeyHere



Adding Your Own new Place using Google Places API

Using Google Places API one can add their own new place to map for which the HTTP URL should look like:

POST https://maps.googleapis.com/maps/api/place/add/json?sensor=true_or_false&key=AddYourOwnKeyHere HTTP/1.1
Host: maps.googleapis.com{
 
"location": {
   
"lat": -33.8669710,
   
"lng": 151.1958750
 
},
 
"accuracy": 50,
 
"name": "Google Shoes!",
 
"types": ["shoe_store"],
 
"language": "en-AU"

}

Deleting a Place

 A Place can only be deleted if:
   
  • It was added by the same application as is requesting its deletion.
  • It has not successfully passed through the Google Maps moderation process, and and is therefore not visible to all applications.

Attempting to delete a Place that does not meet these criteria will return a REQUEST_DENIED status code.

A Place Report delete request is an HTTP POST request of the following form:

POST https://maps.googleapis.com/maps/api/place/delete/json?sensor=true_or_false 
&key=AddYourOwnKeyHere HTTP/1.1
Host: maps.googleapis.com
{
  "reference": "place_reference"
}


Complete Source Code:

Now its time to enjoy source code. To download full fledged working source code for all above modules click the link below
 
PlaceRequest.Java
 
This class have place search, search place details, add new place and delete place
methods.
 
Note: Use Own valid Key in API_KEY = "YourMapKeyHere" and any 
where else needed.


public class PlaceRequest {
 
 // ArraList to store corresponding lat, lng
 static List<Double> latList = new ArrayList<Double>();
 static List<Double> lngList = new ArrayList<Double>();

 // Create our transport.
 private static final HttpTransport transport = new ApacheHttpTransport();
 // The different Places API endpoints.
 // order of data in requested URL doesn'n matter
 private static final String PLACES_SEARCH_URL =  
   "https://maps.googleapis.com/maps/api/place/search/json?";
 private static final String PLACES_DETAILS_URL = 
   "https://maps.googleapis.com/maps/api/place/details/json?";
 private static final String PLACE_ADD_URL = 
   "https://maps.googleapis.com/maps/api/place/add/json?" +
   "key=AIzaSyAnOvJ-Woki5W5jUiZhv5bJ5YGB6ZY3yrs&sensor=false"; 
 private static final String PLACES_DELETE_URL = 
   "https://maps.googleapis.com/maps/api/place/delete/json?" +
   "key=AIzaSyAnOvJ-Woki5W5jUiZhv5bJ5YGB6ZY3yrs&sensor=false";
 
 
 // Fill in the API key you want to use.
 private static final String API_KEY = "YourMapKeyHere";
 static final String LOG_KEY = "GooglePlace";
 
 static ArrayList<String> placeReference =  new ArrayList<String>();
   
 private static String mySearchType = "hospital";  // this is just for testing
 private static String searchName = "OffCourse Golf Hole";
    
 // converting back to -33.8670522, 151.1957362 format
 double latitude = ShowGoogleMap.updated_lat / 1E6;
 double longitude = ShowGoogleMap.updated_lng / 1E6;
 
 // Sydney, Australia
 //double latitude = -33.8670522;
 //double longitude = 151.1957362;
 
 // telenet
 //double latitude = 51.034823;
 //double longitude = 4.483774;
 
 public PlacesList performSearch() throws Exception {
  try {
   Log.v(LOG_KEY, "Start Search...");
   GenericUrl reqUrl = new GenericUrl(PLACES_SEARCH_URL);
   reqUrl.put("key", API_KEY);
   reqUrl.put("location", latitude + "," + longitude);
   reqUrl.put("radius", 5000); // radius of 5Km 
   reqUrl.put("types", mySearchType);
   reqUrl.put("name", searchName);
   reqUrl.put("sensor", "false");
   Log.v(LOG_KEY, "Requested URL= " + reqUrl);
   HttpRequestFactory httpRequestFactory = createRequestFactory(transport);
   HttpRequest request = httpRequestFactory.buildGetRequest(reqUrl);
    
    Log.v(LOG_KEY, request.execute().parseAsString());       
    PlacesList places = request.execute().parseAs(PlacesList.class);
    Log.v(LOG_KEY, "STATUS = " + places.status);
    // empty array lists
    latList.clear();
    lngList.clear();
    for (Place place : places.results) {
     Log.v(LOG_KEY, place.name); 
     latList.add(place.geometry.location.lat);
     lngList.add(place.geometry.location.lng); 
     // assign last added place reference 
     placeReference.add(place.reference);
     
    }          
    return places;

  } catch (HttpResponseException e) {
   Log.v(LOG_KEY, e.getResponse().parseAsString());
   throw e;
  }
  
  catch (IOException e) {
   // TODO: handle exception
   throw e;
  }
 }
 
 public PlaceDetail performDetails(String reference) throws Exception { 
  try {
   Log.v(LOG_KEY, "Perform Place Detail....");
   GenericUrl reqUrl = new GenericUrl(PLACES_DETAILS_URL);
   reqUrl.put("key", API_KEY);
   reqUrl.put("reference", reference);
   reqUrl.put("sensor", "false");
   Log.v(LOG_KEY, "Requested URL= " + reqUrl);
   HttpRequestFactory httpRequestFactory = createRequestFactory(transport);
   HttpRequest request = httpRequestFactory.buildGetRequest(reqUrl);

   Log.v(LOG_KEY, request.execute().parseAsString()); 
   PlaceDetail placeDetail = request.execute().parseAs(PlaceDetail.class);
   
   return placeDetail;
       
  } catch (HttpResponseException e) {
   Log.v(LOG_KEY, e.getResponse().parseAsString());
   throw e;
  }
  catch (IOException e) { 
   // TODO: handle exception
   throw e;
  }
   
 }
 
 public JSONObject addPlace(double lat, double lng, String type, String name) throws Exception {
  try {
   Log.v(LOG_KEY, "Adding Place...");
    String vic = "5/48 Pirrama Road, Pyrmont";
    String formtd_address = "5/48 Pirrama Road, Pyrmont NSW, Australia";
    String formtd_phone_number = "(02) 9374 4000";
    String myUrl = "http://maps.google.com/maps/place?cid=10281119596374313554";
    String myWebsite = "http://www.google.com.au/";
    
   HttpPost post = new HttpPost(PLACE_ADD_URL);
   String postBody = 
      "{"+
               "\"location\": {" +
                 "\"lat\": " + lat + "," +
                 "\"lng\": " + lng +
                "}," + 
                "\"accuracy\":50.0," +
                "\"name\": \"" + name + "\"," +
                "\"types\": [\"" + type + "\"]," +
                "\"vicinity\":\""+ PlaceAdd.vic +"\","+
                "\"formatted_address\":\""+ PlaceAdd.formtd_address +"\","+
                "\"formatted_phone_number\":\""+ PlaceAdd.formtd_phone_number +"\","+
                "\"url\":\""+ PlaceAdd.myUrl +"\","+
                "\"website\":\""+ PlaceAdd.myWebsite +"\","+  
                "\"language\": \"en\" " +
                
           "}"; 
   
   StringEntity se = new StringEntity(postBody,HTTP.UTF_8);
   post.setEntity(se);
   ResponseHandler<String> responseHandler=new BasicResponseHandler();
   String responseBody = new DefaultHttpClient().execute(post, responseHandler);
   JSONObject response = new JSONObject(responseBody);
   Log.v(LOG_KEY, "Requested URL= " + PLACE_ADD_URL); 
        
   return response;

  } catch (HttpResponseException e) {
   Log.v(LOG_KEY, e.getResponse().parseAsString());
   throw e;
  }
  
  catch (IOException e) {
   // TODO: handle exception
   throw e;
  }
 }  
 
 public JSONObject deletePlace(String reference) throws Exception { 
  try {
   Log.v(LOG_KEY, "Deleting Place...");
   HttpPost post = new HttpPost(PLACES_DELETE_URL);   
   String postBody = "{\"reference\":\""+ reference +"\"}";
   StringEntity se = new StringEntity(postBody,HTTP.UTF_8);
   post.setEntity(se);
   ResponseHandler<String> responseHandler = new BasicResponseHandler();
   String responseBody = new DefaultHttpClient().execute(post, responseHandler);
   JSONObject response = new JSONObject(responseBody);
   Log.v(LOG_KEY, "Requested URL= " + PLACES_DELETE_URL); 
        
   return response;
       
  } catch (HttpResponseException e) {
   Log.v(LOG_KEY, e.getResponse().parseAsString());
   throw e;
  }
  catch (IOException e) { 
   // TODO: handle exception
   throw e;
  }
   
 }
 
 public static HttpRequestFactory createRequestFactory(final HttpTransport transport) {
      
    return transport.createRequestFactory(new HttpRequestInitializer() {
     public void initialize(HttpRequest request) {
      GoogleHeaders headers = new GoogleHeaders();
      headers.setApplicationName("Google-Places-DemoApp");
      request.setHeaders(headers);
      JsonHttpParser parser = new JsonHttpParser(new JacksonFactory()) ;
      //JsonHttpParser.builder(new JacksonFactory());
      //parser.jsonFactory = new JacksonFactory();
      request.addParser(parser);
     }
  });
 }

}
 
Now call PlaceRequest.java from PlaceAdd.java to add you actual location 
into Google Map.

PlaceAdd.java


public class PlaceAdd extends Activity{
 
 static String placeName;
 static String vic;
 static String formtd_address;
 static String formtd_phone_number;
 static String myUrl;
 static String myWebsite;
 
 ProgressDialog progressDialog;
 
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
      //set up dialog
      Dialog dialog = new Dialog(this);
      dialog.setContentView(R.layout.addplace);
      dialog.setTitle("Enter Place Details");
      dialog.setCancelable(false);
      
      final EditText name = (EditText) dialog.findViewById(R.id.place_title);
      final EditText vicinity = (EditText) dialog.findViewById(R.id.editText1);
      final EditText formatted_address = (EditText) dialog.findViewById(R.id.editText2);
      final EditText formatted_phone_number = (EditText) dialog.findViewById(R.id.editText3);
      final EditText url = (EditText) dialog.findViewById(R.id.editText4);
      final EditText website = (EditText) dialog.findViewById(R.id.editText5);
     
    
     
      Button ok = (Button) dialog.findViewById(R.id.btn_ok);
      ok.setOnClickListener(new OnClickListener() {
          public void onClick(View v) {
           placeName = name.getText().toString();
           vic = vicinity.getText().toString();
              formtd_address = formatted_address.getText().toString();
              formtd_phone_number = formatted_phone_number.getText().toString();
              myUrl =  url.getText().toString();
              myWebsite = website.getText().toString();
              
           Log.v(PlaceRequest.LOG_KEY, "Description: " + vic);
           Log.v(PlaceRequest.LOG_KEY, "Description: " + formtd_address);
           Log.v(PlaceRequest.LOG_KEY, "Description: " + formtd_phone_number);
           Log.v(PlaceRequest.LOG_KEY, "Description: " + myUrl);
           Log.v(PlaceRequest.LOG_KEY, "Description: " + myWebsite);
           
           AddSrv srv = new AddSrv();   
    //setProgressBarIndeterminateVisibility(true);
    srv.execute();
    //YouTube.this.getApplicationContext()
    progressDialog = ProgressDialog.show(PlaceAdd.this, "",  "Adding Place! Please wait...", true);
            
          }
      });
     
      Button cancel = (Button) dialog.findViewById(R.id.btn_cancel);
      cancel.setOnClickListener(new OnClickListener() {
          public void onClick(View v) {
          Toast.makeText(getBaseContext(), "Adding Place is cancelled!", 
            Toast.LENGTH_SHORT).show();
           finish();
          }
      });
       //now that the dialog is set up, it's time to show it    
       dialog.show();
     
 }
 
 class AddSrv extends AsyncTask<Void, Void, JSONObject>{
     @Override
     protected JSONObject doInBackground(Void... params) {
      JSONObject pl = null;
      try {
       // send place search request from here
        pl =   new PlaceRequest().addPlace(ShowGoogleMap.addLat, 
          ShowGoogleMap.addLng, ShowGoogleMap.locType, placeName);  
      } catch (Exception e) {
       e.printStackTrace();
      }
      return pl;
     }
     
     @Override
     protected void onPostExecute(JSONObject result) {            
   Log.v(PlaceRequest.LOG_KEY, "Place Added is: " + result);
   
   
   if (result != null){
     Toast.makeText(getBaseContext(), "Your Place is added", 
       Toast.LENGTH_SHORT).show();
   }
   else{
    Toast.makeText(getBaseContext(), "Please Try Again", 
      Toast.LENGTH_SHORT).show();
   }
   //setProgressBarIndeterminateVisibility(false);
   progressDialog.dismiss();
   finish();
     }
    } // End of class SearchSrv here   

} 
 
Now call PlaceRequest.java from ShowPlaceDetail.java to view Place detail

public class ShowPlaceDetail extends Activity {
 
 ProgressDialog progressDialog;
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
                 //set up dialog
                 Dialog dialog = new Dialog(ShowPlaceDetail.this);
                 dialog.setContentView(R.layout.maindialog);
                 dialog.setTitle(MyItemizedOverlay.title);
                 dialog.setCancelable(false);
  
                 //set up text
                 TextView text = (TextView) dialog.findViewById(R.id.TextView01);
                 text.setText(ShowGoogleMap.detailText);
  
                 //set up image view
                 ImageView img = (ImageView) dialog.findViewById(R.id.ImageView01);
                 img.setImageResource(R.drawable.user_marker);
  
                 //set up button
                 Button button = (Button) dialog.findViewById(R.id.cancel_button);
                 button.setOnClickListener(new OnClickListener() {
                     public void onClick(View v) {
                      ShowPlaceDetail.this.finish();
                     }
                 });
                 
                 Button deletButton = (Button) dialog.findViewById(R.id.delete);
                 deletButton.setOnClickListener(new OnClickListener() {
                     public void onClick(View v) {
                      DelSrv srv = new DelSrv();    
             //setProgressBarIndeterminateVisibility(true);
             srv.execute();
             progressDialog = ProgressDialog.show(ShowPlaceDetail.this, "", 
                         "Deleting! Please wait...", true);
                     }
                 });
                 
                 Button photoButton = (Button) dialog.findViewById(R.id.photo);
                 photoButton.setOnClickListener(new OnClickListener() {
                     public void onClick(View v) {
                      finish();
                     }
                 });
                 //now that the dialog is set up, it's time to show it    
                 dialog.show();
             }
     
      private class DelSrv extends AsyncTask<Void, Void, JSONObject>{
      @Override
      protected JSONObject doInBackground(Void... params) {
       JSONObject pl = null;
       try {
        // send place search request from here
         pl =   new PlaceRequest().deletePlace(MyItemizedOverlay.reference);  
       } catch (Exception e) {
        e.printStackTrace();
       }
       return pl;
      }
      
      @Override
      protected void onPostExecute(JSONObject result) {             
    Log.v(PlaceRequest.LOG_KEY, "Place Deleted is: " + result);
    
    if (result != null){
      Toast.makeText(getBaseContext(), "Your Place is Deleted", 
                    Toast.LENGTH_SHORT).show();
    }
    else{
     Toast.makeText(getBaseContext(), "Please Try Again", 
           Toast.LENGTH_SHORT).show();
    }
    //setProgressBarIndeterminateVisibility(false);
    progressDialog.dismiss();
    finish();
      }
     } // End of class SearchSrv here
  }
 
 All Bean classes for Search Place, Add Place and Place details look like:
 
public class Place {
 @Key
 public String id;
 
 @Key
 public String name;
 
 @Key
 public String reference;
 
 @Key
 public String types[];
 
 @Key
 public String international_phone_number;
 
 @Key
 public String vicinity;
 
 @Key
 public String formatted_address;
 
 @Key
 public String url;
 
 @Key
 public String rating;
 
 @Key
 public String website;
 
 @Key
 public List<Place> address_components;
 
 @Key
 public String long_name;
 
 @Key
 public String short_name;
 
   
 @Key
 public PlaceGeometry geometry;
 
 public static class PlaceGeometry {
  @Key
  public Location location;
 }

 public static class Location {
  @Key
  public double lat;

  @Key
  public double lng;
 }
 
 @Override
 public String toString() {
  return name + " - " + id + " - " + reference;
 }
}


public class PlaceDetail {

 @Key
 public Place result;

 @Override
 public String toString() {
  if (result!=null) {
   return result.toString();
  }
  return super.toString();
 }
}


public class PlaceAutoComplete {

 @Key
 public String id;
 
 @Key
 public String description;
 
 @Key
 public String reference;

 
 @Override
 public String toString() {
  return description + " - " + id + " - " + reference;
 }
 
}


public class PlacesList {

 @Key
 public String status;

 @Key
 public List<Place> results;

}


 Place Search and Add Place Screen shot look like:
 


 

Click the link below to download complete android source code project:


Download Source Code


6 comments:

  1. This source code is tested and in working condition. If you have any query fee free to add your valuable comments

    ReplyDelete
  2. I would love to download the source code but I do not see a link? Did you publish it?

    ReplyDelete
    Replies
    1. Hi Mate,

      I have added link at bottom, Now u can download complete source code. So enjoy :)

      Delete
  3. I was searching of Google places API, and found complete source code bundle here thanks for sharing. Really great work

    ReplyDelete
  4. It did work for me thanks

    ReplyDelete
  5. Hi,

    In first half you wrote that "key — Your application's API key.". I am creating Android as well as Browser app in "http://code.google.com". If i use your API key and hit the url then i get the JSON data, but using my API key it shows me error like follows:

    {
    "error_message" : "This IP, site or mobile application is not authorized to use this API key.",
    "html_attributions" : [],
    "results" : [],
    "status" : "REQUEST_DENIED"
    }

    Can you please tell me what's the problem?

    ReplyDelete