Migrer vers le client SDK New Places

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Ce guide explique les modifications apportées entre la bibliothèque de compatibilité Places et la nouvelle version autonome du SDK Places pour Android. Si vous avez utilisé la bibliothèque Places de compatibilité au lieu de migrer vers la nouvelle version autonome du SDK Places pour Android, ce guide vous explique comment mettre à jour vos projets afin qu'ils utilisent la nouvelle version du SDK Places pour Android.

Le seul moyen d'accéder aux fonctionnalités et aux corrections de bugs dans le SDK Places pour les versions d'Android supérieures à 2.6.0 sera d'utiliser le SDK Places pour Android. Nous vous recommandons de passer à la nouvelle version du SDK Places pour Android dès que possible.

Modifications apportées

Voici les principaux changements:

  • La nouvelle version du SDK Places pour Android est distribuée en tant que bibliothèque cliente statique. Avant janvier 2019, le SDK Places pour Android était disponible via les services Google Play. Depuis, une bibliothèque de compatibilité Places a été fournie pour faciliter la transition vers le nouveau SDK Places pour Android.
  • Il existe de toutes nouvelles méthodes.
  • Les masques de champ sont désormais compatibles avec les méthodes qui renvoient des détails sur un lieu. Vous pouvez utiliser des masques de champ pour spécifier les types de données de lieu à renvoyer.
  • Les codes d'état utilisés pour signaler les erreurs ont été améliorés.
  • La saisie semi-automatique est désormais compatible avec les jetons de session.
  • Le sélecteur de lieux n'est plus disponible.

À propos de la bibliothèque de compatibilité Places

En janvier 2019, avec la sortie de la version 1.0 du SDK Places pour Android, Google a fourni une bibliothèque de compatibilité facilitant la migration depuis la version hors service des services Google Play du SDK Places pour Android (com.google.android.gms:play-services-places).

Cette bibliothèque de compatibilité a été fournie temporairement pour rediriger et traduire les appels d'API destinés à la version des services Google Play vers la nouvelle version autonome, jusqu'à ce que les développeurs puissent migrer leur code pour utiliser les nouveaux noms dans le SDK autonome. Pour chaque version du SDK Places pour Android publiée entre la version 1.0 et la version 2.6.0, une version correspondante de la bibliothèque de compatibilité Places a été publiée afin de fournir des fonctionnalités équivalentes.

Blocage et abandon de la bibliothèque de compatibilité Places

Toutes les versions de la bibliothèque de compatibilité pour le SDK Places pour Android sont obsolètes depuis le 31 mars 2022. La version 2.6.0 est la dernière version de la bibliothèque Places de compatibilité. Le seul moyen d'accéder aux fonctionnalités et aux corrections de bugs dans le SDK Places pour Android (version ultérieure à la version 2.6.0) consiste à utiliser le SDK Places pour Android.

Google vous recommande de migrer vers le SDK Places pour Android afin d'accéder aux nouvelles fonctionnalités et aux corrections de bugs critiques pour les versions supérieures à la version 2.6.0. Si vous utilisez actuellement la bibliothèque de compatibilité, suivez les étapes ci-dessous dans la section Installer le SDK Places pour Android pour migrer vers le SDK Places pour Android.

Installer la bibliothèque cliente

La nouvelle version du SDK Places pour Android est distribuée en tant que bibliothèque cliente statique.

Utilisez Maven pour ajouter le SDK Places pour Android à votre projet Android Studio:

  1. Si vous utilisez actuellement la bibliothèque Places de compatibilité:

    1. Remplacez la ligne suivante dans la section dependencies:

          implementation 'com.google.android.libraries.places:places-compat:X.Y.Z'

      Voici comment passer au SDK Places pour Android:

          implementation 'com.google.android.libraries.places:places:2.6.0'

  2. Si vous utilisez actuellement la version des services Play du SDK Places pour Android :

    1. Remplacez la ligne suivante dans la section dependencies:

          implementation 'com.google.android.gms:play-services-places:X.Y.Z'

      Voici comment passer au SDK Places pour Android:

          implementation 'com.google.android.libraries.places:places:2.6.0'

  3. Synchronisez votre projet Gradle.

  4. Définissez la valeur minSdkVersion pour votre projet d'application sur 16 ou une version ultérieure.

  5. Mettez à jour vos assets « Powered by Google » :

    @drawable/powered_by_google_light // OLD
    @drawable/places_powered_by_google_light // NEW
    @drawable/powered_by_google_dark // OLD
    @drawable/places_powered_by_google_dark // NEW
    
  6. Créez votre application. Si vous rencontrez des erreurs de compilation en raison de votre conversion vers le SDK Places pour Android, consultez les sections ci-dessous pour savoir comment résoudre ces erreurs.

