새 Places SDK 클라이언트로 마이그레이션

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

이 가이드에서는 Places 호환성 라이브러리와 새로운 독립형 버전의 Android용 Places SDK 간의 변경사항을 설명합니다. 이 가이드에서는 Android용 Places SDK의 새 독립형 버전으로 이전하는 대신 장소 호환성 라이브러리를 사용해 왔습니다. 이 가이드에서는 새로운 버전의 Android용 Places SDK를 사용하도록 프로젝트를 업데이트하는 방법을 설명합니다.

Android용 Places SDK 버전 2.6.0 이상의 기능과 버그 수정에 액세스하는 유일한 방법은 Android용 Places SDK를 사용하는 것입니다. 가능한 한 빨리 호환성 라이브러리에서 새로운 Android용 Places SDK 버전으로 업데이트하는 것이 좋습니다.

변경사항

변경의 주요 영역은 다음과 같습니다.

  • Android용 Places SDK의 새 버전은 정적 클라이언트 라이브러리로 배포됩니다. 2019년 1월 전에는 Google Play 서비스를 통해 Android용 Places SDK가 제공되었습니다. 이후 새로운 Android용 Places SDK로 쉽게 전환할 수 있도록 Places 호환성 라이브러리가 제공됩니다.
  • 새로운 메서드가 있습니다.
  • 이제 장소 세부정보를 반환하는 메서드에 필드 마스크가 지원됩니다. 필드 마스크를 사용하여 반환할 장소 데이터 유형을 지정할 수 있습니다.
  • 오류를 보고하는 데 사용되는 상태 코드가 개선되었습니다.
  • 이제 자동 완성에서 세션 토큰을 지원합니다.
  • 장소 선택 도구를 더 이상 사용할 수 없습니다.

Places 호환성 라이브러리 정보

2019년 1월 Android용 Places SDK 1.0 버전이 출시되면서 Google은 Android용 Places SDK의 사용 중지된 Google Play 서비스 버전(com.google.android.gms:play-services-places)에서 이전하는 데 도움이 되는 호환성 라이브러리를 제공했습니다.

이 호환성 라이브러리는 개발자가 독립형 SDK에서 새 이름을 사용하도록 코드를 이전할 수 있을 때까지 Google Play 서비스 버전을 대상으로 하는 API 호출을 새로운 독립형 버전으로 리디렉션하고 변환하기 위해 일시적으로 제공되었습니다. 버전 1.0에서 버전 2.6.0까지 출시된 Android용 Places SDK의 각 버전에 대해 동등한 기능을 제공하기 위해 해당하는 버전의 Places 호환성 라이브러리가 출시되었습니다.

Places 호환성 라이브러리 동결 및 지원 중단

Android용 Places SDK의 호환성 라이브러리 버전은 2022년 3월 31일부터 지원이 중단되었습니다. 버전 2.6.0은 장소 호환성 라이브러리의 마지막 버전입니다. Places SDK for Android 2.6.0 이상 버전에서 기능 및 버그 수정에 액세스하는 유일한 방법은 Android용 Places SDK를 사용하는 것입니다.

버전 2.6.0 이상의 새로운 기능과 중요한 버그 수정을 이용하려면 Android용 Places SDK로 이전하는 것이 좋습니다. 현재 호환성 라이브러리를 사용하는 경우 아래 Android용 Places SDK 설치 섹션의 단계에 따라 Android용 Places SDK를 이전하세요.

클라이언트 라이브러리 설치

Android용 Places SDK의 새 버전은 정적 클라이언트 라이브러리로 배포됩니다.

Maven을 사용하여 Android용 Places SDK를 Android 스튜디오 프로젝트에 추가합니다.

  1. 현재 Places 호환성 라이브러리를 사용 중인 경우:

    1. dependencies 섹션에서 다음 줄을

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

      이 줄을 사용하여 Android용 Places SDK로 전환하려면 다음 단계를 따르세요.

          implementation 'com.google.android.libraries.places:places:2.6.0'

  2. 현재 Android용 Places SDK의 Play 서비스 버전을 사용 중인 경우

    1. dependencies 섹션에서 다음 줄을

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

      이 줄을 사용하여 Android용 Places SDK로 전환하려면 다음 단계를 따르세요.

          implementation 'com.google.android.libraries.places:places:2.6.0'

  3. Gradle 프로젝트를 동기화합니다.

  4. 애플리케이션 프로젝트의 minSdkVersion16 이상으로 설정합니다.

  5. '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. 앱을 빌드합니다. Android용 Places SDK로 변환하여 빌드 오류가 발생하면 아래 섹션에서 이러한 오류 해결 방법에 대한 정보를 확인하세요.

새 Places SDK 클라이언트 초기화

다음 예와 같이 새 Places SDK 클라이언트를 초기화합니다.

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

상태 코드

