Je suis en train de migrer du SDK Places déprécié vers l'API Places comme décrit ici , en utilisant la bibliothèque de compatibilité. Tout fonctionnait bien avant de tenter la migration. J'ai
1) J'ai mis à jour mes dépendances
2) Modifie mes instructions d'importation
3) Le SDK minimum était déjà de 21
J'en ai deux ( apparemment liées). ne peut pas trouver la variable de symbole GEO_DATA_API
et ne peut pas trouver la variable de symbole GeoDataApi
le code
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; }
et
googleApiClient = new GoogleApiClient.Builder(PlacesActivity.this) .addApi(Places.GEO_DATA_API) //***HERE*** .enableAutoManage(this, GOOGLE_API_CLIENT_ID, this) .addConnectionCallbacks(this) .build();
3 Réponses :
Problème 1: impossible de trouver la variable de symbole GEO_DATA_API
Solution 1: Tout d'abord, comprenons l'utilisation de Places.GEO_DATA_API
Il dit que "L'API Geo Data permet d'obtenir des informations sur les lieux par identifiant de lieu, en complétant automatiquement la requête de recherche d'un utilisateur par nom ou adresse, et en ajoutant de nouvelles lieux dans la base de données Google Adresses. "
source ( https://developers.google.com/android/reference/com/google/android/gms/location/places/GeoDataApi )
Donc, si nous voulons obtenir des informations sur le lieu à partir de l'identifiant du lieu, nous devons utilisez le code ci-dessous:
// 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()); } });
Problème 2: impossible de trouver la variable de symbole GeoDataApi
Solution 2: En tant que nouveaux lieux api indique que "Utilisez findAutocompletePredictions () pour renvoyer des prédictions de lieu en réponse aux requêtes de recherche des utilisateurs. findAutocompletePredictions () fonctionne de la même manière que getAutocompletePredictions ()."
source ( https://developers.google.com/places/android-sdk/client-migration )
Donc, pour obtenir des prédictions automatiques, nous pouvons utiliser le code ci-dessous:
// 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()); } });
Une réécriture complète du code est requise. Voici le code de travail pour obtenir lat, lng et name (par exemple)
<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>
example xml
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); } }); } }
Comment puis-je obtenir des composants d'adresse tels que l'état, la ville, l'épinglage via l'API de lieu lorsque nous utilisons le géocodage?
Remplacer GoogleApiClient par GeoDataClient
mGoogleApiClient = Places.getGeoDataClient (this, null);
Remplacez AutocompletePredictionBuffer par AutocompletePredictionBufferResponse
private ArrayList getAutocomplete (contrainte CharSequence) {
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; }