Android용 Places SDK 시작하기(Kotlin)

1. 시작하기 전에

이 Codelab에서는 Android용 Places SDK를 앱과 통합하고 각 Places SDK 기능을 사용하는 방법을 알아봅니다.

Places 데모 앱

사전 준비 사항

  • Kotlin 및 Android 개발에 대한 기본 지식

과정 내용

  • Kotlin 확장 프로그램을 사용하여 Android용 Places SDK를 설치하는 방법
  • 특정 장소의 장소 세부정보를 로드하는 방법
  • Place Autocomplete 위젯을 앱에 추가하는 방법
  • 기기의 현재 보고된 위치를 기반으로 현재 장소를 로드하는 방법

필요한 사항

이 Codelab을 완료하려면 아래의 계정, 서비스 및 도구가 필요합니다.

2. 설정

아래의 사용 설정 단계에서 Places API를 사용 설정합니다.

Google Maps Platform 설정하기

Google Cloud Platform 계정 및 결제가 사용 설정된 프로젝트가 없는 경우 Google Maps Platform 시작하기 가이드를 참고하여 결제 계정 및 프로젝트를 만듭니다.

  1. Cloud Console에서 프로젝트 드롭다운 메뉴를 클릭하고 이 Codelab에 사용할 프로젝트를 선택합니다.

  1. Google Cloud Marketplace에서 이 Codelab에 필요한 Google Maps Platform API 및 SDK를 사용 설정합니다. 이 동영상 또는 이 문서의 단계를 따릅니다.
  2. Cloud Console의 사용자 인증 정보 페이지에서 API 키를 생성합니다. 이 동영상 또는 이 문서의 단계를 따릅니다. Google Maps Platform에 대한 모든 요청에는 API 키가 필요합니다.

3. 빠른 시작

빠르게 시작하려면 이 Codelab을 따라 하는 데 도움이 되는 시작 코드를 다운로드하세요. 솔루션으로 바로 넘어갈 수도 있지만, 모든 단계를 따라 하면서 직접 빌드하려면 계속 읽어주시기 바랍니다.

  1. git를 설치한 경우 저장소를 클론합니다.
git clone https://github.com/googlemaps/codelab-places-101-android.git

또는 이 버튼을 클릭하여 소스 코드를 다운로드합니다.

  1. 코드를 다운로드한 후 Android 스튜디오의 /starter 디렉터리 내에 있는 프로젝트를 엽니다. 이 프로젝트에는 Codelab을 완료하는 데 필요한 기본 파일 구조가 포함되어 있습니다. 작업해야 하는 모든 항목은 /starter 디렉터리에 있습니다.

실행 중인 전체 솔루션 코드를 확인하려면 /solution 디렉터리에서 완료된 코드를 확인하세요.

4. Android용 Places SDK 설치하기

이 섹션에서는 Android용 Places SDK를 앱의 종속 항목에 추가합니다.

API 키 추가하기

Android용 Places SDK에서 키를 앱과 연결할 수 있도록 이전에 만든 API 키를 앱에 제공합니다.

  1. 프로젝트의 루트 디렉터리(gradle.propertiessettings.gradle과 동일한 수준)에서 local.properties라는 파일을 엽니다.
  2. 새 키 GOOGLE_MAPS_API_KEY를 정의하고 해당 키의 값을 내가 만든 API 키로 설정합니다.

local.properties

GOOGLE_MAPS_API_KEY=YOUR_KEY_HERE

local.properties는 Git 저장소의 .gitignore 파일에 나열되어 있습니다. 이는 API 키가 민감한 정보로 간주되며 가급적 소스 관리에 체크인하면 안 되기 때문입니다.

  1. 다음으로, 앱 전체에서 사용할 수 있도록 API 키를 노출하려면 app/ 디렉터리에 있는 앱의 build.gradle 파일에 Secrets Gradle Plugin for Android 플러그인을 포함하고 plugins 블록 내에 다음 줄을 추가합니다.

