Yeni Yerler SDK İstemcisine Taşıma

Avrupa Ekonomik Alanı (AEA) geliştiricileri

Bu kılavuzda, Yerler uyumluluk kitaplığı ile Android için Yerler SDK'sının yeni bağımsız sürümü arasındaki değişiklikler açıklanmaktadır. Android için Yerler SDK'sının yeni bağımsız sürümüne geçmek yerine Yerler uyumluluk kitaplığını kullanıyorsanız bu kılavuzda projelerinizi Android için Yerler SDK'sının yeni sürümünü kullanacak şekilde nasıl güncelleyeceğiniz gösterilmektedir.

Android için Yerler SDK'sında 2.6.0 sürümünden sonraki özelliklere ve hata düzeltmelerine erişmenin tek yolu Android için Yerler SDK'sını kullanmaktır. Google, uyumluluk kitaplığından yeni Android için Yerler SDK'sı sürümüne en kısa sürede güncelleme yapmanızı önerir.

Hata: 9005 PLACES_API_RATE_LIMIT_EXCEEDED

Neler değişti?

Değişikliğin yapıldığı başlıca alanlar şunlardır:

  • Android için Yerler SDK'sının yeni sürümü statik bir istemci kitaplığı olarak dağıtılır. Ocak 2019'dan önce Android için Yerler SDK'sı Google Play Hizmetleri üzerinden kullanıma sunuluyordu. O zamandan beri, yeni Android için Yerler SDK'sına geçişi kolaylaştırmak amacıyla bir Yerler uyumluluk kitaplığı sunuldu.
  • Tamamen yeni yöntemler var.
  • Yer ayrıntılarını döndüren yöntemler için artık alan maskeleri destekleniyor. Hangi tür yer verilerinin döndürüleceğini belirtmek için alan maskelerini kullanabilirsiniz.
  • Hataları bildirmek için kullanılan durum kodları iyileştirildi.
  • Otomatik tamamlama artık oturum jetonlarını destekliyor.
  • Yer seçici artık kullanılamıyor.

Places uyumluluk kitaplığı hakkında

Ocak 2019'da bağımsız Android için Yerler SDK'sının 1.0 sürümünün yayınlanmasıyla birlikte Google, hizmetten kaldırılan Android için Yerler SDK'sının Google Play Hizmetleri sürümünden (com.google.android.gms:play-services-places) taşınmaya yardımcı olmak için bir uyumluluk kitaplığı sağladı.

Bu uyumluluk kitaplığı, geliştiriciler kodlarını bağımsız SDK'daki yeni adları kullanacak şekilde taşıyana kadar Google Play Hizmetleri sürümünü hedefleyen API çağrılarını yeni bağımsız sürüme yönlendirmek ve çevirmek için geçici olarak sağlanmıştır. Android için Yerler SDK'sının 1.0 sürümünden 2.6.0 sürümüne kadar yayınlanan her sürümü için eşdeğer işlevsellik sağlamak üzere Yerler uyumluluk kitaplığının ilgili sürümü yayınlanmıştır.

Places Uyumluluk Kitaplığı'nı dondurma ve desteğini sonlandırma

Android için Yerler SDK'sının uyumluluk kitaplığının tüm sürümleri 31 Mart 2022 itibarıyla kullanımdan kaldırıldı. 2.6.0 sürümü, Yerler uyumluluk kitaplığının son sürümüdür. Android için Yerler SDK'sında 2.6.0 sürümünden sonraki özelliklere ve hata düzeltmelerine erişmenin tek yolu Android için Yerler SDK'sını kullanmaktır.

Google, 2.6.0 sürümünün üzerindeki sürümlerde yeni özelliklere ve önemli hata düzeltmelerine erişmek için Android için Yerler SDK'sına geçmenizi önerir. Şu anda uyumluluk kitaplığını kullanıyorsanız Android için Yerler SDK'sına geçmek üzere aşağıdaki Android için Yerler SDK'sını yükleme bölümündeki adımları uygulayın.