Initialiser le nouveau client SDK Places

Initialisez le nouveau client SDK Places, comme indiqué dans l'exemple suivant:

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

Codes d'état

Le code d'état pour les erreurs de limite de RPS a changé. Les erreurs de limite de RPS sont désormais renvoyées via PlaceStatusCodes.OVER_QUERY_LIMIT. Il n'y a plus de limite de RPJ.

Les codes d'état suivants ont été ajoutés:

  • REQUEST_DENIED : la requête a été refusée. Voici quelques-unes des raisons qui peuvent expliquer ces écarts :

    • Aucune clé API n'a été fournie.
    • Une clé API non valide a été fournie.
    • L'API Places n'a pas été activée dans Cloud Console.
    • Une clé API a été fournie avec des restrictions de clé incorrectes.
  • INVALID_REQUEST : la requête n'est pas valide en raison d'un argument manquant ou non valide.

  • NOT_FOUND : aucun résultat n'a été trouvé pour la requête donnée.

Nouvelles méthodes

La nouvelle version du SDK Places pour Android introduit de nouvelles méthodes, conçues dans un souci de cohérence. Toutes les nouvelles méthodes s'appliquent aux éléments suivants:

  • Les points de terminaison n'utilisent plus le verbe get.
  • Les objets de requête et de réponse portent le même nom que la méthode cliente correspondante.
  • Les objets de requête disposent maintenant des compilateurs. Les paramètres requis sont transmis en tant que paramètres du générateur de requêtes.
  • Les tampons ne sont plus utilisés.

Cette section présente les nouvelles méthodes et leur fonctionnement.

Extraire un lieu par ID

Utilisez fetchPlace() pour obtenir des informations sur un lieu particulier. fetchPlace() fonctionne de manière semblable à getPlaceById().

Pour récupérer un lieu, procédez comme suit:

  1. Appelez fetchPlace() en transmettant un objet FetchPlaceRequest spécifiant un ID de lieu et une liste de champs spécifiant les données Place à renvoyer.

    // Define a Place ID.
    String placeId = "INSERT_PLACE_ID_HERE";
    
    // Specify the fields to return.
    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();
    
    
  2. Appelez addOnSuccessListener() pour gérer FetchPlaceResponse. Un seul résultat Place est renvoyé.

    // Add a listener to handle the response.
    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());
        }
    });
    

Récupérer une photo de lieu

Utilisez fetchPhoto() pour obtenir une photo de lieu. fetchPhoto() renvoie les photos d'un lieu. Le schéma de demande de photo a été simplifié. Vous pouvez maintenant demander PhotoMetadata directement à partir de l'objet Place. Il n'est plus nécessaire d'envoyer une requête distincte. La largeur et la hauteur des photos ne doivent pas dépasser 1 600 pixels. fetchPhoto() fonctionne de la même manière que getPhoto().

Pour récupérer des photos de lieux:

  1. Configurez un appel vers fetchPlace(). Veillez à inclure le champ PHOTO_METADATAS dans votre requête:

    List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
    
  2. Obtenez un objet Place (cet exemple utilise fetchPlace(), mais vous pouvez également utiliser findCurrentPlace()):

    FetchPlaceRequest placeRequest = FetchPlaceRequest.builder(placeId, fields).build();
    
  3. Ajoutez un OnSuccessListener pour obtenir les métadonnées de la photo du Place obtenu dans le FetchPlaceResponse, puis utilisez les métadonnées de la photo obtenue pour obtenir un bitmap et un texte d'attribution:

    placesClient.fetchPlace(placeRequest).addOnSuccessListener((response) -> {
        Place place = response.getPlace();
    
        // Get the photo metadata.
        PhotoMetadata photoMetadata = place.getPhotoMetadatas().get(0);
    
        // Get the attribution text.
        String attributions = photoMetadata.getAttributions();
    
        // Create a FetchPhotoRequest.
        FetchPhotoRequest photoRequest = FetchPhotoRequest.builder(photoMetadata)
                .setMaxWidth(500) // Optional.
                .setMaxHeight(300) // Optional.
                .build();
        placesClient.fetchPhoto(photoRequest).addOnSuccessListener((fetchPhotoResponse) -> {
            Bitmap bitmap = fetchPhotoResponse.getBitmap();
            imageView.setImageBitmap(bitmap);
        }).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());
            }
        });
    });
    