앱 수준 build.gradle

plugins {
    // ...
    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
  1. 다음 클래스 경로를 포함하도록 프로젝트 수준 build.gradle 파일을 수정합니다.

프로젝트 수준 build.gradle

buildscript {
    dependencies {
        // ...
        classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
    }
}

이 플러그인은 local.properties 파일 내에서 정의한 키를 Android 매니페스트 파일의 빌드 변수로 제공하고 빌드 시간에 이를 Gradle에서 생성된 BuildConfig 클래스의 변수로 사용할 수 있게 합니다. 이 플러그인을 사용하면 local.properties에서 속성을 읽는 데 필요한 상용구 코드가 제거되어 앱 전체에서 액세스할 수 있습니다.

Android용 Places SDK 종속 항목 추가하기

  1. 앱 내에서 API 키에 액세스할 수 있게 되었으므로, Android용 Places SDK 종속 항목을 앱의 build.gradle 파일에 추가하세요.

이 Codelab과 함께 제공되는 시작 프로젝트에서는 이 종속 항목이 이미 추가되어 있습니다.

앱 수준 build.gradle

dependencies {
   // Dependency to include Places SDK for Android
   implementation 'com.google.android.libraries.places:places:2.6.0'
}
  1. 앱을 실행합니다.

이제 앱이 빈 화면과 함께 표시됩니다. 계속하여 이 화면을 3개의 데모로 채웁니다.

5. Places Android KTX 설치하기

Google Maps Platform Android SDK를 하나 이상 사용하는 Kotlin 앱의 경우, Kotlin 확장 프로그램(KTX) 라이브러리를 사용하면 코루틴, 확장 프로그램 속성/함수 등과 같은 Kotlin 언어 기능을 활용할 수 있습니다. 각 Google Maps SDK에는 아래와 같이 해당하는 KTX 라이브러리가 있습니다.

Google Maps Platform KTX 다이어그램

이 작업에서는 Places Android KTX 라이브러리를 사용하여 앱에서 Kotlin 관련 언어 기능을 사용합니다.

Places Android KTX 종속 항목 추가하기

Kotlin 관련 기능을 활용하려면 앱 수준 build.gradle 파일에 이 SDK에 해당하는 KTX 라이브러리를 포함하세요.

build.gradle

dependencies {
    // ...

    // Places SDK for Android KTX Library
    implementation 'com.google.maps.android:places-ktx:2.0.0'
}

6. Places Client 초기화하기

애플리케이션 범위에 대해 Places SDK 초기화하기

app/src/main/java/com/google/codelabs/maps/placesdemo 폴더의 DemoApplication.kt 파일 내에서 Android용 Places SDK를 초기화합니다. onCreate 함수의 끝에 다음 행을 붙여넣습니다.

        // Initialize the SDK with the Google Maps Platform API key
        Places.initialize(this, BuildConfig.GOOGLE_MAPS_API_KEY)

앱을 빌드할 때 Android용 Secrets Gradle Plugin에서 local.properties 파일의 API 키를 BuildConfig.GOOGLE_MAPS_API_KEY로 제공합니다.

매니페스트에 애플리케이션 파일 추가하기

DemoApplication으로 Application을 확장했으므로 매니페스트를 업데이트해야 합니다. android:name 속성을 app/src/main에 있는 AndroidManifest.xml 파일의 application 요소에 추가합니다.

    <application
        android:name=".DemoApplication"
        ...
    </application>

이 코드는 애플리케이션 매니페스트를 src/main/java/com/google/codelabs/maps/placesdemo/ 폴더의 DemoApplication 클래스로 설정합니다.

7. 장소 세부정보 가져오기

세부정보 화면 만들기

app/src/main/res/layout/ 폴더에 빈 LinearLayout이 포함된 activity_details.xml 레이아웃을 사용할 수 있습니다. <LinearLayout> 대괄호 사이에 다음 코드를 추가하여 선형 레이아웃을 채웁니다.

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/details_input"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/details_input_hint"
            android:text="@string/details_input_default" />

    </com.google.android.material.textfield.TextInputLayout>

    <Button
        android:id="@+id/details_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/button_details" />

    <TextView
        android:id="@+id/details_response_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="16dp"
        android:textIsSelectable="true" />

이 코드는 사용자가 장소 ID를 입력하거나 제공된 기본값을 사용할 수 있는 텍스트 입력란, 장소 세부정보 요청을 시작할 수 있는 버튼, 응답의 정보를 표시하는 TextView를 추가합니다. 연결된 문자열은 src/main/res/values/strings.xml 파일에 정의되어 있습니다.

세부정보 활동 만들기

  1. src/main/java/com/google/codelabs/maps/placesdemo/ 폴더에 DetailsActivity.kt 파일을 만들고 방금 만든 레이아웃과 연결합니다. 다음 코드를 파일에 붙여넣습니다.
class DetailsActivity : AppCompatActivity() {
    private lateinit var placesClient: PlacesClient
    private lateinit var detailsButton: Button
    private lateinit var detailsInput: TextInputEditText
    private lateinit var responseView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_details)

        // Set up view objects
        detailsInput = findViewById(R.id.details_input)
        detailsButton = findViewById(R.id.details_button)
        responseView = findViewById(R.id.details_response_content)

    }
}
  1. 이 활동과 함께 사용할 Places Client를 만듭니다. onCreate 함수에서 설정된 뷰 객체 뒤에 다음 코드를 붙여넣습니다.
        // Retrieve a PlacesClient (previously initialized - see DemoApplication)
        placesClient = Places.createClient(this)
  1. Places Client가 설정된 후 버튼에 클릭 리스너를 첨부합니다. onCreate 함수에 Places Client가 생성된 후 다음 코드를 붙여넣습니다.
        // Upon button click, fetch and display the Place Details
        detailsButton.setOnClickListener {
            val placeId = detailsInput.text.toString()
            val placeFields = listOf(
                Place.Field.NAME,
                Place.Field.ID,
                Place.Field.LAT_LNG,
                Place.Field.ADDRESS
            )
            lifecycleScope.launch {
                try {
                    val response = placesClient.awaitFetchPlace(placeId, placeFields)
                    responseView.text = response.prettyPrint()
                } catch (e: Exception) {
                    e.printStackTrace()
                    responseView.text = e.message
                }
            }
        }

