Eseguire la migrazione al client SDK New Places

Questa guida spiega le modifiche tra i luoghi libreria di compatibilità e la nuova versione standalone SDK Places per Android. Se hai utilizzato la libreria di compatibilità di Places anziché eseguire la migrazione a la nuova versione autonoma di Places SDK per Android, questa guida mostra come aggiornare i progetti per utilizzare la nuova versione dell'SDK Places per Android.

L'unico modo per accedere a funzionalità e correzioni di bug in Places SDK per Android superiore alla 2.6.0 utilizzerà l'SDK Places per Android. Google consiglia di eseguire l'aggiornamento dalla libreria di compatibilità al nuovo Versione di Places SDK per Android il prima possibile.

Che cosa è cambiato?

Le principali aree interessate sono le seguenti:

  • Viene distribuita la nuova versione dell'SDK Places per Android come libreria client statica. Prima di gennaio 2019, l'SDK Places per Android è stato reso disponibile tramite Google Play Services. Da allora, un'istanza di Places per facilitare la transizione al nuovo SDK Places per Android.
  • Esistono metodi completamente nuovi.
  • Le maschere dei campi sono ora supportate per i metodi che restituiscono informazioni sul luogo i dettagli. Puoi utilizzare le maschere dei campi per specificare quali tipi di dati dei luoghi per tornare indietro.
  • I codici di stato utilizzati per segnalare gli errori sono stati migliorati.
  • Il completamento automatico ora supporta i token di sessione.
  • Il Selettore di luoghi non è più disponibile.

Informazioni sulla libreria di compatibilità di Places

A gennaio 2019, con il rilascio della versione 1.0 dell'SDK Places autonomo per Android, Google ha fornito una libreria di compatibilità per facilitare la migrazione dalla versione dismessa di Google Play Services di Places SDK per Android (com.google.android.gms:play-services-places).

Questa libreria di compatibilità è stata fornita temporaneamente per reindirizzare e tradurre Chiamate API destinate alla versione di Google Play Services alla nuova versione autonoma finché gli sviluppatori non hanno potuto eseguire la migrazione del codice per utilizzare i nuovi nomi nel l'SDK standalone. Per ogni versione dell'SDK Places per Android che è stato rilasciato dalla Versione 1.0 alla Versione 2.6.0, una versione corrispondente della libreria di compatibilità di Places è stato rilasciato per fornire equivalenti funzionalità.

Blocco e ritiro della libreria di compatibilità di Places

Tutte le versioni della libreria di compatibilità per Places SDK for Android sono ritirate il 31 marzo 2022. La versione 2.6.0 è l'ultima versione del Libreria per la compatibilità di Places. L'unico modo per accedere a funzionalità e correzioni di bug in Places L'SDK per Android superiore alla versione 2.6.0 utilizzerà Places SDK per Android.

Google consiglia di eseguire la migrazione a Places SDK per Android per accedere a nuove funzioni e correzioni di bug critici per le versioni superiori alla 2.6.0. Se al momento utilizzi la libreria di compatibilità, segui i passaggi riportati di seguito nella Installa la sezione Places SDK per Android per eseguire la migrazione. all'SDK Places per Android.

installa la libreria client

La nuova versione di Places SDK per Android viene distribuita come libreria client statica.

Utilizza Maven per aggiungere SDK Places per Android nel tuo progetto Android Studio:

  1. Se al momento utilizzi la libreria di compatibilità di Places:

    1. Sostituisci la seguente riga nella sezione dependencies:

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

      Con questa riga per passare a Places SDK per Android:

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

  2. Se al momento utilizzi la versione Play Services dell'SDK Places per Android:

    1. Sostituisci la seguente riga nella sezione dependencies:

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

      Con questa riga per passare a Places SDK per Android:

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

  3. Sincronizza il tuo progetto Gradle.

  4. Imposta minSdkVersion per il progetto dell'applicazione su 16 o superiore.

  5. Aggiorna il tuo "Powered by Google" asset:

    @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. Crea la tua app. Se riscontri errori di generazione dovuti alla conversione in Places SDK per Android. Per informazioni, consulta le sezioni seguenti sulla risoluzione di questi errori.

Inizializza il nuovo client Places SDK

Inizializza il nuovo client SDK Places come mostrato nell'esempio seguente:

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

Codici di stato

