I am following http://examples.javacodegeeks.com/android/android-google-places-autocomplete-api-example/ this tutorial to get google place autocomplete in my app,
Now that it is working fine but I need to keep the place suggestion country specific, I have tried giving country like india , china but it is not showing any result.
Could you please help me out and tell where should I need to change the code to get it done.
Thanks,
Prashant
From Documentation for Places API
To get a list of predicted place names and/or addresses, call
GeoDataApi.getAutocompletePredictions(), passing the following
parameters:
Required: A query string containing the text typed by the user.
Required: A LatLngBounds object, restricting the results to a specific
area specified by latitude and longitude bounds.
When making request
You can specify bounds for India.
This can serve you
String apiKey = getString(R.string.places_api_key);
if (!Places.isInitialized()) {
Places.initialize(getApplicationContext(), apiKey);
PlacesClient placesClient = Places.createClient(this);
}else{
Toast.makeText(PlaceAutocompleteActivity.this, "-----initialize-----", Toast.LENGTH_LONG).show();
}
// Initialize the AutocompleteSupportFragment.
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
// PlaceFields
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG));
// autocompleteFragment.setOnPlaceSelectedListener(MapsActivity.this);
try {
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(#NonNull Place place) {
displayLocation(place.getLatLng().latitude,place.getLatLng().longitude,place.getName());
Toast.makeText(getApplicationContext(), "getName: " + place.getName() + " getLatLng: "+ place.getLatLng(), Toast.LENGTH_LONG).show();
// Intent i = Intent(this, idnow.se MainActivity.class);
// i.putExtra("getLatLng",place.getLatLng());
// startActivity(i);
// finish();
}
#Override
public void onError(#NonNull Status status) {
Toast.makeText(getApplicationContext(), "" + status.toString(), Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
Toast.makeText(PlaceAutocompleteActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
// PlaceFields - HERE
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG));
https://github.com/EddyEU/GooglePlaceAutocomplete
Related
I'm going through the process of migrating from depricated Places SDK to the Places API as described here, using the compatibility library. Everything had been working fine prior to attempting the migration. I've
1) Updated my dependencies
2) Changes my import statements
3) Min SDK was already 21
I am getting two (seemingly related) errors. cannot find symbol variable GEO_DATA_API and cannot find symbol variable GeoDataApi
the code
googleApiClient = new GoogleApiClient.Builder(PlacesActivity.this)
.addApi(Places.GEO_DATA_API) //***HERE***
.enableAutoManage(this, GOOGLE_API_CLIENT_ID, this)
.addConnectionCallbacks(this)
.build();
and
private ArrayList<PlaceAutocomplete> getPredictions(CharSequence constraint) {
if (googleApiClient !=null) {
PendingResult<AutocompletePredictionBuffer> results = Places.GeoDataApi.getAutocompletePredictions( // ***AND HERE***
googleApiClient,
constraint.toString(),
latLngBounds,
autocompleteFilter
);
// Wait for predictions, set the timeout.
AutocompletePredictionBuffer autocompletePredictions = results.await(60, TimeUnit.SECONDS);
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
//auto complete fail
autocompletePredictions.release();
return null;
}
//auto complete success
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList<PlaceAutocomplete> resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(), prediction.getFullText(null)));
}
// Buffer release
autocompletePredictions.release();
return resultList;
}
return null;
}
An entire re write of code is required. Here is working code for getting lat, lng, and name (for example)
public class MainActivity extends AppCompatActivity {
String TAG = "placeautocomplete";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize Places.
Places.initialize(getApplicationContext(), "YOUR_API_KEY");
// Create a new Places client instance.
PlacesClient placesClient = Places.createClient(this);
// Initialize the AutocompleteSupportFragment.
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
// Specify the types of place data to return.
autocompleteFragment.setPlaceFields(Arrays.asList(
Place.Field.NAME,
Place.Field.LAT_LNG
));
// Set up a PlaceSelectionListener to handle the response.
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
String name = place.getName();
double lat, lng;
if (place.getLatLng() !=null){
lat =place.getLatLng().latitude;
lng =place.getLatLng().longitude;
}
//do something
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
}
}
example xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<android.support.v7.widget.CardView
android:id="#+id/idCardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="4dp"
>
<fragment
android:id="#+id/autocomplete_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
/>
</android.support.v7.widget.CardView>
</LinearLayout>
Problem 1: cannot find symbol variable GEO_DATA_API
Solution 1:
First of all lets understand the usage of Places.GEO_DATA_API
It says that "The Geo Data API provides access to getting information about places by place ID, autocompleting a user's search query by name or address, and adding new places to Google's Places database."
source (https://developers.google.com/android/reference/com/google/android/gms/location/places/GeoDataApi)
So if we want to get place information from place id then we have to
use below code:
// Define a Place ID.
String placeId = "INSERT_PLACE_ID_HERE";
// Specify the fields to return (in this example all fields are returned).
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME);
// Construct a request object, passing the place ID and fields array.
FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields).build();
placesClient.fetchPlace(request).addOnSuccessListener((response) -> {
Place place = response.getPlace();
Log.i(TAG, "Place found: " + place.getName());
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
int statusCode = apiException.getStatusCode();
// Handle error with given status code.
Log.e(TAG, "Place not found: " + exception.getMessage());
}
});
Problem 2: cannot find symbol variable GeoDataApi
Solution 2: As new places api indicates that "Use findAutocompletePredictions() to return place predictions in response to user search queries. findAutocompletePredictions() functions similarly to getAutocompletePredictions()."
source (https://developers.google.com/places/android-sdk/client-migration)
So to get auto complete predictions we can use below code:
// Create a new token for the autocomplete session. Pass this to FindAutocompletePredictionsRequest,
// and once again when the user makes a selection (for example when calling fetchPlace()).
AutocompleteSessionToken token = AutocompleteSessionToken.newInstance();
// Create a RectangularBounds object.
RectangularBounds bounds = RectangularBounds.newInstance(
new LatLng(-33.880490, 151.184363),
new LatLng(-33.858754, 151.229596));
// Use the builder to create a FindAutocompletePredictionsRequest.
FindAutocompletePredictionsRequest request = FindAutocompletePredictionsRequest.builder()
// Call either setLocationBias() OR setLocationRestriction().
.setLocationBias(bounds)
//.setLocationRestriction(bounds)
.setCountry("au")
.setTypeFilter(TypeFilter.ADDRESS)
.setSessionToken(token)
.setQuery(query)
.build();
placesClient.findAutocompletePredictions(request).addOnSuccessListener((response) -> {
for (AutocompletePrediction prediction : response.getAutocompletePredictions()) {
Log.i(TAG, prediction.getPlaceId());
Log.i(TAG, prediction.getPrimaryText(null).toString());
}
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
Log.e(TAG, "Place not found: " + apiException.getStatusCode());
}
});
Replace GoogleApiClient with GeoDataClient
mGoogleApiClient = Places.getGeoDataClient(this, null);
Replace AutocompletePredictionBuffer with AutocompletePredictionBufferResponse
private ArrayList getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient != null) {
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
Task<AutocompletePredictionBufferResponse> results = mGoogleApiClient.getAutocompletePredictions(constraint.toString(), null, mPlaceFilter);
// This method should have been called off the main UI thread. Block and wait for at most 60s
// for a result from the API.
try {
Tasks.await(results, 60, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException e) {
Utils.handleException(e);
}
AutocompletePredictionBufferResponse autocompletePredictions = results.getResult();
// Freeze the results immutable representation that can be stored safely.
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
return null;
}
I am writing an Android App using Xamarin which uses Xamarin.GooglePlayServices.Maps Nuget Package. I need to get to a particular place on the map using the name of the place. For this purpose I loaded Xamarin.GooglePlayServices.Places. I am able to pass a partial place name to the GetAutocompletePredictionsAsync as so:
var autocompletePredictions = await
PlacesClass.GeoDataApi.GetAutocompletePredictionsAsync(
Adapter.googleApiClient, constraint.ToString(),
Adapter.bounds, Adapter.autoCompleteFilter);
The result I get back is basically a collection of IAutocompletePrediction. The only item in this object that has to do with location is the PlaceId. I cannot find any way to use this on the Google Maps API. I tried seeing if I could get any more information by calling the GetPlaceById:
var place = PlacesClass.GeoDataApi.GetPlaceById(googleApiClient, item.PlaceId);
But I didn't see any location information at all in that result. Does anyone know how to get LatLng information from the Google Places API?
Update: I used information from several responses to get the answer:
Task.Run(async () =>
{
PlaceBuffer places = await PlacesClass.GeoDataApi.GetPlaceByIdAsync(googleApiClient, item.PlaceId);
if (places.Status.IsSuccess)
{
foreach (var place in places)
try
{
//IPlace place = (IPlace)places.Get(0);
MarkOnMap(place.NameFormatted.ToString(), place.AddressFormatted.ToString(), place.LatLng);
UpdateCameraPosition(place.LatLng);
}
catch (Exception ex)
{
Log.Error("WhatNow", ex.ToString());
}
}
places.Dispose();
});
The odd thing was when I enumerated the places in the foreach, the place was an IPlace type. However
IPlace place = (IPlace)places.Get(0);
Did not cast to an IPlace. Who knows? I just hope that Dispose() releases the buffer as recommended in the Docs. Xamarin is always just a little different from Java.
Thanks to everyone who helped.
I have used this, you can try this code.
I am using autoCompleteTextView.
dropLocationEt.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final PlaceAutoCompleteAdapter.PlaceAutocomplete item = mAdapter.getItem(position);
final String placeId = String.valueOf(item.placeId);
Log.i(TAG, "Autocomplete item selected: " + item.description);
/*
Issue a request to the Places Geo Data API to retrieve a Place object with additional
details about the place.
*/
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(googleApiClient, placeId);
placeResult.setResultCallback(new ResultCallback<PlaceBuffer>() {
#Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
// Request did not complete successfully
Log.e(TAG, "Place query did not complete. Error: " + places.getStatus().toString());
places.release();
return;
}
// Get the Place object from the buffer.
final Place place = places.get(0);
latLngDrop = place.getLatLng();
StaticMethods.hideKeyboard(getActivity());
dropLocationEt.setSelection(0);
}
});
}
});
From the latlngDrop, you can retrieve the lat and lng, eg: latlngDrop.getLatitude, latlngDrop.getLongitude
I want to get route between two locations,for that i have found esri sample service i.e :http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World.
But if i use this service i am getting error as Unauthorized access to a secure.
I am unable to use this service,Please tell me if any free service for getting route on arcgis map
Thanks.
my code:
public void getRouteFromSource(Geometry current_location,Geometry destination_point,boolean isCurrentLocation){
routeLayer = new GraphicsLayer();
mMapView.addLayer(routeLayer);
// Initialize the RouteTask
try {
String routeTaskURL = "http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World";
mRouteTask = RouteTask.createOnlineRouteTask(routeTaskURL, null);
} catch (Exception e1) {
e1.printStackTrace();
}
// Add the hidden segments layer (for highlighting route segments)
hiddenSegmentsLayer = new GraphicsLayer();
mMapView.addLayer(hiddenSegmentsLayer);
QueryDirections(current_location, destination_point,isCurrentLocation);
}
private void QueryDirections(final Geometry sourceGeometry, final Geometry destinationGeometry,boolean isCurrentLocation) {
// Show that the route is calculating
if(isCurrentLocation==false){
dialog = ProgressDialog.show(mContext, PollingStationLocatorContant.plase_wait,
"Calculating route...", true);
}
// Log.e("mLocation", "mLocation "+sourceGeometry);
// Log.e("POINTTT", "POINTTT"+p);
// Spawn the request off in a new thread to keep UI responsive
Thread t = new Thread() {
private RouteResult mResults;
#Override
public void run() {
try {
// Start building up routing parameters
/*Point startPoint = new Point(78.4867, 17.3850);
Point stopPoint = new Point(79.5941, 17.9689);*/
// Log.e("mLocation.getX()",""+ p.getX()+"---"+ p.getY());
// Log.e("mLocation.getY()",""+ mLocation.getX() +"----"+ mLocation.getY());
//Point startPoint = new Point(mLocation.getX(), mLocation.getY());
//Point stopPoint = new Point(p.getX(), p.getY());
StopGraphic point1 = new StopGraphic(sourceGeometry);
StopGraphic point2 = new StopGraphic(destinationGeometry);
Log.e("point1", ""+point1);
Log.e("point2", ""+point2);
NAFeaturesAsFeature rfaf = new NAFeaturesAsFeature();
// Convert point to EGS (decimal degrees)
// Create the stop points (start at our location, go
// to pressed location)
rfaf.setFeatures(new Graphic[] { point1, point2 });
rfaf.setCompressedRequest(true);
// RouteParameters r = new RouteParameters();
RouteParameters rp = mRouteTask.retrieveDefaultRouteTaskParameters();
//rp.setImpedanceAttributeName("Length");
rp.setReturnDirections(false);
// Assign the first cost attribute as the impedance
rp.setStops(rfaf);
// Set the routing service output SR to our map
// service's SR
rp.setOutSpatialReference(mMapView.getSpatialReference());
//rp.setImpedanceAttributeName("");
// Solve the route and use the results to update UI
// when received
mResults = mRouteTask.solve(rp);
List<Route> routes = mResults.getRoutes();
Route mRoute = routes.get(0);
Geometry routeGeom = mRoute.getRouteGraphic().getGeometry();
Graphic symbolGraphic = new Graphic(routeGeom, new SimpleLineSymbol(Color.BLUE,5));
//SimpleMarkerSymbol sls = new SimpleMarkerSymbol(Color.RED, 10,STYLE.CIRCLE);
PictureMarkerSymbol pls=new PictureMarkerSymbol(mContext.getResources().getDrawable(R.drawable.animation_image));
mMapView.setExtent(routeGeom, 20);
Graphic destinatonGraphic = new Graphic(sourceGeometry, pls);
mGraphicsLayer.addGraphic(symbolGraphic);
mDestinationGraphicLayer.addGraphic(destinatonGraphic);
mMapView.addLayer(mGraphicsLayer);
mMapView.addLayer(mDestinationGraphicLayer);
mHandler.post(mUpdateResults);
} catch (Exception e) {
mDestinationGraphicLayer.removeAll();
noRouteFound=true;
e.printStackTrace();
mHandler.post(mUpdateResults);
}
}
};
// Start the operation
t.start();
}
void updateUI() {
if(dialog!=null && dialog.isShowing()){
dialog.dismiss();
if(noRouteFound){
Toast.makeText(mContext, "Unable to find route.Please select with in State", Toast.LENGTH_LONG).show();
}
}
}
Disregarding geocoding services (which may be called for free if data is not stored) routing services do require a token.
As stated in the documentation:
Required parameters: token
Use this parameter to specify a token that provides the identity of a
user that has the permissions to access the service. Accessing
services provided by Esri provides more information on how such an
access token can be obtained.
What you can do is to go here and register a free developer account. You will receive a free token and its related amount of free credits that you can use to query the routing API.
However, the documentation linked above shows samples of response for all possible situations (error, route ok, route not found).
After creating a free developer account follow these steps.
Inside your getRouteFromSource function replace the existing code with this.
TOKEN = "The token you receive after you sign up";
CLIENT_ID = "The client_id you receive after you sign up";
try {
UserCredentials authenticate= new UserCredentials();
authenticate.setUserAccount("your username", "your password");
authenticate.setUserToken(TOKEN, CLIENT_ID);
mRouteTask = RouteTask
.createOnlineRouteTask(
"http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World",
authenticate);
} catch (Exception e1) {
e1.printStackTrace();
}
This should solve your problem.
Im triying to authenticate with google, I´m currently using the way i´t is recomended on his documentation, but.. is there any EASY way to get the refresh token?, I make the auth and get the token, but it have been impossible for me to take the refresh token , and I need id.
I have tried lots of ways, I have spend more than a week with this issue, is it possible to get that token? I´ve tried with lots of manuals, tutorials... but I can´t.
Anyone Knows any place where I can Know how to get the resfresh_token and it is good explained and that is currently working?.
Thanks a lot!!
Pd: is a native android App.
EDIT:
Ok, for More info, I´m making the auth as is in google´s documentation to auth with GoogleApiClient with little variations( because I´m using it as a cain of manager) . THIS PART RUN´S OK:
Firs instead of calling on create I call:
public void logginGooglePlus(GooglePlusAuthCallback googlePlusAuthCallback) {
gPAuthCallback = googlePlusAuthCallback;
// Initializing google plus api client
String scope = "audience:server:client_id:" + SERVER_CLIENT_ID;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
mGoogleApiClient.connect();
mSignInClicked = true;
signInWithGplus(gPAuthCallback);
}
I continue just with copy&paste with the google´s:
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
// GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
// this,
// 0).show();
if (gPAuthCallback != null) {
gPAuthCallback.onLoginError(result.toString());
}
return;
}
if (!mIntentInProgress) {
// Store the ConnectionResult for later usage
mConnectionResult = result;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
#Override
public void onActivityResult(int requestCode, int responseCode,
Intent intent) {
super.onActivityResult(requestCode, responseCode, intent);
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
// Get user's information
if (gPAuthCallback != null) {
gPAuthCallback.onLoginSuccesful();
}
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
/**
* Sign-in into google
* */
public void signInWithGplus(GooglePlusAuthCallback googlePlusAuthCallback) {
gPAuthCallback = googlePlusAuthCallback;
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
/**
* Method to resolve any signin errors
* */
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
And finally I call to get the persons data:
public void getProfileInformation(
GooglePlusGetPersonCallback getPersonCallback) {
this.googlePlusGetPersonCallback = getPersonCallback;
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e("GPlus", "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);
new getTokenAsyncTask().execute();
}
} catch (Exception e) {
if (googlePlusGetPersonCallback != null) {
// googlePlusGetPersonCallback.ongeGooglePersonError(e.getCause()
// .toString());
}
e.printStackTrace();
}
}
Ok, leaving here is easy, now It starts the funny part: I need the Refresh Token because I have to sign in with a server, and I have to pass the access_token, refresh_token and user_id.
reading this: https://developers.google.com/accounts/docs/CrossClientAuth
I understand that I have to make the getToken call with a different Scope, so I change it: the method for get token is :
// GET TOKEN 2o plano
public class getTokenAsyncTask extends AsyncTask<Void, Boolean, String> {
#Override
protected String doInBackground(Void... params) {
try {
String acountname = Plus.AccountApi
.getAccountName(mGoogleApiClient);
// agregamos el scope del server para que me loguee para la app
// "crossclient"
String serverScope = "audience:server:client_id:"
+ SERVER_CLIENT_ID;
String token = GoogleAuthUtil.getToken(GooglePlusManager.this,
acountname, serverScope);
return token;
} catch (UserRecoverableAuthException e) {
// startActivityForResult(e.getIntent(), "NECESITA AUT");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace(); // TODO: handle the exception
}
return null;
}
#Override
protected void onPostExecute(String code) {
String token = code;
if (googlePlusGetPersonCallback != null) {
googlePlusGetPersonCallback.ongeGooglePersonSuccesful(
currentPerson, token);
}
}
}
According to documentation, with this I´ll get a token that: "The ID token will contain several data fields", and I´m only retrieving a string token ( but it does not give any crash or issue so I suppose it is Ok). I haven´t got access to the Server, but I´ve suppose that it is ok, because the ios app is running ok already ( another company have done it in Ios), do I have to ask them to make in the server any thing so I can authenticate my android app with the server?
The ios app is passing to the server the parameter I´ve already said (acces, refres, id) So I Imagine that I have to pass the same in android, I have acces to the console and I have declared the android app in the same project.
well, from the part I am, that I have an supposed valid token.. how can I get the refresh token? I´m completely lost...
If anyone knows how to get it.. I´ll invite as much beer as you can ( I have lost so many hours with this :S ).
xcuses for the really really big post :( ( it´s my first one!).
According to the google documentation you can exchange tokens.
So, if you post required parameters to below link, then you will obtain a refresh token
https://www.googleapis.com/oauth2/v3/token
Parameters,
var params = {
code: 'FROM ANDROID [ONE TIME CODE]',
client_id: 'FROM YOUR GOOGLE CONSOLE',
client_secret: 'FROM YOUR GOOGLE CONSOLE',
redirect_uri: 'FROM YOUR GOOGLE CONSOLE',
grant_type: 'authorization_code'
access_type:'offline'
};
The only thing you must send from android is one-time code. Other parameters are static, store they in a config file.
var params = {
code: 'FROM ANDROID [ONE TIME CODE]',
Android side, Enable server-side API access for your app, after implementing this, you will have an one-time code
I hope these will be helpful for you.
I have implemented Google Place API autocomplete functionality for my application like this: https://developers.google.com/places/training/autocomplete-android
No it just makes a Toast with that address.
How can I get the latitude and longitude from the selected address?
Use the method
public List<Address> getFromLocationName (String locationName, int maxResults) from Android Geocoder API, pass in the location name and the maximum number of results you would like and you should be good to go.
Eg.
Geocoder coder = new Geocoder(this);
try {
ArrayList<Address> adresses = (ArrayList<Address>) coder.getFromLocationName("Some Address", 10);
for(Address add : adresses){
double longitude = add.getLongitude();
double latitude = add.getLatitude();
}
} catch (IOException e) {
e.printStackTrace();
} catch(IllegalArgumentException e){
e.printStackTrace();
}
If it helps, I've recently created a library in Java for Google Places API.
Autocompletion is as simple as:
GooglePlaces client = new GooglePlace("apiKey");
List<Prediction> predictions = client.getPlacePredictions("Empire");
for (Prediction prediction : predictions) {
String description = prediction.getDescription();
// etc etc
}
And getting a latitude-longitude from an address is as simple as.
List<Place> places = client.getPlacesByQuery(address, GooglePlaces.MAXIMUM_RESULTS);
for (Place place : places) {
if (place.getAddress().equals(address)) {
double lat = place.getLatitude();
double lng = place.getLongitude();
}
}
https://github.com/windy1/google-places-api-java
You can simply use google maps api to get the lat and long
http://maps.google.com/maps/api/geocode/json?address=&sensor=false
In the above link u have to add the address next to "address=" and u can get the json data with lat and long and some other infos.
Try GeoDataClient. Refer GeoDataClient and Place IDs and details.
geoDataClient.getPlaceById(autoCompletePredictionItem.getPlaceId())
.addOnCompleteListener(new OnCompleteListener<PlaceBufferResponse>() {
#Override
public void onComplete(#NonNull Task<PlaceBufferResponse> task) {
if (task.isSuccessful()) {
PlaceBufferResponse places = task.getResult();
Place myPlace = places.get(0);
Log.e(TAG, "Place found: " + myPlace.getLatLng().toString());
places.release();
} else {
Log.e(TAG, "Place not found.");
}
}
});
According to updated documents, GeoDAtaClient is deprecated. New way is to use this:
// Define a Place ID. val placeId = "INSERT_PLACE_ID_HERE"
// Specify the fields to return. val placeFields = listOf(Place.Field.ID, Place.Field.NAME)
// Construct a request object, passing the place ID and fields array. val request = FetchPlaceRequest.newInstance(placeId, placeFields)
placesClient.fetchPlace(request)
.addOnSuccessListener { response: FetchPlaceResponse ->
val place = response.place
Log.i(PlaceDetailsActivity.TAG, "Place found: ${place.name}")
}.addOnFailureListener { exception: Exception ->
if (exception is ApiException) {
Log.e(TAG, "Place not found: ${exception.message}")
val statusCode = exception.statusCode
TODO("Handle error with given status code")
}
}
https://developers.google.com/maps/documentation/places/android-sdk/place-details#maps_places_get_place_by_id-kotlin