Autocomplete Support Fragment issue : closes search bar during typing - android

I have been trying to apply Android Google Places Autocomplete feature using new Places SDK by below steps:
added dependency
implementation 'com.google.android.libraries.places:places:2.2.0'
implementation 'androidx.cardview:cardview:1.0.0'
added permission
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
at xml file
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginTop="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"/>
</androidx.cardview.widget.CardView>
at my Activity file
// Initialize Places.
Places.initialize(getApplicationContext(), "My 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.ID, Place.Field.NAME));
// 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.
//Log.i(TAG, "Place: " + place.getName() + ", " + place.getId());
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
//Log.i(TAG, "An error occurred: " + status);
}
});
Problem is while I am trying to type any key on search bar it close the search window.
Note : API key is enabled, and after enabling the API key I got same API which I already enable in this project for 'Maps SDK for Android'.
If anybody got the solution please provide.
Thanks in advance.

This place picker method is already deprecated in 2019. please follow the latest one to implement the place picker here is the link https://developers.google.com/places/android-sdk/client-migration

Related

How to implement Places AutoCompleteFragment in 2019 SINCE DEPRECATION

Trying to get autocomplete fragment to work in my code. TAG causes an error in the code, if you remove the Log statement it causes an error for the whole paragraph. it also does not let me TAG create a variable for tag to remove the error, if i do this the whole paragraph gets an error as well.
Have gone through the deprecation steps and added the new dependencies and imports and it still wont work...
also Places API is definitely already enabled
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME));
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
Log.i(TAG, "Place: " + place.getName() + ", " + place.getId());
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
Meanwhile the Places SDK for Android provides this API:
dependencies {
implementation "com.google.android.gms:play-services-places:16.0.0"
implementation "com.google.android.libraries.places:places:1.0.0"
}
The AutocompleteSupportFragment in this package is not deprecated, but the whole package you are using. See the migration guide, in case you may already have some code which runs against that deprecated package.
And if TAG is unknown, you probably should define it; for example:
private static final String TAG = "PlacesActivity";

New Google Places Autocomplete crashes on Click

I used new dependency of Google places. And app crashes when click on the Autocomplete View. Error is as follows.,
java.lang.NullPointerException: Place Fields must be set.
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:889)
at com.google.android.libraries.places.internal.dt.onClick(Unknown Source)
at android.view.View.performClick(View.java:6207)
at android.widget.TextView.performClick(TextView.java:11094)
at android.view.View$PerformClick.run(View.java:23639)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6688)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
The Initiating method. I used this inside a Fragment so I used to getFragmentManager() in initialize the Fragment.
private void setUpLocationPicker(){
if (!Places.isInitialized()) {
Places.initialize(this.getActivity(), getString(R.string.google_maps_key));
}
// Initialize the AutocompleteSupportFragment.
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getFragmentManager().findFragmentById(R.id.autocomplete_fragment);
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME));
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
Log.i(TAG, "Place: " + place.getName() + ", " + place.getId());
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
}
And the XML layout.
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/autocomplete_fragment"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/pickup_address" />
</android.support.constraint.ConstraintLayout>
Why autocomplete View Returns null in Onclick event. How to solve this?
I found the way of doing this and post the answer here.
// Initialize place API
if (!Places.isInitialized()) {
Places.initialize(mContext, mContext.getString(R.string.google_maps_key));
}
PlacesClient placesClient = Places.createClient(mContext);
// 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();
// Specify the fields to return.
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG);
additionally I got the answer from the Place Migration Guide. Hope this will help.
late answer if it is helpful for someone.In my case android:noHistory="true" making the problem as i made android:noHistory="false" it started work again

Android Place Autocomplete Fragment: Unable to set text

