Panduan ini menjelaskan perubahan antara dua Tempat kompatibilitas mundur dan versi mandiri baru dari Places SDK for Android. Jika Anda telah menggunakan library kompatibilitas Places daripada bermigrasi ke versi mandiri Places SDK for Android yang baru, panduan ini menunjukkan cara memperbarui project agar dapat menggunakan Places SDK for Android versi baru.
Satu-satunya cara untuk mengakses fitur dan perbaikan bug di Places SDK for Android di atas Versi 2.6.0 adalah menggunakan Places SDK for Android. Google merekomendasikan untuk mengupdate dari library kompatibilitas ke versi baru Places SDK for Android versi sesegera mungkin.
Apa saja yang berubah?
Area utama perubahan adalah sebagai berikut:
- Versi baru Places SDK for Android didistribusikan sebagai library klien statis. Sebelum Januari 2019, Places SDK for Android telah disediakan melalui layanan Google Play. Sejak itu, Places library kompatibilitas disediakan untuk memudahkan transisi ke Places SDK for Android.
- Ada metode yang sama sekali baru.
- Mask kolom kini didukung untuk metode yang menampilkan tempat spesifikasi pendukung. Anda bisa menggunakan mask kolom untuk menentukan jenis data tempat kembali.
- Kode status yang digunakan untuk melaporkan error telah ditingkatkan.
- Pelengkapan otomatis kini mendukung token sesi.
- Place Picker tidak lagi tersedia.
Tentang library kompatibilitas Tempat
Pada Januari 2019 dengan dirilisnya Versi 1.0 Places SDK for Android mandiri,
Google menyediakan library kompatibilitas untuk membantu migrasi
dari versi Layanan Google Play yang dihentikan dari Places SDK for Android
(com.google.android.gms:play-services-places
).
Library kompatibilitas ini disediakan sementara untuk mengalihkan dan menerjemahkan Panggilan API yang ditujukan untuk versi Layanan Google Play ke versi mandiri baru versi baru hingga developer dapat memigrasikan kode mereka untuk menggunakan nama baru di SDK mandiri. Untuk setiap versi Places SDK for Android yang telah dirilis dari Versi 1.0 hingga Versi 2.6.0, versi terkait library kompatibilitas Places telah dirilis untuk menyediakan fungsionalitasnya.
Membekukan dan menghentikan penggunaan library kompatibilitas Places
Semua versi library kompatibilitas untuk Places SDK for Android tidak digunakan lagi mulai 31 Maret 2022. Versi 2.6.0 adalah versi terakhir dari Library kompatibilitas Tempat. Satu-satunya cara untuk mengakses fitur dan perbaikan bug di Places SDK untuk Android di atas Versi 2.6.0 akan menggunakan Places SDK for Android.
Google menyarankan agar Anda bermigrasi ke Places SDK for Android guna mengakses fitur baru dan perbaikan bug penting untuk rilis di atas Versi 2.6.0. Jika saat ini Anda menggunakan library kompatibilitas, ikuti langkah-langkah di bawah ini di Instal bagian Places SDK for Android untuk melakukan migrasi ke Places SDK for Android.
Menginstal library klien
Versi baru Places SDK for Android didistribusikan sebagai library klien statis.
Gunakan Maven untuk menambahkan Places SDK for Android ke project Android Studio Anda:
Jika saat ini Anda menggunakan library kompatibilitas Places:
Ganti baris berikut di bagian
dependencies
:implementation 'com.google.android.libraries.places:places-compat:X.Y.Z'
Dengan baris ini untuk beralih ke Places SDK for Android:
implementation 'com.google.android.libraries.places:places:3.3.0'
Jika saat ini Anda menggunakan Places SDK for Android versi Layanan Play:
Ganti baris berikut di bagian
dependencies
:implementation 'com.google.android.gms:play-services-places:X.Y.Z'
Dengan baris ini untuk beralih ke Places SDK for Android:
implementation 'com.google.android.libraries.places:places:3.3.0'
Sinkronkan project Gradle Anda.
Tetapkan
minSdkVersion
untuk project aplikasi Anda ke 16 atau yang lebih baru.Perbarui "Dengan teknologi Google" aset:
@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
Bangun aplikasi Anda. Jika Anda melihat error build karena konversi ke Places SDK for Android, lihat bagian di bawah untuk mendapatkan informasi untuk mengatasi kesalahan ini.
Melakukan inisialisasi klien Places SDK baru
Lakukan inisialisasi klien Places SDK baru seperti yang ditunjukkan pada contoh berikut:
// 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);
Kode status
Kode status untuk error batas QPS telah berubah. Error batas QPS kini
dikembalikan melalui PlaceStatusCodes.OVER_QUERY_LIMIT
. Tidak ada lagi batas QPD.
Kode status berikut telah ditambahkan:
REQUEST_DENIED
— Permintaan ditolak. Kemungkinan alasannya adalah:- Tidak ada kunci API yang diberikan.
- Kunci API yang diberikan tidak valid.
- Places API belum diaktifkan di Konsol Cloud.
- Kunci API disediakan dengan pembatasan kunci yang salah.
INVALID_REQUEST
— Permintaan tidak valid karena file tidak ada atau tidak valid argumen.NOT_FOUND
— Tidak ada hasil yang ditemukan untuk permintaan yang dimaksud.
Metode baru
Versi baru Places SDK for Android memperkenalkan metode, yang telah dirancang untuk konsistensi. Semua metode baru mematuhi hal berikut:
- Endpoint tidak lagi menggunakan kata kerja
get
. - Objek permintaan dan respons memiliki nama yang sama dengan objek klien.
- Objek request kini memiliki builder; parameter yang diperlukan diteruskan sebagai permintaan parameter builder.
- Buffer tidak lagi digunakan.
Bagian ini memperkenalkan metode baru, dan menunjukkan cara kerjanya.
Mengambil tempat menurut ID
Gunakan fetchPlace()
untuk mendapatkan detail tentang tempat tertentu. Fungsi fetchPlace()
mirip dengan
getPlaceById()
.
Ikuti langkah-langkah berikut untuk mengambil tempat:
Memanggil
fetchPlace()
, dengan meneruskan objekFetchPlaceRequest
yang menentukan Tempat ID dan daftar kolom yang menentukan data Tempat yang akan ditampilkan.// 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();
Panggil
addOnSuccessListener()
untuk menanganiFetchPlaceResponse
. Satu HasilPlace
ditampilkan.// 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()); } });
Mengambil foto tempat
Gunakan fetchPhoto()
untuk mendapatkan foto tempat. fetchPhoto()
menampilkan foto untuk suatu tempat. Polanya
untuk meminta foto telah disederhanakan. Anda kini dapat meminta PhotoMetadata
langsung dari objek Place
; permintaan terpisah tidak lagi diperlukan.
Foto dapat memiliki lebar atau tinggi maksimum 1600 piksel. fetchPhoto()
fungsi
mirip dengan getPhoto()
.
Ikuti langkah-langkah berikut untuk mengambil foto tempat:
Siapkan panggilan ke
fetchPlace()
. Pastikan untuk menyertakan KolomPHOTO_METADATAS
dalam permintaan Anda:List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
Mendapatkan objek Tempat (contoh ini menggunakan
fetchPlace()
, tetapi Anda juga dapat menggunakanfindCurrentPlace()
):FetchPlaceRequest placeRequest = FetchPlaceRequest.builder(placeId, fields).build();
Tambahkan
OnSuccessListener
untuk mendapatkan metadata foto dari hasilPlace
diFetchPlaceResponse
, lalu gunakan metadata foto yang dihasilkan untuk mendapatkan bitmap dan teks atribusi: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()); } }); });
Menemukan tempat dari lokasi pengguna
Gunakan findCurrentPlace()
untuk menemukan lokasi
perangkat pengguna saat ini. findCurrentPlace()
menampilkan daftar PlaceLikelihood
yang menunjukkan tempat perangkat pengguna
kemungkinan besar ditemukan. Fungsi findCurrentPlace()
mirip dengan
getCurrentPlace()
.
Ikuti langkah-langkah berikut untuk mendapatkan lokasi perangkat pengguna saat ini:
Pastikan aplikasi Anda meminta
ACCESS_FINE_LOCATION
dan IzinACCESS_WIFI_STATE
. Pengguna harus memberikan izin untuk mengakses lokasi perangkat saat ini. Lihat Meminta Aplikasi Izin untuk spesifikasi pendukung.Buat
FindCurrentPlaceRequest
, termasuk daftar jenis data tempat untuk kembali.// 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();
Panggil findCurrentPlace dan tangani responsnya, periksa terlebih dahulu untuk memverifikasi bahwa pengguna telah memberikan izin untuk menggunakan lokasi perangkatnya.
// 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(); }
Menemukan prediksi pelengkapan otomatis
Gunakan findAutocompletePredictions()
untuk mengembalikan prediksi tempat sebagai respons atas kueri penelusuran pengguna.
Fungsi findAutocompletePredictions()
mirip dengan
getAutocompletePredictions()
.
Contoh berikut menunjukkan cara memanggil 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 sesi
Token sesi mengelompokkan fase kueri dan pemilihan penelusuran pengguna ke dalam sesi terpisah untuk tujuan penagihan. Sebaiknya gunakan token sesi untuk semua sesi pelengkapan otomatis. Sesi dimulai ketika pengguna mulai mengetik kueri, dan menyimpulkan saat mereka memilih tempat. Setiap sesi dapat memiliki beberapa diikuti dengan satu pilihan tempat. Setelah sesi selesai, token sudah tidak valid; aplikasi Anda harus menghasilkan token baru untuk setiap sesi.
Mask kolom
Dalam metode yang menampilkan detail tempat, Anda harus menentukan jenis tempat data yang ditampilkan bersama setiap permintaan. Hal ini membantu memastikan bahwa Anda hanya meminta (dan bayar) data yang benar-benar akan Anda gunakan.
Untuk menentukan jenis data yang akan ditampilkan, teruskan array Place.Field
di
FetchPlaceRequest
, seperti yang ditunjukkan dalam contoh berikut:
// Include address, ID, and phone number.
List<Place.Field> placeFields = Arrays.asList(Place.Field.ADDRESS,
Place.Field.ID,
Place.Field.PHONE_NUMBER);
Anda dapat menggunakan satu atau beberapa kolom berikut:
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
Baca selengkapnya tentang SKU Data Places.
Update Place Picker dan Autocomplete
Bagian ini menjelaskan perubahan pada widget Tempat (Place Picker dan Pelengkapan Otomatis).
Pelengkapan otomatis terprogram
Perubahan berikut dilakukan untuk pelengkapan otomatis:
PlaceAutocomplete
diganti namanya menjadiAutocomplete
.PlaceAutocomplete.getPlace
diganti namanya menjadiAutocomplete.getPlaceFromIntent
.PlaceAutocomplete.getStatus
diganti namanya menjadiAutocomplete.getStatusFromIntent
.
PlaceAutocomplete.RESULT_ERROR
diganti namanya menjadiAutocompleteActivity.RESULT_ERROR
(penanganan error untuk fragmen pelengkapan otomatis TIDAK berubah).
Place Picker
Place Picker tidak digunakan lagi pada 29 Januari 2019. Fitur ini dinonaktifkan pada 29 Juli 2019, dan tidak tersedia lagi. Penggunaan berkelanjutan akan menghasilkan menampilkan pesan {i>error<i}. SDK baru tidak mendukung Place Picker.
Widget pelengkapan otomatis
Widget pelengkapan otomatis telah diupdate:
- Awalan
Place
telah dihapus dari semua class. - Menambahkan dukungan untuk token sesi. Widget ini mengelola token untuk Anda secara otomatis di latar belakang.
- Menambahkan dukungan untuk mask kolom, yang memungkinkan Anda memilih jenis tempat data yang akan ditampilkan setelah pengguna membuat pilihan.
Bagian berikut menunjukkan cara menambahkan widget pelengkapan otomatis ke project Anda.
Sematkan AutocompleteFragment
Untuk menambahkan fragmen pelengkapan otomatis, lakukan langkah-langkah berikut:
Tambahkan fragmen ke tata letak XML aktivitas Anda, seperti yang ditampilkan dalam contoh.
<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" />
Untuk menambahkan widget pelengkapan otomatis ke aktivitas, lakukan langkah-langkah berikut:
- Lakukan inisialisasi
Places
, dengan meneruskan konteks aplikasi dan kunci API Anda. - Inisialisasi
AutocompleteSupportFragment
. - Panggil
setPlaceFields()
untuk menunjukkan jenis data tempat yang Anda inginkan untuk mendapatkannya. - Tambahkan
PlaceSelectionListener
untuk melakukan sesuatu dengan hasil, serta menangani {i>error<i} apa pun yang mungkin terjadi.
Contoh berikut menampilkan penambahan widget pelengkapan otomatis ke aktivitas:
/** * 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); } });
- Lakukan inisialisasi
Menggunakan intent untuk meluncurkan aktivitas pelengkapan otomatis
- Melakukan inisialisasi
Places
, dengan meneruskan konteks aplikasi dan kunci API Anda - Gunakan
Autocomplete.IntentBuilder
untuk membuat intent, dengan meneruskan ModePlaceAutocomplete
(layar penuh atau overlay). Intent harus memanggilstartActivityForResult
, yang meneruskan kode permintaan yang mengidentifikasi intent. - Ganti callback
onActivityResult
untuk menerima tempat yang dipilih.
Contoh berikut menampilkan cara menggunakan intent untuk meluncurkan pelengkapan otomatis, lalu tangani hasilnya:
/**
* 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.
}
}
}
Place Picker tidak lagi tersedia
Place Picker tidak digunakan lagi pada 29 Januari 2019. Fitur ini dinonaktifkan pada 29 Juli 2019, dan tidak tersedia lagi. Penggunaan berkelanjutan akan menghasilkan menampilkan pesan {i>error<i}. SDK baru tidak mendukung Place Picker.