Il codice di stato per gli errori relativi al limite di QPS è cambiato. Gli errori relativi al limite di QPS sono ora restituito tramite PlaceStatusCodes.OVER_QUERY_LIMIT. Non ci sono più limiti QPD.

Sono stati aggiunti i seguenti codici di stato:

  • REQUEST_DENIED: la richiesta è stata rifiutata. Di seguito sono elencati alcuni possibili motivi:

    • Nessuna chiave API fornita.
    • È stata fornita una chiave API non valida.
    • L'API Places non è stata abilitata nella console Cloud.
    • È stata fornita una chiave API con limitazioni errate.
  • INVALID_REQUEST: la richiesta non è valida perché manca o non è valida. .

  • NOT_FOUND: non è stato trovato alcun risultato per la richiesta specificata.

Nuovi metodi

La nuova versione dell'SDK Places per Android introduce che sono stati progettati per garantire coerenza. Tutti i nuovi metodi adempiere a quanto segue:

  • Gli endpoint non utilizzano più il verbo get.
  • Gli oggetti di richiesta e risposta hanno lo stesso nome dell'oggetto il metodo client.
  • Gli oggetti di richiesta ora hanno builder. i parametri obbligatori vengono passati come richiesta e i parametri del builder.
  • I buffer non vengono più utilizzati.

Questa sezione introduce i nuovi metodi e mostra come funzionano.

Recupera un luogo per ID

Utilizza fetchPlace() per ottenere dettagli su un luogo specifico. fetchPlace() funziona in modo simile a getPlaceById()

Per recuperare un luogo, procedi nel seguente modo:

  1. Chiama fetchPlace(), passando un oggetto FetchPlaceRequest che specifica un luogo ID e un elenco di campi che specificano i dati di Place da restituire.

    // 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. Chiama addOnSuccessListener() per gestire FetchPlaceResponse. Un singolo Viene restituito Place risultato.

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

Recuperare una foto di un luogo

Utilizza fetchPhoto() per scattare una foto di un luogo. fetchPhoto() restituisce le foto di un luogo. Lo schema per richiedere una foto è stata semplificata. Ora puoi richiedere PhotoMetadata direttamente dall'oggetto Place; non è più necessaria una richiesta separata. Le foto possono avere una larghezza o un'altezza massima di 1600 px. fetchPhoto() funzioni in modo simile a getPhoto().

Procedi nel seguente modo per recuperare le foto dei luoghi:

  1. Configura una chiamata al numero fetchPlace(). Assicurati di includere i campi Campo PHOTO_METADATAS nella richiesta:

    List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
    
  2. Recupera un oggetto Place (in questo esempio viene utilizzato fetchPlace(), ma puoi utilizzare anche findCurrentPlace()):

    FetchPlaceRequest placeRequest = FetchPlaceRequest.builder(placeId, fields).build();
    
  3. Aggiungi un elemento OnSuccessListener per recuperare i metadati della foto dal risultato Place in FetchPlaceResponse, quindi utilizza i metadati della foto risultanti per ottenere una bitmap e un testo di attribuzione:

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

Trova un luogo dalla posizione dell'utente

Utilizza findCurrentPlace() per trovare la posizione attuale del dispositivo dell'utente. findCurrentPlace() restituisce un elenco di PlaceLikelihood che indicano i luoghi in cui il dispositivo dell'utente ha maggiori probabilità di trovarsi. findCurrentPlace() funziona in modo simile a getCurrentPlace().

Per conoscere la posizione attuale del dispositivo dell'utente, procedi nel seguente modo:

  1. Assicurati che la tua app richieda ACCESS_FINE_LOCATION e Autorizzazioni ACCESS_WIFI_STATE. L'utente deve concedere l'autorizzazione ad accedere al proprio posizione attuale del dispositivo. Vedi Richiesta di app Autorizzazioni per i dettagli.

  2. Crea un FindCurrentPlaceRequest, includendo un elenco dei tipi di dati dei luoghi per per tornare indietro.

      // 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. Chiama FindCurrentPlace e gestisci la risposta, controllando prima che sia possibile l'utente ha concesso l'autorizzazione a utilizzare la posizione del proprio dispositivo.

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

Trovare le previsioni di completamento automatico

Utilizza findAutocompletePredictions() per restituire previsioni sui luoghi in risposta alle query di ricerca degli utenti. findAutocompletePredictions() funziona in modo simile a getAutocompletePredictions().

