Bermigrasi ke Klien Places SDK Baru

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Panduan ini menjelaskan perubahan antara library kompatibilitas Places dan versi mandiri baru dari Places SDK for Android. Jika Anda telah menggunakan library kompatibilitas Places, bukan bermigrasi ke Places SDK for Android versi mandiri yang baru, panduan ini menunjukkan cara memperbarui project untuk 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 Places SDK for Android yang baru sesegera mungkin.

Apa saja yang berubah?

Area utama perubahan adalah sebagai berikut:

  • Places SDK for Android versi baru didistribusikan sebagai library klien statis. Sebelum Januari 2019, Places SDK for Android tersedia melalui layanan Google Play. Sejak itu, library kompatibilitas Places disediakan untuk memudahkan transisi ke Places SDK for Android yang baru.
  • Ada metode baru.
  • Mask kolom kini didukung untuk metode yang menampilkan detail tempat. Anda dapat menggunakan mask kolom untuk menentukan jenis data tempat yang akan ditampilkan.
  • Kode status yang digunakan untuk melaporkan error telah ditingkatkan.
  • Autocomplete kini mendukung token sesi.
  • Place Picker tidak tersedia lagi.

Tentang library kompatibilitas Places

Pada bulan Januari 2019 dengan rilis Versi 1.0 Places SDK for Android mandiri, Google menyediakan library kompatibilitas untuk membantu migrasi dari versi Layanan Google Play yang dinonaktifkan pada Places SDK for Android (com.google.android.gms:play-services-places).

Library kompatibilitas ini disediakan untuk sementara guna mengalihkan dan menerjemahkan panggilan API yang ditujukan untuk versi Layanan Google Play ke versi mandiri yang 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 library kompatibilitas Places yang sesuai telah dirilis untuk memberikan fungsi yang setara.

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 library kompatibilitas Places. 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 agar Anda bermigrasi ke Places SDK for Android untuk 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 pada bagian Menginstal Places SDK for Android untuk bermigrasi ke Places SDK for Android.

Menginstal library klien

Places SDK for Android versi baru didistribusikan sebagai library klien statis.

Gunakan Maven untuk menambahkan Places SDK for Android ke project Android Studio Anda:

  1. Jika saat ini Anda menggunakan library kompatibilitas Places:

    1. 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:2.7.0'

  2. Jika saat ini Anda menggunakan Places SDK for Android versi Layanan Play:

    1. 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:2.7.0'

  3. Sinkronkan project Gradle Anda.

  4. Setel minSdkVersion untuk project aplikasi Anda ke 16 atau yang lebih tinggi.

  5. Perbarui aset "Dengan teknologi 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. Build aplikasi Anda. Jika melihat error build karena konversi Anda ke Places SDK for Android, lihat bagian di bawah untuk mendapatkan informasi tentang cara menyelesaikan error 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 sekarang ditampilkan melalui PlaceStatusCodes.OVER_QUERY_LIMIT. Tidak ada lagi batas QPD.

Kode status berikut telah ditambahkan:

  • REQUEST_DENIED — Permintaan ditolak. Kemungkinan alasannya mencakup:

    • Tidak ada kunci API yang disediakan.
    • Kunci API yang diberikan tidak valid.
    • Places API belum diaktifkan di Cloud Console.
    • Kunci API diberikan dengan pembatasan kunci yang salah.
  • INVALID_REQUEST — Permintaan tidak valid karena argumen yang hilang atau tidak valid.

  • NOT_FOUND — Tidak ditemukan hasil untuk permintaan tertentu.

Metode baru

Places SDK for Android versi baru memperkenalkan metode baru, yang telah dirancang agar konsisten. Semua metode baru mematuhi hal berikut:

  • Endpoint tidak lagi menggunakan kata kerja get.
  • Objek permintaan dan respons memiliki nama yang sama dengan metode klien yang sesuai.
  • Objek permintaan kini memiliki builder; parameter yang diperlukan diteruskan sebagai parameter builder permintaan.
  • Buffer tidak lagi digunakan.

Bagian ini memperkenalkan metode baru, dan menunjukkan cara kerjanya.

Mengambil tempat berdasarkan ID

Gunakan fetchPlace() untuk mendapatkan detail tentang tempat tertentu. Fungsi fetchPlace() mirip dengan getPlaceById().

Ikuti langkah-langkah berikut untuk mengambil tempat:

  1. Panggil fetchPlace(), dengan meneruskan objek FetchPlaceRequest yang menentukan ID Tempat dan daftar kolom yang menentukan data Tempat untuk 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();
    
    
  2. Panggil addOnSuccessListener() untuk menangani FetchPlaceResponse. Satu hasil Place akan 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. Pola untuk meminta foto telah disederhanakan. Anda sekarang dapat meminta PhotoMetadata langsung dari objek Place, permintaan terpisah tidak lagi diperlukan. Foto dapat memiliki lebar atau tinggi maksimum 1600 piksel. Fungsi fetchPhoto() mirip dengan getPhoto().