Rechercher un lieu à partir de la position de l'utilisateur

Utilisez findCurrentPlace() pour trouver la position actuelle de l'appareil de l'utilisateur. findCurrentPlace() affiche la liste des éléments PlaceLikelihood indiquant les endroits où l'appareil de l'utilisateur est le plus susceptible de se trouver. findCurrentPlace() fonctionne de manière semblable à getCurrentPlace().

Procédez comme suit pour obtenir la position actuelle de l'appareil de l'utilisateur:

  1. Assurez-vous que votre application demande les autorisations ACCESS_FINE_LOCATION et ACCESS_WIFI_STATE. L'utilisateur doit accorder l'autorisation d'accéder à la position actuelle de son appareil. Pour en savoir plus, consultez la page Demander des autorisations pour une application.

  2. Créez un FindCurrentPlaceRequest avec une liste de types de données de lieu à renvoyer.

      // Use fields to define the data types to return.
      List<Place.Field> placeFields = Arrays.asList(Place.Field.NAME);
    
      // Use the builder to create a FindCurrentPlaceRequest.
      FindCurrentPlaceRequest request =
              FindCurrentPlaceRequest.builder(placeFields).build();
    
  3. Appelez FindCurrentPlace et gérez la réponse, en vérifiant d'abord que l'utilisateur a autorisé l'utilisation de la position de l'appareil.

      // Call findCurrentPlace and handle the response (first check that the user has granted permission).
      if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
          placesClient.findCurrentPlace(request).addOnSuccessListener(((response) -> {
              for (PlaceLikelihood placeLikelihood : response.getPlaceLikelihoods()) {
                  Log.i(TAG, String.format("Place '%s' has likelihood: %f",
                          placeLikelihood.getPlace().getName(),
                          placeLikelihood.getLikelihood()));
                  textView.append(String.format("Place '%s' has likelihood: %f\n",
                          placeLikelihood.getPlace().getName(),
                          placeLikelihood.getLikelihood()));
              }
          })).addOnFailureListener((exception) -> {
              if (exception instanceof ApiException) {
                  ApiException apiException = (ApiException) exception;
                  Log.e(TAG, "Place not found: " + apiException.getStatusCode());
              }
          });
      } else {
          // A local method to request required permissions;
          // See https://developer.android.com/training/permissions/requesting
          getLocationPermission();
      }
    

Rechercher des prédictions de saisie semi-automatique

Utilisez findAutocompletePredictions() pour renvoyer des prédictions de lieu en réponse aux requêtes de recherche des utilisateurs. findAutocompletePredictions() fonctionne de manière semblable à getAutocompletePredictions().

L'exemple suivant vous montre comment appeler findAutocompletePredictions() :

// 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());
   }
});

Jetons de session

Les jetons de session regroupent les phases de requête et de sélection d'une recherche d'utilisateur dans une session discrète à des fins de facturation. Nous vous recommandons d'utiliser des jetons de session pour toutes les sessions de saisie semi-automatique. La session commence lorsque l'utilisateur commence à saisir une requête et se termine lorsqu'il sélectionne un lieu. Chaque session peut comporter plusieurs requêtes, suivies d'une sélection de lieu. Une fois la session terminée, le jeton n'est plus valide. Votre application doit générer un nouveau jeton pour chaque session.

Masques de champ

Dans les méthodes qui renvoient des détails sur un lieu, vous devez spécifier les types de données de lieu à renvoyer avec chaque requête. Cela garantit que vous ne demandez (et ne payez que) les données que vous utiliserez réellement.

Pour spécifier les types de données à renvoyer, transmettez un tableau de Place.Field dans votre FetchPlaceRequest, comme illustré dans l'exemple suivant:

// Include address, ID, and phone number.
List<Place.Field> placeFields = Arrays.asList(Place.Field.ADDRESS,
                                              Place.Field.ID,
                                              Place.Field.PHONE_NUMBER);

Vous pouvez utiliser un ou plusieurs des champs suivants:

  • Place.Field.ADDRESS
  • Place.Field.ID
  • Place.Field.LAT_LNG
  • Place.Field.NAME
  • Place.Field.OPENING_HOURS
  • Place.Field.PHONE_NUMBER
  • Place.Field.PHOTO_METADATAS
  • Place.Field.PLUS_CODE
  • Place.Field.PRICE_LEVEL
  • Place.Field.RATING
  • Place.Field.TYPES
  • Place.Field.USER_RATINGS_TOTAL
  • Place.Field.VIEWPORT
  • Place.Field.WEBSITE_URI