이 코드는 입력란에 입력된 장소 ID를 가져오고, 장소에 대해 요청할 입력란을 정의하고, FetchPlaceRequest를 만들고, 작업을 시작하고, 성공 또는 실패 여부를 수신합니다. 요청에 성공하면 함수에서는 요청된 세부정보로 TextView를 채웁니다.

  1. 확장 함수를 정의하여 FetchPlaceResponse를 텍스트로 변환합니다. Places SDK 응답을 사람이 읽을 수 있는 문자열로 쉽게 변환할 수 있도록 StringUtil.kt 파일이 제공됩니다.

DetailsActivity.kt 파일의 끝에서 Fetch Place 응답 객체를 문자열로 변환하는 함수를 정의합니다.

fun FetchPlaceResponse.prettyPrint(): String {
    return StringUtil.stringify(this, false)
}

매니페스트에 세부정보 활동 추가하기

DetailsActivity<activity> 요소를 app/src/main에 있는 AndroidManifest.xml 파일에서 <application> 요소의 하위 요소로 추가합니다.

        <activity android:name=".DetailsActivity" />

데모 메뉴에 세부정보 활동 추가하기

홈 화면에 사용 가능한 데모를 표시할 수 있도록 빈 Demo 모듈이 제공됩니다. 이제 장소 세부정보 활동을 만들었으므로 다음 코드를 사용하여 src/main/java/com/google/codelabs/maps/placesdemo/ 폴더의 Demo.kt 파일에 추가합니다.

    DETAILS_FRAGMENT_DEMO(
        R.string.details_demo_title,
        R.string.details_demo_description,
        DetailsActivity::class.java
    ),