QPS 한도 오류의 상태 코드가 변경되었습니다. 이제 QPS 한도 오류가 PlaceStatusCodes.OVER_QUERY_LIMIT를 통해 반환됩니다. 더 이상 QPD 제한이 없습니다.

다음 상태 코드가 추가되었습니다.

  • REQUEST_DENIED — 요청이 거부되었습니다. 여기에는 다음과 같은 여러 이유가 있을 수 있습니다.

    • API 키가 제공되지 않았습니다.
    • 잘못된 API 키가 제공되었습니다.
    • Cloud Console에서 Places API가 사용 설정되지 않았습니다.
    • API 키에 잘못된 키 제한이 있습니다.
  • INVALID_REQUEST — 누락되거나 잘못된 인수로 인해 요청이 잘못되었습니다.

  • NOT_FOUND — 주어진 요청에 대한 결과를 찾을 수 없습니다.

새 메서드

Android용 Places SDK의 새 버전에서는 일관성을 위해 설계된 완전히 새로운 메서드가 도입되었습니다. 모든 새 메서드는 다음을 준수합니다.

  • 엔드포인트에서 더 이상 get 동사를 사용하지 않습니다.
  • 요청 객체와 응답 객체는 해당 클라이언트 메서드와 동일한 이름을 공유합니다.
  • 요청 객체에 빌더가 추가되었습니다. 필수 매개변수는 요청 빌더 매개변수로 전달됩니다.
  • 버퍼는 더 이상 사용되지 않습니다.

이 섹션에서는 새로운 메서드를 소개하고 작동 방식을 보여줍니다.

ID로 장소 가져오기

fetchPlace()를 사용하여 특정 장소에 대한 세부정보를 가져옵니다. fetchPlace()getPlaceById()와 유사하게 작동합니다.

장소를 가져오려면 다음 단계를 따르세요.

  1. fetchPlace()를 호출하여 장소 ID를 지정하는 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.NAME);
    
    // Construct a request object, passing the place ID and fields array.
    FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields)
            .build();
    
    
  2. addOnSuccessListener()를 호출하여 FetchPlaceResponse을 처리합니다. 단일 Place 결과가 반환됩니다.

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

장소 사진 가져오기

fetchPhoto()를 사용하여 장소 사진을 가져옵니다. fetchPhoto()는 장소의 사진을 반환합니다. 사진 요청 패턴이 간소화되었습니다. 이제 Place 객체에서 직접 PhotoMetadata를 요청할 수 있습니다. 더 이상 별도의 요청이 필요하지 않습니다. 사진의 최대 너비 또는 높이는 1600픽셀입니다. fetchPhoto()getPhoto()와 유사하게 작동합니다.

장소 사진을 가져오려면 다음 단계를 따르세요.

  1. fetchPlace() 호출을 설정합니다. 요청에 PHOTO_METADATAS 필드를 포함해야 합니다.

    List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
    
  2. Place 객체를 가져옵니다 (이 예에서는 fetchPlace()를 사용하지만 findCurrentPlace()도 사용할 수 있음).

    FetchPlaceRequest placeRequest = FetchPlaceRequest.builder(placeId, fields).build();
    
  3. OnSuccessListener를 추가하여 FetchPlaceResponse의 결과 Place에서 사진 메타데이터를 가져온 후 결과 사진 메타데이터를 사용하여 비트맵과 기여 분석 텍스트를 가져옵니다.

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

사용자의 위치에서 장소 찾기

findCurrentPlace()를 사용하여 사용자 기기의 현재 위치를 찾습니다. findCurrentPlace()는 사용자 기기의 위치일 가능성이 가장 높은 위치를 나타내는 PlaceLikelihood 목록을 반환합니다. findCurrentPlace()getCurrentPlace()와 비슷하게 작동합니다.

사용자 기기의 현재 위치를 가져오려면 다음 단계를 따르세요.

  1. 앱에서 ACCESS_FINE_LOCATIONACCESS_WIFI_STATE 권한을 요청하는지 확인합니다. 사용자는 현재 기기 위치에 액세스할 수 있는 권한을 부여해야 합니다. 자세한 내용은 앱 권한 요청을 참고하세요.

  2. 반환할 장소 데이터 유형 목록을 포함하여 FindCurrentPlaceRequest를 만듭니다.

      // 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. findCurrentPlace를 호출하고 응답을 처리하여 먼저 사용자가 기기 위치 사용 권한을 부여했는지 확인합니다.

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

자동 완성 예상 검색어 찾기

사용자 검색어에 대한 응답으로 장소 예상 검색어를 반환하려면 findAutocompletePredictions()를 사용하세요. findAutocompletePredictions()getAutocompletePredictions()와 비슷하게 작동합니다.

다음 예는 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")
   .setTypeFilter(TypeFilter.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());
   }
});

세션 토큰

