1. 始める前に
この Codelab では、Google Maps Platform Navigation SDK を使用して、事前に設定された目的地に移動する簡単な Android アプリを作成する方法を学びます。
完成したアプリの外観は次のようになります。

前提条件
- Kotlin による基本的な Android アプリ開発の知識
- 地図、位置情報、座標など、Google Maps SDK の基本概念をある程度理解している。
学習内容
- Navigation SDK を使用して目的地に移動するシンプルな Android アプリを作成する方法。
- リモートの Google Maven リポジトリから Navigation SDK を統合する方法
- Navigation SDK のエンドユーザー利用規約で位置情報の権限とユーザー契約を管理する方法
- SDK を初期化する方法
- 目的地を設定してナビゲーション ガイダンスを開始する方法。
必要なもの
- Android Studio の最新の安定版がインストールされている。この Codelab は Android Studio 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」を検索します。
検索結果が 1 件表示されます。
![Google Cloud コンソールの [API ライブラリ] 画面。Navigation SDK ページが表示されています。](https://codelabs.developers.google.com/static/codelabs/maps-platform/navigation-sdk-101-android/img/26a3150f17089deb.png?hl=ja)
Navigation SDK の結果をクリックして、[プロダクトの詳細] ページを開きます。[有効にする] ボタンをクリックして、プロジェクトで SDK を有効にします。
Google Maps SDK for Android についても、このプロセスを繰り返します。
API キーを作成する
Cloud Console の [認証情報] ページで API キーを生成します。Google Maps Platform スタートガイドのクイックスタート セクションの手順 3 をご覧ください。Google Maps Platform へのすべてのリクエストで API キーが必要になります。
3. サンプル プロジェクト ファイルを取得する
このセクションでは、この Codelab の GitHub リポジトリからファイルを複製して、基本的な空の Android Studio プロジェクトを設定する方法について説明します。Github リポジトリには、Codelab コードの変更前と変更後のバージョンが含まれています。この Codelab では、空のプロジェクト テンプレートから始めて、完成した状態まで構築します。行き詰まった場合は、リポジトリ内の完成したプロジェクトを参考にしてください。
この GitHub リポジトリのクローンを作成して、この Codelab のコードを取得します。
git clone https://github.com/googlemaps-samples/codelab-navigation-101-android-kotlin.git
git がインストールされていない場合は、次のボタンをクリックしてコードを取得します。
できるだけ早く演習を開始できるように、この Codelab で使用できるスターター コードが Starter フォルダに用意されています。スターター プロジェクトには基本的なアプリ UI とビルド構成が用意されていますが、Navigation SDK は追加されていません。また、いつでも先に進んだり、進捗状況を確認したりできるように、完成した Solution プロジェクトも用意されています。
Android Studio でクローンを作成したリポジトリを開く
リポジトリをローカルに複製したら、Android Studio を使用して Starter フォルダを既存のプロジェクトとして開きます。
- [Welcome to Android Studio] ダイアログで、[Open] ボタンをクリックします。
- クローンを作成したリポジトリを保存したフォルダに移動し、最上位の「
codelab-navigation-101-android-kotlin」フォルダ内のStarterフォルダを選択します。 - プロジェクトがビルドされて実行されることを確認します。
仮想デバイスを追加するか、ハードウェア デバイスを接続する
Android デバイスをパソコンに接続するには、ハードウェア デバイス上でのアプリの実行に関する Android Studio の手順に沿って操作します。または、Android Virtual Device(AVD)Manager を使用して仮想デバイスを設定することもできます。エミュレータを指定する際は、Google API を含むイメージを選択する必要があります。
Android Studio で、[Run] メニュー オプションまたはプレイボタン アイコンをクリックします。表示される指示に沿ってデバイスを選択します。
4. アプリに Navigation SDK を追加する
Navigation SDK ライブラリと API キーをプロジェクトに追加する
Navigation SDK ライブラリをアプリに追加するには、アプリレベルの build.gradle.kts を変更して、Google Maven リポジトリから Navigation SDK を取得し、バージョン番号を構成する必要があります。
ビルド構成に Navigation SDK のバージョン番号を保存する変数を作成します。
アプリレベルの build.gradle.kts に変数を設定して、アプリで使用する Navigation SDK のバージョン値を格納します。これにより、将来的に最新バージョンに簡単に変更できるようになります。
最新のバージョン番号については、Navigation SDK リリースノートをご覧ください。
val navSdkVersion by extra("6.0.0")
[File] > [Project Structure] > [Variables] にあるダイアログを使用して、この変数や他の変数の値を変更することもできます。

ビルド構成に依存関係を追加する
次に、アプリレベルの build.gradle.kts. の dependencies ブロックに次の API 依存関係を追加します。使用されるバージョンは、アプリレベルの build.gradle.kts で設定した ${navSdkVersion} の値になります。
dependencies {
// Include the Google Navigation SDK.
api("com.google.android.libraries.navigation:navigation:${navSdkVersion}")
...
API キーを追加する
Secrets Gradle プラグインを使用して API キーを管理する
アプリで API キーを安全に管理するには、Secrets Gradle プラグインを使用することをおすすめします。このプラグインは、最上位の 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 信号に依存して動作するため、アプリはユーザーに正確な位置情報データへのアクセス権の付与を求める必要があります。正確な位置情報にアクセスする権限を、AndroidManifest.xml の <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 Studio で新しい空の Views アクティビティを作成したときに作成される UI を使用します。これを適応させて、ナビゲーション UI のアクティビティにコードを追加する前に、位置情報の利用許可のチェックを行います。
コードエディタで MainActivity.kt ファイルを開き、基本的な UI を示すコードを確認します。
実行時に位置情報へのアクセス権限をリクエストする
アプリは、Navigation SDK が初期化される前に、正確な位置情報へのアクセスをリクエストする必要があります。
アプリの起動時にこのチェックが実行されるようにするには、Activity のオーバーライドされた 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
MainActivity クラスに onLocationPermissionGranted という新しい関数を追加します。この関数は、ユーザーが位置情報の共有を許可したときの結果を処理します。次の手順では、ここに新しいナビゲーション アクティビティを起動するコードを追加します。
private fun onLocationPermissionGranted() {
//code to initialize Navigation SDK will go here
}
プロジェクトをビルドします。ビルドエラーが発生した場合は、エラーを見つけて修正します。
新しい仮想デバイスでプロジェクトを実行します。アプリがインストールされて起動すると、権限リクエスト ダイアログが表示されます。
6. ナビゲーション ユーザー インターフェースを追加する
ナビゲーション UI を追加するには、SupportNavigationFragment または NavigationView の 2 つの方法があります。
この 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 Studio で、エディタで MainActivity.kt ファイルを開きます。
ナビゲーション エクスペリエンスがアプリ内で正しく機能するように、基本的な設定コードを追加します。MainActivity.kt ファイルで、次の変更を行います。
NavigationViewを参照する変数をMainActivityクラスで宣言します。
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 アクティビティの設定が完了したので、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 が初期化されると、NavigationListener.onNavigatorReady メソッドが呼び出され、Navigator オブジェクトがパラメータとして渡されます。上記のコードは、前に宣言した mNavigator 変数を、このメソッドに渡された初期化済みの Navigator オブジェクトで更新します。
最後に、onLocationPermissionGranted メソッドから initializeNavigationApi メソッドの呼び出しを追加します。
private fun onLocationPermissionGranted() {
initializeNavigationApi()
}
8. キー ナビゲーション イベントのリスナーを追加します。
ユーザーがガイダンスに従っている場合、Navigation SDK は、ユーザーがルートを変更したときや目的地に到着したときなど、ルート上の重要な状態の変化をアプリに通知できるイベントを発生させます。MainActivity.kt ファイルで、これらのイベントを処理するリスナーを追加します。
MainActivityクラス内で、イベント リスナー オブジェクトを参照する 2 つの変数を宣言します。
private var arrivalListener: Navigator.ArrivalListener? = null
private var routeChangedListener: Navigator.RouteChangedListener? = null
- Navigator が初期化されたときにリスナーを設定する
registerNavigationListeners()メソッドを追加します。このメソッドは、Arrival イベントがトリガーされたときに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()
}
- ユーザー インターフェースを構成します。ガイダンスの実行中に、ナビゲーション ユーザー インターフェースのさまざまな側面を制御できます。重要なカスタマイズの 1 つはカメラの位置です。次のように、
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 Place ID Finder ユーティリティを使用するか、Places API 呼び出しからプレイス ID を取得します。
ナビゲーションをシミュレートする場合は、コードでユーザーの位置を設定するか、接続されたデバイスから取得できます。この Codelab では、英国のロンドンの位置をシミュレートすることを前提としています。
MainActivityクラスにコンパニオン オブジェクトを追加して、開始位置とプレイス ID を保存します。この 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 キャンパスに設定されている可能性があります。
その場合、アプリが設定した Place ID(デフォルトではオーストラリアのシドニー オペラハウス)へのルートを見つけられないことがあります。これは、showToast() メソッドによって表示される「ルートが見つかりません」というメッセージで示されます。

開始位置をハードコードする
コードで別の場所を設定するには、MainActivity.kt の navigateToPlace() メソッドで、mNavigator.startGuidance() の呼び出しの前に次の行を追加します。
mNavigator?.simulator?.setUserLocation(startLocation)
選択したデフォルトの場所でエミュレータを起動する
デバイス エミュレータで別の位置を設定するには、エミュレータがまだ実行されていない場合は起動し、ツールチップ「拡張コントロール」が表示された 3 つのドットのメニューをクリックします。開いたダイアログに [位置情報] のメニュー オプションがあります。
たとえば、シドニー オペラハウスのプレイス ID を目的地として使用している場合は、オーストラリアのシドニーにある場所を選択します。たとえば、「ボンダイ ビーチ」を検索し、候補を選択して、ダイアログの右下にある [場所を保存] をクリックします。[Save Point] をクリックして、場所を保存済みリストに追加し、後で使用することもできます。
![Android デバイス マネージャーの [拡張コントロール] ダイアログ。場所選択ツールと、オーストラリアのボンダイ ビーチを中心とした地図が表示されている。](https://codelabs.developers.google.com/static/codelabs/maps-platform/navigation-sdk-101-android/img/c32cd294befb2da7.png?hl=ja)
別のプレイス ID を目的地として設定する場合は、シミュレートされたルートが現実的なものになり、デバッグが容易になるように、その近くの場所を選択します。
アプリを再起動すると、目的地に移動するようになります。

11. 完了
この Codelab は終了です。お疲れさまでした。目的地に到着しました。コーディングをお楽しみください。

12. さらに活用する
アプリ開発をさらに進めたい場合は、次のトピックを参考にしてください。
- その他のナビゲーション イベントをリッスンします。ドライバーがルートを変更した場合や到着した場合にメッセージを表示するコードを追加します。
- ナビゲーション インターフェースをカスタマイズします。
- さらに難しい課題に挑戦したい場合は、Places API の Place Picker コントロールを追加して、ユーザーが目的地を設定できるようにしてみてください。ヒント: GitHub の Navigation SDK デモアプリには、実装例があります。
- Github の Navigation SDK デモアプリで使用されているアプローチを採用して、Navigator オブジェクトと GoogleMap オブジェクトを非同期で呼び出す際に発生する可能性のある問題を回避します。より複雑なアプリのシナリオでは、コードの実行時にこれらのオブジェクトの初期化が完了していない可能性があります。ヒント: InitializedNavScope クラスを MainActivity.kt ファイルの最後に追加すると、実装を迅速に行うことができます。