I'm just doing a rebuild of my iOS App in Android, here and there horrible to do. One horrible part is that map thing.
I need to get places around users location by query like "park", "cafe", "bakery" etc.
In swift I just used localSearchRequest.naturalLanguageQuery
self.localSearchRequest = MKLocalSearchRequest()
self.localSearchRequest.naturalLanguageQuery = mapSearchQuery
self.localSearchRequest.region = region
self.localSearch = MKLocalSearch(request: self.localSearchRequest)
for item in localSearchResponse!.mapItems
let annotation = MKPointAnnotation()
annotation.coordinate = item.placemark.coordinate
annotation.title = item.name
self.mapView.addAnnotation(annotation)
}
Is there a similar way to do the same in Android by using GoogleMaps API? The only way I found was to get them via JSON from https://developers.google.com/places/web-service/search and I'm not even sure if this is for Android applications.
The GooglePlaces API for Android just list all places around a location without a way to filter them or something.
after long trying I was going with the following solution. Using the GooglePlaces webservice (link in my question):
final String PLACES_API_BASE_URL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?";
final String LOCATION_PARAM = "location";
final String RADIUS_PARAM = "radius";
final String KEYWORD_PARAM = "keyword";
final String LANGUAGE_PARAM = "language";
final String KEY_PARAM = "key";
mDestinationUri = Uri.parse(PLACES_API_BASE_URL).buildUpon()
.appendQueryParameter(LOCATION_PARAM, String.valueOf(latitude)+","+String.valueOf(longitude))
.appendQueryParameter(RADIUS_PARAM, "1000")
.appendQueryParameter(KEYWORD_PARAM, naturalLanguageQuery)
.appendQueryParameter(KEY_PARAM, "YOUR_API_KEY")
.build();
If this will accept from google we will see.
For better distinction, usage of the following APIs for Android are as follows:
Google Maps Android API to add maps to your Android app. Integrate base maps, 3D buildings, indoor floor plans, Street View and Satellite imagery, custom markers and more.
Google Places API for Android to implement device place detection, auto-complete and add information about millions of locations to your app.
And to get places around users location, try Current Place.
You can call PlaceDetectionApi.getCurrentPlace() to find the local business or other place where the device is currently located. You can optionally specify a PlaceFilter to restrict the results to one or more place IDs (up to a maximum of 10), or to select only places that are currently open. If no filter is specified, the results are not filtered.
The following code sample retrieves the list of places where the device is most likely to be located, and logs the name and likelihood for each place.
PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
.getCurrentPlace(mGoogleApiClient, null);
result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
#Override
public void onResult(PlaceLikelihoodBuffer likelyPlaces) {
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
Log.i(TAG, String.format("Place '%s' has likelihood: %g",
placeLikelihood.getPlace().getName(),
placeLikelihood.getLikelihood()));
}
likelyPlaces.release();
}
});
Please try going through the given documentations for more information such as regarding permissions and usage limits in using this API.
Related
I am integrated new place API and I am using the below method to get the nearest place list.
private fun getNearestPlaceList(placesClient: PlacesClient) {
val placeFields = listOf(Place.Field.NAME, Place.Field.ID, Place.Field.LAT_LNG)
val request = FindCurrentPlaceRequest.builder(placeFields).build()
placesClient.findCurrentPlace(request).addOnSuccessListener { response ->
placeList.clear()
response.placeLikelihoods.map { placeLikelihood -> placeLikelihood.place }
.filter { place -> !place.id.isNullOrEmpty() && !place.name.isNullOrEmpty() }
.forEach { place ->
val placeModel = PlaceModel(place.name!!, place.id!!)
placeList.add(placeModel)
}
setAdapter(placeList)
}.addOnFailureListener { exception ->
if (exception is ApiException) {
Log.e(TAG, "Place not found: " + exception.statusCode)
}
}
}
The current API is only collecting the nearest location of my device current location. But My requirement is to get the nearest place of a Specific(Different) location. So Is it possible to input location info(Different Lat Long) to the API and get the nearest list of that location?. Currently, the API is automatically collecting the current location and it's sending a list of nearest places. Anyone have a solution, please update?
Getting the nearest places from a specific location (not the device's current location) is not currently available in the Places SDK. To clarify, the PlaceLikelihood's from the FindCurrentPlaceResponse are places where the device is likely to be located.
The FindCurrentPlaceResponse contains a list of PlaceLikelihood
objects representing places where the device is likely to be located.
For each place, the result includes an indication of the likelihood
that the place is the right one. The list may be empty, if there is no
known place corresponding to the given device location.
As I understand your use-case, you can get a list of nearby places for a specific location through Places API - Nearby Search.
A Nearby Search lets you search for places within a specified area.
You can refine your search request by supplying keywords or specifying
the type of place you are searching for.
Sample request:
https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670522,151.1957362&radius=1500&type=restaurant&keyword=cruise&key=YOUR_API_KEY
There are also available open source client libraries that you can use for Google Maps Web Services. More info here.
Lastly, there is also an existing feature request for this in Google's Public Issue Tracker. I'd recommend you "star" it to receive updates.
https://issuetracker.google.com/issues/133276015
Hope this helps!
I'm not sure if this has been answered. This feels like such a basic question but I've been looking for a way to do this and all the examples I came across showed a list of places near the device. What I'm trying to do is to specify a location via button click, then show the places near it.
Specifically, if the user clicks button 1, this means the user wants to see the places near train station A, probably in another activity with a RecyclerView.
I was using http://www.zoftino.com/current-location-and-nearby-places-android-example for reference. I followed it all the way to adding the API key in the manifest file but I got stuck trying to analyze how I'm supposed to define a specific location instead of getting the device's location.
I'm not sure if I'm approaching this correctly but so far, I've made a Java bean that can get which station was selected...
public class Station {
String station;
public Station (String station) {
this.station = station;
}
public Station () {
}
public String getStation() {
return station;
}
public void setStation(String station) {
this.station = station;
}
I also have an activity with an onClick method to check which button was clicked...
public void onClick (View v) {
switch (v.getId()) {
case R.id.img1: station = getString(R.string.StationName1);
Log.d("project", "selected station is " + station);
break;
//other cases deleted to make this more concise
}
Station selected = new Station (station);
Log.d("project", "content of station bean is " + selected.getStation());
}
I'm testing this using a phone running Android 7.1.1. From the logcat, I know that the Station bean is able to get the selected station correctly. I honestly don't know why I decided to use getString(R.string.StationName1) but considering I'm doing this for 4 train lines and I'm already past the project's deadline. I'd rather not have to change them, if possible.
I was thinking of adding some sort of "coordinates" attribute to the Java bean and passing the exact coordinates using the switch case above but even if I did that, I still wouldn't know how to use it so I can show the nearby locations.
Edit: I'm using Android Studio 3.2.1
The linked tutorial has the following code block where places are being detected and displayed:
#SuppressLint("MissingPermission")
private void getCurrentPlaceData() {
Task<PlaceLikelihoodBufferResponse> placeResult = placeDetectionClient.
getCurrentPlace(null);
placeResult.addOnCompleteListener(new OnCompleteListener<PlaceLikelihoodBufferResponse>() {
#Override
public void onComplete(#NonNull Task<PlaceLikelihoodBufferResponse> task) {
Log.d(TAG, "current location places info");
List<Place> placesList = new ArrayList<Place>();
PlaceLikelihoodBufferResponse likelyPlaces = task.getResult();
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
placesList.add(placeLikelihood.getPlace().freeze());
}
likelyPlaces.release();
PlacesRecyclerViewAdapter recyclerViewAdapter = new
PlacesRecyclerViewAdapter(placesList,
CurrentLocationNearByPlacesActivity.this);
recyclerView.setAdapter(recyclerViewAdapter);
}
});
}
Here, the getCurrentPlace method uses the current device location, which is the likely cause of your issue. In fact, the Place Detection Client documentation itself notes that: (emphasis mine)
The Place Detection API provides quick access to the device's current place, and offers the opportunity to report the location of the device at a particular place (like a check in).
Like you said, there doesn't seem to be any API in the Android Places SDK that offers a 'Nearby Places' functionality for a location. Even the above is attempting to associate the current user location with a known place (as opposed to a set of coordinates with no extra info), and doesn't seem to be meant to search for nearby places by design (though it can clearly be done).
However, the Place Search API can be used for your requirements (I have used it in an app that does something similar to what you are looking to do). It includes an endpoint for Nearby Search Requests, where a static location can be passed. The only downside is that you will have to handle the HTTP calls through Retrofit or something similar, since the SDK doesn't have an existing framework for this API.
I'm to get all nearby "point of interest" for a given latitude/longitude within a given radius without giving any search key.
I started with google place web api. But this api gives desired data when using on web only, not on android. I tried using separate keys on android for same api, even though, the place web api didn't work on android any how. It always said on android, "invalid api key".
Then I moved to google place android api. But this gives data when we use their custom UI, not in any other ways. (But I just want to get location data, not data on google's UI. Since, I want to show POI on camera).
I thought a GEO_DATA_API may help me on android. But somehow it's giving me empty result.
Here is my code for GEO_DATA_API that gave me zero result:
Places.GeoDataApi.getAutocompletePredictions(mGoogleApiClient, query, bounds, null)
.setResultCallback(
new ResultCallback<AutocompletePredictionBuffer>() {
#Override
public void onResult(AutocompletePredictionBuffer buffer) {
if (buffer.getStatus().isSuccess()) {
for (AutocompletePrediction prediction : buffer) {
PlaceResult placeResult = new PlaceResult();
placeResult.setPlaceId(prediction.getPlaceId());
placeResult.setName(prediction.getFullText(null).toString());
}
}
//Prevent memory leak by releasing buffer
buffer.release();
}
}, 60, TimeUnit.SECONDS);
}
I was created one application for android TV which is already in Google Play store and works fine.
Now my new requirement is to use the Google Maps Geolocation API in Android TV so I was refereed this link but no luck.
So my question is that Is it possible to use Google Maps Geolocation API in Android TV?
After many research finally I got the answer.Yes it is possible to use Google Maps Geolocation API in Android TV but with some limitation.As per the documentation given by the The Google Maps Geolocation API their are mainly Two way to achieve this
1) Using Cell tower.
2) Using WiFi Access Points.
Now, For the 1st way ofCourse it is not possible because Android TV do not have Calling or SIM facility so it can not connect to Cell Tower so it is not working.
Now, For the 2nd way it is quite interesting. I was research on this thing and finally Successfully implemented this thing. Another thing I noticed that and also given in the documentation that using IP address it will give the highest accuracy ratio then the Cell Tower and WIFI access points.So, I consider both WIFI access points and "considerIp": "true" for highest accuracy ratio.
After this much of research my actual task is to implement this thing it is quite easy for me to implement this because I know how to get the WIFI Access Points.So, I used the following way to get WIFI Access Points.
List<ScanResult> results;
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
results = wifiManager.getScanResults();
String message = "No results found.Please Check your wireless is on";
if (results != null)
{
final int size = results.size();
if (size == 0)
message = "No access points in range";
else
{
ScanResult bestSignal = results.get(0);
int count = 1;
for (ScanResult result : results)
{
if (WifiManager.compareSignalLevel(bestSignal.level, result.level) < 0)
{
bestSignal = result;
}
}
}
}
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
After getting list of WIFI Access Points create a JSONObject which Pass to Call the API "https://www.googleapis.com/geolocation/v1/geolocate?key=your_key".I was used Volley to call this API.For creating the JSONObject which contains WIFI Access points here is the way which I was used.
JSONObject parent;
try {
parent = new JSONObject();
parent.put("considerIp", false);
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject;
for (int i = 0; i < results.size(); i++) {
jsonObject = new JSONObject();
jsonObject.put("macAddress", results.get(i).BSSID);
jsonObject.put("signalStrength", results.get(i).level);
jsonObject.put("signalToNoiseRatio", 0);
jsonArray.put(jsonObject);
System.out.println("jsonObject: " + jsonObject.toString(4));
}
parent.put("wifiAccessPoints", jsonArray);
Log.d("output", parent.toString());
System.out.println("parenttttt: " + parent.toString(4));
txt_request.setText(parent.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
From the above code I was used "parent.put("considerIp", false)" the reason behind use false was nothing but just to checked whether I got the accurate result using WIFI Access Points or not.You can make it true and see the result what you get.
After successful response you got the result which gives the Latitude and Longitude with the Accuracy ratio which shows how accurate the result was.You got the response something like this.
{
"location":
{
"lat": your latitude,
"lng": your longitude
},
"accuracy": How accurate the result was [like 1523, 1400.25 etc.]
}
This is the way to achieve Google Maps Geolocation API in Android TV that's it.
From the TV developer guide:
TVs are stationary, indoor devices, and do not have built-in global positioning system (GPS) receivers. If your app uses location information, you can still allow users to search for a location, or use a static location provider such as a zip code configured during the TV device setup.
If you follow the link, you'll see some code how the achieve this. Unfortunately you won't get the exact position, but depending on your requirements, this might be sufficient.
Ok. You'd think this would be relatively simple, but nope.
I am using Open street maps on my website, as the data is free to use, edit, and update - my project follows this mantra, and alongside googles API usage restrictions/saving data restrictions, google maps simply was not suitable for me.. at least on the web.
Given this I thought i'd follow suit with my android app, and so I setup osmdroid utilizing open street maps data.
I can have a nice map in my activity.. I also followed a tutorial, and it seemed to work at least such that I can have a map view in a fragment within a tabhost/viewpager. What i really want however (for tablets), is a list of establishments in a fragment on the left, and a map fragment on the right showing where these establishments are.
Simple enough i would have thought, but hours and hours of research suggest this is not possible unless you use some complex code and some deprecated methods..
So.. the fragment (containing a map view) loads and runs perfectly in a tabhost.. i can access methods within the fragment from my activity etc.. yet nothing to just simply have two fragments side by side.
Now.. I know google have just come out with their API v2.. I installed it and had a play.. not really knowing how osmdroid works, I thought i could update so I have MapFragment instead of SherlockFragment (I use ABS).. this then just threw up logcat errors asking for API keys etc.. and given that I dont want to use google map data, I assumed that I had gone wrong.
So.. could anyone advise on how I can get a list fragment, and a map fragment side by side using anything that is available on the market, but preferably utilizing Open source map data such that their are no usage restrictions.
I'm sure an overall overview of "what is available, and how it works" would be very much appreciated by loads of users.. so if anyone could advise it would be amazing !
Before the new Google Maps API came out, I was forced into using OSMDroid for my purposes. However, after having to dig through the source several times to figure out why it was doing what it was (often incorrectly), I was dying for a new library.
Fortunately, the new Google Maps API fits the bill. You can use the Google Maps API v2 in your application and never have to use Google's basemaps, but yes, unfortunately you must get an API key first.
I am assuming you want to use OpenStreetMap as an online map source, so the code below will be tailored towards that.
GoogleMap map = <get-map-instance>;
map.setMapType(GoogleMap.MAP_TYPE_NONE);
TileOverlayOptions options = new TileOverlayOptions();
options.tileProvider(new UrlTileProvider(256, 256) {
#Override
public URL getTileUrl(int x, int y, int z) {
try {
String f = "http://tile.openstreetmap.org/%d/%d/%d.png";
return new URL(String.format(f, z, x, y));
}
catch (MalformedURLException e) {
return null;
}
}
});
map.addTileOverlay(options);
You can find a more formalized version of this code in my Google Maps API v2 add-ons library here.
Also, if you are targeting pre-Fragment Android versions, which I believe you are based on you using ABS, instead of using MapFragment, make sure you use SupportMapFragment.
The Sample Code delivered with Google Maps Android API v2 contains the class com.example.mapdemo.TileOverlayDemoActivity. I little update to this class will show OpenStreetMap tiles within the new v2 framework. Cool! No need to use osmdroid or sherlock-fragments anymore. However... the tiles are not cached :(
Anyway, all additions/updates to the TileOverlayDemoActivity class are shown below:
private static final String OPEN_STREET_MAP_URL_FORMAT =
"http://tile.openstreetmap.org/%d/%d/%d.png";
private void setUpMap() {
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
mMap.setMyLocationEnabled(true);
TileProvider tileProvider = new UrlTileProvider(256, 256) {
#Override
public synchronized URL getTileUrl(int x, int y, int zoom) {
String s = String.format(Locale.US, OPEN_STREET_MAP_URL_FORMAT, zoom, x, y);
URL url = null;
try {
url = new URL(s);
} catch (MalformedURLException e) {
throw new AssertionError(e);
}
return url;
}
};
mMap.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));
}