Showing nearby places and place details using Google Places API and Google Maps Android API V2

June 7, 2013
By

In this article, we are going to develop an Android application which shows nearby places of current location in Google Maps Android API V2. On taping the InfoWindow of the marker, the details of the corresponding place will be displayed in a separate activity.



This application makes use of Google services like Google Maps Android API V2, Google Places API and Google Place Details API.

This application is developed in Eclipse (4.2.1) with ADT plugin (22.0.1) and Android SDK (22.0.1) and tested in real devices with Android versions 2.3.6  ( GingerBread ) and 4.0.4 ( Ice Cream Sandwich ).



1. Create a new Android application project namely “LocationPlaceDetailsV2″

Create new Android application project

Figure 1 : Create new Android application project


2. Configure the project

Configuring the application project

Figure 2 : Configuring the application project


3. Design application launcher icon

Design application launcher icon

Figure 3 : Design application launcher icon


4. Create a blank activity

Create a blank activity

Figure 4 : Create a blank activity


5. Enter MainActivity details

Enter MainActivity details

Figure 5 : Enter MainActivity details


6. Download and configure Google Play Services Library in Eclipse

Please follow the given below link to setup Google Play Service library in Eclipse.

http://developer.android.com/google/play-services/setup.html


7. Add Google Play Services Library to this project

Link Google Play Services library to this project

Figure 6 : Link Google Play Services library to this project


8. Get the API key for Google Maps Android API V2

We need to get an API key from Google to use Google Maps in Android application.

Please follow the given below link to get the API key for Google Maps Android API v2.

https://developers.google.com/maps/documentation/android/start


9. Get the API key for Google Places API

We can create API key for Google Place API by clicking “Create new Browser key”  available at the “API Access” pane of the Google console URL : http://code.google.com/apis/console.

Also ensure that, “Places API” is enabled in the “Services” pane of the Google console.


10. Add Android Support library to this project

By default, Android support library (android-support-v4.jar ) is added to this project by Eclipse IDE to the directory libs. If it is not added, we can do it manually by doing the following steps :

  • Open Project Explorer by Clicking “Window -> Show View -> Project Explorer”
  • Right click this project
  • Then from popup menu, Click “Android Tools -> Add Support Library “

11. Update the file res/values/strings.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">LocationPlaceDetailsV2</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="str_btn_find">Find</string>

    <string-array name="place_type">
        <item>airport</item>
        <item>atm</item>
        <item>bank</item>
        <item>bus_station</item>
        <item>church</item>
        <item>doctor</item>
        <item>hospital</item>
        <item>mosque</item>
        <item>movie_theater</item>
        <item>hindu_temple</item>
        <item>restaurant</item>
    </string-array>

    <string-array name="place_type_name">
        <item>Airport</item>
        <item>ATM</item>
        <item>Bank</item>
        <item>Bus Station</item>
        <item>Church</item>
        <item>Doctor</item>
        <item>Hospital</item>
        <item>Mosque</item>
        <item>Movie Theater</item>
        <item>Hindu Temple</item>
        <item>Restaurant</item>
    </string-array>
</resources>


12. Update the layout 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"
    tools:context=".MainActivity" >

    <Spinner
        android:id="@+id/spr_place_type"
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:layout_alignParentTop="true" />

    <Button
        android:id="@+id/btn_find"
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@id/spr_place_type"
        android:text="@string/str_btn_find" />

    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/map"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/spr_place_type"
        class="com.google.android.gms.maps.SupportMapFragment" />

</RelativeLayout>


13. Create a layout file res/layout/activity_place_details.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <WebView
        android:id="@+id/wv_place_details"
        android:layout_width="fill_parent"
        android:layout_height="match_parent" />
</LinearLayout>


14. Create a new class namely “PlaceJSONParser” in the file src/in/wptrafficanalyzer/locationplacedetailsv2/PlaceJSONParser.java


