1. 시작하기 전에
이 Codelab에서는 Google Maps Platform Navigation SDK를 사용하여 미리 구성된 목적지로 이동하는 간단한 Android 앱을 만드는 방법을 알아봅니다.
완료되면 앱은 다음과 같이 표시됩니다.

기본 요건
- Kotlin을 사용한 기본 Android 앱 개발에 관한 지식
- 지도, 위치, 좌표와 같은 기본적인 Google Maps SDK 개념에 관한 어느 정도의 지식
학습할 내용
- Navigation SDK를 사용하여 목적지로 이동하는 간단한 Android 앱을 만드는 방법
- 원격 Google Maven 저장소에서 Navigation SDK를 통합하는 방법
- Navigation SDK 최종 사용자 약관에 따른 위치 정보 사용 권한 및 사용자 동의를 관리하는 방법
- SDK를 초기화하는 방법
- 목적지를 설정하고 내비게이션 안내를 시작하는 방법
필요한 항목
- Android 스튜디오의 최신 안정화 버전이 설치되어 있어야 합니다. 이 Codelab은 Android 스튜디오 Jellyfish를 사용하여 만들었습니다. 다른 버전을 사용하는 경우 인터페이스와 구성요소의 모양과 레이아웃이 다를 수 있습니다.
- 결제가 사용 설정된 Google 계정 및 프로젝트
- 개발자 모드에 있고 USB 디버깅이 사용 설정된 Android 기기 또는 Android 에뮬레이터 어떤 방법을 선택하든 Navigation SDK의 최소 요구사항을 충족해야 합니다.
2. 설정
Google Cloud Platform 계정 및 결제가 사용 설정된 프로젝트가 없는 경우 Google Maps Platform 시작하기 안내(https://developers.google.com/maps/gmp-get-started)에 따라 Google Cloud 프로젝트를 설정합니다.
콘솔에서 Google Cloud 프로젝트를 선택합니다.
Cloud Console에서 프로젝트 드롭다운 메뉴를 클릭하고 이 Codelab에 사용할 프로젝트를 선택합니다.

프로젝트에서 Navigation SDK 사용 설정
Google Cloud Marketplace에서 이 Codelab에 필요한 Google Maps Platform API 및 SDK를 사용 설정합니다.
Google Cloud 콘솔에서 API 및 서비스 > 라이브러리로 이동하여 'Navigation SDK'를 검색합니다.
검색 결과가 하나 표시됩니다.

Navigation SDK 결과를 클릭하여 제품 세부정보 페이지를 엽니다. 사용 설정 버튼을 클릭하여 프로젝트에서 SDK를 사용 설정합니다.
Android용 Google Maps SDK에 대해서도 이 과정을 반복합니다.
API 키 만들기
Cloud Console의 사용자 인증 정보 페이지에서 API 키를 생성합니다. Google Maps Platform 시작하기의 빠른 시작 섹션에 있는 3단계를 따르세요. Google Maps Platform에 대한 모든 요청에는 API 키가 필요합니다.
3. 샘플 프로젝트 파일 가져오기
이 섹션에서는 이 Codelab의 GitHub 저장소에서 파일을 클론하여 기본 빈 Android 스튜디오 프로젝트를 설정하는 방법을 설명합니다. GitHub 저장소에는 Codelab 코드의 이전 버전과 이후 버전이 포함되어 있습니다. Codelab은 빈 프로젝트 템플릿으로 시작하여 완성된 상태로 빌드됩니다. 막히는 부분이 있으면 저장소의 완료된 프로젝트를 참고하세요.
이 GitHub 저장소를 클론하여 이 Codelab의 코드를 가져옵니다.
git clone https://github.com/googlemaps-samples/codelab-navigation-101-android-kotlin.git
git이 설치되어 있지 않은 경우 이 버튼을 클릭하여 코드를 가져오세요.
빠르게 시작할 수 있도록 저장소의 Starter 폴더에는 이 Codelab을 따라 하는 데 도움이 되는 시작 코드가 포함되어 있습니다. 스타터 프로젝트는 기본 앱 UI와 빌드 구성을 제공하지만 Navigation SDK가 추가되어 있지 않습니다. 언제든지 앞으로 건너뛰거나 진행 상황을 확인할 수 있도록 완성된 Solution 프로젝트도 있습니다.
Android 스튜디오에서 클론된 저장소 열기
저장소를 로컬로 클론한 후 Android 스튜디오를 사용하여 Starter 폴더를 기존 프로젝트로 엽니다.
- Welcome to Android Studio 대화상자에서 Open 버튼을 클릭합니다.
- 클론된 저장소를 저장한 폴더로 이동하여 최상위 '
codelab-navigation-101-android-kotlin' 폴더 내의Starter폴더를 선택합니다. - 프로젝트가 빌드되고 실행되는지 확인합니다.
가상 기기 추가 또는 하드웨어 기기 연결
Android 기기를 컴퓨터에 연결하려면 하드웨어 기기에서 앱 실행하기에 관한 Android 스튜디오 안내를 따르세요. 또는 Android Virtual Device (AVD) Manager를 사용하여 가상 기기를 구성할 수 있습니다. 에뮬레이터를 선택할 때 Google API가 포함된 이미지를 선택해야 합니다.
Android 스튜디오에서 실행 메뉴 옵션 또는 재생 버튼 아이콘을 클릭합니다. 표시되는 메시지에 따라 기기를 선택합니다.
4. 앱에 Navigation SDK 추가
프로젝트에 Navigation SDK 라이브러리 및 API 키 추가
앱에 Navigation SDK 라이브러리를 추가하려면 앱 수준 build.gradle.kts을 수정하여 Google Maven 저장소에서 Navigation SDK를 가져오고 버전 번호를 구성해야 합니다.
빌드 구성에서 Navigation SDK 버전 번호를 저장하는 변수를 만듭니다.
앱에서 사용되는 Navigation SDK 버전을 포함하도록 앱 수준 build.gradle.kts에 변수를 설정하여 나중에 최신 버전으로 쉽게 변경할 수 있습니다.
최신 버전 번호는 Navigation SDK 출시 노트를 참고하세요.
val navSdkVersion by extra("6.0.0")
파일 > 프로젝트 구조 > 변수에 있는 대화상자를 사용하여 이 변수와 다른 변수의 값을 수정할 수도 있습니다.

빌드 구성에 종속 항목 추가
이제 앱 수준 build.gradle.kts.의 종속 항목 블록에 다음 API 종속 항목을 추가합니다. 사용되는 버전은 앱 수준 build.gradle.kts에서 방금 설정한 ${navSdkVersion} 값입니다.
dependencies {
// Include the Google Navigation SDK.
api("com.google.android.libraries.navigation:navigation:${navSdkVersion}")
...
API 키 추가
Secrets Gradle 플러그인을 사용하여 API 키 관리
Secrets Gradle 플러그인을 사용하여 앱에서 API 키를 안전하게 관리하는 것이 좋습니다. 이 플러그인은 최상위 build.gradle.kts 파일에 종속 항목으로 초기 프로젝트 템플릿에 추가되었습니다.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") version "2.0.1" apply false
//... other plugin definitions here
}
최상위 수준 디렉터리에서 secrets.properties 파일을 연 후 YOUR_API_KEY을 API 키로 바꿉니다. secrets.properties가 버전 제어 시스템에 체크인되는 데서 제외되었으므로 키를 이 파일에 저장합니다.
MAPS_API_KEY=YOUR_API_KEY
이 주제에 관한 자세한 내용은 Navigation SDK 문서의 앱에 API 키 추가를 참고하세요.
local.defaults.properties의 콘텐츠 확인
빈 프로젝트에는 최상위 디렉터리(secrets.properties 파일과 동일한 폴더)에 local.defaults.properties 파일도 포함되어 있습니다. 열고 다음 코드를 확인합니다.
MAPS_API_KEY=DEFAULT_API_KEY
이는 secrets.properties이 프로젝트에 추가되지 않아 빌드가 실패하지 않도록 MAPS_API_KEY 속성의 백업 값을 제공하기 위해 존재합니다. 이 파일은 수정할 필요가 없습니다. MAPS_API_KEY의 secrets.properties 정의를 찾을 수 없는 경우 기본값으로 인해 런타임에 앱이 중지되고 API 키 오류가 발생합니다.
Android 매니페스트에서 지정한 API 키를 사용하고 있는지 확인
app/src/main/AndroidManifest.xml을 엽니다. MAPS_API_KEY 속성이 애플리케이션의 API 키를 설정하는 데 사용됩니다.
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
앱 수준 build.gradle.kts 파일을 열고 secrets 속성을 찾습니다.
플러그인의 propertiesFileName 설정은 secrets.properties로 설정해야 하고 defaultPropertiesFileName은 local.defaults.properties로 읽어야 합니다.
secrets {
// Optionally specify a different file name containing your secrets.
// The plugin defaults to "local.properties"
propertiesFileName = "secrets.properties"
// A properties file containing default secret values. This file can be
// checked in version control.
defaultPropertiesFileName = "local.defaults.properties"
}
모든 파일을 저장하고 프로젝트를 Gradle과 동기화합니다.
5. 앱 권한 구성 및 기본 UI 추가
정확한 위치 정보 액세스 권한 요청
Navigation SDK는 작동하기 위해 GPS 신호에 의존하므로 앱에서 사용자에게 정확한 위치 데이터에 대한 액세스 권한을 부여하도록 요청해야 합니다. Android 매니페스트의 <manifest> 요소의 하위 요소로 정확한 위치에 액세스할 수 있는 권한을 추가합니다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
/>
</manifest>
Android 위치 정보 액세스 권한에 관한 자세한 내용은 Android 개발자 문서의 위치 정보 액세스 권한 요청 섹션을 참고하세요.
Android 14 기기에서 앱을 실행하려면 정확한 위치 액세스 권한과 동일한 위치에 다음 uses-permission 태그를 추가하여 포그라운드 서비스 위치 정보 액세스 권한을 요청하세요.
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
기본 UI로 실행 활동 추가
앱이 실행되면 시작 중에 실행되는 코드가 사용자가 위치 정보 액세스 권한을 부여했는지 확인하고, 아직 부여되지 않은 경우 권한을 요청하여 가능한 각 시나리오를 처리해야 합니다. 이렇게 하려면 앱에 기본 사용자 인터페이스를 추가하세요. 이 Codelab에서는 Android 스튜디오에서 새 빈 Views 활동을 만들 때 생성되는 UI를 사용합니다. 탐색 UI의 활동에 코드를 추가하기 전에 위치 정보 액세스 권한 확인을 실행하도록 이를 적용합니다.
코드 편집기에서 MainActivity.kt 파일을 열고 기본 UI를 보여주는 코드를 검사합니다.
런타임에 위치 정보 액세스 권한 요청
앱은 Navigation SDK가 초기화되기 전에 정확한 위치에 액세스하는 요청을 트리거해야 합니다.
앱이 시작될 때 이 검사가 실행되도록 하려면 활동의 재정의된 onCreate() 메서드에서 MainActivity 클래스에 코드를 추가하세요.
다음 코드는 사용자가 상세한 위치 정보 액세스 권한을 부여했는지 확인합니다. 권한이 없다면 권한을 요청합니다. onCreate() 메서드 내에 다음 코드를 추가합니다.
val permissions =
if (VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {
arrayOf(permission.ACCESS_FINE_LOCATION, permission.POST_NOTIFICATIONS)
} else {
arrayOf(permission.ACCESS_FINE_LOCATION)
}
if (permissions.any { !checkPermissionGranted(it) }) {
if (permissions.any { shouldShowRequestPermissionRationale(it) }) {
// Display a dialogue explaining the required permissions.
}
val permissionsLauncher =
registerForActivityResult(
RequestMultiplePermissions(),
{ permissionResults ->
if (permissionResults.getOrDefault(permission.ACCESS_FINE_LOCATION, false)) {
onLocationPermissionGranted()
} else {
finish()
}
},
)
permissionsLauncher.launch(permissions)
} else {
android.os.Handler(Looper.getMainLooper()).postDelayed({ onLocationPermissionGranted() }, SPLASH_SCREEN_DELAY_MILLIS)
}
}
private fun checkPermissionGranted(permissionToCheck: String): Boolean =
ContextCompat.checkSelfPermission(this, permissionToCheck) == PackageManager.PERMISSION_GRANTED
사용자가 위치 공유 권한을 부여할 때 결과를 처리하는 onLocationPermissionGranted이라는 새 함수를 MainActivity 클래스에 추가합니다. 다음 단계에서는 여기에 코드를 추가하여 새 탐색 활동을 시작합니다.
private fun onLocationPermissionGranted() {
//code to initialize Navigation SDK will go here
}
프로젝트를 빌드합니다. 빌드 오류가 있으면 찾아 수정합니다.
새 가상 기기에서 프로젝트를 실행합니다. 앱이 설치되고 시작되면 권한 요청 대화상자가 표시됩니다.
6. 탐색 사용자 인터페이스 추가
탐색 UI를 추가하는 방법에는 SupportNavigationFragment 또는 NavigationView의 두 가지가 있습니다.
이 Codelab에서는 편의상 NavigationView을 사용합니다.
레이아웃 수정하기
res/layout/activity_main.xml을 수정하여 NavigationView의 레이아웃을 추가합니다.
- 파일을 열고 코드 보기로 전환합니다.
- 파일의 전체 콘텐츠를 아래 예와 같이
RelativeLayout내부에 있는NavigationView의 새 레이아웃으로 바꿉니다. 앱에 탐색 뷰만 추가하면 되므로 간단한 레이아웃으로 충분합니다. - NavigationView에 '
@+id/navigation_view' ID를 지정합니다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.libraries.navigation.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
탐색 활동 설정
Android 스튜디오에서 편집기의 MainActivity.kt 파일을 엽니다.
앱에서 탐색 환경이 올바르게 작동하도록 기본 설정 코드를 추가합니다. MainActivity.kt 파일에서 다음 변경사항을 적용합니다.
MainActivity클래스에서NavigationView를 참조하는 변수를 선언합니다.
private lateinit var navView: NavigationView
onCreate()메서드에 코드를 추가하여NavigationView에 대한 참조를 가져옵니다.
navView = findViewById(R.id.navigation_view)
navView.onCreate(savedInstanceState)
onCreate()메서드에 코드를 추가하여 내비게이션 안내 중에 화면이 계속 켜져 있도록 합니다.
// Ensure the screen stays on during nav.
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
ViewCompat.setOnApplyWindowInsetsListener를 호출하는 코드를 수정하여NavigationView의 ID를 참조합니다.
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.navigation_view)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
- 클래스에
showToast()메서드를 추가하여 사용자에게 피드백을 표시합니다.
private fun showToast(errorMessage: String) {
Toast.makeText(this@MainActivity, errorMessage, Toast.LENGTH_LONG).show()
}
7. Navigation SDK 초기화
이제 기본 탐색 활동 설정을 완료했으므로 Navigation SDK를 초기화할 수 있습니다. 이렇게 하려면 MainActivity.kt 파일에 다음 코드를 추가하세요.
/** Starts the Navigation API, capturing a reference when ready. */
@SuppressLint("MissingPermission")
private fun initializeNavigationApi() {
NavigationApi.getNavigator(
this,
object : NavigatorListener {
override fun onNavigatorReady(navigator: Navigator) {
// store a reference to the Navigator object
mNavigator = navigator
// code to start guidance will go here
}
override fun onError(@NavigationApi.ErrorCode errorCode: Int) {
when (errorCode) {
NavigationApi.ErrorCode.NOT_AUTHORIZED -> {
// Note: If this message is displayed, you may need to check that
// your API_KEY is specified correctly in AndroidManifest.xml
// and is been enabled to access the Navigation API
showToast(
"Error loading Navigation API: Your API key is " +
"invalid or not authorized to use Navigation."
)
}
NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED -> {
showToast(
"Error loading Navigation API: User did not " +
"accept the Navigation Terms of Use."
)
}
else -> showToast("Error loading Navigation API: $errorCode")
}
}
},
)
}
이 코드는 initializeNavigationApi()이라는 새 메서드를 만듭니다. 이 메서드는 NavigationApi.getNavigator()을 호출하여 Navigator 객체에 대한 참조를 가져오고 콜백을 처리하기 위해 NavigatorListener를 구현합니다.
Navigation API가 초기화되면 Navigator 객체가 매개변수로 전달되어 NavigationListener.onNavigatorReady 메서드가 호출됩니다. 위 코드는 이 메서드에 전달된 초기화된 Navigator 객체로 앞서 선언한 mNavigator 변수를 업데이트합니다.
마지막으로 onLocationPermissionGranted 메서드에서 initializeNavigationApi 메서드 호출을 추가합니다.
private fun onLocationPermissionGranted() {
initializeNavigationApi()
}
8. 키 탐색 이벤트 리스너 추가
사용자가 안내를 따르는 경우 Navigation SDK는 사용자가 경로를 변경하거나 목적지에 도착하는 등 이동 중에 발생하는 주요 상태 변경을 앱에 알릴 수 있는 이벤트를 발생시킵니다. MainActivity.kt 파일에서 이러한 이벤트를 처리하는 리스너를 추가합니다.
MainActivity클래스 내에서 이벤트 리스너 객체를 참조하는 두 변수를 선언합니다.
private var arrivalListener: Navigator.ArrivalListener? = null
private var routeChangedListener: Navigator.RouteChangedListener? = null
- Navigator가 초기화될 때 리스너를 설정하는
registerNavigationListeners()메서드를 추가합니다. 이 메서드는 도착 이벤트가 발생할 때Navigator.clearDestinations()를 호출하여NavigationView를 재설정합니다.
/**
* Registers a number of example event listeners that show an on screen message when certain
* navigation events occur (e.g. the driver's route changes or the destination is reached).
*/
private fun registerNavigationListeners() {
withNavigatorAsync {
arrivalListener =
Navigator.ArrivalListener { // Show an onscreen message
showToast("User has arrived at the destination!")
mNavigator?.clearDestinations()
}
mNavigator?.addArrivalListener(arrivalListener)
routeChangedListener =
Navigator.RouteChangedListener { // Show an onscreen message when the route changes
showToast("onRouteChanged: the driver's route changed")
}
mNavigator?.addRouteChangedListener(routeChangedListener)
}
}
initializeNavigationApi메서드의onNavigatorReady콜백 코드에서registerNavigationListeners()호출을 추가합니다.
override fun onNavigatorReady(navigator: Navigator) {
// store a reference to the Navigator object
mNavigator = navigator
//listen for events en route
registerNavigationListeners()
}
- 사용자 인터페이스를 구성합니다. 안내가 실행 중일 때 탐색 사용자 인터페이스의 다양한 측면을 제어할 수 있습니다. 중요한 맞춤설정 중 하나는 카메라 위치입니다. 다음과 같이
onNavigatorReady에서 반환된navigator객체의setTaskRemovedBehaviour메서드 호출을 추가합니다. 이렇게 하면 앱이 스와이프되어 닫힌 경우 안내와 알림이 종료됩니다.
// Disables the guidance notifications and shuts down the app and background service
// when the user dismisses/swipes away the app from Android's recent tasks.
navigator.setTaskRemovedBehavior(Navigator.TaskRemovedBehavior.QUIT_SERVICE)
GoogleMap.followMyLocation호출을 추가하여CameraPerspective을 지정합니다.GoogleMap는 다음과 같이NavigatorView.getMapAsync()메서드를 통해 액세스됩니다.
navView.getMapAsync {
googleMap ->
googleMap.followMyLocation(GoogleMap.CameraPerspective.TILTED)
}
- 앱 수명 주기 전반에서 탐색이 원활하게 작동하도록 하려면
MainActivity클래스에서 다음 메서드를 구현하세요.
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
navView.onSaveInstanceState(savedInstanceState)
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
navView.onTrimMemory(level)
}
override fun onStart() {
super.onStart()
navView.onStart()
}
override fun onResume() {
super.onResume()
navView.onResume()
}
override fun onPause() {
navView.onPause()
super.onPause()
}
override fun onConfigurationChanged(configuration: Configuration) {
super.onConfigurationChanged(configuration)
navView.onConfigurationChanged(configuration)
}
override fun onStop() {
navView.onStop()
super.onStop()
}
override fun onDestroy() {
navView.onDestroy()
withNavigatorAsync {
// Unregister event listeners to avoid memory leaks.
if (arrivalListener != null) {
navigator.removeArrivalListener(arrivalListener)
}
if (routeChangedListener != null) {
navigator.removeRouteChangedListener(routeChangedListener)
}
navigator.simulator?.unsetUserLocation()
navigator.cleanup()
}
super.onDestroy()
}
9. 대상 설정
이제 목적지를 설정하고 내비게이션 안내를 시작할 수 있습니다. MainActivity.kt 파일에서 다음과 같이 변경합니다.
- 탐색 대상을 설정하고
placeId매개변수를 허용하는 새navigateToPlace()메서드를 추가합니다.
/**
* Requests directions from the user's current location to a specific place (provided by the
* Place ID).
*/
private fun navigateToPlace(placeId: String) {
}
navigateToPlace()메서드에서Waypoint.builder()메서드를 사용하여 메서드에 전달된 장소 ID로부터Waypoint를 만듭니다. 장소 ID가 정확한 주소로 확인되지 않는 상황을 위해 이 예외가 발생할 수 있는UnsupportedPlaceIdException를 처리합니다.
val waypoint: Waypoint? =
// Set a destination by using a Place ID (the recommended method)
try {
Waypoint.builder().setPlaceIdString(placeId).build()
} catch (e: Waypoint.UnsupportedPlaceIdException) {
showToast("Place ID was unsupported.")
return
}
navigateToPlace()메서드에 다음 코드를 추가하여 경유지를 사용하여 목적지를 설정합니다.
val pendingRoute = mNavigator?.setDestination(waypoint)
// Set an action to perform when a route is determined to the destination
pendingRoute?.setOnResultListener { code ->
when (code) {
RouteStatus.OK -> {
// Code to start guidance will go here
}
RouteStatus.ROUTE_CANCELED -> showToast("Route guidance canceled.")
RouteStatus.NO_ROUTE_FOUND,
RouteStatus.NETWORK_ERROR ->
// TODO: Add logic to handle when a route could not be determined
showToast("Error starting guidance: $code")
else -> showToast("Error starting guidance: $code")
}
}
Navigator 객체에는 다양한 매개변수를 사용할 수 있는 setDestinations() 메서드가 있습니다. 가장 기본적인 옵션은 Waypoint를 제공하는 것입니다. 기본값은 4륜 자동차에 적합한 이동 수단인 DRIVING입니다. setDestinations() 메서드는 RouteStatus 객체가 포함된 ListenableResultFuture 객체를 반환합니다. RouteStatus는 목적지로 가는 경로가 발견되었는지 여부를 나타내며, 경로가 없는 경우 다양한 오류 상태를 처리할 수 있습니다.
- 탐색 사용자 환경을 개선하기 위해 추가 구성 변경을 실행합니다.
// Hide the toolbar to maximize the navigation UI
supportActionBar?.hide()
// Enable voice audio guidance (through the device speaker)
mNavigator?.setAudioGuidance(Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE)
// Simulate vehicle progress along the route (for demo/debug builds)
if (BuildConfig.DEBUG) {
mNavigator?.simulator?.simulateLocationsAlongExistingRoute(
SimulationOptions().speedMultiplier(5f)
)
}
이러한 변경사항에는 다음과 같은 개선사항이 포함됩니다.
- 탐색 UI의 공간을 최대화하기 위해 작업 표시줄을 숨깁니다.
- 알림 및 내비게이션 안내를 말하도록 오디오 안내를 사용 설정합니다.
- 속도 승수를 지정하여 디버깅을 위해 시뮬레이터를 설정합니다.
- 목적지 역할을 할 장소 ID를 찾습니다. 사용자 위치에서 너무 멀지 않은 것이 좋습니다. Google Maps Platform 장소 ID 찾기 유틸리티를 사용하거나 Places API 호출에서 장소 ID를 가져옵니다.
탐색을 시뮬레이션하는 경우 코드에서 사용자 위치를 설정하거나 연결된 기기에서 가져올 수 있습니다. Codelab에서는 영국 런던의 위치를 시뮬레이션한다고 가정합니다.
- 시작 위치와 장소 ID를 저장할
MainActivity클래스에 컴패니언 객체를 추가합니다. 이 Codelab에서는 런던의 시작 위치와 트라팔가 광장의 장소 ID를 사용합니다.
companion object{
const val TRAFALGAR_SQUARE ="ChIJH-tBOc4EdkgRJ8aJ8P1CUxo" //London, UK
val startLocation = LatLng(51.345678, -0.1234456)
}
initializeNavigationApi메서드 내의onNavigatorReady콜백에서navigateToPlace()메서드 호출을 추가하고 디버그 모드에서 실행되어 사용자 위치를 설정하는 로직 분기를 추가합니다.
// Disables the guidance notifications and shuts down the app and background service
// when the user dismisses/swipes away the app from Android's recent tasks.
navigator.setTaskRemovedBehavior(Navigator.TaskRemovedBehavior.QUIT_SERVICE)
mNavigator = navigator
if (BuildConfig.DEBUG) {
mNavigator?.simulator?.setUserLocation(MainActivity.startLocation)
}
//listen for events en route
registerNavigationListeners()
navView.getMapAsync {
googleMap ->
googleMap.followMyLocation(GoogleMap.CameraPerspective.TILTED)
}
//navigate to a destination
navigateToPlace(MainActivity.TRAFALGAR_SQUARE)
10. 코드 빌드 및 실행
앱을 처음 실행할 때는 앱에 위치 정보 액세스 권한을 부여하고 Navigation SDK 이용약관에 동의해야 합니다.
참고: 앱을 실행하면 setDestinations() 메서드가 호출되며, 처음 1,000개의 대상이 사용된 후에는 요금이 청구됩니다. 자세한 내용은 사용량 및 결제를 참고하세요.


