使用 Google 地圖平台 Navigation SDK 建構簡易的 Android 導航應用程式

使用 Google 地圖平台 Navigation SDK 建構簡易的 Android 導航應用程式

程式碼研究室簡介

subject上次更新時間:10月 10, 2024
account_circle作者:Ed Boiling

1. 事前準備

本程式碼研究室將說明如何建立簡單的 Android 應用程式,使用 Google 地圖平台導航 SDK 前往預先設定的目的地。

完成後,應用程式會如下所示。

b6c535afde7abd20.png

  • 具備使用 Kotlin 進行基本 Android 應用程式開發作業的知識
  • 對 Google Maps SDK 的基本概念 (例如地圖、位置、座標) 有一定程度的瞭解。

課程內容

  • 如何建立簡易的 Android 應用程式,以使用 Navigation SDK 前往目的地。
  • 如何從遠端 Google Maven 存放區整合 Navigation SDK
  • 如何根據 Navigation SDK 使用者條款,管理位置存取權和使用者協議
  • 如何初始化 SDK
  • 如何設定目的地並開始導航指引。

軟硬體需求

  • 已安裝最新的穩定版 Android Studio。本程式碼研究室是使用 Android Studio Jellyfish 建立的。如果您使用其他版本,介面和元件的外觀和版面配置可能會有所不同。
  • Google 帳戶和專案已啟用計費功能。
  • 處於開發人員模式且已啟用 USB 偵錯功能的 Android 裝置,或 Android 模擬器。無論您選擇哪個版本,都必須符合 Navigation SDK 的最低要求

2. 做好準備