İstemci kitaplığını yükleme

Android için Yerler SDK'sının yeni sürümü statik istemci kitaplığı olarak dağıtılır.

Android için Places SDK'yı Android Studio projenize eklemek üzere Maven'ı kullanın:

  1. Şu anda Places uyumluluk kitaplığını kullanıyorsanız:

    1. dependencies bölümündeki aşağıdaki satırı değiştirin:

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

      Android için Yerler SDK'sına geçmek üzere bu satırı kullanın:

          implementation("com.google.android.libraries.places:places:4.3.1")

  2. Şu anda Android için Yerler SDK'sının Play Hizmetleri sürümünü kullanıyorsanız:

    1. dependencies bölümündeki aşağıdaki satırı değiştirin:

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

      Android için Yerler SDK'sına geçmek üzere bu satırı kullanın:

          implementation("com.google.android.libraries.places:places:4.3.1")

  3. Gradle projenizi senkronize edin.

  4. Uygulama projenizin minSdkVersion değerini 23 veya daha yüksek bir değere ayarlayın.

  5. "Google ile desteklenir" öğelerinizi güncelleyin:

    @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. Uygulamanızı oluşturun. Android için Yerler SDK'sına geçişiniz nedeniyle derleme hataları görürseniz bu hataları çözmeyle ilgili bilgi için aşağıdaki bölümlere bakın.

Yeni Yerler SDK'sı istemcisini başlatma

Yeni Places SDK istemcisini aşağıdaki örnekte gösterildiği gibi başlatın:

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

Durum kodları

Sorgu sayısı sınırı hatalarının durum kodu değişti. QPS sınırı hataları artık PlaceStatusCodes.OVER_QUERY_LIMIT üzerinden döndürülüyor. Artık QPD sınırı yoktur.

Aşağıdaki durum kodları eklendi:

  • REQUEST_DENIED: İstek reddedildi. Bunun olası nedenleri şunlardır:

    • API anahtarı sağlanmadı.
    • Geçersiz bir API anahtarı sağlandı.
    • Places API, Cloud Console'da etkinleştirilmemiştir.
    • Yanlış anahtar kısıtlamalarıyla bir API anahtarı sağlandı.
  • INVALID_REQUEST: İstek, eksik veya geçersiz bir bağımsız değişken nedeniyle geçersiz.

  • NOT_FOUND: Belirtilen istek için sonuç bulunamadı.

Yeni yöntemler

Android için Yerler SDK'sının yeni sürümünde, tutarlılık için tasarlanmış yepyeni yöntemler sunuluyor. Yeni yöntemlerin tümü aşağıdaki koşullara uygundur:

  • Uç noktalar artık get fiilini kullanmıyor.
  • İstek ve yanıt nesneleri, ilgili istemci yöntemiyle aynı adı paylaşır.
  • İstek nesneleri artık oluşturuculara sahip. Zorunlu parametreler, istek oluşturucu parametreleri olarak iletiliyor.
  • Arabellekler artık kullanılmamaktadır.

Bu bölümde yeni yöntemler tanıtılmakta ve nasıl çalıştıkları gösterilmektedir.

Kimliğe göre yer getirme

Belirli bir yerle ilgili ayrıntıları almak için fetchPlace() simgesini kullanın. fetchPlace(), getPlaceById() ile benzer şekilde çalışır.

Bir yeri getirmek için aşağıdaki adımları uygulayın:

  1. Yer kimliği ve döndürülecek yer verilerini belirten bir alan listesi içeren bir fetchPlace() nesnesi ileterek fetchPlace() işlevini çağırın.FetchPlaceRequest

    // 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();
    
    
  2. FetchPlaceResponse işlemini gerçekleştirmek için addOnSuccessListener() numaralı telefonu arayın. Tek bir Place sonucu döndürülür.

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

Yer fotoğrafı getirme