Ikuti langkah-langkah berikut untuk mengambil foto tempat:

  1. Siapkan panggilan ke fetchPlace(). Pastikan untuk menyertakan kolom PHOTO_METADATAS dalam permintaan Anda:

    List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
    
  2. Dapatkan objek Tempat (contoh ini menggunakan fetchPlace(), tetapi Anda juga dapat menggunakan findCurrentPlace()):

    FetchPlaceRequest placeRequest = FetchPlaceRequest.builder(placeId, fields).build();
    
  3. Tambahkan OnSuccessListener untuk mendapatkan metadata foto dari Place yang dihasilkan di FetchPlaceResponse, 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 kemungkinan besar perangkat pengguna berada. Fungsi findCurrentPlace() mirip dengan getCurrentPlace().

Ikuti langkah-langkah berikut untuk mendapatkan lokasi perangkat pengguna saat ini:

  1. Pastikan aplikasi Anda meminta izin ACCESS_FINE_LOCATION dan ACCESS_WIFI_STATE. Pengguna harus memberikan izin untuk mengakses lokasi perangkatnya saat ini. Lihat bagian Meminta Izin Aplikasi untuk mengetahui detailnya.

  2. Buat FindCurrentPlaceRequest, termasuk daftar jenis data tempat untuk ditampilkan.

      // 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. Panggil findCurrentPlace dan tangani respons, 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 menampilkan prediksi tempat sebagai respons terhadap 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 dari penelusuran pengguna ke dalam sesi terpisah untuk tujuan penagihan. Sebaiknya gunakan token sesi untuk semua sesi pelengkapan otomatis. Sesi dimulai saat pengguna mulai mengetik kueri, dan berakhir saat mereka memilih tempat. Setiap sesi dapat memiliki beberapa kueri, diikuti dengan satu pilihan tempat. Setelah sesi selesai, token tidak lagi valid; aplikasi Anda harus membuat token baru untuk setiap sesi.

Mask kolom

Dalam metode yang menampilkan detail tempat, Anda harus menentukan jenis data tempat yang akan ditampilkan dengan setiap permintaan. Cara ini membantu memastikan bahwa Anda hanya meminta (dan membayar) data yang benar-benar akan digunakan.

Untuk menentukan jenis data yang akan ditampilkan, teruskan array Place.Field dalam FetchPlaceRequest, seperti yang ditunjukkan pada 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 Tempat.

Update Place Picker dan Autocomplete

Bagian ini menjelaskan perubahan pada widget Places (Alat Pilih Tempat dan Pelengkapan Otomatis).

Pelengkapan otomatis terprogram

Perubahan berikut telah dibuat untuk melengkapi otomatis:

  • PlaceAutocomplete diganti namanya menjadi Autocomplete.
    • PlaceAutocomplete.getPlace diganti namanya menjadi Autocomplete.getPlaceFromIntent.
    • PlaceAutocomplete.getStatus diganti namanya menjadi Autocomplete.getStatusFromIntent.
  • PlaceAutocomplete.RESULT_ERROR diganti namanya menjadi AutocompleteActivity.RESULT_ERROR (penanganan error untuk fragmen pelengkapan otomatis TIDAK berubah).

Place Picker

Place Picker tidak digunakan lagi pada tanggal 29 Januari 2019. Fitur ini dinonaktifkan pada tanggal 29 Juli 2019, dan tidak lagi tersedia. Penggunaan yang terus-menerus akan menghasilkan pesan error. SDK baru tidak mendukung Place Picker.

Widget pelengkapan otomatis

Widget pelengkapan otomatis telah diperbarui:

  • Awalan Place telah dihapus dari semua class.
  • Menambahkan dukungan untuk token sesi. Widget akan mengelola token untuk Anda secara otomatis di latar belakang.
  • Menambahkan dukungan untuk mask kolom, yang memungkinkan Anda memilih jenis data tempat 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:

  1. Tambahkan fragmen ke tata letak XML aktivitas Anda, seperti yang ditunjukkan pada contoh berikut.

    <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. 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 ingin Anda dapatkan.
    • Tambahkan PlaceSelectionListener untuk melakukan sesuatu dengan hasilnya, serta menangani error yang mungkin terjadi.

    Contoh berikut menunjukkan 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);
        }
    });
    

Menggunakan intent untuk meluncurkan aktivitas pelengkapan otomatis

  1. Menginisialisasi Places, dengan meneruskan konteks aplikasi dan kunci API Anda
  2. Gunakan Autocomplete.IntentBuilder untuk membuat intent, dengan meneruskan mode PlaceAutocomplete yang diinginkan (layar penuh, atau overlay). Intent harus memanggil startActivityForResult, yang meneruskan kode permintaan yang mengidentifikasi intent Anda.
  3. Ganti callback onActivityResult untuk menerima tempat yang dipilih.

Contoh berikut menunjukkan cara menggunakan intent untuk meluncurkan pelengkapan otomatis, lalu menangani 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.
            }
        }
    }

Pemilih Tempat tidak lagi tersedia

Place Picker tidak digunakan lagi pada tanggal 29 Januari 2019. Fitur ini dinonaktifkan pada tanggal 29 Juli 2019, dan tidak lagi tersedia. Penggunaan yang terus-menerus akan menghasilkan pesan error. SDK baru tidak mendukung Place Picker.