연결된 문자열은 src/main/res/values/strings.xml 파일에 정의됩니다.

MainActivity.kt를 검사하고 Demo 모듈의 콘텐츠를 반복하여 채워진 ListView를 만드는지 확인합니다. 사용자가 목록의 항목을 탭하면 클릭 리스너가 연결된 활동을 엽니다.

앱 실행

  1. 앱을 실행합니다. 이번에는 장소 세부정보 데모를 표시하는 항목이 목록에 표시됩니다.
  2. 장소 세부정보 텍스트를 탭합니다. 생성된 뷰가 입력란 및 버튼과 함께 표시됩니다.
  3. '세부정보 보기' 버튼을 탭합니다. 기본 장소 ID를 사용한 경우 그림 1과 같이 장소 이름, 주소, 지도 좌표가 표시됩니다.

응답이 있는 장소 세부정보 활동

그림 1. 응답이 표시된 장소 세부정보 활동

8. Place Autocomplete 추가하기

자동 완성 화면 만들기

LinearLayout이 있는 activity_autocomplete.xml 레이아웃이 app/src/main/res/layout/ 폴더에 제공됩니다. <LinearLayout> 대괄호 사이에 다음 코드를 추가하여 선형 레이아웃을 채웁니다.

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/autocomplete_fragment"
        android:background="@android:color/white"
        android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/autocomplete_response_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="16dp"
        android:textIsSelectable="true" />

이 코드는 AutocompleteSupportFragment 위젯과 TextView를 추가하여 응답의 정보를 표시합니다. 연결된 문자열은 src/main/res/values/strings.xml 파일에 정의됩니다.

자동 완성 활동 만들기

  1. src/main/java/com/google/codelabs/maps/placesdemo/ 폴더에 AutocompleteActivity.kt 파일을 만들고 다음 코드로 정의합니다.
class AutocompleteActivity : AppCompatActivity() {
    private lateinit var responseView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_autocomplete)

        // Set up view objects
        responseView = findViewById(R.id.autocomplete_response_content)
        val autocompleteFragment =
            supportFragmentManager.findFragmentById(R.id.autocomplete_fragment)
                    as AutocompleteSupportFragment
    }
}

