Hello Guys. Hope all of you are doing well. In this tutorial, we will learn how to add the markers on nearby places in Google Maps API using Retrofit . We will name this App as Google Maps Nearby Places API. You can see demo of this tutorial in above video. This is one of the most crystal clear tutorials where minimum code is used to implement nearby places app using retrofit. We made a similar tutorial on Google Maps Search Nearby, but that was implemented using Async Task. Now Async task has become pretty much mediocre and people are using Retrofit to capture data from URL, So we made this tutorial on similar lines. Now you don’t have to make any JSON Parser or Data capture class. Retrofit Android automatically takes care of it.
Pre-requisites
1) Android Studio installed on your PC (Unix or Windows).
2) A real time android device (Smartphone or Tablet) configured with Android Studio.
3) A basic knowledge of Android lifecycle and different classes & functions used in Android Studio.
Now let’s make it. We hope you would have already made an App to display current user location.
Creating new project
Please follow following steps:
- Open Android Studio and make a new project with name “Google Maps Retrofit” or “Google Maps Nearby Places API” and company domain application.example.com (I used my company domain i.e androidtutorialpoint.com. Similarly you can use yours).
- Click Next and choose android version Lollipop. Again Click Next and Choose Google Maps Activity (as shown in following pic).
- Leave all things remaining same and Click Finish.
Now you will be able to see three files:
- google_maps_api.xml (…/GoogleMapsSearchNearby/app/src/debug/res/values/google_maps_api.xml)
- MapsActivity.java (…/GoogleMapsSearchNearby/app/src/main/java/com/androidtutorialpoint/googlemapssearchnearby
/MapsActivity.java) - AndroidManifest.xml ( …/GoogleMapsSearchNearby/app/src/main/AndroidManifest.xml)
Open google_maps_api.xml. Here you will find a lot of information along with a link. Copy-Paste this link in your web browser. Make a Gmail account through which you will configure google play services.
Now at the browser choose “Create New Project” and Click Continue. Following screen will be displayed:
Click on Go to credentials. Below screen will appear.
Create your key by clicking Create. Now a key will be created but there is one big change here as compared to our previous Google Maps tutorials. Here you will need a Server Key. So to generate a Server Key click on Create Credentials and then API Key as shown in the following image:
Click on Server Key. Below screen will appear:
Click Create and copy the Server Key generated. You shall copy and paste this key in google_maps_api.xml. Copy paste it in place where YOUR_KEY_HERE is written:
Code inside google_maps_api.xml is complete.
google_maps_api.xml
<resources>
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">LVwrKoLOEMgwUBXGiut0bkFhoAjOiaVemoMlymg</string>
</resources>
Code Inside AndroidManifest.xml
If you go inside AndroidManifest.xml then this key will be displayed in meta tags. Here you need to add permissions for accessing location of device. The required permission should be as follows:
ACCESS_NETWORK_STATE
– To check network state i.e if we are connected to any network or not.
INTERNET
– If we are connected to Internet or not.
ACCESS_COARSE_LOCATION
– To determine user’s location using WiFi and mobile. It will give us an approximate location.
ACCESS_FINE_LOCATION
– To determine user’s location using GPS. It will give us precise location.
OpenGL ES V2 – Required for Google Maps V2
AndroidManifest.xml
="1.0"="utf-8"
<manifest package="com.androidtutorialpoint.googlemapsdrawroute"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="com.androidtutorialpoint.mymapsappsdirection.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"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key"/>
<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Code inside activity_maps.xml
Here we will add three buttons each for Restaurant, Hospitals and Schools such that when user clicks on Restaurant then markers will be added on nearby restaurants. Similarly in case of other two buttons. For this, we will use FrameLayout . Refer below code:
activity_maps.xml
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<fragment android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.androidtutorialpoint.googlemapsretrofit.MapsActivity"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/btnRestaurant"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nearby Restaurants" />
<Button
android:id="@+id/btnHospital"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nearby Hospitals" />
<Button
android:id="@+id/btnSchool"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nearby Schools" />
<TextView
android:id="@+id/tv_lat"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_lng"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</FrameLayout>
Note: Please see your build.gradle file. It should have following code:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.google.code.gson:gson:1.7.2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.okhttp:okhttp:2.4.0'
}
Fourth line compile ‘com.google.android.gms:play-services:8.4.0’
is responsible for inserting Google Play Services. Please make sure this line is present in build.gradle. Remaining lines after 4th line are responsible for adding Retrofit Android library files. Sync the Project.
Implementation of Google Maps using Retrofit
This is what will return by Google Server while we search for nearby places around current location of user. As you could see in the link we have JSON Object and Array as data returned from Google Maps. We have to capture this data in our App and accordingly add marker at each location. To capture this data using Retrofit Android, we have to make POJO Class. This class is actually composed of Getter and Setter methods.
Adding POJO Class
Add following classes in a separate folder named POJO at path …/GoogleMapsRetrofit/app/src/main/java/com/androidtutorialpoint/googlemapsretrofit/POJO
Example.java
package com.androidtutorialpoint.googlemapsretrofit.POJO;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class Example {
@SerializedName("html_attributions")
@Expose
private List<Object> htmlAttributions = new ArrayList<Object>();
@SerializedName("next_page_token")
@Expose
private String nextPageToken;
@SerializedName("results")
@Expose
private List<Result> results = new ArrayList<Result>();
@SerializedName("status")
@Expose
private String status;
public List<Object> getHtmlAttributions() {
return htmlAttributions;
}
public void setHtmlAttributions(List<Object> htmlAttributions) {
this.htmlAttributions = htmlAttributions;
}
public String getNextPageToken() {
return nextPageToken;
}
public void setNextPageToken(String nextPageToken) {
this.nextPageToken = nextPageToken;
}
public List<Result> getResults() {
return results;
}
public void setResults(List<Result> results) {
this.results = results;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
Location.java
package com.androidtutorialpoint.googlemapsretrofit.POJO;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Location {
@SerializedName("lat")
@Expose
private Double lat;
@SerializedName("lng")
@Expose
private Double lng;
public Double getLat() {
return lat;
}
public void setLat(Double lat) {
this.lat = lat;
}
public Double getLng() {
return lng;
}
public void setLng(Double lng) {
this.lng = lng;
}
}
Geometry.java
package com.androidtutorialpoint.googlemapsretrofit.POJO;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Geometry {
@SerializedName("location")
@Expose
private Location location;
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
}
Result.java
package com.androidtutorialpoint.googlemapsretrofit.POJO;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class Result {
@SerializedName("geometry")
@Expose
private Geometry geometry;
@SerializedName("icon")
@Expose
private String icon;
@SerializedName("id")
@Expose
private String id;
@SerializedName("name")
@Expose
private String name;
@SerializedName("opening_hours")
@Expose
private OpeningHours openingHours;
@SerializedName("photos")
@Expose
private List<Photo> photos = new ArrayList<Photo>();
@SerializedName("place_id")
@Expose
private String placeId;
@SerializedName("rating")
@Expose
private Double rating;
@SerializedName("reference")
@Expose
private String reference;
@SerializedName("scope")
@Expose
private String scope;
@SerializedName("types")
@Expose
private List<String> types = new ArrayList<String>();
@SerializedName("vicinity")
@Expose
private String vicinity;
@SerializedName("price_level")
@Expose
private Integer priceLevel;
public Geometry getGeometry() {
return geometry;
}
public void setGeometry(Geometry geometry) {
this.geometry = geometry;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public OpeningHours getOpeningHours() {
return openingHours;
}
public void setOpeningHours(OpeningHours openingHours) {
this.openingHours = openingHours;
}
public List<Photo> getPhotos() {
return photos;
}
public void setPhotos(List<Photo> photos) {
this.photos = photos;
}
public String getPlaceId() {
return placeId;
}
public void setPlaceId(String placeId) {
this.placeId = placeId;
}
public Double getRating() {
return rating;
}
public void setRating(Double rating) {
this.rating = rating;
}
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public List<String> getTypes() {
return types;
}
public void setTypes(List<String> types) {
this.types = types;
}
public String getVicinity() {
return vicinity;
}
public void setVicinity(String vicinity) {
this.vicinity = vicinity;
}
public Integer getPriceLevel() {
return priceLevel;
}
public void setPriceLevel(Integer priceLevel) {
this.priceLevel = priceLevel;
}
}
Photo.java
package com.androidtutorialpoint.googlemapsretrofit.POJO;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class Photo {
@SerializedName("height")
@Expose
private Integer height;
@SerializedName("html_attributions")
@Expose
private List<String> htmlAttributions = new ArrayList<String>();
@SerializedName("photo_reference")
@Expose
private String photoReference;
@SerializedName("width")
@Expose
private Integer width;
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
public List<String> getHtmlAttributions() {
return htmlAttributions;
}
public void setHtmlAttributions(List<String> htmlAttributions) {
this.htmlAttributions = htmlAttributions;
}
public String getPhotoReference() {
return photoReference;
}
public void setPhotoReference(String photoReference) {
this.photoReference = photoReference;
}
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
}
OpeningHours.java
package com.androidtutorialpoint.googlemapsretrofit.POJO;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class OpeningHours {
@SerializedName("open_now")
@Expose
private Boolean openNow;
@SerializedName("weekday_text")
@Expose
private List<Object> weekdayText = new ArrayList<Object>();
public Boolean getOpenNow() {
return openNow;
}
public void setOpenNow(Boolean openNow) {
this.openNow = openNow;
}
public List<Object> getWeekdayText() {
return weekdayText;
}
public void setWeekdayText(List<Object> weekdayText) {
this.weekdayText = weekdayText;
}
}
File structure will finally look like this:
These POJO classes will be used to get data from URL from its “get” functions. We will see this later.
Interface Declaration
Make a new interface named RetrofitMaps.java and add following code:
package com.androidtutorialpoint.googlemapsretrofit;
import com.androidtutorialpoint.googlemapsretrofit.POJO.Example;
import retrofit.Call;
import retrofit.http.GET;
import retrofit.http.Query;
public interface RetrofitMaps {
@GET("api/place/nearbysearch/json?sensor=true&key=AIzaSyDN7RJFmImYAca96elyZlE5s_fhX-MMuhk")
Call<Example> getNearbyPlaces(@Query("type") String type, @Query("location") String location, @Query("radius") int radius);
}
Let’s have a look at above interface. @GET is used to call server (corresponding to URL). It is predefined part of Retrofit android library, only end part of URL will be added here. Here we have added key and sensor as part of the URL while rest of the variable (like location and radius) will be passed at run time using Query in getNearbyPlaces()
. getNearbyPlaces
method is used to get details of the points returned from Google Server and Example is a POJO class to store that response. One more point to note down here is location coordinates passed in getNearbyPlaces
will be current location of the user as we will see later. Corresponding to these coordinates, Google will return nearby places location.
MapsActivity.java Code of Google Maps Search Nearby App
As you know, this is heart of our Google Maps Nearby Places API and hence it needs special attention. Here we will first build Retrofit and then will add Markers at the points returned by getter methods of POJO Class. Here we won’t discuss code related to getting current user location.
First of all, we will check if Google Play Services available or not in onCreate()
function of MainActivity.java. For that we will use function CheckGooglePlayServices()
.
CheckGooglePlayServices()
private boolean CheckGooglePlayServices() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int result = googleAPI.isGooglePlayServicesAvailable(this);
if(result != ConnectionResult.SUCCESS) {
if(googleAPI.isUserResolvableError(result)) {
googleAPI.getErrorDialog(this, result,
0).show();
}
return false;
}
return true;
}
GoogleApiAvailability
is the Helper
class for verifying that the Google Play services APK is available and up-to-date on android device. If result is ConnectionResult.SUCCESS then connection was successful otherwise, we will return false.
Now comes the most important part of our Google Maps Nearby Places API code i.e. onMapReady()
function. Here we will first build a Google API Client and then enable current user location using mMap.setMyLocationEnabled(true)
.
buildGoogleApiClient
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
So now we will directly refer to the working of buttons and how to get nearby places using it. I will explain here functionality of Nearby Restaurants button. Rest of the two buttons will share same functionality except string passed will be Hospital or School according to button clicked.
Finding nearby Restaurants on Google Maps
We will start its implementation by setting setOnClickListener()
and as soon as user clicks on it, code inside onClick(View v)
executed.
Button btnRestaurant = (Button) findViewById(R.id.btnRestaurant);
btnRestaurant.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
build_retrofit_and_get_response("restaurant");
}
});
Build Retrofit and add Markers
Here we will build Retrofit and add markers at the points returned by Google Server. Add following code in function build_retrofit_and_get_response()
.
private void build_retrofit_and_get_response(String type) {
String url = "https://maps.googleapis.com/maps/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitMaps service = retrofit.create(RetrofitMaps.class);
Call<Example> call = service.getNearbyPlaces(type, latitude + "," + longitude, PROXIMITY_RADIUS);
call.enqueue(new Callback<Example>() {
@Override
public void onResponse(Response<Example> response, Retrofit retrofit) {
try {
mMap.clear();
for (int i = 0; i < response.body().getResults().size(); i++) {
Double lat = response.body().getResults().get(i).getGeometry().getLocation().getLat();
Double lng = response.body().getResults().get(i).getGeometry().getLocation().getLng();
String placeName = response.body().getResults().get(i).getName();
String vicinity = response.body().getResults().get(i).getVicinity();
MarkerOptions markerOptions = new MarkerOptions();
LatLng latLng = new LatLng(lat, lng);
markerOptions.position(latLng);
markerOptions.title(placeName + " : " + vicinity);
Marker m = mMap.addMarker(markerOptions);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
}
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
In the above code we build Retrofit using Retrofit.Builder()
and converted JSON data into accessible data object using GsonConverterFactory
. You can read more about GSON. After this we passed our interface RetrofitMaps to the retrofit to get details of the nearby places. Now comes the last but most important part i.e. Executing call and adding marker on each point on Google Maps Nearby Places API.
Calls may be executed synchronously with execute()
, or asynchronously with enqueue()
. enqueue()
will Asynchronously send the request and notify callback of its response or if an error occurred talking to the server, creating the request, or processing the response. If response comes then onResponse
will be automatically called. If response doesn’t come out then onFailure
will be called and reason of failure will be printed.
While calling getNearbyPlaces
we are passing latitude and longitude coordinates of current location of user. Also PROXIMITY_RADIUS is provided to search nearby places only under that radius. After getting response from server onResponse
is called automatically. In this method we first cleared Google Maps using mMap.clear()
so that any pre-deposited markers are deleted. Then a loop is inititated to get every nearby place and one by one marker is added at each location. We get the coordinates of nearby places through getter methods defined in POJO Classes. For Example to get the longitude and latitude we used getLat()
and getLng()
from Location.java.
So finally our tutorial of Google Maps Nearby Places API is complete. You can see full code of MainActivity.java here:
package com.androidtutorialpoint.googlemapsretrofit;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.androidtutorialpoint.googlemapsretrofit.POJO.Example;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.HashMap;
import retrofit.Call;
import retrofit.Callback;
import retrofit.GsonConverterFactory;
import retrofit.Response;
import retrofit.Retrofit;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap mMap;
double latitude;
double longitude;
private int PROXIMITY_RADIUS = 10000;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
LocationRequest mLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
if (!isGooglePlayServicesAvailable()) {
Log.d("onCreate", "Google Play Services not available. Ending Test case.");
finish();
}
else {
Log.d("onCreate", "Google Play Services available. Continuing.");
}
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
private boolean isGooglePlayServicesAvailable() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int result = googleAPI.isGooglePlayServicesAvailable(this);
if(result != ConnectionResult.SUCCESS) {
if(googleAPI.isUserResolvableError(result)) {
googleAPI.getErrorDialog(this, result,
0).show();
}
return false;
}
return true;
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
} else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
Button btnRestaurant = (Button) findViewById(R.id.btnRestaurant);
btnRestaurant.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
build_retrofit_and_get_response("restaurant");
}
});
Button btnHospital = (Button) findViewById(R.id.btnHospital);
btnHospital.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
build_retrofit_and_get_response("hospital");
}
});
Button btnSchool = (Button) findViewById(R.id.btnSchool);
btnSchool.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
build_retrofit_and_get_response("school");
}
});
}
private void build_retrofit_and_get_response(String type) {
String url = "https://maps.googleapis.com/maps/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitMaps service = retrofit.create(RetrofitMaps.class);
Call<Example> call = service.getNearbyPlaces(type, latitude + "," + longitude, PROXIMITY_RADIUS);
call.enqueue(new Callback<Example>() {
@Override
public void onResponse(Response<Example> response, Retrofit retrofit) {
try {
mMap.clear();
for (int i = 0; i < response.body().getResults().size(); i++) {
Double lat = response.body().getResults().get(i).getGeometry().getLocation().getLat();
Double lng = response.body().getResults().get(i).getGeometry().getLocation().getLng();
String placeName = response.body().getResults().get(i).getName();
String vicinity = response.body().getResults().get(i).getVicinity();
MarkerOptions markerOptions = new MarkerOptions();
LatLng latLng = new LatLng(lat, lng);
markerOptions.position(latLng);
markerOptions.title(placeName + " : " + vicinity);
Marker m = mMap.addMarker(markerOptions);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
}
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onLocationChanged(Location location) {
Log.d("onLocationChanged", "entered");
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
latitude = location.getLatitude();
longitude = location.getLongitude();
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
Log.d("onLocationChanged", String.format("latitude:%.3f longitude:%.3f", latitude, longitude));
Log.d("onLocationChanged", "Exit");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
}
}
We would suggest you to turn on GPS and Internet Connection. Run this Google Maps Nearby Places API on any real android device. It will first display your location. Now according to button clicked it will display nearby Restaurants, Schools or Hospitals as shown in following figure:
You can see demo of Google Maps Nearby Places API in the Youtube video given at the start of tutorial. We have tried to explain each and every step but still if you have any doubt then please comment. Also we are open to suggestions of any future tutorials. All the best .