如果您還沒有 Google Cloud Platform 帳戶,也還沒有已啟用計費功能的專案,請按照「Google 地圖平台入門」操作說明 (https://developers.google.com/maps/gmp-get-started) 設定 Google Cloud 專案。

在主控台中選取您的 Google Cloud 專案

Cloud 控制台中,按一下專案下拉式選單,然後選取要用於這個程式碼研究室的專案。

Google Cloud 控制台中的專案選取器下拉式選單。

在專案中啟用 Navigation SDK

Google Cloud Marketplace 中啟用本程式碼研究室所需的 Google 地圖平台 API 和 SDK。

前往 API,然後服務 >Google Cloud 控制台中的程式庫,並搜尋「Navigation SDK」。

畫面上應會顯示一個搜尋結果。

Google Cloud 控制台的 API 程式庫畫面,顯示 Navigation SDK 頁面。

按一下 Navigation SDK 結果,開啟「產品詳細資料」頁面。按一下「啟用」按鈕,在專案上啟用 SDK。

針對 Google Maps SDK for Android 重複這個程序。

建立 API 金鑰

在 Cloud 控制台的「憑證」頁面中產生 API 金鑰。您可按照「開始使用 Google 地圖平台」中快速入門導覽課程一節的步驟 3 操作。所有傳送至 Google 地圖平台的要求都需要 API 金鑰。

3. 取得範例專案檔案

本節說明如何從本程式碼研究室的 GitHub 存放區複製檔案,藉此設定基本空白的 Android Studio 專案。GitHub 存放區包含程式碼研究室程式碼的舊版和新版。程式碼研究室會從空白專案範本開始,並建構至完成狀態。如果您遇到問題,可以參考存放區中已完成的專案。

複製這個 GitHub 存放區,取得本程式碼研究室的程式碼。

git clone https://github.com/googlemaps-samples/codelab-navigation-101-android-kotlin.git

如果尚未安裝 Git,請按一下這個按鈕取得程式碼:

為了讓您盡快開始學習,這個存放區在 Starter 資料夾中提供了一些範例程式碼,方便您跟著本程式碼研究室學習。這項 Starter 專案提供基本應用程式 UI 和建構設定,但未加入 Navigation SDK。您也可以完成已完成的 Solution 專案,以便繼續操作或隨時查看進度。

在 Android Studio 中開啟複製的存放區

在本機複製存放區後,請使用 Android Studio 將 Starter 資料夾當做現有專案開啟。

  1. 在「Welcome to Android Studio」對話方塊中,按一下「Open」按鈕。
  2. 前往儲存複製的儲存庫的資料夾,然後選取頂層「codelab-navigation-101-android-kotlin」資料夾中的 Starter 資料夾。
  3. 確認專案可順利建構並執行。

新增虛擬裝置或連結硬體裝置

如要將 Android 裝置連接至電腦,請按照 Android Studio 的在硬體裝置上執行應用程式說明操作。您也可以使用 Android 虛擬裝置管理工具 (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」(檔案) > 中的對話方塊,修改這個變數和其他變數的值專案架構 >變數:

668332736b67dc82.png

在建構設定中新增依附元件

現在,請將下列 API 依附元件新增至應用程式層級的依附元件區塊。build.gradle.kts.所使用的版本會是您剛在應用程式層級 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_KEYsecrets.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.propertiesdefaultPropertiesFileName 則應讀取 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 新增啟動活動

應用程式開始執行時,應用程式需要在啟動期間執行的程式碼來檢查使用者是否已授予存取位置資訊的權限,並處理所有可能情境 (如果尚未授予權限)。如要這麼做,請在應用程式中新增基本使用者介面。本程式碼研究室會使用您在 Android Studio 中建立空白 View 活動時所建立的 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

將名為 onLocationPermissionGranted 的新函式新增至 MainActivity 類別,該類別會在使用者授予分享位置的權限時處理結果。在後續步驟中,我們會在此新增程式碼,啟動新的導覽活動。

private fun onLocationPermissionGranted() {
   //code to initialize Navigation SDK will go here
}

建構專案。如果有任何建構錯誤,請找出並修正。

在新的虛擬裝置上執行專案。應用程式安裝及啟動時,您應會看到權限要求對話方塊。

6. 新增導覽使用者介面

新增 Navigation UI 的方法有兩種:SupportNavigationFragmentNavigationView

為了方便起見,本程式碼研究室會使用 NavigationView

編輯版面配置

編輯 res/layout/activity_main.xml 為 NavigationView 新增版面配置。

  1. 開啟檔案並切換至程式碼檢視模式。
  2. 將檔案的整個內容,替換為 RelativeLayoutNavigationView 的新版面配置,如以下範例所示。您只需要在應用程式中新增導覽檢視畫面,就可以採用簡單的版面配置。
  3. 請為 NavigationView 指定 ID「@+id/navigation_view」。
<?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>

設定 Navigation 活動

在 Android Studio 中,在編輯器中開啟 MainActivity.kt 檔案。

請新增一些基本設定程式碼,確保應用程式中的導航功能正常運作。在 MainActivity.kt 檔案中進行下列變更:

  1. MainActivity 類別中宣告變數,以便參照 NavigationView
private lateinit var navView: NavigationView
  1. 請在 onCreate() 方法中加入一些程式碼,取得 NavigationView 的參照:
navView = findViewById(R.id.navigation_view)
navView.onCreate(savedInstanceState)
  1. 請在 onCreate() 方法中新增一些程式碼,確保導航指引期間螢幕保持開啟:
// Ensure the screen stays on during nav.
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
  1. 編輯呼叫 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
}
  1. 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() 並實作 NavigatorListener 來處理回呼,藉此取得 Navigator 物件的參照。

請注意,當 Navigation API 初始化時,系統會叫用 NavigationListener.onNavigatorReady 方法,並將 Navigator 物件傳遞做為參數。上述程式碼會使用傳遞至此方法的初始化 Navigator 物件,更新您先前宣告的 mNavigator 變數。

最後,透過 onLocationPermissionGranted 方法新增對 initializeNavigationApi 方法的呼叫。

private fun onLocationPermissionGranted() {
   initializeNavigationApi()
}

8. 新增主要導覽事件的監聽器

當使用者遵循指示時,Navigation SDK 會觸發事件,以便在路途上通知應用程式關鍵狀態變更,例如使用者重新導航或抵達目的地時。在 MainActivity.kt 檔案中,新增事件監聽器來處理這些事件:

  1. MainActivity 類別中,宣告兩個變數來參照事件監聽器物件:
private var arrivalListener: Navigator.ArrivalListener? = null
private var routeChangedListener: Navigator.RouteChangedListener? = null
  1. 新增 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)
   }
}
  1. 請在 initializeNavigationApi 方法的 onNavigatorReady 回呼程式碼中,新增對 registerNavigationListeners() 的呼叫:
override fun onNavigatorReady(navigator: Navigator) {
   // store a reference to the Navigator object
   mNavigator = navigator

   //listen for events en route
   registerNavigationListeners()


}
  1. 設定使用者介面。執行指引時,您可以控制導覽使用者介面的各個層面。其中一個重要的自訂選項是攝影機位置。如以下所示,新增對 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)
  1. 新增對 GoogleMap.followMyLocation 的呼叫,以指定 CameraPerspective。您可以透過 NavigatorView.getMapAsync() 方法存取 GoogleMap,如下所示:
navView.getMapAsync {
   googleMap  ->
   googleMap.followMyLocation(GoogleMap.CameraPerspective.TILTED)
}
  1. 為確保導覽在應用程式的生命週期中正常運作,請在 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 檔案中進行下列變更:

  1. 新增 navigateToPlace() 方法,用於設定導覽目的地,並接受 placeId 參數。
/**
* Requests directions from the user's current location to a specific place (provided by the
* Place ID).
*/
private fun navigateToPlace(placeId: String) {

}
  1. navigateToPlace() 方法中,使用 Waypoint.builder() 方法,根據傳遞至方法的 Place 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
}
  1. 將下列程式碼新增至 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。預設的交通模式為 DRIVING,適合四輪車輛。setDestinations() 方法會傳回包含 RouteStatus 物件的 ListenableResultFuture 物件。RouteStatus 會指出系統是否找到路線至目的地,如果不需要,則可處理各種錯誤狀態。

  1. 進行其他設定變更,改善導覽使用者體驗:
// 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 騰出空間。
  • 啟用語音導引,聽取快訊和導航指示。
  • 指定速度調節係數,設定模擬器以便進行偵錯。
  1. 找出要用做目的地的 Place ID。在理想情況下,這項資訊不會太遠。使用 Google 地圖平台地點 ID 尋找工具,或透過 Places API 呼叫取得地點 ID。

如果要模擬導航,可以在程式碼中設定使用者位置,或透過已連結的裝置擷取使用者位置。本程式碼研究室會假設您要模擬位於英國倫敦的某個地點。

  1. 請在 MainActivity 類別中新增伴隨物件,以便儲存起始位置和地點 ID。本程式碼研究室會使用倫敦的起點位置和特拉法加廣場的地點 ID:
companion object{
   const val TRAFALGAR_SQUARE ="ChIJH-tBOc4EdkgRJ8aJ8P1CUxo" //London, UK
   val startLocation = LatLng(51.345678, -0.1234456)
}
  1. 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 個目的地後產生費用。詳情請參閱「用量與計費」一文。

93aa433000a14dfc.png

Navigation SDK 使用者條款對話方塊。

設定位置

根據預設,模擬裝置的位置可能會設為加州山景市 Google 校園,除非您在程式碼中或使用模擬器的屬性對話方塊中設定位置。

若是如此,您可能會發現應用程式找不到前往所設地點 ID 的路線 (根據預設,澳洲雪梨歌劇院)。系統會透過 showToast() 方法顯示「找不到路線」訊息,指出這項情況。

導航應用程式地圖檢視畫面,顯示加州山景城的 Google 辦公室。

硬式編碼起始位置

如要在程式碼中設定其他位置,請在 MainActivity.kt 的 navigateToPlace() 方法中加入下列行程式碼,並在呼叫 mNavigator.startGuidance() 之前執行:

mNavigator?.simulator?.setUserLocation(startLocation)

在您選擇的預設位置啟動模擬器

如要在裝置模擬器中設定其他位置,如果模擬器尚未執行,請啟動該模擬器,然後按一下含有「Extended Controls」工具提示的三點選單。隨即開啟的對話方塊會顯示「位置」選單選項。

舉例來說,如果您使用雪梨歌劇院的地點 ID 做為目的地,請選擇澳洲雪梨的地點。舉例來說,您可以搜尋「Bondi Beach」,然後選取建議的回覆,再按一下 [儲存地點]。你也可以按一下「儲存點」將地點加入已儲存清單,以供日後使用。

Android 裝置管理工具中的「Extended Controls」對話方塊,顯示以澳洲 Bondi 海灘為中心的地點挑選器和地圖。

如果您將不同的地點 ID 設為目的地,請選擇附近的地點,讓系統能實際規劃模擬路線,且不會因為太久而易於偵錯。

重新啟動應用程式,且應用程式現在應導覽至目的地。

導航應用程式提供前往目的地的路線指引的螢幕截圖。

11. 恭喜!

您已完成本程式碼研究室。你已抵達目的地,祝您程式設計一切順利 :-)

55812f33256c0596.png

12. 後續步驟

如要進一步開發應用程式,請參考下列主題尋找靈感。