package in.wptrafficanalyzer.locationplacedetailsv2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class PlaceJSONParser {

    /** Receives a JSONObject and returns a list */
    public List<HashMap<String,String>> parse(JSONObject jObject){

        JSONArray jPlaces = null;
        try {
            /** Retrieves all the elements in the 'places' array */
            jPlaces = jObject.getJSONArray("results");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        /** Invoking getPlaces with the array of json object
        * where each json object represent a place
        */
        return getPlaces(jPlaces);
    }

    private List<HashMap<String, String>> getPlaces(JSONArray jPlaces){
        int placesCount = jPlaces.length();
        List<HashMap<String, String>> placesList = new ArrayList<HashMap<String,String>>();
        HashMap<String, String> place = null;

        /** Taking each place, parses and adds to list object */
        for(int i=0; i<placesCount;i++){
            try {
                /** Call getPlace with place JSON object to parse the place */
                place = getPlace((JSONObject)jPlaces.get(i));
                placesList.add(place);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return placesList;
    }

    /** Parsing the Place JSON object */
    private HashMap<String, String> getPlace(JSONObject jPlace){

        HashMap<String, String> place = new HashMap<String, String>();
        String placeName = "-NA-";
        String vicinity="-NA-";
        String latitude="";
        String longitude="";
        String reference="";

        try {
            // Extracting Place name, if available
            if(!jPlace.isNull("name")){
                placeName = jPlace.getString("name");
            }

            // Extracting Place Vicinity, if available
            if(!jPlace.isNull("vicinity")){
                vicinity = jPlace.getString("vicinity");
            }

            latitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lat");
            longitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lng");
            reference = jPlace.getString("reference");

            place.put("place_name", placeName);
            place.put("vicinity", vicinity);
            place.put("lat", latitude);
            place.put("lng", longitude);
            place.put("reference", reference);

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return place;
    }
}


15. Create a new class namely “PlaceDetailsJSONParser” in the file src/in/wptrafficanalyzer/locationnearby/PlaceDetailsJSONParser.java


package in.wptrafficanalyzer.locationplacedetailsv2;

import java.util.HashMap;

import org.json.JSONException;
import org.json.JSONObject;

public class PlaceDetailsJSONParser {

    /** Receives a JSONObject and returns a list */
    public HashMap<String,String> parse(JSONObject jObject){

        JSONObject jPlaceDetails = null;
        try {
            /** Retrieves all the elements in the 'places' array */
            jPlaceDetails = jObject.getJSONObject("result");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        /** Invoking getPlaces with the array of json object
        * where each json object represent a place
        */
        return getPlaceDetails(jPlaceDetails);
    }

    /** Parsing the Place Details Object object */
    private HashMap<String, String> getPlaceDetails(JSONObject jPlaceDetails){

        HashMap<String, String> hPlaceDetails = new HashMap<String, String>();

        String name = "-NA-";
        String icon = "-NA-";
        String vicinity="-NA-";
        String latitude="";
        String longitude="";
        String formatted_address="-NA-";
        String formatted_phone="-NA-";
        String website="-NA-";
        String rating="-NA-";
        String international_phone_number="-NA-";
        String url="-NA-";

        try {
            // Extracting Place name, if available
            if(!jPlaceDetails.isNull("name")){
                name = jPlaceDetails.getString("name");
            }

            // Extracting Icon, if available
            if(!jPlaceDetails.isNull("icon")){
                icon = jPlaceDetails.getString("icon");
            }

            // Extracting Place Vicinity, if available
            if(!jPlaceDetails.isNull("vicinity")){
                vicinity = jPlaceDetails.getString("vicinity");
            }

            // Extracting Place formatted_address, if available
            if(!jPlaceDetails.isNull("formatted_address")){
                formatted_address = jPlaceDetails.getString("formatted_address");
            }

            // Extracting Place formatted_phone, if available
            if(!jPlaceDetails.isNull("formatted_phone_number")){
                formatted_phone = jPlaceDetails.getString("formatted_phone_number");
            }

            // Extracting website, if available
            if(!jPlaceDetails.isNull("website")){
                website = jPlaceDetails.getString("website");
            }

            // Extracting rating, if available
            if(!jPlaceDetails.isNull("rating")){
                 rating = jPlaceDetails.getString("rating");
            }

            // Extracting rating, if available
            if(!jPlaceDetails.isNull("international_phone_number")){
                international_phone_number = jPlaceDetails.getString("international_phone_number");
            }

            // Extracting url, if available
            if(!jPlaceDetails.isNull("url")){
                url = jPlaceDetails.getString("url");
            }

            latitude = jPlaceDetails.getJSONObject("geometry").getJSONObject("location").getString("lat");
            longitude = jPlaceDetails.getJSONObject("geometry").getJSONObject("location").getString("lng");

            hPlaceDetails.put("name", name);
            hPlaceDetails.put("icon", icon);
            hPlaceDetails.put("vicinity", vicinity);
            hPlaceDetails.put("lat", latitude);
            hPlaceDetails.put("lng", longitude);
            hPlaceDetails.put("formatted_address", formatted_address);
            hPlaceDetails.put("formatted_phone", formatted_phone);
            hPlaceDetails.put("website", website);
            hPlaceDetails.put("rating", rating);
            hPlaceDetails.put("international_phone_number", international_phone_number);
            hPlaceDetails.put("url", url);

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return hPlaceDetails;
    }
}


16. Create a new class “PlaceDetailsActivity” in the file src/in/wptrafficanalyzer/locationplacedetailsv2/PlaceDetailsActivity.java


package in.wptrafficanalyzer.locationplacedetailsv2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;

import org.json.JSONObject;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;

public class PlaceDetailsActivity extends Activity {
    WebView mWvPlaceDetails;

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_place_details);

        // Getting reference to WebView ( wv_place_details ) of the layout activity_place_details
        mWvPlaceDetails = (WebView) findViewById(R.id.wv_place_details);

        mWvPlaceDetails.getSettings().setUseWideViewPort(false);

        // Getting place reference from the map
        String reference = getIntent().getStringExtra("reference");

        StringBuilder sb = new StringBuilder("https://maps.googleapis.com/maps/api/place/details/json?");
        sb.append("reference="+reference);
        sb.append("&sensor=true");
        sb.append("&key=YOUR_BROWSER_API_KEY_FOR_PLACES");

        // Creating a new non-ui thread task to download Google place details
        PlacesTask placesTask = new PlacesTask();

        // Invokes the "doInBackground()" method of the class PlaceTask
        placesTask.execute(sb.toString());

    };

    /** A method to download json data from url */
    private String downloadUrl(String strUrl) throws IOException{
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try{
            URL url = new URL(strUrl);

            // Creating an http connection to communicate with url
            urlConnection = (HttpURLConnection) url.openConnection();

            // Connecting to url
            urlConnection.connect();

            // Reading data from url
            iStream = urlConnection.getInputStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

            StringBuffer sb = new StringBuffer();

            String line = "";
            while( ( line = br.readLine()) != null){
                sb.append(line);
            }

            data = sb.toString();
                br.close();

        }catch(Exception e){
            Log.d("Exception while downloading url", e.toString());
        }finally{
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }
    /** A class, to download Google Place Details */
    private class PlacesTask extends AsyncTask<String, Integer, String>{

        String data = null;

        // Invoked by execute() method of this object
        @Override
        protected String doInBackground(String... url) {
            try{
                data = downloadUrl(url[0]);
            }catch(Exception e){
                Log.d("Background Task",e.toString());
            }
            return data;
        }

        // Executed after the complete execution of doInBackground() method
        @Override
        protected void onPostExecute(String result){
            ParserTask parserTask = new ParserTask();

            // Start parsing the Google place details in JSON format
            // Invokes the "doInBackground()" method of the class ParseTask
            parserTask.execute(result);
        }
    }

    /** A class to parse the Google Place Details in JSON format */
    private class ParserTask extends AsyncTask<String, Integer, HashMap<String,String>>{

        JSONObject jObject;

        // Invoked by execute() method of this object
        @Override
        protected HashMap<String,String> doInBackground(String... jsonData) {

            HashMap<String, String> hPlaceDetails = null;
            PlaceDetailsJSONParser placeDetailsJsonParser = new PlaceDetailsJSONParser();

            try{
                jObject = new JSONObject(jsonData[0]);

                // Start parsing Google place details in JSON format
                hPlaceDetails = placeDetailsJsonParser.parse(jObject);

            }catch(Exception e){
                Log.d("Exception",e.toString());
            }
            return hPlaceDetails;
        }

        // Executed after the complete execution of doInBackground() method
        @Override
        protected void onPostExecute(HashMap<String,String> hPlaceDetails){

            String name = hPlaceDetails.get("name");
            String icon = hPlaceDetails.get("icon");
            String vicinity = hPlaceDetails.get("vicinity");
            String lat = hPlaceDetails.get("lat");
            String lng = hPlaceDetails.get("lng");
            String formatted_address = hPlaceDetails.get("formatted_address");
            String formatted_phone = hPlaceDetails.get("formatted_phone");
            String website = hPlaceDetails.get("website");
            String rating = hPlaceDetails.get("rating");
            String international_phone_number = hPlaceDetails.get("international_phone_number");
            String url = hPlaceDetails.get("url");

            String mimeType = "text/html";
            String encoding = "utf-8";

            String data = "<html>"+
                          "<body><img style='float:left' src="+icon+" /><h1><center>"+name+"</center></h1>" +
                          "<br style='clear:both' />" +
                          "<hr />"+
                          "<p>Vicinity : " + vicinity + "</p>" +
                          "<p>Location : " + lat + "," + lng + "</p>" +
                          "<p>Address : " + formatted_address + "</p>" +
                          "<p>Phone : " + formatted_phone + "</p>" +
                          "<p>Website : " + website + "</p>" +
                          "<p>Rating : " + rating + "</p>" +
                          "<p>International Phone : " + international_phone_number + "</p>" +
                          "<p>URL : <a href='" + url + "'>" + url + "</p>" +
                          "</body></html>";

            // Setting the data in WebView
            mWvPlaceDetails.loadDataWithBaseURL("", data, mimeType, encoding, "");
        }
    }
}


17. Update the class “MainActivity” in the file src/in/wptrafficanalyzer/locationplacedetailsv2/MainActivity.java

package in.wptrafficanalyzer.locationplacedetailsv2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;

import org.json.JSONObject;

import android.app.Dialog;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends FragmentActivity implements LocationListener{

    GoogleMap mGoogleMap;
    Spinner mSprPlaceType;

    String[] mPlaceType=null;
    String[] mPlaceTypeName=null;

    double mLatitude=0;
    double mLongitude=0;

    HashMap<String, String> mMarkerPlaceLink = new HashMap<String, String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Array of place types
        mPlaceType = getResources().getStringArray(R.array.place_type);

        // Array of place type names
        mPlaceTypeName = getResources().getStringArray(R.array.place_type_name);

        // Creating an array adapter with an array of Place types
        // to populate the spinner
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, mPlaceTypeName);

        // Getting reference to the Spinner
        mSprPlaceType = (Spinner) findViewById(R.id.spr_place_type);

        // Setting adapter on Spinner to set place types
        mSprPlaceType.setAdapter(adapter);

        Button btnFind;

        // Getting reference to Find Button
        btnFind = ( Button ) findViewById(R.id.btn_find);

        // Getting Google Play availability status
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
        if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available

            int requestCode = 10;
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
            dialog.show();
        }else { // Google Play Services are available

            // Getting reference to the SupportMapFragment
            SupportMapFragment fragment = ( SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

            // Getting Google Map
            mGoogleMap = fragment.getMap();

            // Enabling MyLocation in Google Map
            mGoogleMap.setMyLocationEnabled(true);

            // Getting LocationManager object from System Service LOCATION_SERVICE
            LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

            // Creating a criteria object to retrieve provider
            Criteria criteria = new Criteria();

            // Getting the name of the best provider
            String provider = locationManager.getBestProvider(criteria, true);

            // Getting Current Location From GPS
            Location location = locationManager.getLastKnownLocation(provider);

            if(location!=null){
                onLocationChanged(location);
            }

            locationManager.requestLocationUpdates(provider, 20000, 0, this);

            mGoogleMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {

                @Override
                public void onInfoWindowClick(Marker arg0) {
                    Intent intent = new Intent(getBaseContext(), PlaceDetailsActivity.class);
                    String reference = mMarkerPlaceLink.get(arg0.getId());
                    intent.putExtra("reference", reference);

                    // Starting the Place Details Activity
                    startActivity(intent);
                }
            });

            // Setting click event lister for the find button
            btnFind.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    int selectedPosition = mSprPlaceType.getSelectedItemPosition();
                    String type = mPlaceType[selectedPosition];

                    StringBuilder sb = new StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
                    sb.append("location="+mLatitude+","+mLongitude);
                    sb.append("&radius=5000");
                    sb.append("&types="+type);
                    sb.append("&sensor=true");
                    sb.append("&key=YOUR_BROWSER_API_KEY_FOR_PLACES");

                    // Creating a new non-ui thread task to download Google place json data
                    PlacesTask placesTask = new PlacesTask();

                    // Invokes the "doInBackground()" method of the class PlaceTask
                    placesTask.execute(sb.toString());
                }
            });
        }
    }

    /** A method to download json data from url */
    private String downloadUrl(String strUrl) throws IOException{
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try{
            URL url = new URL(strUrl);

            // Creating an http connection to communicate with url
            urlConnection = (HttpURLConnection) url.openConnection();

            // Connecting to url
            urlConnection.connect();

            // Reading data from url
            iStream = urlConnection.getInputStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

            StringBuffer sb = new StringBuffer();

            String line = "";
            while( ( line = br.readLine()) != null){
                sb.append(line);
            }

            data = sb.toString();

            br.close();

        }catch(Exception e){
            Log.d("Exception while downloading url", e.toString());
        }finally{
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }
    /** A class, to download Google Places */
    private class PlacesTask extends AsyncTask<String, Integer, String>{

        String data = null;

        // Invoked by execute() method of this object
        @Override
        protected String doInBackground(String... url) {
            try{
                data = downloadUrl(url[0]);
            }catch(Exception e){
                Log.d("Background Task",e.toString());
            }
            return data;
        }

        // Executed after the complete execution of doInBackground() method
        @Override
        protected void onPostExecute(String result){
            ParserTask parserTask = new ParserTask();

            // Start parsing the Google places in JSON format
            // Invokes the "doInBackground()" method of the class ParseTask
            parserTask.execute(result);
        }
    }

    /** A class to parse the Google Places in JSON format */
    private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String,String>>>{

        JSONObject jObject;

        // Invoked by execute() method of this object
        @Override
        protected List<HashMap<String,String>> doInBackground(String... jsonData) {

            List<HashMap<String, String>> places = null;
            PlaceJSONParser placeJsonParser = new PlaceJSONParser();

            try{
                jObject = new JSONObject(jsonData[0]);

                /** Getting the parsed data as a List construct */
                places = placeJsonParser.parse(jObject);

            }catch(Exception e){
                Log.d("Exception",e.toString());
            }
            return places;
        }

        // Executed after the complete execution of doInBackground() method
        @Override
        protected void onPostExecute(List<HashMap<String,String>> list){

            // Clears all the existing markers
            mGoogleMap.clear();

            for(int i=0;i<list.size();i++){

                // Creating a marker
                MarkerOptions markerOptions = new MarkerOptions();

                // Getting a place from the places list
                HashMap<String, String> hmPlace = list.get(i);

                // Getting latitude of the place
                double lat = Double.parseDouble(hmPlace.get("lat"));

                // Getting longitude of the place
                double lng = Double.parseDouble(hmPlace.get("lng"));

                // Getting name
                String name = hmPlace.get("place_name");

                // Getting vicinity
                String vicinity = hmPlace.get("vicinity");

                LatLng latLng = new LatLng(lat, lng);

                // Setting the position for the marker
                markerOptions.position(latLng);

                // Setting the title for the marker.
                //This will be displayed on taping the marker
                markerOptions.title(name + " : " + vicinity);

                // Placing a marker on the touched position
                Marker m = mGoogleMap.addMarker(markerOptions);

                // Linking Marker id and place reference
                mMarkerPlaceLink.put(m.getId(), hmPlace.get("reference"));
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onLocationChanged(Location location) {
        mLatitude = location.getLatitude();
        mLongitude = location.getLongitude();
        LatLng latLng = new LatLng(mLatitude, mLongitude);

        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(12));
    }

    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub
    }

@Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub
    }
}