L'esempio seguente mostra la chiamata a 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")
   .setTypesFilter(Arrays.asList(PlaceTypes.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());
   }
});

Token di sessione

I token di sessione raggruppano le fasi di query e selezione della ricerca di un utente in un sessione discreta ai fini della fatturazione. Ti consigliamo di utilizzare i token di sessione tutte le sessioni di completamento automatico. La sessione inizia quando l'utente inizia a digitare query e si conclude quando selezionano un luogo. Ogni sessione può avere più query di ricerca, seguite dalla selezione di un luogo. Al termine di una sessione, token non più valido; la tua app deve generare un nuovo token durante la sessione.

Maschere dei campi

Nei metodi che restituiscono dettagli su un luogo, devi specificare i tipi di luogo i dati da restituire con ogni richiesta. In questo modo avrai la certezza che (e pagare) i dati che utilizzerai effettivamente.

Per specificare quali tipi di dati restituire, trasmetti un array di Place.Field in FetchPlaceRequest, come mostrato nell'esempio seguente:

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

Puoi utilizzare uno o più dei seguenti campi:

  • 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

Scopri di più sugli SKU dei dati di Places.

Aggiornamenti relativi a Selettore di luoghi e Completamento automatico

In questa sezione vengono spiegate le modifiche ai widget Luoghi (Selettore di luoghi e completamento automatico).

Completamento automatico programmatico

Sono state apportate le seguenti modifiche al completamento automatico:

  • PlaceAutocomplete è stato rinominato in Autocomplete.
    • PlaceAutocomplete.getPlace è stato rinominato in Autocomplete.getPlaceFromIntent.
    • PlaceAutocomplete.getStatus è stato rinominato in Autocomplete.getStatusFromIntent.
  • PlaceAutocomplete.RESULT_ERROR è stato rinominato AutocompleteActivity.RESULT_ERROR (la gestione degli errori per il frammento di completamento automatico NON è cambiata).

Selettore luogo

Il selettore di luoghi è stato ritirato il 29 gennaio 2019. È stato disattivato il giorno 29 luglio 2019 e non è più disponibile. L'uso continuato comporterà un messaggio di errore. Il nuovo SDK non supporta il Selettore luoghi.

Widget di completamento automatico

I widget di completamento automatico sono stati aggiornati:

  • Il prefisso Place è stato rimosso da tutti i corsi.
  • Aggiunto il supporto per i token di sessione. Il widget gestisce i token per te automaticamente in background.
  • Aggiunto il supporto per le maschere dei campi, che ti consentono di scegliere i tipi di luogo i dati da restituire dopo che l'utente ha effettuato una selezione.

Le sezioni seguenti mostrano come aggiungere un widget di completamento automatico al tuo progetto.

Incorpora AutocompleteFragment

Per aggiungere un frammento con completamento automatico, segui questi passaggi:

  1. Aggiungi un frammento al layout XML dell'attività, come mostrato di seguito esempio.

    <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. Per aggiungere il widget di completamento automatico all'attività, segui questi passaggi:

    • Inizializza Places, passando il contesto dell'applicazione e la chiave API.
    • Inizializza AutocompleteSupportFragment.
    • Chiama setPlaceFields() per indicare i tipi di dati dei luoghi che vuoi da ottenere.
    • Aggiungi PlaceSelectionListener per eseguire operazioni con il risultato, nonché per gestire eventuali errori che potrebbero verificarsi.

    L'esempio seguente mostra l'aggiunta di un widget di completamento automatico a un'attività:

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

Utilizzare un intent per avviare l'attività di completamento automatico

  1. Inizializza Places, trasmettendo il contesto dell'app e la chiave API
  2. Utilizza Autocomplete.IntentBuilder per creare un intent, trasmettendo i contenuti desiderati Modalità PlaceAutocomplete (a schermo intero o overlay). L'intent deve chiamare startActivityForResult, trasmettendo un codice di richiesta che identifica l'intento.
  3. Sostituisci il callback onActivityResult per ricevere il luogo selezionato.

L'esempio seguente mostra come utilizzare un intent per avviare il completamento automatico. e quindi gestire il risultato:

    /**
     * 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.
            }
        }
    }

Selettore luogo non più disponibile

Il selettore di luoghi è stato ritirato il 29 gennaio 2019. È stato disattivato il giorno 29 luglio 2019 e non è più disponibile. L'uso continuato comporterà un messaggio di errore. Il nuovo SDK non supporta il Selettore luoghi.