Yer fotoğrafı almak için fetchPhoto() simgesini kullanın. fetchPhoto(), bir yerle ilgili fotoğrafları döndürür. Fotoğraf isteme kalıbı basitleştirildi. Artık doğrudan PhotoMetadata Place nesnesinden isteyebilirsiniz. Ayrı bir istek göndermeniz gerekmez. Fotoğrafların maksimum genişliği veya yüksekliği 1.600 piksel olabilir. fetchPhoto() işlevi, getPhoto() işlevine benzer şekilde çalışır.

Yer fotoğraflarını getirmek için aşağıdaki adımları uygulayın:

  1. fetchPlace() ile görüşme ayarlayın. İsteğinize PHOTO_METADATAS alanını eklediğinizden emin olun:

    List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
    
  2. Yer nesnesi alma (bu örnekte fetchPlace() kullanılmaktadır ancak findCurrentPlace() de kullanabilirsiniz):

    FetchPlaceRequest placeRequest = FetchPlaceRequest.builder(placeId, fields).build();
    
  3. OnSuccessListener ekleyerek FetchPlaceResponse içindeki sonuçlanan Place öğesinden fotoğraf meta verilerini alın. Ardından, sonuçlanan fotoğraf meta verilerini kullanarak bit eşlem ve ilişkilendirme metni alın:

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

Kullanıcının konumuna göre yer bulma

Kullanıcının cihazının mevcut konumunu bulmak için findCurrentPlace() simgesini kullanın. findCurrentPlace() Kullanıcının cihazının PlaceLikelihood konumunda olma olasılığının en yüksek olduğu yerleri gösteren bir liste döndürür. findCurrentPlace(), getCurrentPlace() ile benzer şekilde çalışır.

Kullanıcının cihazının mevcut konumunu almak için şu adımları uygulayın:

  1. Uygulamanızın ACCESS_FINE_LOCATION ve ACCESS_WIFI_STATE izinlerini istediğinden emin olun. Kullanıcı, mevcut cihaz konumuna erişim izni vermelidir. Ayrıntılar için Uygulama İzinleri İste başlıklı makaleyi inceleyin.

  2. Döndürülecek yer veri türlerinin listesini içeren bir FindCurrentPlaceRequest oluşturun.

      // 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();
    
  3. findCurrentPlace'i çağırın ve yanıtı işleyin. Öncelikle kullanıcının cihaz konumunu kullanma izni verdiğini doğrulayın.

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

Otomatik tamamlama tahminlerini bulma

Kullanıcıların arama sorgularına yanıt olarak yer tahminleri döndürmek için findAutocompletePredictions() kullanın. findAutocompletePredictions(), getAutocompletePredictions() ile benzer şekilde çalışır.

Aşağıdaki örnekte findAutocompletePredictions() çağrısı gösterilmektedir:

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

Oturum jetonları

Oturum jetonları, kullanıcı aramasının sorgu ve seçim aşamalarını faturalandırma amacıyla ayrı bir oturumda gruplandırır. Tüm otomatik tamamlama oturumları için oturum jetonları kullanmanızı öneririz. Oturum, kullanıcının sorgu yazmaya başlamasıyla başlar ve bir yer seçmesiyle sona erer. Her oturumda birden fazla sorgu ve ardından bir yer seçimi olabilir. Bir oturum sona erdiğinde jeton geçerliliğini kaybeder. Uygulamanız her oturum için yeni bir jeton oluşturmalıdır.

Alan maskeleri

Yer ayrıntılarını döndüren yöntemlerde, her istekle birlikte hangi yer verisi türlerinin döndürüleceğini belirtmeniz gerekir. Bu sayede yalnızca gerçekten kullanacağınız verileri isteyebilir (ve bu veriler için ödeme yapabilirsiniz).

Hangi veri türlerinin döndürüleceğini belirtmek için aşağıdaki örnekte gösterildiği gibi FetchPlaceRequest dizisini FetchPlaceRequest içinde iletin:Place.Field

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

Alan maskesinde kullanabileceğiniz alanların listesi için Yer Verileri Alanları (Yeni) başlıklı makaleyi inceleyin.