이 코드는 활동을 레이아웃 파일에 정의한 뷰 및 AutocompleteSupportFramgent와 연결합니다.

  1. 그런 다음 사용자가 Place Autocomplete에서 표시하는 예상 검색어 중 하나를 선택할 때 발생하는 결과를 정의합니다. 이 코드를 onCreate 함수의 끝에 추가합니다.
        // Specify the types of place data to return.
        autocompleteFragment.setPlaceFields(listOf(Place.Field.NAME, Place.Field.ID, Place.Field.LAT_LNG, Place.Field.ADDRESS))

        // Listen to place selection events
        lifecycleScope.launchWhenCreated {
            autocompleteFragment.placeSelectionEvents().collect { event ->
                when (event) {
                    is PlaceSelectionSuccess -> {
                        val place = event.place
                        responseView.text = StringUtil.stringifyAutocompleteWidget(place, false)
                    }
                    is PlaceSelectionError -> Toast.makeText(
                        this@AutocompleteActivity,
                        "Failed to get place '${event.status.statusMessage}'",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }

이 코드는 장소에 대해 요청할 입력란을 정의하고, 장소 선택 이벤트를 수신하고, 성공 또는 실패 여부를 수신합니다. 요청에 성공하면 함수에서는 장소 세부정보로 TextView를 채웁니다. Place Autocomplete는 장소 객체를 반환합니다. Place Autocomplete 위젯을 사용하면 장소 세부정보를 별도로 요청할 필요가 없습니다.

매니페스트에 자동 완성 활동 추가하기

AutocompleteActivity<activity> 요소를 app/src/main에 있는 AndroidManifest.xml 파일에서 <application> 요소의 하위 요소로 추가합니다.

        <activity android:name=".AutocompleteActivity" />

데모 메뉴에 자동 완성 활동 추가하기

전과 마찬가지로 Place Autocomplete 데모를 Demo 모듈의 목록에 추가하여 홈 화면에 추가합니다. 이제 Place Autocomplete 활동을 만들었으므로 src/main/java/com/google/codelabs/maps/placesdemo/ 폴더의 Demo.kt 파일에 추가합니다. DETAILS_FRAGMENT_DEMO 항목 바로 뒤에 다음 코드를 붙여넣습니다.

    AUTOCOMPLETE_FRAGMENT_DEMO(
        R.string.autocomplete_fragment_demo_title,
        R.string.autocomplete_fragment_demo_description,
        AutocompleteActivity::class.java
    ),

연결된 문자열은 src/main/res/values/strings.xml 파일에 정의됩니다.

앱 실행

  1. 앱을 실행합니다. 이번에는 홈 화면 목록에 두 개의 항목이 표시됩니다.
  2. Place Autocomplete 행을 탭합니다. 그림 2와 같이 Place Autocomplete 입력 팝업이 표시됩니다.
  3. 장소의 이름을 입력합니다. 시설 이름, 주소 또는 지역을 입력할 수 있습니다. 입력 내용에 따라 예상 검색어가 표시됩니다.
  4. 예상 검색어 중 하나를 선택합니다. 그림 3과 같이 예상 검색어가 사라지고 이제 TextView에는 선택된 장소에 대한 세부정보가 표시됩니다.

사용자가 입력란을 탭한 후 자동 완성 활동

그림 2. 사용자가 입력란을 탭한 후 자동 완성 활동

사용자가 &ldquo;Niagara Falls&rdquo;를 입력 및 선택한 후 자동 완성 활동

그림 3. 사용자가 'Niagara Falls'를 입력 및 선택한 후 자동 완성 활동

9. 기기의 현재 장소 가져오기

현재 장소 화면 만들기

LinearLayout이 있는 activity_current.xml 레이아웃이 app/src/main/res/layout/ 폴더에 제공됩니다. <LinearLayout> 대괄호 사이에 다음 코드를 추가하여 선형 레이아웃을 채웁니다.

    <Button
        android:id="@+id/current_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/current_button" />

    <TextView
        android:id="@+id/current_response_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="16dp"
        android:scrollbars = "vertical"
        android:textIsSelectable="true" />

현재 장소 활동 만들기

  1. src/main/java/com/google/codelabs/maps/placesdemo/ 폴더에 CurrentActivity.kt 파일을 만들고 다음 코드로 정의합니다.
class CurrentPlaceActivity : AppCompatActivity() {
    private lateinit var placesClient: PlacesClient
    private lateinit var currentButton: Button
    private lateinit var responseView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_current)

        // Retrieve a PlacesClient (previously initialized - see DemoApplication)
        placesClient = Places.createClient(this)

        // Set view objects
        currentButton = findViewById(R.id.current_button)
        responseView = findViewById(R.id.current_response_content)

        // Set listener for initiating Current Place
        currentButton.setOnClickListener {
            checkPermissionThenFindCurrentPlace()
        }
    }
}

이 코드는 활동을 레이아웃 파일에 정의한 뷰와 연결합니다. 버튼이 클릭되면 checkPermissionThenFindCurrentPlace 함수를 호출하는 버튼에 클릭 리스너도 추가됩니다.

  1. checkPermissionThenFindCurrentPlace()를 정의하여 정확한 위치 정보 액세스 권한을 확인하고 아직 부여되지 않은 경우 권한을 요청합니다. onCreate 함수 뒤에 다음 코드를 붙여넣습니다.
    /**
     * Checks that the user has granted permission for fine or coarse location.
     * If granted, finds current Place.
     * If not yet granted, launches the permission request.
     * See https://developer.android.com/training/permissions/requesting
     */
    private fun checkPermissionThenFindCurrentPlace() {
        when {
            (ContextCompat.checkSelfPermission(
                this,
                ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
                this,
                ACCESS_COARSE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED) -> {
                // You can use the API that requires the permission.
                findCurrentPlace()
            }
            shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)
            -> {
                Log.d(TAG, "Showing permission rationale dialog")
                // TODO: In an educational UI, explain to the user why your app requires this
                // permission for a specific feature to behave as expected. In this UI,
                // include a "cancel" or "no thanks" button that allows the user to
                // continue using your app without granting the permission.
            }
            else -> {
                // Ask for both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION
                    ),
                    PERMISSION_REQUEST_CODE
                )
            }
        }
    }

    companion object {
        private val TAG = "CurrentPlaceActivity"
        private const val PERMISSION_REQUEST_CODE = 9
    }
  1. checkPermissionThenFindCurrentPlace 함수의 else 브랜치에서 requestPermissions를 호출하면 앱에서 사용자에게 권한 요청 대화상자를 표시합니다. OS 버전이 Android 12보다 낮은 기기를 실행 중인 사용자는 정확한 위치 정보 액세스 권한만 부여할 수 있습니다. Android 12 이상을 실행하는 기기를 사용하는 사용자는 그림 4와 같이 정확한 위치 대신 대략적인 위치 권한을 부여할 수 있습니다.

