In diesem Leitfaden werden die Änderungen zwischen der Places-Kompatibilitätsbibliothek und der neuen eigenständigen Version des Places SDK for Android erläutert. Wenn Sie die Places-Kompatibilitätsbibliothek verwendet haben, anstatt zum neuen eigenständigen Places SDK for Android zu migrieren, erfahren Sie in diesem Leitfaden, wie Sie Ihre Projekte aktualisieren, um die neue Version des Places SDK for Android zu verwenden.
Nach Version 2.6.0 des Places SDK for Android kann nur noch direkt über das SDK auf Funktionen und Fehlerkorrekturen zugegriffen werden. Google empfiehlt, so schnell wie möglich von der Kompatibilitätsbibliothek auf die neue Version des Places SDK for Android umzustellen.
Fehler: 9005 PLACES_API_RATE_LIMIT_EXCEEDED
Was hat sich geändert?
Die wichtigsten Änderungen sind:
- Die neue Version des Places SDK for Android wird als statische Clientbibliothek bereitgestellt. Vor Januar 2019 wurde das Places SDK for Android über die Google Play-Dienste bereitgestellt. Seitdem wurde eine Places-Kompatibilitätsbibliothek bereitgestellt, um den Übergang zum neuen Places SDK for Android zu erleichtern.
- Es gibt völlig neue Methoden.
- Feldmasken werden jetzt für Methoden unterstützt, die Ortsdetails zurückgeben. Mit Feldmasken können Sie angeben, welche Arten von Ortsdaten zurückgegeben werden sollen.
- Die Statuscodes, die zum Melden von Fehlern verwendet werden, wurden verbessert.
- Die automatische Vervollständigung unterstützt jetzt Sitzungstokens.
- Die Ortsauswahl ist nicht mehr verfügbar.
Places-Kompatibilitätsbibliothek
Im Januar 2019 hat Google mit der Veröffentlichung von Version 1.0 des eigenständigen Places SDK for Android eine Kompatibilitätsbibliothek bereitgestellt, um die Migration von der eingestellten Google Play-Dienste-Version des Places SDK for Android (com.google.android.gms:play-services-places
) zu erleichtern.
Diese Kompatibilitätsbibliothek wurde vorübergehend bereitgestellt, um API-Aufrufe, die auf die Google Play-Dienste-Version ausgerichtet sind, an die neue eigenständige Version weiterzuleiten und zu übersetzen, bis Entwickler ihren Code migrieren konnten, um die neuen Namen im eigenständigen SDK zu verwenden. Für jede Version des Places SDK for Android, die von Version 1.0 bis Version 2.6.0 veröffentlicht wurde, wurde eine entsprechende Version der Places-Kompatibilitätsbibliothek mit gleichwertigen Funktionen veröffentlicht.
Einstellung und Außerbetriebnahme der Places-Kompatibilitätsbibliothek
Am 31. März 2022 wurden alle Versionen der Kompatibilitätsbibliothek für das Places SDK for Android eingestellt. Version 2.6.0 ist die letzte Version der Places-Kompatibilitätsbibliothek. Nach Version 2.6.0 des Places SDK for Android kann nur noch direkt über das SDK auf Funktionen und Fehlerkorrekturen zugegriffen werden.
Google empfiehlt, zum Places SDK for Android zu migrieren, um auf neue Funktionen und wichtige Fehlerkorrekturen für Versionen über 2.6.0 zuzugreifen. Wenn Sie derzeit die Kompatibilitätsbibliothek verwenden, folgen Sie der Anleitung im Abschnitt Places SDK for Android installieren, um zum Places SDK for Android zu migrieren.
Clientbibliothek installieren
Die neue Version des Places SDK for Android wird als statische Clientbibliothek bereitgestellt.
Verwenden Sie Maven, um das Places SDK for Android Ihrem Android Studio-Projekt hinzuzufügen:
Wenn Sie derzeit die Places-Kompatibilitätsbibliothek verwenden:
Ersetzen Sie die folgende Zeile im Abschnitt
dependencies
:implementation 'com.google.android.libraries.places:places-compat:X.Y.Z'
Mit dieser Zeile wechseln Sie zum Places SDK for Android:
implementation("com.google.android.libraries.places:places:4.3.1")
Wenn Sie derzeit die Play-Dienste-Version des Places SDK for Android verwenden:
Ersetzen Sie die folgende Zeile im Abschnitt
dependencies
:implementation 'com.google.android.gms:play-services-places:X.Y.Z'
Mit dieser Zeile wechseln Sie zum Places SDK for Android:
implementation("com.google.android.libraries.places:places:4.3.1")
Synchronisiere dein Gradle-Projekt.
Legen Sie
minSdkVersion
für Ihr Anwendungsprojekt auf 23 oder höher fest.„Powered by Google“-Assets aktualisieren:
@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
Erstellen Sie Ihre App. Wenn Sie aufgrund der Umstellung auf das Places SDK for Android Build-Fehler sehen, finden Sie in den folgenden Abschnitten Informationen zum Beheben dieser Fehler.
Neuen Places SDK-Client initialisieren
Initialisieren Sie den neuen Places SDK-Client wie im folgenden Beispiel:
// 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);
Statuscodes
Der Statuscode für Fehler aufgrund von QPS-Limits wurde geändert. Fehler aufgrund von QPS-Limits werden jetzt über PlaceStatusCodes.OVER_QUERY_LIMIT
zurückgegeben. Es gibt keine Beschränkungen hinsichtlich der Abfragen pro Tag (QPD) mehr.
Die folgenden Statuscodes wurden hinzugefügt:
REQUEST_DENIED
: Die Anfrage wurde abgelehnt. Mögliche Gründe sind z. B. folgende:- Es wurde kein API-Schlüssel angegeben.
- Es wurde ein ungültiger API-Schlüssel angegeben.
- Die Places API wurde in der Cloud Console nicht aktiviert.
- Ein API-Schlüssel wurde mit falschen Schlüsseleinschränkungen angegeben.
INVALID_REQUEST
: Die Anfrage ist aufgrund eines fehlenden oder ungültigen Arguments ungültig.NOT_FOUND
: Für die angegebene Anfrage wurde kein Ergebnis gefunden.
Neue Methoden
In der neuen Version des Places SDK for Android werden völlig neue Methoden eingeführt, die auf Konsistenz ausgelegt sind. Alle neuen Methoden entsprechen den folgenden Anforderungen:
- Endpunkte verwenden das Verb
get
nicht mehr. - Anfrage- und Antwortobjekte haben denselben Namen wie die entsprechende Clientmethode.
- Anfrageobjekte haben jetzt Builder. Erforderliche Parameter werden als Anfrage-Builder-Parameter übergeben.
- Puffer werden nicht mehr verwendet.
In diesem Abschnitt werden die neuen Methoden vorgestellt und ihre Funktionsweise erläutert.
Ort anhand der ID abrufen
Mit fetchPlace()
lassen sich Details zu einem bestimmten Ort abrufen. fetchPlace()
funktioniert ähnlich wie getPlaceById()
.
So rufen Sie einen Ort ab:
Rufen Sie
fetchPlace()
auf und übergeben Sie einFetchPlaceRequest
-Objekt, das eine Orts-ID und eine Liste von Feldern enthält, mit denen die zurückzugebenden Ortsdaten angegeben werden.// 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.DISPLAY_NAME); // Construct a request object, passing the place ID and fields array. FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields) .build();
Rufe
addOnSuccessListener()
auf, umFetchPlaceResponse
zu verarbeiten. Es wird ein einzelnesPlace
-Ergebnis zurückgegeben.// 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()); } });
Ortsfoto abrufen
Mit fetchPhoto()
können Sie ein Ortsfoto abrufen. fetchPhoto()
gibt Fotos für einen Ort zurück. Das Muster zum Anfordern eines Fotos wurde vereinfacht. Sie können PhotoMetadata
jetzt direkt über das Place
-Objekt anfordern. Eine separate Anfrage ist nicht mehr erforderlich.
Fotos dürfen eine maximale Breite oder Höhe von 1.600 Pixeln haben. fetchPhoto()
funktioniert ähnlich wie getPhoto()
.
So rufen Sie Ortsfotos ab:
Richte einen Anruf an
fetchPlace()
ein. Geben Sie in Ihrer Anfrage das FeldPHOTO_METADATAS
an:List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
Rufen Sie ein Place-Objekt ab. In diesem Beispiel wird
fetchPlace()
verwendet, Sie können aber auchfindCurrentPlace()
verwenden:FetchPlaceRequest placeRequest = FetchPlaceRequest.builder(placeId, fields).build();
Fügen Sie ein
OnSuccessListener
hinzu, um die Fotometadaten aus dem resultierendenPlace
imFetchPlaceResponse
abzurufen. Verwenden Sie dann die resultierenden Fotometadaten, um ein Bitmap und einen Attributions-Text abzurufen: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()); } }); });
Orte in der Nähe des Standorts des Nutzers finden
Verwenden Sie findCurrentPlace()
, um den aktuellen Standort des Geräts des Nutzers zu ermitteln. findCurrentPlace()
gibt eine Liste von PlaceLikelihood
s zurück, die Orte angeben, an denen sich das Gerät des Nutzers höchstwahrscheinlich befindet. findCurrentPlace()
funktioniert ähnlich wie getCurrentPlace()
.
So rufen Sie den aktuellen Standort des Geräts des Nutzers ab:
Ihre App muss die Berechtigungen
ACCESS_FINE_LOCATION
undACCESS_WIFI_STATE
anfordern. Der Nutzer muss die Berechtigung zum Zugriff auf den aktuellen Gerätestandort erteilen. Weitere Informationen finden Sie unter App-Berechtigungen anfordern.Erstellen Sie eine
FindCurrentPlaceRequest
, die eine Liste der zurückzugebenden Ortsdatentypen enthält.// Use fields to define the data types to return. List<Place.Field> placeFields = Arrays.asList(Place.Field.DISPLAY_NAME); // Use the builder to create a FindCurrentPlaceRequest. FindCurrentPlaceRequest request = FindCurrentPlaceRequest.builder(placeFields).build();
Rufen Sie „findCurrentPlace“ auf und verarbeiten Sie die Antwort. Prüfen Sie zuerst, ob der Nutzer die Berechtigung zur Verwendung des Gerätestandorts erteilt hat.
// 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(); }
Automatische Vervollständigungen finden
Verwenden Sie findAutocompletePredictions()
, um Ortsvorschläge als Reaktion auf Suchanfragen von Nutzern zurückzugeben.
findAutocompletePredictions()
funktioniert ähnlich wie getAutocompletePredictions()
.
Hier sehen Sie, wie findAutocompletePredictions()
aufgerufen wird:
// 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());
}
});
Sitzungstokens
Sitzungstokens fassen die Abfrage- und Auswahlphasen einer Nutzersuche zu Abrechnungszwecken zu einer separaten Sitzung zusammen. Wir empfehlen, Sitzungstokens für alle Sitzungen zu verwenden, bei denen eine automatische Vervollständigung erfolgt. Die Sitzung wird gestartet, wenn der Nutzer mit der Eingabe beginnt, und endet, wenn er einen Ort auswählt. Jede Sitzung kann mehrere Abfragen und eine Ortsauswahl umfassen. Sobald eine Sitzung beendet wird, ist das Token nicht mehr gültig. Ihre App muss für jede Sitzung ein neues Token generieren.
Feldmasken
Bei Methoden, die Ortsdetails zurückgeben, müssen Sie für jede Anfrage angeben, welche Arten von Ortsdaten zurückgegeben werden sollen. So wird sichergestellt, dass Sie nur Daten anfordern (und dafür bezahlen), die Sie tatsächlich verwenden.
Wenn Sie angeben möchten, welche Datentypen zurückgegeben werden sollen, übergeben Sie ein Array von Place.Field
s in Ihrem FetchPlaceRequest
, wie im folgenden Beispiel gezeigt:
// Include address, ID, and phone number.
List<Place.Field> placeFields = Arrays.asList(Place.Field.FORMATTED_ADDRESS,
Place.Field.ID,
Place.Field.INTERNATIONAL_PHONE_NUMBER);
Eine Liste der Felder, die Sie in einer Feldmaske verwenden können, finden Sie unter Ortsdatenfelder (neu) .
Weitere Informationen zu Places-Daten-SKUs
Updates für Place Picker und Autocomplete
In diesem Abschnitt werden die Änderungen an den Places-Widgets (Place Picker und Autocomplete) erläutert.
Programmatische automatische Vervollständigung
Die folgenden Änderungen wurden an der automatischen Vervollständigung vorgenommen:
PlaceAutocomplete
wird inAutocomplete
umbenannt.PlaceAutocomplete.getPlace
wird inAutocomplete.getPlaceFromIntent
umbenannt.PlaceAutocomplete.getStatus
wird inAutocomplete.getStatusFromIntent
umbenannt.
PlaceAutocomplete.RESULT_ERROR
wurde inAutocompleteActivity.RESULT_ERROR
umbenannt. (Die Fehlerbehandlung für das Autocomplete-Fragment hat sich NICHT geändert.)
Ortsauswahl
Die Ortsauswahl wurde am 29. Januar 2019 eingestellt. Sie wurde am 29. Juli 2019 deaktiviert und ist nicht mehr verfügbar. Eine weitere Verwendung führt zu einer Fehlermeldung. Das neue SDK unterstützt die Ortsauswahl nicht.
Autocomplete-Widgets
Die Autocomplete-Widgets wurden aktualisiert:
- Das Präfix
Place
wurde aus allen Klassen entfernt. - Unterstützung für Sitzungstokens hinzugefügt. Das Widget verwaltet Tokens automatisch im Hintergrund.
- Unterstützung für Feldmasken hinzugefügt, mit denen Sie auswählen können, welche Arten von Ortsdaten zurückgegeben werden sollen, nachdem der Nutzer eine Auswahl getroffen hat.
In den folgenden Abschnitten wird beschrieben, wie Sie Ihrem Projekt ein Autocomplete-Widget hinzufügen.
AutocompleteFragment
einbetten
So fügen Sie ein Autocomplete-Fragment hinzu:
Fügen Sie dem XML-Layout Ihrer Aktivität ein Fragment hinzu, wie im folgenden Beispiel gezeigt.
<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" />
So fügen Sie der Aktivität das Widget für die automatische Vervollständigung hinzu:
- Initialisieren Sie
Places
und übergeben Sie den Anwendungskontext und Ihren API-Schlüssel. - Initialisieren Sie
AutocompleteSupportFragment
. - Rufen Sie
setPlaceFields()
auf, um die Arten von Ortsdaten anzugeben, die Sie abrufen möchten. - Fügen Sie ein
PlaceSelectionListener
hinzu, um etwas mit dem Ergebnis zu tun und alle Fehler zu behandeln, die auftreten können.
Im folgenden Beispiel wird gezeigt, wie Sie einer Aktivität ein Autocomplete-Widget hinzufügen:
/** * 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.DISPLAY_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); } });
- Initialisieren Sie
Intent zum Starten der Aktivität für die automatische Vervollständigung verwenden
Places
initialisieren und App-Kontext und API-Schlüssel übergeben- Verwenden Sie
Autocomplete.IntentBuilder
, um eine Intention zu erstellen und den gewünschtenPlaceAutocomplete
-Modus (Vollbild oder Overlay) zu übergeben. Der Intent mussstartActivityForResult
aufrufen und einen Anfragecode übergeben, der den Intent identifiziert. - Überschreiben Sie den Callback
onActivityResult
, um den ausgewählten Ort zu empfangen.
Das folgende Beispiel zeigt, wie Sie mit einer Absicht die automatische Vervollständigung starten und das Ergebnis verarbeiten:
/**
* 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.DISPLAY_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.
}
}
}
Die Ortsauswahl ist nicht mehr verfügbar
Die Ortsauswahl wurde am 29. Januar 2019 eingestellt. Sie wurde am 29. Juli 2019 deaktiviert und ist nicht mehr verfügbar. Eine weitere Verwendung führt zu einer Fehlermeldung. Das neue SDK unterstützt die Ortsauswahl nicht.