세션 토큰은 결제 목적으로 사용자 검색의 쿼리 및 선택 단계를 별도의 세션으로 그룹화합니다. 모든 자동 완성 세션에 세션 토큰을 사용하는 것이 좋습니다. 세션은 사용자가 쿼리를 입력하기 시작할 때 시작되고, 장소를 선택할 때 종료됩니다. 각 세션에는 여러 개의 쿼리가 있는데, 그다음으로 하나의 장소가 선택됩니다. 세션이 종료되면 토큰은 더 이상 유효하지 않습니다. 앱은 각 세션에 대해 새로운 토큰을 생성해야 합니다.

필드 마스크

장소 세부정보를 반환하는 메서드에서는 각 요청 시 반환할 장소 데이터 유형을 지정해야 합니다. 이렇게 하면 실제로 사용할 데이터만 요청하고 비용을 지불할 수 있습니다.

반환할 데이터 유형을 지정하려면 다음 예와 같이 FetchPlaceRequestPlace.Field 배열을 전달합니다.

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

다음 필드 중 하나 이상을 사용할 수 있습니다.

  • 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

Places Data SKU에 대해 자세히 알아보세요.

장소 선택 도구 및 자동 완성 업데이트

이 섹션에서는 장소 위젯 (장소 선택 도구 및 자동 완성)의 변경사항을 설명합니다.

프로그래매틱 자동 완성

자동 완성이 다음과 같이 변경되었습니다.

  • PlaceAutocomplete의 이름이 Autocomplete로 변경되었습니다.
    • PlaceAutocomplete.getPlace의 이름이 Autocomplete.getPlaceFromIntent로 변경되었습니다.
    • PlaceAutocomplete.getStatus의 이름이 Autocomplete.getStatusFromIntent로 변경되었습니다.
  • PlaceAutocomplete.RESULT_ERROR의 이름이 AutocompleteActivity.RESULT_ERROR로 변경되었습니다(자동 완성 프래그먼트의 오류 처리는 변경되지 않음).

장소 선택기

장소 선택 도구는 2019년 1월 29일에 지원 중단되었습니다. 이 서비스는 2019년 7월 29일에 사용 중지되었으며 더 이상 사용할 수 없습니다. 계속 사용하면 오류 메시지가 표시됩니다. 새 SDK는 장소 선택 도구를 지원하지 않습니다.

자동 완성 위젯

자동 완성 위젯이 업데이트되었습니다.

  • Place 접두사가 모든 클래스에서 삭제되었습니다.
  • 세션 토큰에 대한 지원이 추가되었습니다. 위젯은 백그라운드에서 자동으로 토큰을 관리합니다.
  • 사용자가 선택한 후 반환할 장소 데이터 유형을 선택할 수 있는 필드 마스크에 대한 지원이 추가되었습니다.

다음 섹션에서는 자동 완성 위젯을 프로젝트에 추가하는 방법을 보여줍니다.

AutocompleteFragment 삽입

자동 완성 프래그먼트를 추가하려면 다음 단계를 따르세요.

  1. 다음 예와 같이 프래그먼트를 활동의 XML 레이아웃에 추가합니다.

    <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. 활동에 자동 완성 위젯을 추가하려면 다음 단계를 따르세요.

    • Places를 초기화하여 애플리케이션 컨텍스트 및 API 키를 전달합니다.
    • AutocompleteSupportFragment를 초기화합니다.
    • setPlaceFields()를 호출하여 가져오려는 장소 데이터의 유형을 표시합니다.
    • PlaceSelectionListener를 추가하여 그 결과로 발생하는 작업을 실행하고 발생할 수 있는 모든 오류를 처리합니다.

    다음 예시는 활동에 자동 완성 위젯을 추가하는 방법을 보여줍니다.

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

인텐트를 사용하여 자동 완성 활동을 실행합니다.

  1. 앱 컨텍스트 및 API 키를 전달하여 Places를 초기화합니다.
  2. Autocomplete.IntentBuilder를 사용하여 인텐트를 만들고 원하는 PlaceAutocomplete 모드 (전체 화면 또는 오버레이)를 전달합니다. 인텐트는 startActivityForResult를 호출하여 인텐트를 식별하는 요청 코드를 전달해야 합니다.
  3. 선택한 장소를 수신하려면 onActivityResult 콜백을 재정의합니다.

다음 예시에서는 인텐트를 사용하여 자동 완성을 실행한 후 결과를 처리하는 방법을 보여줍니다.

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

장소 선택 도구를 더 이상 사용할 수 없습니다.

장소 선택 도구는 2019년 1월 29일에 지원 중단되었습니다. 이 서비스는 2019년 7월 29일에 사용 중지되었으며 더 이상 사용할 수 없습니다. 계속 사용하면 오류 메시지가 표시됩니다. 새 SDK는 장소 선택 도구를 지원하지 않습니다.