Android 12 이상을 실행하는 기기에서의 사용자 권한 요청

그림 4. Android 12 이상을 실행하는 기기에서 사용자 권한을 요청하면 정확한 위치 또는 대략적인 위치 권한을 부여할 수 있는 옵션이 표시됩니다.

사용자가 시스템 권한 대화상자에 응답하면 시스템은 앱의 onRequestPermissionsResult 구현을 호출합니다. 시스템에서는 사용자 응답과 정의된 요청 코드를 권한 대화상자에 전달합니다. checkPermissionThenFindCurrentPlace 아래에 다음 코드를 붙여넣어 onRequestPermissionResult를 재정의하고 이 장소 활동과 관련된 위치 정보 액세스 권한의 요청 코드를 처리하세요.

    @SuppressLint("MissingPermission")
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>, grantResults: IntArray
    ) {
        if (requestCode != PERMISSION_REQUEST_CODE) {
            super.onRequestPermissionsResult(
                requestCode,
                permissions,
                grantResults
            )
            return
        } else if (permissions.toList().zip(grantResults.toList())
                .firstOrNull { (permission, grantResult) ->
                    grantResult == PackageManager.PERMISSION_GRANTED && (permission == ACCESS_FINE_LOCATION || permission == ACCESS_COARSE_LOCATION)
                } != null
        )
            // At least one location permission has been granted, so proceed with Find Current Place
            findCurrentPlace()
    }
  1. 권한이 부여되면 findCurrentPlace 함수가 실행됩니다. onRequestPermissionsResult 함수 뒤에 다음 코드를 사용하여 함수를 정의합니다.
    /**
     * Fetches a list of [PlaceLikelihood] instances that represent the Places the user is
     * most
     * likely to be at currently.
     */
    @RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])
    private fun findCurrentPlace() {
        // Use fields to define the data types to return.
        val placeFields: List<Place.Field> =
            listOf(Place.Field.NAME, Place.Field.ID, Place.Field.ADDRESS, Place.Field.LAT_LNG)

        // Use the builder to create a FindCurrentPlaceRequest.
        val request: FindCurrentPlaceRequest = FindCurrentPlaceRequest.newInstance(placeFields)

        // Call findCurrentPlace and handle the response (first check that the user has granted permission).
        if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) ==
            PackageManager.PERMISSION_GRANTED ||
            ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) ==
            PackageManager.PERMISSION_GRANTED
        ) {
            // Retrieve likely places based on the device's current location
            lifecycleScope.launch {
                try {
                    val response = placesClient.awaitFindCurrentPlace(placeFields)
                    responseView.text = response.prettyPrint()

                    // Enable scrolling on the long list of likely places
                    val movementMethod = ScrollingMovementMethod()
                    responseView.movementMethod = movementMethod
                } catch (e: Exception) {
                    e.printStackTrace()
                    responseView.text = e.message
                }
            }
        } else {
            Log.d(TAG, "LOCATION permission not granted")
            checkPermissionThenFindCurrentPlace()

        }
    }