Google has recently updated their Places SDK for android, so now I'm updating my code too. I'm trying to use the AutocompleteSupportFragment to allow the user to set their address.
This is my code:
mAddressEditText = (AutocompleteSupportFragment) getSupportFragmentManager().findFragmentById(R.id.address);
mAddressEditText.setPlaceFields(Arrays.asList(Place.Field.ADDRESS, Place.Field.LAT_LNG));
mAddressEditText.setHint("Address");
mAddressEditText.setText("Test1"); // Works fine at the beginning, disappears after selecting a place and shows only the hint
mAddressEditText.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
Log.d(TAG, "Place Selected");
// Other Stuff
mAddressEditText.setText("Test2"); // Doesn't Work, all I can see is the hint
mAddressEditText.setText(place.getAddress()); // Doesn't Work, all I can see is the hint
}
#Override
public void onError(Status status) {
Log.e(TAG, "An error occurred: " + status);
invalidAddressDialog.show();
}
});
In the previous SDK, the fragment would set the text to the selected address automatically. This doesn't work in the new SDK (not sure if that's intentional or not).
So I'm trying to set it manually instead. As you can see in the comments in my code, using setText works fine outside the listeners. Inside the listener they don't.
Am I doing something wrong or is this a bug?
EDIT:
So long and I still can't get a proper fix to this.
To be perfectly clear, I can get the address correctly from the fragment, the only thing that doesn't work is setText.
However, since some answers state they're not getting the same problem, I started thinking it might be related to the library versions I'm using?
These are the libraries I have in my build.gradle:
api 'com.android.support:appcompat-v7:28.0.0'
api 'com.android.support:support-annotations:28.0.0'
api 'com.android.support:multidex:1.0.3'
api 'com.google.firebase:firebase-core:16.0.8'
api 'com.google.firebase:firebase-auth:16.2.1'
api 'com.google.firebase:firebase-firestore:18.2.0'
api 'com.google.firebase:firebase-storage:16.1.0'
api 'com.google.android.libraries.places:places:1.1.0'
setText has been giving me the same problem - it must be a bug I think. However I found a little work around with the hint. In your onPlaceSelected you can put the following:
Java
EditText etPlace = (EditText) autocompleteFragment.getView().findViewById(R.id.places_autocomplete_search_input);
etPlace.setHint(place.getAddress())
Kotlin
val etPlace = autocompleteFragment.view?.findViewById(R.id.places_autocomplete_search_input) as EditText
etPlace.hint = place.address
This is the code that I am using and it is working perfectly fine.
Make some changes to build.gradle (app level)
Add this to build.gradle:
android{
...
ext {
googlePlayServicesVersion = "15.0.1"
}
}
Add those dependencies:
dependencies {
...
//Also if you're using any firebase dependencies make sure that the are up to date
implementation 'com.google.android.gms:play-services-places:16.0.0'
implementation 'com.google.android.libraries.places:places:1.1.0'
}
apply plugin: 'com.google.gms.google-services'
In xml layout:
<fragment
android:id="#+id/autocomplete_fragment"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
The code in Activity:
private void initGooglePlacesApi() {
// Initialize Places.
Places.initialize(getApplicationContext(), "YOUR_API_KEY");
// Create a new Places client instance.
PlacesClient placesClient = Places.createClient(getApplicationContext());
// Initialize the AutocompleteSupportFragment.
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
autocompleteFragment.setHint(getString(R.string.select_location_search_bar));
// autocompleteFragment.setLocationRestriction(RectangularBounds.newInstance(
// new LatLng(34.7006096, 19.2477876),
// new LatLng(41.7488862, 29.7296986))); //Greece bounds
autocompleteFragment.setCountry("gr");
// Specify the types of place data to return.
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ADDRESS, Place.Field.ADDRESS_COMPONENTS));
autocompleteFragment.setTypeFilter(TypeFilter.ADDRESS);
// Set up a PlaceSelectionListener to handle the response.
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
if(place.getAddressComponents().asList().get(0).getTypes().get(0).equalsIgnoreCase("route")){
binding.textViewLocation.setText(place.getAddress()); //Works well
location = place.getAddress();
}else{ //If user does not choose a specific place.
AndroidUtils.vibratePhone(getApplication(), 200);
TastyToast.makeText(getApplicationContext(),
getString(R.string.choose_an_address), TastyToast.DEFAULT, TastyToast.CONFUSING);
}
Log.i(TAG, "Place: " + place.getAddressComponents().asList().get(0).getTypes().get(0) + ", " + place.getId() + ", " + place.getAddress());
}
#Override
public void onError(Status status) {
Log.i(TAG, "An error occurred: " + status);
}
});
}
I found a pretty simple solution..just delay a little bit the moment you set the text in the EditText. So in your PlaceSelectionListener just do it this way:
Handler().postDelayed({
mAddressEditText.setText(place.getAddress());
}, 300)
PS: This is kotlin code but It's almost similar in Java
By setting "NAME" in setPlaceFields, a selected address is automatically shown in the fragment:
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
// Set "Place.Field.NAME" as below here to show the selected item //
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, **Place.Field.NAME**,Place.Field.ADDRESS,Place.Field.LAT_LNG));
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(#NonNull Place place) {
// TODO: Get info about the selected place. }
#Override
public void onError(#NonNull Status status) {
// TODO: Handle the error. }
});
I believe this is a bug, because it doesn't make sense to have it working like this.
What does work is set other autocomplete's texts but not its own.
This has to be a bug.
EDIT: here is my updated answer
# When you are using AutocompleteSupportFragment or AutocompleteActivity
# in Fragments, do this:
public class YourFragment extends Fragment {
/.../
#Override
public void onActivityResult (int requestCode,int resultCode,
#Nullable Intent data){
# AUTOCOMPLETE_REQUEST_CODE is just a unique constant, define it
if (requestCode == AUTOCOMPLETE_REQUEST_CODE) {
if (resultCode == AutocompleteActivity.RESULT_OK) {
Place place = Autocomplete.getPlaceFromIntent(data);
// when resultcode is RESULT_OK
mAddressEditText.setText(place.getName());
// Notice this line, update your editText up here
}else if (resultCode == AutocompleteActivity.RESULT_ERROR) {
Status status = Autocomplete.getStatusFromIntent(data);
// Handle error
} else if (resultCode == AutocompleteActivity.RESULT_CANCELED) {
// Handle results if canceled
}
super.onActivityResult(requestCode, resultCode, data);
}
}
/.../
}
# If you are extending AppCompatActivity, you might want to do this
# ONLY when you are already doing something in onActivityResult
public class YourActivity extends AppCompatActivity{
/.../
#Override
public void onActivityResult (int requestCode,int resultCode,#Nullable Intent data){
# your logic here.
/.../
# if you are already overriding onActivityResult,
# do not forget to put this line
super.onActivityResult(requestCode, resultCode, data);
}
/.../
}
I was having the problem too. Turns out you HAVE to override this and implement it anyway, whether using AutocompleteSupportFragment or AutocompleteActivity if you are working in Fragments.
If you are using AppCompatActivity you do not have to implement it, but if you are already overiding onActivityResult to do something, do not forget to call the base method super.onActivityResult
get the reference of AutoCompleteFragment and then set text to the autocomplete fragment
like
autoCompleteFragment.setText("Address")
for reference you can have a look at the documentation
https://developers.google.com/android/reference/com/google/android/gms/location/places/ui/PlaceAutocompleteFragment
I tried CacheMeOutside's solution but it didn't work at all. So, I decided to try Matthias's solution and it did work because the text actually sets and then immediately removes for some reason. A small delay fixes it. The delay can be as small as 1 millisecond.
If my solution doesn't work for you, you can try to experiment with the delay. It also seems that it doesn't stop view rendering, so you can set any time you want.
private lateinit var autocomplete: AutocompleteSupportFragment
override fun onPlaceSelected(place: Place) {
Timer("SetAddress", false).schedule(1) {
autocomplete.setText(place.address)
}
}
The code snippet in Kotlin. If your code is in Java, just find some instrument to delay code execution for some time.
The solution by Matthias is working but it is in kotlin. Below is the same implementation in Java
#Override
public void onPlaceSelected(Place place) {
String name = place.getName()+", "+place.getAddress();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
autocompleteFragmentDestination.setText(name);
}
},300);
}
Simple. Use a Spannable string to set the color!
val autocompleteFragment = childFragmentManager.findFragmentById(R.id.location_filter_autocomplete) as AutocompleteSupportFragment
val text = SpannableString("Enter a location")
text.setSpan(ForegroundColorSpan(Color.BLACK), 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
autocompleteFragment.setHint(text)
Do the same inside onPlaceSelectedListener()

How to resolve PLACES_API_ACCESS_NOT_CONFIGURED in Place Autocomplete Fragment

I'm having problems with Android Google Places API - autocomplete feature. I use the same key that I used for Android Google Maps API but it is not open place fragment. Its only show Maps but when open a Place Autocomplete Fragment but its open and automatically close and show PLACES_API_ACCESS_NOT_CONFIGURED error. Please help me out to this issue and show the right to handle the issue. Here My Manifest XML:
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyARQ78yaNEJH12aJLM1Y-112WY12p95ZOEGI"/>
And Here My Code for open Place AutocolmpleteFragment:
try {
Intent intent =
new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
.build(getActivity());
startActivityForResult(intent, 1);
} catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
And Here My code for getting a place response:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode ==RESULT_OK) {
Place place = PlaceAutocomplete.getPlace(getActivity(), data);
onPlaceSelected(place,1);
bar.setVisibility(View.GONE);
autoCompleteTextViewPickup.setFocusable(true);
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(getActivity(), data);
this.onError(status,1);
bar.setVisibility(View.GONE);
autoCompleteTextViewPickup.setFocusable(true);
}
}
I was having the same problem but i have been able to fix it.
The problem is that The Google Play Services version of the Places SDK for Android (in Google Play Services 16.0.0) is deprecated as of January 29, 2019, and will be turned off on July 29, 2019.
And if you check under the google API console, it only have the PLACES API and there is nothing like PLACES SDK FOR ANDROID anymore.
In the dependencies section of your app-level build.gradle file, add a dependency for the new SDK client library, as shown in the following example:
implementation 'com.google.android.libraries.places:places:1.0.0'
Then, you initialize it.
// Add an import statement for the client library.
import com.google.android.libraries.places.api.Places;
...
// Initialize Places.
Places.initialize(getApplicationContext(), apiKey);
// Create a new Places client instance.
PlacesClient placesClient = Places.createClient(this);
Programmatic autocomplete
The following changes were made to autocomplete:
PlaceAutocomplete is renamed to Autocomplete.
PlaceAutocomplete.getPlace is renamed to Autocomplete.getPlaceFromIntent.
PlaceAutocomplete.getStatus is renamed to Autocomplete.getStatusFromIntent.
PlaceAutocomplete.RESULT_ERROR is renamed to AutocompleteActivity.RESULT_ERROR (error handling for the autocomplete fragment has NOT changed).
If you are using the autocomplete widget like my case you can use this.
<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"
/>
Then initialize places
/**
* Initialize Places. For simplicity, the API key is hard-coded. In a production
* environment we recommend using a secure mechanism to manage API keys.
*/
if (!Places.isInitialized()) {
Places.initialize(getApplicationContext(), "YOUR_API_KEY");
}
// Initialize the AutocompleteSupportFragment.
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME));
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
Log.i(TAG, "Place: " + place.getName() + ", " + place.getId());
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
Check here for more information
Migrating to the New Place SDK
looks like you are getting the PLACES_API_ACCESS_NOT_CONFIGURED alert because you don't have some configuration that needs to be done :
1) Go to google cloud platform
2) Enable your place API inside the console
3) If you already did - you need to check 2 things :
3-A) Is your API key is up to date?(in the credentials page)
3-B) In the credentials page - check for any kind of restrictions that could prevent your from getting acces to the API.

Multiple PlaceAutoCompleteFragment opens when clicked on it very quickly

I am using Google's PlaceAutoCompleteFragment in a recent project that I am currently working on. When I click on the PlaceAutoCompleteFragment very quickly it open multiple overlays on my app which is really annoying. how can I prevent it from opening multiple overlays? My code for the fragment is given below:
if (autocompleteFragment == null) {
autocompleteFragment = (PlaceAutocompleteFragment)getFragmentManager().findFragmentById(R.id.place_autocompletehome_fragment);
}
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
try {
Log.i("esty", "Place: " + place.getName());
} catch (Exception e) {
Log.e("esty", "Error: " + e.getMessage());
}
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.e("esty", "An error occurred: " + status);
}
});
It looks like this is a bug in PlaceAutocompleteFragment (and SupportPlaceAutocompleteFragment). Thank you for bringing it to our attention. We'll look at fixing this in an upcoming release.
Why don't you try a hack to solve this problem.
Put a on click listener on the whole fragment and use multi click blocker to pass the click event once.
Refer to the below solution :
https://stackoverflow.com/a/23103227/4901098

Categories

Resources