I'm Trying to Search Nearby Places Such as Banks, Restaurants, Atms Inside the Drawn Area on Google Maps in Android

Google Places' Search Functionality Is Not Retrieving The Same Data As Google Maps'

The Google Places API may have improved since I asked this question but one solution to this problem is to use the Google Maps Web API.

Search specific nearby places using google places api web services for android

First of all, you're connecting to GooglePlayServices, but never actually using GooglePlayServices for the location.

Instead of this:

Location myLocation = locationManager.getLastKnownLocation(provider);

You probably wanted to do this:

Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);

However, these methods always have a chance of returning null, so always do a null check on the result of the above methods. Your lack of a null check on this location object before calling mLatitude=myLocation.getLatitude(); is what was causing your NullPointerException.

However, I would also advise against calling getLastLocation() at all, which has a high tendency to return null. It also does not request a new location, so even if you get a location returned, it could be very old, and not reflect the current location of the device. It's better to register a listener, even if you just unregister after you get the first onLocationChanged() callback.

It looks like you basically want to combine this answer and this answer.

I just basically did that, and also cleaned up the code a bit.

Here's the entire class code:

import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
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 org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
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.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MapsActivity2 extends AppCompatActivity
implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {

GoogleMap mGoogleMap;
SupportMapFragment mapFrag;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
boolean firstRun = true;

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
}

@Override
public void onPause() {
super.onPause();

//stop location updates when Activity is no longer active
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}

@Override
public void onMapReady(GoogleMap googleMap)
{
mGoogleMap=googleMap;
mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

//Initialize Google Play Services
buildGoogleApiClient();
mGoogleApiClient.connect();
}

public StringBuilder sbMethod(Location currentLocation) {
//current location
double mLatitude = currentLocation.getLatitude();
double mLongitude = currentLocation.getLongitude();

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=" + "restaurant");
sb.append("&sensor=true");

sb.append("&key=AIza********************");

Log.d("Map", "<><>api: " + sb.toString());

return sb;
}

protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}

@Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}

@Override
public void onConnectionSuspended(int i) {}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {}

@Override
public void onLocationChanged(Location location)
{
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}

//Place current location marker
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 = mGoogleMap.addMarker(markerOptions);

//move map camera
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(11));

//query places with current location
StringBuilder sbValue = new StringBuilder(sbMethod(location));
PlacesTask placesTask = new PlacesTask();
placesTask.execute(sbValue.toString());

if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}

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) {
Log.d("result", "<><> result: " + result);
ParserTask parserTask = new ParserTask();

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

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", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}

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;
Place_JSON placeJson = new Place_JSON();

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

places = placeJson.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) {

Log.d("Map", "list size: " + list.size());
// Clears all the existing markers;
if (!firstRun) {

mGoogleMap.clear();
}
firstRun = false;

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");

Log.d("Map", "place: " + name);

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

LatLng latLng = new LatLng(lat, lng);

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

markerOptions.title(name + " : " + vicinity);

markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));

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

}
}
}
public class Place_JSON {

/**
* 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;
}
}

}

Result:

Sample Image

Google places API authorization error

You have not enabled Geocoding service. To get Place google require Geocoding enabled.

Google Console

select Google Maps Geocoding API and Enabled it.



Related Topics



Leave a reply



Submit