이 코드는 예상 장소에 요청할 필드를 정의하고 FindCurrentPlaceRequest를 만들고, 작업을 시작하고, 요청한 세부정보로 TextView를 채웁니다.

  1. 확장 함수를 정의하여 FindCurrentPlaceResponse를 텍스트로 변환합니다. Places SDK 응답을 사람이 읽을 수 있는 문자열로 쉽게 변환할 수 있도록 StringUtil.kt 파일이 제공됩니다.

CurrentPlaceActivity.kt 파일의 끝에서 현재 장소 응답 객체를 문자열로 변환하는 함수를 정의합니다.

fun FindCurrentPlaceResponse.prettyPrint(): String {
    return StringUtil.stringify(this, false)
}

매니페스트에 현재 장소 활동 추가하기

CurrentPlaceActivity<activity> 요소를 app/src/main에 있는 AndroidManifest.xml 파일에서 <application> 요소의 하위 요소로 추가합니다.

        <activity android:name=".CurrentPlaceActivity" />

데모 메뉴에 현재 장소 활동 추가하기

전과 마찬가지로 현재 장소 데모를 Demo 모듈의 목록에 추가하여 홈 화면에 추가합니다. 이제 현재 장소 활동을 만들었으므로 src/main/java/com/google/codelabs/maps/placesdemo/ 폴더의 Demo.kt 파일에 추가합니다. AUTOCOMPLETE_FRAGMENT_DEMO 항목 바로 뒤에 다음 코드를 붙여넣습니다.

    CURRENT_FRAGMENT_DEMO(
        R.string.current_demo_title,
        R.string.current_demo_description,
        CurrentPlaceActivity::class.java
    ),

연결된 문자열은 src/main/res/values/strings.xml 파일에 정의됩니다.

앱 실행

  1. 앱을 실행합니다. 이번에는 홈 화면 목록에 세 개의 항목이 표시됩니다.
  2. 현재 장소 행을 탭합니다. 화면에 버튼이 표시됩니다.
  3. 버튼을 탭합니다. 이전에 이 앱에 위치 정보 액세스 권한을 부여하지 않은 경우 권한 요청이 팝업으로 표시됩니다.
  4. 앱에 기기의 위치에 액세스할 수 있는 권한을 부여합니다.
  5. 버튼을 다시 탭합니다. 이번에는 그림 5와 같이 최대 20개의 주변 장소와 노출 가능성이 포함된 목록이 표시됩니다.

기기의 보고된 위치와 일치할 가능성이 있는 현재 장소 표시

그림 5. 기기의 보고된 위치와 일치할 가능성이 있는 현재 장소 표시

10. 축하합니다

Android용 Places SDK를 사용하여 Android 앱을 성공적으로 빌드하셨습니다.

학습한 내용

다음 단계

  • 더 많은 아이디어를 얻으려면 샘플 및 데모의 android-places-demos GitHub 저장소를 탐색하거나 포크하세요.
  • Google Maps Platform으로 Android 앱을 빌드하는 방법은 추가 Kotlin Codelab에서 알아보세요.
  • 다음 질문에 답하여 Google에서 가장 유용한 콘텐츠를 만들 수 있도록 도와주세요.

다른 Codelab에서 어떤 내용을 다뤘으면 하시나요?

지도에서의 데이터 시각화 내 지도의 스타일 맞춤설정에 관한 추가 정보 지도에서 3D 상호작용 빌드하기

원하는 Codelab이 나와 있지 않나요? 여기에서 새로운 문제로 요청하세요.