Places Data SKU'ları hakkında daha fazla bilgi edinin.

Yer seçici ve otomatik tamamlama güncellemeleri

Bu bölümde, Yer widget'larında (Yer Seçici ve Otomatik Tamamlama) yapılan değişiklikler açıklanmaktadır.

Programatik otomatik tamamlama

Otomatik tamamlama özelliğinde aşağıdaki değişiklikler yapıldı:

  • PlaceAutocomplete, Autocomplete olarak yeniden adlandırıldı.
    • PlaceAutocomplete.getPlace, Autocomplete.getPlaceFromIntent olarak yeniden adlandırıldı.
    • PlaceAutocomplete.getStatus, Autocomplete.getStatusFromIntent olarak yeniden adlandırıldı.
  • PlaceAutocomplete.RESULT_ERROR, AutocompleteActivity.RESULT_ERROR olarak yeniden adlandırıldı (Otomatik tamamlama parçası için hata işleme DEĞİŞMEDİ).

Yer Seçici

Yer seçici, 29 Ocak 2019'da kullanımdan kaldırıldı. 29 Temmuz 2019'da devre dışı bırakıldı ve artık kullanılamıyor. Devam eden kullanım, hata mesajına neden olur. Yeni SDK, yer seçiciyi desteklemiyor.

Otomatik tamamlama widget'ları

Otomatik tamamlama widget'ları güncellendi:

  • Place öneki tüm sınıflardan kaldırıldı.
  • Oturum jetonları için destek eklendi. Widget, jetonları arka planda sizin için otomatik olarak yönetir.
  • Kullanıcı seçim yaptıktan sonra hangi tür yer verilerinin döndürüleceğini seçmenize olanak tanıyan alan maskeleri için destek eklendi.

Aşağıdaki bölümlerde, projenize otomatik tamamlama widget'ı ekleme adımları gösterilmektedir.

AutocompleteFragment yerleştirme

Otomatik tamamlama parçası eklemek için aşağıdaki adımları uygulayın:

  1. Aşağıdaki örnekte gösterildiği gibi etkinliğinizin XML düzenine bir parça ekleyin.

    <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. Etkinliğe otomatik tamamlama widget'ı eklemek için aşağıdaki adımları uygulayın:

    • Uygulama bağlamını ve API anahtarınızı ileterek Places öğesini başlatın.
    • AutocompleteSupportFragment öğesini başlatın.
    • Almak istediğiniz yer verisi türlerini belirtmek için setPlaceFields() numaralı telefonu arayın.
    • Sonuçla ilgili bir işlem yapmak ve oluşabilecek hataları işlemek için PlaceSelectionListener ekleyin.

    Aşağıdaki örnekte, bir etkinliğe otomatik tamamlama widget'ı ekleme işlemi gösterilmektedir:

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

Otomatik tamamlama etkinliğini başlatmak için bir amaç kullanın.

  1. Places öğesini başlatın, uygulama bağlamını ve API anahtarınızı iletin.
  2. İstediğiniz Autocomplete.IntentBuilder modu (tam ekran veya yer paylaşımı) ileterek bir amaç oluşturmak için PlaceAutocomplete kullanın. Amaç, startActivityForResult işlevini çağırmalı ve isteğinizi tanımlayan bir istek kodu iletmelidir.
  3. Seçili yeri almak için onActivityResult geri çağırmasını geçersiz kılın.

Aşağıdaki örnekte, otomatik tamamlamayı başlatmak için bir amaç nasıl kullanılacağı ve ardından sonucun nasıl işleneceği gösterilmektedir:

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

Yer seçici artık kullanılamıyor

Yer seçici, 29 Ocak 2019'da kullanımdan kaldırıldı. 29 Temmuz 2019'da devre dışı bırakıldı ve artık kullanılamıyor. Devam eden kullanım, hata mesajına neden olur. Yeni SDK, yer seçiciyi desteklemiyor.