위치 설정
기본적으로 에뮬레이터 속성 대화상자를 사용하거나 코드에서 위치를 설정하지 않은 경우 에뮬레이션된 기기의 위치가 캘리포니아주 마운틴뷰의 Google 캠퍼스로 설정될 수 있습니다.
이 경우 앱에서 구성한 장소 ID (기본값은 시드니 오페라 하우스, 시드니, 오스트레일리아)로 가는 경로를 찾을 수 없습니다. 이는 showToast() 메서드에 표시되는 '경로를 찾을 수 없음'이라는 메시지로 표시됩니다.

시작 위치 하드 코딩
코드에서 다른 위치를 설정하려면 mNavigator.startGuidance() 호출 전에 MainActivity.kt의 navigateToPlace() 메서드에 다음 줄을 추가하세요.
mNavigator?.simulator?.setUserLocation(startLocation)
원하는 기본 위치에서 에뮬레이터 시작
기기 에뮬레이터에서 다른 위치를 설정하려면 에뮬레이터가 아직 실행되지 않은 경우 에뮬레이터를 시작하고 도움말이 '확장 컨트롤'인 점 3개 메뉴를 클릭합니다. 열리는 대화상자에는 '위치' 메뉴 옵션이 있습니다.
예를 들어 시드니 오페라 하우스의 장소 ID를 대상으로 사용하는 경우 오스트레일리아 시드니의 위치를 선택합니다. 예를 들어 '본디 비치'를 검색하고 추천을 선택한 다음 대화상자의 오른쪽 하단에 있는 '위치 저장'을 클릭합니다. '저장 지점'을 클릭하여 나중에 사용할 수 있도록 저장된 목록에 위치를 추가할 수도 있습니다.

