Questa guida spiega i cambiamenti tra la libreria di compatibilità di Places e la nuova versione autonoma dell'SDK Places per Android. Se hai utilizzato la libreria di compatibilità di Places invece di eseguire la migrazione alla nuova versione autonoma dell'SDK Places per Android, questa guida ti mostrerà come aggiornare i progetti per utilizzare la nuova versione dell'SDK Places per Android.
L'unico modo per accedere alle funzionalità e alle correzioni di bug nell'SDK Places per Android superiore alla versione 2.6.0 è utilizzare l'SDK Places per Android. Google consiglia di eseguire l'aggiornamento dalla libreria di compatibilità alla nuova versione di Places per Android al più presto.
Che cosa è cambiato?
Le principali aree di cambiamento sono le seguenti:
- La nuova versione dell'SDK Places per Android viene distribuita come libreria client statica. Prima di gennaio 2019, l'SDK Places per Android era stato reso disponibile tramite Google Play Services. Da allora, è stata fornita una libreria di compatibilità di Places per facilitare la transizione al nuovo SDK Places for Android.
- Esistono nuovi metodi.
- Le mascherine di campo sono ora supportate per i metodi che restituiscono dettagli sul luogo. Puoi utilizzare le maschere di campo per specificare quali tipi di dati luogo vengono restituiti.
- I codici di stato utilizzati per segnalare 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 per Android autonomo, Google ha fornito una libreria di compatibilità per agevolare la migrazione dalla versione di Google Play Services dismessa dell'SDK Places per Android (com.google.android.gms:play-services-places
).
Questa libreria di compatibilità è stata fornita temporaneamente per reindirizzare e tradurre le chiamate API indirizzate 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 nell'SDK autonomo. Per ciascuna versione dell'SDK Places per Android rilasciata dalla versione 1.0 alla versione 2.6.0, è stata rilasciata una versione corrispondente della libreria di compatibilità Places per offrire funzionalità equivalenti.
Blocco e ritiro della libreria di compatibilità di Places
Tutte le versioni della libreria di compatibilità per l'SDK Places per Android sono state ritirate a partire dal 31 marzo 2022. La versione 2.6.0 è l'ultima versione della libreria di compatibilità di Places. L'unico modo per accedere alle funzionalità e alle correzioni di bug nell'SDK Places per Android superiore alla versione 2.6.0 è utilizzare l'SDK Places per Android.
Google consiglia di eseguire la migrazione all'SDK Places per Android per accedere a nuove funzionalità e correzioni di bug critiche per le release precedenti alla 2.6.0. Se al momento utilizzi la libreria di compatibilità, segui la procedura riportata nella sezione Installare l'SDK Places per Android per eseguire la migrazione all'SDK Places per Android.
Installa la libreria client
La nuova versione dell'SDK Places per Android viene distribuita come libreria client statica.
Utilizza Maven per aggiungere l'SDK Places per Android al tuo progetto Android Studio:
Se al momento utilizzi la libreria di compatibilità di Places:
Sostituisci la seguente riga nella sezione
dependencies
:implementation 'com.google.android.libraries.places:places-compat:X.Y.Z'
Con questa riga per passare all'SDK Places per Android:
implementation 'com.google.android.libraries.places:places:3.1.0'
Se attualmente utilizzi la versione di Play Services dell'SDK Places per Android:
Sostituisci la seguente riga nella sezione
dependencies
:implementation 'com.google.android.gms:play-services-places:X.Y.Z'
Con questa riga per passare all'SDK Places per Android:
implementation 'com.google.android.libraries.places:places:3.1.0'
Sincronizza il tuo progetto Gradle.
Imposta
minSdkVersion
per il progetto della tua applicazione su 16 o superiore.Aggiorna gli asset "Forniti da 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
Crea la tua app. Se visualizzi errori di build a causa della tua conversione nell'SDK Places per Android, consulta le sezioni riportate di seguito per informazioni sulla risoluzione di questi errori.
Inizializzare il nuovo client Places SDK
Inizializza il nuovo client dell'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 degli errori dei limiti QPS è cambiato. Gli errori relativi ai limiti QPS vengono ora
ripristinati tramite PlaceStatusCodes.OVER_QUERY_LIMIT
. Non ci sono altri limiti QPD.
Sono stati aggiunti i seguenti codici di stato:
REQUEST_DENIED
: la richiesta è stata rifiutata. Di seguito sono elencati alcuni possibili motivi:- Non è stata fornita alcuna chiave API.
- È stata fornita una chiave API non valida.
- L'API Places non è stata abilitata nella console Cloud.
- È stata fornita una chiave API con restrizioni delle chiavi errate.
INVALID_REQUEST
: la richiesta non è valida a causa di un argomento mancante o non valido.NOT_FOUND
: non è stato trovato alcun risultato per la richiesta specificata.
Nuovi metodi
La nuova versione dell'SDK Places per Android introduce metodi completamente nuovi, progettati per la coerenza. Tutti i nuovi metodi seguono i seguenti suggerimenti:
- Gli endpoint non utilizzano più il verbo
get
. - Gli oggetti di richiesta e risposta condividono lo stesso nome del metodo client corrispondente.
- Gli oggetti di richiesta ora hanno builder, i parametri obbligatori vengono passati come parametri del builder di richieste.
- I buffer non sono più utilizzati.
Questa sezione introduce i nuovi metodi e il loro funzionamento.
Recupera un luogo per ID
Utilizza fetchPlace()
per visualizzare i dettagli di un luogo specifico. fetchPlace()
funziona in modo simile a
getPlaceById()
.
Per recuperare un luogo, procedi nel seguente modo:
Richiama
fetchPlace()
, trasmettendo un oggettoFetchPlaceRequest
che specifica un ID luogo e un elenco di campi che specificano i dati del luogo 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();
Chiama
addOnSuccessListener()
per gestireFetchPlaceResponse
. Viene restituito un singolo risultato diPlace
.// 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()); } });
Recupera la foto di un luogo
Utilizza fetchPhoto()
per scattare una foto del luogo. fetchPhoto()
restituisce le foto di un luogo. Il modello per richiedere una foto è stato semplificato. 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()
funziona
in modo simile a getPhoto()
.
Per recuperare le foto dei luoghi:
Imposta una chiamata al numero
fetchPlace()
. Assicurati di includere il campoPHOTO_METADATAS
nella richiesta:List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
Ottieni un oggetto Place (in questo esempio viene utilizzato
fetchPlace()
, ma puoi anche utilizzarefindCurrentPlace()
):FetchPlaceRequest placeRequest = FetchPlaceRequest.builder(placeId, fields).build();
Aggiungi un elemento
OnSuccessListener
per recuperare i metadati della foto dall'elementoPlace
inFetchPlaceResponse
, quindi utilizza questi metadati 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 località dell'utente
Utilizza findCurrentPlace()
per trovare la posizione attuale del dispositivo dell'utente. findCurrentPlace()
restituisce un elenco di PlaceLikelihood
che indica i luoghi in cui è più probabile che si trovino il dispositivo dell'utente. findCurrentPlace()
funziona in modo simile a
getCurrentPlace()
.
Segui questa procedura per conoscere la posizione attuale del dispositivo dell'utente:
Assicurati che la tua app richieda le autorizzazioni
ACCESS_FINE_LOCATION
eACCESS_WIFI_STATE
. L'utente deve concedere l'autorizzazione ad accedere alla posizione attuale del dispositivo. Per i dettagli, consulta Richiedere le autorizzazioni app.Crea un
FindCurrentPlaceRequest
, incluso un elenco di tipi di dati relativi al luogo da restituire.// 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();
Chiama FindCurrentPlace e gestisci la risposta, verificando prima di verificare che l'utente abbia concesso l'autorizzazione a utilizzare la posizione del suo 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(); }
Trova previsioni di completamento automatico
Utilizza findAutocompletePredictions()
per restituire previsioni di luogo 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 di una ricerca dell'utente in una sessione discreta ai fini della fatturazione. Ti consigliamo di utilizzare i token di sessione per tutte le sessioni con completamento automatico. La sessione inizia quando l'utente inizia a digitare una query e termina quando seleziona un luogo. Ogni sessione può avere più query, seguite da una selezione del luogo. Al termine di una sessione, il token non è più valido; l'app deve generare un token nuovo per ogni sessione.
Maschere da campo
Nei metodi che restituiscono dettagli sui luoghi, devi specificare i tipi di dati sui luoghi da restituire per ogni richiesta. In questo modo ti assicuri di richiedere (e pagare) solo i dati effettivamente utilizzati.
Per specificare i tipi di dati da restituire, passa 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 di dati dei luoghi.
Aggiornamenti sul selettore dei luoghi e sul completamento automatico
Questa sezione spiega le modifiche ai widget Places (selettore luoghi e completamento automatico).
Completamento automatico della pubblicità programmatica
Sono state apportate le seguenti modifiche al completamento automatico:
PlaceAutocomplete
è stato rinominato inAutocomplete
.PlaceAutocomplete.getPlace
è stato rinominato inAutocomplete.getPlaceFromIntent
.PlaceAutocomplete.getStatus
è stato rinominato inAutocomplete.getStatusFromIntent
.
PlaceAutocomplete.RESULT_ERROR
è stato rinominato inAutocompleteActivity.RESULT_ERROR
(la gestione degli errori per il frammento di completamento automatico NON è cambiata).
Selettore luogo
Il Selettore luogo è stato ritirato il 29 gennaio 2019. È stato disattivato il 29 luglio 2019 e non è più disponibile. Se continui, verrà visualizzato un messaggio di errore. Il nuovo SDK non supporta il selettore di luoghi.
Widget con completamento automatico
I widget del 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 automaticamente i token per te in background.
- È stato aggiunto il supporto per le maschere di campo, che consentono di scegliere quali tipi di dati luogo mostrare dopo che l'utente ha effettuato una selezione.
Le seguenti sezioni mostrano come aggiungere un widget di completamento automatico al progetto.
Incorpora un AutocompleteFragment
Per aggiungere un frammento di completamento automatico, procedi nel seguente modo:
Aggiungi un frammento al layout XML della tua attività, come mostrato nell'esempio seguente.
<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" />
Per aggiungere il widget del completamento automatico all'attività, segui questi passaggi:
- Inizializza
Places
, passando il contesto dell'applicazione e la chiave API. - Inizializzare
AutocompleteSupportFragment
. - Chiama
setPlaceFields()
per indicare i tipi di dati relativi al luogo che vuoi ottenere. - Aggiungi un elemento
PlaceSelectionListener
per svolgere un'azione con il risultato, nonché gestire gli 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); } });
- Inizializza
Utilizza un intent per avviare l'attività di completamento automatico
- Inizializza
Places
, passando il contesto dell'app e la chiave API - Utilizza
Autocomplete.IntentBuilder
per creare un intent, passando la modalitàPlaceAutocomplete
che preferisci (schermo intero o overlay). L'intent deve chiamarestartActivityForResult
, trasmettendo un codice di richiesta che identifichi il tuo intento. - Sostituisci il callback
onActivityResult
per ricevere il luogo selezionato.
L'esempio seguente mostra come utilizzare un intent per avviare il completamento automatico e 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 luogo è stato ritirato il 29 gennaio 2019. È stato disattivato il 29 luglio 2019 e non è più disponibile. Se continui, verrà visualizzato un messaggio di errore. Il nuovo SDK non supporta il selettore di luoghi.