18. Update the file AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="in.wptrafficanalyzer.locationplacedetailsv2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <permission
        android:name="in.wptrafficanalyzer.locationplacedetailsv2.permission.MAPS_RECEIVE"
        android:protectionLevel="signature"/>

    <uses-permission android:name="in.wptrafficanalyzer.locationplacedetailsv2.permission.MAPS_RECEIVE"/>

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="in.wptrafficanalyzer.locationplacedetailsv2.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name="in.wptrafficanalyzer.locationplacedetailsv2.PlaceDetailsActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name=".PlaceDetails" />
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
        </activity>

        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="YOUR_ANDROID_API_KEY"/>
    </application>
</manifest>


19. Screenshots of the application

Showing nearby doctors of the current location

Figure 7 : Showing nearby doctors of the current location

Showing place details on taping the InfoWindow

Figure 7 : Showing place details on taping the InfoWindow


20. Download Source Code


How to hire me?

I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in

You can hire me on hourly basis or on project basis for Android applications development.

For hiring me, please mail your requirements to info@wptrafficanalyzer.in.

My other blogs
store4js.blogspot.com


Android Knowledge Quiz

Ready to test your knowledge in Android? Take this quiz :



Tags: , , , ,

87 Responses to Showing nearby places and place details using Google Places API and Google Maps Android API V2

  1. Basribaz on June 10, 2013 at 2:31 pm

    not able to Indonesian territory

    • Kaustav Ghosh on February 25, 2014 at 2:51 pm

      Dear sir,
      Can you please tell me that are my BROWSER API KEY FOR PLACES and my Google API key are same??if not then how to generate a browser api key??

      • karanveer Singh on August 25, 2014 at 3:22 pm

        1.follow tutorial on address androidhive google play tutorial

        2.your browser api key is diffrent
        3.in google api console click on credintials and then clikc on genrate key
        4.then clikc on genrate android key
        5.find your sha1 key from ecllise-> window->prefreence and click in androoid->build there is your sha1 key copy it

        • Gaurav on January 28, 2016 at 1:56 pm

          how can i generate BROWSER API KEY FOR PLACES???

      • Nashinski on July 1, 2016 at 4:29 am

        i follow this, and found it really healpful

    • Md Selim Raza on January 14, 2016 at 1:53 pm

      This code is not work to me. Just get map , but want to get nearby atm or hospital or busStop etc. please help me to, I use android Studio IDE to develop my application.

  2. chris on June 11, 2013 at 2:16 pm

    hello
    since i update adt no one map works

    have you got idea why???
    thank
    Chris

    • george on June 11, 2013 at 3:15 pm

      Hello Chris,

      Please do the following :

      * Open properties window by right clicking the project from project explorer

      * Select Java Build Path -> Order and Export tab

      * Ensure “Android Private Libraries” is checked

      * If unchecked, “check” it and click ok

      * Clean and Build the project and run the application

      • chris on June 12, 2013 at 11:30 am

        thanks,
        when i do it:
        the place of lib google play service isn’t at the good position and i don’t know how to put in ‘android depencies’ and ‘android private librairie’??
        for me it just in librairie as .jar
        in the project is in ‘referenced librairies’ path

        thanks
        chris

  3. MedO on June 11, 2013 at 9:27 pm

    how to activiate Places API
    they require Please provide additional information about your company or organization
    I don’t have a company

  4. Jack on June 11, 2013 at 10:20 pm

    Dear sir, I think the key word of tel number is “formatted_phone_number”

    • george on June 11, 2013 at 10:45 pm

      Hi Jack,
      According to the documentation, “formatted_phone_number” contains place’s telephone number in local format. Whereas the “international_phone_number” contains place’s telephone number in international format.

      • Jack on June 14, 2013 at 5:30 pm

        Dear sir, that not what I mean.
        Oh my poor English
        I mean the key word you use in the code above is “formatted_phone”, rather than “formatted_phone_number”.
        I found it because when I run the app, it always shows nothing of the phone number

        • george on June 14, 2013 at 6:12 pm

          Hi Jack,
          Thanks for reporting this.
          Now it is corrected in the article and in the source code.

  5. dianhosen on June 13, 2013 at 7:30 pm

    Hi, It is a nice tutorial. I’m trying to follow the tutorial …The map appears but the places are not there. Do we need to define more details the places somewhere in the code? Sorry if I’m a bit slow as a beginner…

  6. David on July 1, 2013 at 2:45 am

    Hi,

    The app crashes and I’m not sure why…
    My emulator doesn’t work so I try to run it and once I get the apk file, I email it to myself and install it on my Galaxy S2.
    However, after I load the app, it crashes within seconds…
    Any reason it may happen? I have both of the keys (Android Apps and browser apps) and inputted them in the correct locations.
    For the rest, I just copy-pasted.

    Also, where is all of the data taken from? perhaps I’m not connecting to the source or the database correctly.

    Thanks,
    David

    • David on July 1, 2013 at 4:29 am

      Hi again,

      Okay, I found the mistake and the app loads… however, I don’t see the map itself and the locations… any reason why it may happen?

      Thanks…

      • george on July 1, 2013 at 7:33 am

        Please check, you entered the correct places api and android api keys. Also ensure that Places API is enabled.

        • David on July 5, 2013 at 2:40 am

          I have two keys,
          “Key for Android apps”
          &
          “Key for browser apps”

          I entered the first one once in AndroidManifest.xml
          and the second one twice (one time in MainActivity.java and the second time in PlaceDetailsActivity.java).

          Did I miss anything?

          Thanks.

          • hieu on May 31, 2014 at 8:24 pm

            Can you tell me how to generate browser key, please?
            I register in https://code.google.com/apis/console/ but I don’t understand fill information in URL.

        • David on July 5, 2013 at 2:42 am

          And, how do I know that Places API is enabled?

          • David on July 5, 2013 at 5:50 am

            I think I was able to enable it through Google Developers… but I still see nothing…

          • george on July 5, 2013 at 5:58 am

            You can enable Place API via, https://code.google.com/apis/console/

        • David on July 6, 2013 at 8:52 pm

          I did enable Places API and it even asked me to create a Billing account…
          Now I have two APIs enables:
          Google Maps Android API v2
          and
          Places API

          • David on July 7, 2013 at 6:35 am

            Found my mistake…
            I was using the incorrect SHA1 value…

            thanks.

      • bonzo on November 13, 2013 at 1:43 pm

        Hey, I’m getting the same problem….my app also crashes when i run it on emulator or my galaxy grand…how did you solve your problem

        Thanks

      • Melvin on March 17, 2015 at 10:22 pm

        Please tell me how did you solve your app crash I could not find any solution.

    • Moath on April 30, 2014 at 5:25 am

      Hey, I’m getting the same problem….my app also crashes when i run it on emulator or my galaxy S2
      Can you Please tell me how did you solve your problem

  7. David on July 7, 2013 at 9:36 pm

    Hello again,

    I’m facing another problem… I now can see the map but I don’t see the locations… how do I enable the locations?
    Do I need to use my own database?

    Thanks

    • mhmod on May 1, 2016 at 4:07 am

      I have the same problem if you solve it please help me

  8. Danny on July 13, 2013 at 9:51 pm

    Application crashed when I click on the name of the places.
    .wptrafficanalyzer.locationplacedetailsv2.PlaceDetailsActivity$ParserTask.onPostExecute(PlaceDetailsActivity.java:152)

  9. David on July 15, 2013 at 3:32 am

    Still struggling to get business places in action…
    I have all of the API codes set and Places API is enabled… what could be other reasons for this problem?
    I see the map and my current location, but that’s about it… I click ‘Find’ and nothing happens…

  10. Bob Sagget on August 4, 2013 at 8:02 am

    Thanks for the tutorial! The only problem I am having is that the app crashes when I click on a location’s name. Any idea why this might be happening?

    • george on August 4, 2013 at 8:11 am

      Are you getting any hint from logcat?

      • Bob Sagget on August 4, 2013 at 9:26 am

        Yes! logcat helped and I resolved that issue. Now another issue has come up.. The details page for the locations is displaying a black screen. Sometimes when I click on the screen a portion of the data will appear and I can see the information. It is similar to having weird artifact errors… maybe it is something with the webview?

        • Bob Sagget on August 4, 2013 at 9:41 am

          Ok to fix the black screen being displayed I had to remove LinearLayout from the .xml file and just leave the WebView. This fixed the issue.

    • xavi on August 9, 2013 at 8:21 pm

      Hi Bob,

      I have the same problem when I click on a location’s name. Do you remember how did you solved this?

      Thank you

  11. xavi on August 16, 2013 at 5:03 pm

    Hi George, thanks for your tutorials!

    I have a probem when I click on a location’s name: the app crashes and the logCat says that there’s a NullPointerException on PlaceDetailsActivity.ParserTask.onPostExecute, on the first line of this function.

    I’m not able to solve it, would you give me some advice?

    Thanks a lot

    Xavi

  12. akhwan on August 22, 2013 at 5:25 pm

    it is not work in indonesia -_- “

  13. babu s on September 6, 2013 at 8:53 pm

    hi,

    I want to only one map location type at a time..if i select school and then atm, it shows both.i want to show only atm.then what to do ?

  14. Abhay Sood on October 13, 2013 at 1:00 pm

    I have a probem when I click on a location’s name: the app crashes and the logCat says that there’s a NullPointerException on PlaceDetailsActivity.ParserTask.onPostExecute, on the first line of this function.

    I’m not able to solve it, would you give me some advice?

    Thanks a lot

  15. kandarp on November 13, 2013 at 1:04 am

    sir nice tutorail but i m total new , may be silly question but
    what is “YOUR_BROWSER_API_KEY_FOR_PLACES”
    and how can i get it ??

  16. marmik on November 13, 2013 at 10:21 pm

    Sir,
    My application crashes as soon as I run it on emulator or my phone. I can’t figure out the problem.
    Thanks…

  17. shefi on November 27, 2013 at 4:53 pm

    I getting this error pls help

    The Google Play services resources were not found. Check your project configuration to ensure that the resources are included.

  18. divna on December 2, 2013 at 10:43 am

    Hi George,

    I am getting the Google Play services resources were not found. Check your project configuration to ensure that the resources are included.

    Though i have included it in my project. Please help. Would really appreciate.

    Thanks

  19. Gambie on January 24, 2014 at 9:07 pm

    Can you tell me the difference between PlaceJSONParser.java and PlaceDetailsJSONParser.java please I am a bit confused…

  20. Aman on February 10, 2014 at 3:14 pm

    Hiii Sir

    I have used both keys from the apis console but app crashes on start in my phone but on emulator drop downs comes and also a prompt which shows to update Google play services after adding tag

  21. rimesh on April 17, 2014 at 3:46 pm

    I am getting map displayed and also getting my current location, but nothing happens when I press Find button. please help.

    • budi on May 29, 2015 at 6:23 pm

      same with me,

  22. prakash on April 25, 2014 at 10:56 pm

    hi,

    i have tried your code. Emulator has started..but when i tried to run the apps..it is showing error “Unfortunately LocationPlaceDetailsV@ has been stopped”.

    how to fix this error..pls let me know

    regards
    prakash

  23. Arjun Narahari on January 2, 2015 at 2:51 pm

    sir awesome tutorial thank you
    i just wanted to know , how can we display distance in the same program , like after URL , i want to show Distance : 2km
    can u help me in just displaying distance?
    thanking you
    Regards
    Arjun Narahari

  24. pragya pandey on January 3, 2015 at 3:38 pm

    sir,
    this is awesome tutorial thank you
    i just wanted to known if i am added another filled like railway station and
    police station in nearby tutorials it is not working please help me sir
    Thank you
    Regards
    pragya pandey

  25. leela on February 8, 2015 at 12:06 pm

    Can you tell me how to download photos of the place as well in this app?

  26. akmal on February 25, 2015 at 3:19 pm

    Sir., thank for your tutorial .. it work smoothly .. thanks .. when i click on location it show the name of location.. now i want make if user click on name location it will intent to other page.. can you help me ?

  27. abhishek on March 11, 2015 at 1:28 pm

    Thank’s a lot sir its working fine…

  28. Rameshwari on March 24, 2015 at 11:13 pm

    Sir, i tried ua code.. there are no errors but wen i run it on my device, the project loads n den “Unfortunately Project has stopped” m getting this.. i have enabled Google Maps Android Api v2 and Places Api and created android key using SHA1 fingerprint and have created Browser key.. But have kept “ACCEPT REQUESTS FROM THESE HTTP REFERERS (WEB SITES)” this as blank coz i didnt knew wht shld i enter into it.. Plzz help me wht m i missing..?

  29. Emyl on May 11, 2015 at 12:36 pm

    Hi thanks for the great tutorial.

    I would like to add some new Places like “Hotel” and “Shopping Mall” however it doesnt work like other options. The map will appear empty. Can you help me with that?

  30. Neeru on May 12, 2015 at 5:55 pm

    Hello sir,
    I implemented the tutorial you’ve provided.It shows the spinner,find button and map also.But when i click on Find button No resulting places are shown on the map.
    I also tried to implement your Showing nearby places using Google Places API and Google Map Android API V2 tutorial .here also i get the same problem No markers are shown on the map.
    Help me out as i am not able to locate the error.

  31. Keshava Koushik S on May 13, 2015 at 3:41 pm

    Hi sir,

    I tries your code in Android Studio. Find button is not working. When I select Find button nothing happens. Please let me know what mistake am I making.

  32. Chhavi on June 5, 2015 at 11:15 am

    Hello Sir,
    Thanks for sharing this tutorial. But I am facing a problem while running this. It shows the map but is not able to show my current location. I have enabled all the api required and entered the correct api key at the required places. Thanking you in anticipation.

  33. Abdul Khalik on June 18, 2015 at 1:57 pm

    sir,
    this is awesome tutorial thank you
    i just wanted to known when I click on the marker I get info but when I click for details the application has been stopped can you help me how can I solve this problem. please help me sir as early as possible sir

    Thank you
    Regards
    Abdul Khalik

  34. sam on June 19, 2015 at 1:36 am

    Hi
    I tried displaying the maps with nearby locations. But I am able to see only , the map and current location of me. Unable to see the places nearby. And I am using my HTC device to run it.
    Please give me the suggestion.

  35. Guest on June 25, 2015 at 6:56 pm

    Hi,

    I have followed your tutorial and it loads the map ok but it doesnt show any nearby places and no errors appear. Can any one tell me how to fix this issue

    • Nashinski on July 1, 2016 at 4:37 am

      Make sure you have enabled Google Places Web Service and you have a Browser Api Key,

  36. vinay on June 28, 2015 at 9:27 pm

    hi sir
    I am getting Map but when am clicking on find button it is not showing any nearby places please help me
    i generated browser correctly and also maps api key then want went wrong??

  37. Anant on July 3, 2015 at 5:29 pm

    Sir I am not able to run your app.
    Error is coming showing that my API key is not valid.

    Please help me to understand which API key is really required
    in Manifest file and in PlaceDetailsActivity.java file .

    • Nashinski on July 1, 2016 at 4:35 am

      The api key required at the manifest file is the Android Api Key, while that in the PlaceDetailsActivity.java file, is the Browser Api Key.

  38. mahesh on July 13, 2015 at 11:59 am

    hi sir,

    i am getting only maps but i pressed the find i am not locating the places that i am facing the problem

  39. Pradeep on July 14, 2015 at 5:35 pm

    Can u please help me
    How to Display Phone no in custom marker before Detail activity class

    please share code snippet

  40. Aswanth on August 3, 2015 at 11:03 am

    Thank you Mr.George Mathew This tutorial helps me a lot to do my project, Thank you verymuch

  41. Akshyapadma Mohapatra on August 12, 2015 at 4:30 pm

    Hello,
    When I run your downloaded source code or even when I create my own project with this code, I get an error “android.view.InflateException:Binary XML file line #21: Error inflating class fragment”. Kindly check.

  42. ohood on August 16, 2015 at 6:07 pm

    i see the map but when i want to find places i’m getting audio autput flag_fast denied by client

  43. Vivek Rathod on September 5, 2015 at 11:30 am

    Sir,how do we get more than 20 results in nearby search..

  44. prshant kumar on September 7, 2015 at 2:57 pm

    this is not run my phone
    Error is Unfortunately MyPlaceDetailsV2(Package name) has stoped.
    I don’t know what is that error.

  45. chandan on October 12, 2015 at 1:56 pm

    I am getting Map but when am clicking on find button it is not showing any nearby places …. plz reply me soon …..

  46. Mainak Dev on December 22, 2015 at 12:31 am

    Sir, I have tried running your app with an Android API key for the manifest file and a Browser key for Main Activity and Place Details activity, I have followed your tutorial completely and my both my Google Maps API and Places API are enabled on my developer console, but still when I go ahead and run the app it force closes, Any help would be appreciated

  47. Shire on December 28, 2015 at 9:15 am

    Thank you sir for your clear explanation that has remind a guide for newbies like me for year. Your work is truly inspiring and helping other out. I was adding another view to your work the list of places in a list view. So that the user will have an option to view it on a map or list. However, when ever i run my application will crush? will you pls highlighten a bit on how to do it.

  48. Shire on December 30, 2015 at 2:52 pm

    Thanks for developing such an easy application which makes understanding easier for newbies. I have used your application and it works perfectly, However, recently I am trying to create another activity which displays the nearby places in a list view. However, I am having problem and my code crashes everything I try to do it. Would you please guide me on how to do it. Thanx in advance.

  49. Anupam on January 7, 2016 at 7:51 pm

    How to get place in between 2 cities ? For ex. How to locate fuel pumps in between city X and city Y on our website ?

  50. Bhavana on February 9, 2016 at 11:50 am

    Hello, George this is a great tutorial !! Thanx a ton :-) and guys it works use SERVER KEY in MainActivity and PlaceDetailsActivity it works. If you find it hard in getting your location try hardcoding latitude and longitude in line number 140 it should work

  51. vijairaj on February 22, 2016 at 4:45 pm

    I am not getting nearby places in map.Please response me soon.

  52. harsh on March 7, 2016 at 2:16 pm

    I am getting Map but when am clicking on find button it is not showing any nearby places …. plz reply me soon …..

  53. princy on March 12, 2016 at 12:59 pm

    am gettin map but not the places …help me to solve this plz

  54. Shubham Dhingra on June 27, 2016 at 8:19 pm

    I am not getting the nearby places when i click on find button
    I am waiting for your response.

Leave a Reply to Anupam Cancel reply

Your email address will not be published. Required fields are marked *

Be friend at g+

Subscribe for Lastest Updates

FBFPowered by ®Google Feedburner