다른 장소 ID를 대상으로 설정하는 경우 시뮬레이션된 경로가 현실적이고 디버깅하기에 너무 길지 않도록 근처 위치를 선택하세요.
앱을 다시 시작하면 이제 목적지로 이동합니다.

11. 축하합니다.
이 Codelab을 완료했습니다. 잘하셨습니다. 목적지에 도착했습니다. 즐거운 코딩 되세요 :-)

12. 그 외 수행 가능한 작업
앱 개발을 더 진행하고 싶다면 다음 주제에서 아이디어를 얻으세요.
- 더 많은 탐색 이벤트 수신 대기 운전자가 경로를 변경하거나 도착할 때 메시지를 표시하는 코드를 추가합니다.
- 탐색 인터페이스를 맞춤설정합니다.
- 더 큰 도전을 원한다면 사용자가 목적지를 설정할 수 있도록 Places API 장소 선택 도구 컨트롤을 추가해 보세요. 힌트: GitHub의 Navigation SDK 데모 앱에는 샘플 구현이 있습니다.
- Github의 Navigation SDK 데모 앱에서 사용되는 접근 방식을 채택하여 Navigator 및 GoogleMap 객체를 비동기적으로 호출할 때 발생할 수 있는 문제를 방지합니다. 더 복잡한 앱 시나리오에서는 코드가 실행될 때 이러한 객체의 초기화가 완료되지 않았을 수 있습니다. 도움말: 매우 빠르게 구현하려면 MainActivity.kt 파일 끝에 InitializedNavScope 클래스를 추가하면 됩니다.