En savoir plus sur les codes SKU Places Data

Mises à jour du sélecteur de lieux et de la saisie semi-automatique

Cette section explique les modifications apportées aux widgets Places (Sélecteur de lieux et Autocomplete).

Saisie semi-automatique programmatique

Les modifications suivantes ont été apportées à la saisie semi-automatique :

  • PlaceAutocomplete a été renommé Autocomplete.
    • PlaceAutocomplete.getPlace a été renommé Autocomplete.getPlaceFromIntent.
    • PlaceAutocomplete.getStatus a été renommé Autocomplete.getStatusFromIntent.
  • PlaceAutocomplete.RESULT_ERROR est renommé AutocompleteActivity.RESULT_ERROR (la gestion des erreurs pour le fragment de saisie semi-automatique N'A PAS changé).

Sélecteur de lieux

Le sélecteur de lieux a été abandonné le 29 janvier 2019. Elle a été désactivée le 29 juillet 2019 et n'est plus disponible. Si vous continuez à l'utiliser, un message d'erreur s'affichera. Le nouveau SDK n'est pas compatible avec le sélecteur de lieux.

Widgets Autocomplete

Les widgets de la saisie semi-automatique ont été mis à jour:

  • Le préfixe Place a été supprimé de toutes les classes.
  • Ajout de la compatibilité avec les jetons de session. Le widget gère automatiquement les jetons en arrière-plan.
  • Ajout de la compatibilité avec les masques de champ, qui vous permettent de choisir les types de données de lieu à afficher après que l'utilisateur a fait sa sélection.

Les sections suivantes expliquent comment ajouter un widget Autocomplete à votre projet.

Intégrer un AutocompleteFragment

Pour ajouter un fragment de saisie semi-automatique, procédez comme suit:

  1. Ajoutez un fragment à la mise en page XML de votre activité, comme illustré dans l'exemple suivant.

    <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"
      />
    
  2. Pour ajouter le widget de saisie semi-automatique à l'activité, procédez comme suit:

    • Initialisez Places, en transmettant le contexte de l'application et votre clé API.
    • Initialisez AutocompleteSupportFragment.
    • Appelez setPlaceFields() pour indiquer les types de données de lieu que vous souhaitez obtenir.
    • Ajoutez un PlaceSelectionListener pour effectuer une action sur le résultat et gérer les erreurs qui pourraient se produire.

    L'exemple suivant montre comment ajouter un widget de saisie semi-automatique à une activité:

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

Utiliser un intent pour lancer l'activité de saisie semi-automatique

  1. Initialisez Places, en transmettant le contexte de l'application et votre clé API
  2. Utilisez Autocomplete.IntentBuilder pour créer un intent en transmettant le mode PlaceAutocomplete souhaité (plein écran ou superposition). L'intent doit appeler startActivityForResult en transmettant un code de requête qui l'identifie.
  3. Ignorez le rappel onActivityResult pour recevoir le lieu sélectionné.

L'exemple suivant montre comment utiliser un intent pour lancer la saisie semi-automatique, puis gérer le résultat:

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

    ...

    // Set the fields to specify which types of place data to return.
    List<Place.Field> fields = Arrays.asList(Place.Field.ID, Place.Field.NAME);

    // Start the autocomplete intent.
    Intent intent = new Autocomplete.IntentBuilder(
            AutocompleteActivityMode.FULLSCREEN, fields)
            .build(this);
    startActivityForResult(intent, AUTOCOMPLETE_REQUEST_CODE);

    ...

    /**
     * Override the activity's onActivityResult(), check the request code, and
     * do something with the returned place data (in this example its place name and place ID).
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == AUTOCOMPLETE_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                Place place = Autocomplete.getPlaceFromIntent(data);
                Log.i(TAG, "Place: " + place.getName() + ", " + place.getId());
            } else if (resultCode == AutocompleteActivity.RESULT_ERROR) {
                // TODO: Handle the error.
                Status status = Autocomplete.getStatusFromIntent(data);
                Log.i(TAG, status.getStatusMessage());
            } else if (resultCode == RESULT_CANCELED) {
                // The user canceled the operation.
            }
        }
    }

Le sélecteur de lieu n'est plus disponible

Le sélecteur de lieux a été abandonné le 29 janvier 2019. Elle a été désactivée le 29 juillet 2019 et n'est plus disponible. Si vous continuez à l'utiliser, un message d'erreur s'affichera. Le nouveau SDK n'est pas compatible avec le sélecteur de lieux.