1. לפני שמתחילים
במעבדה הזו תלמדו ליצור אפליקציית Android פשוטה שמשתמשת ב-Google Maps Platform Navigation SDK כדי לנווט ליעד שהוגדר מראש.
כך תיראה האפליקציה בסיום.
דרישות מוקדמות
- ידע בסיסי בפיתוח אפליקציות ל-Android ב-Kotlin
- היכרות מסוימת עם מושגים בסיסיים של Google Maps SDK, כמו מפות, מיקומים, קואורדינטות.
מה תלמדו
- איך יוצרים אפליקציית Android פשוטה שמשתמשת ב-Navigation SDK כדי לנווט ליעד.
- איך לשלב את Navigation SDK ממאגר Google Maven המרוחק
- איך מנהלים את הרשאות המיקום ואת הסכמת המשתמש באמצעות התנאים של Navigation SDK למשתמש קצה
- איך מפעילים את ה-SDK
- איך מגדירים יעד ומתחילים את הוראות הניווט
מה צריך להכין
- הגרסה היציבה האחרונה של Android Studio מותקנת. ה-Codelab הזה נוצר באמצעות Android Studio Jellyfish. אם משתמשים בגרסה שונה, המראה והפריסה של הממשק והרכיבים עשויים להשתנות.
- חשבון Google ופרויקט עם חיוב מופעל.
- מכשיר Android במצב פיתוח עם ניפוי באגים ב-USB מופעל, או אמולטור של Android. בכל מקרה, הגרסה צריכה לעמוד בדרישות המינימליות ל-Navigation SDK
2. להגדרה
אם עדיין אין לכם חשבון Google Cloud Platform ופרויקט שהחיוב מופעל בו, עליכם להגדיר את הפרויקט ב-Google Cloud לפי ההוראות במאמר https://developers.google.com/maps/gmp-get-started (תחילת העבודה עם הפלטפורמה של מפות Google).
בוחרים את הפרויקט ב-Google Cloud במסוף.
ב-Cloud Console, לוחצים על התפריט הנפתח של הפרויקט ובוחרים את הפרויקט שבו רוצים להשתמש ב-codelab הזה.
הפעלת Navigation SDK בפרויקט
מפעילים את ממשקי ה-API וערכות ה-SDK של הפלטפורמה של מפות Google הנדרשים לסדנת הקוד הזו ב-Google Cloud Marketplace.
ניווט לממשקי ה-API שירותים > בספרייה במסוף Google Cloud ומחפשים את Navigation SDK.
אמורה להופיע תוצאת חיפוש אחת.
לוחצים על התוצאה Navigation SDK כדי לפתוח את דף פרטי המוצר. יש ללחוץ על הלחצן 'הפעלה' כדי להפעיל את ה-SDK בפרויקט.
חוזרים על התהליך הזה עבור Google Maps SDK ל-Android.
יצירת מפתח API
יוצרים מפתח API בדף Credentials במסוף Cloud. אפשר לפעול לפי השלבים שמפורטים בשלב 3 בקטע 'תחילת העבודה' במאמר תחילת העבודה עם הפלטפורמה של מפות Google. כל הבקשות לפלטפורמה של מפות Google מחייבות מפתח API.
3. הורדת קבצים של פרויקטים לדוגמה
בקטע הזה מוסבר איך להגדיר פרויקט Android Studio ריק בסיסי על ידי שכפול קבצים מהמאגר ב-GitHub לצורך הקודלאב הזה. מאגר GitHub מכיל גרסאות לפני ואחרי גרסאות של קוד ה-Codelab. ה-Codelab יתחיל עם תבנית פרויקט ריקה ויסתיים עד למצב הסופי. אם נתקעת, אפשר להשתמש בפרויקט המוכן במאגר כחומר עזר.
כדי לקבל את הקוד של Codelab הזה, צריך לשכפל את המאגר הזה ב-Github.
git clone https://github.com/googlemaps-samples/codelab-navigation-101-android-kotlin.git
אם git לא מותקן, לוחצים על הלחצן הזה כדי לקבל את הקוד:
כדי לעזור לכם להתחיל במהירות האפשרית, המאגר מכיל קוד להתחלה בתיקייה Starter
שיעזור לכם לעקוב אחרי הקוד ב-Codelab הזה. הפרויקט למתחילים מספק ממשק משתמש בסיסי של אפליקציה והגדרות build, אבל לא נוסף אליו Navigation SDK. בנוסף, יש פרויקט Solution
שהסתיים, למקרה שיהיה ברצונך להתקדם או לבדוק את ההתקדמות שלך בכל שלב.
פתיחת המאגר המשובט ב-Android Studio
אחרי שמשכפלים את המאגר באופן מקומי, צריך להשתמש ב-Android Studio כדי לפתוח את התיקייה Starter
כפרויקט קיים.
- בתיבת הדו-שיח 'ברוך בואך אל Android Studio', לוחצים על הלחצן 'פתיחה'.
- עוברים לתיקייה שבה שמרת את המאגר המשוכפל ובוחרים את התיקייה
Starter
ברמה העליונה 'codelab-navigation-101-android-kotlin
' . - בודקים אם הפרויקט נוצר ופועל.
הוספת מכשיר וירטואלי או חיבור של מכשיר חומרה
כדי לחבר מכשיר Android למחשב, פועלים לפי ההוראות של Android Studio להפעלת אפליקציות במכשיר חומרה. לחלופין, אפשר להגדיר מכשיר וירטואלי באמצעות מנהל מכשיר Android וירטואלי (AVD). כשבוחרים אמולטור, חשוב לבחור תמונה שכוללת את Google APIs.
ב-Android Studio, לוחצים על אפשרות התפריט 'הפעלה' או על סמל לחצן ההפעלה. בוחרים מכשיר בהתאם להנחיה.
4. הוספת Navigation SDK לאפליקציה
הוספה של ספריית ה-SDK לניווט ומפתח ה-API לפרויקט
כדי להוסיף את ספריית הניווט SDK לאפליקציה, צריך לשנות את רמת האפליקציה build.gradle.kts
כדי לאחזר את ה-Navigation SDK ממאגר Google Maven ולהגדיר מספר גרסה.
יוצרים משתנה בהגדרת ה-build כדי לשמור את מספר הגרסה של Navigation SDK.
מגדירים משתנה ב-build.gradle.kts
ברמת האפליקציה, כך שיכיל את הערך של גרסת Navigation SDK שבה נעשה שימוש באפליקציה. כך יהיה קל לעבור לגרסה האחרונה בעתיד.
מספר הגרסה העדכנית מופיע בנתוני הגרסה של Navigation SDK.
val navSdkVersion by extra("6.0.0")
אפשר גם לשנות את הערכים של המשתנה הזה ומשתנים אחרים באמצעות תיבת הדו-שיח שמופיעה בקטע File (קובץ) > Project Structure (מבנה הפרויקט) > Variables (משתנים):
הוספת תלות לתצורת ה-build
עכשיו צריך להוסיף את תלות ה-API הבאה לבלוק של יחסי התלות ברמת האפליקציה build.gradle.kts.
הגרסה שבה תשתמש תהיה הערך של ${navSdkVersion}
שהגדרת עכשיו ב-build.gradle.kts
ברמת האפליקציה:
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
מידע נוסף בנושא הזה זמין במאמר הוספת מפתח ה-API לאפליקציה במסמכי התיעוד של Navigation SDK.
מאמתים את התוכן של Local.defaults.properties.
הפרויקט הריק מכיל גם קובץ local.defaults.properties
בספריית הרמה העליונה, באותה תיקייה שבה נמצא הקובץ secrets.properties
. פותחים אותו ומעיינים בקוד הבא.
MAPS_API_KEY=DEFAULT_API_KEY
המאפיין הזה קיים כדי לספק ערך לגיבוי של המאפיין MAPS_API_KEY
למקרה ש-secrets.properties
לא יתווסף לפרויקט, כדי שה-builds לא יכשלו. אין צורך לערוך את הקובץ הזה. אם ההגדרה secrets.properties
של MAPS_API_KEY
לא נמצאת, ערך ברירת המחדל יפסיק את הפעלת האפליקציה בזמן הריצה, עם שגיאה של מפתח 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. הגדרת הרשאות הניתנות לאפליקציה והוספת ממשק משתמש בסיסי
שליחת בקשה להרשאת גישה למיקום מדויק
כדי לפעול, Navigation SDK מסתמך על אותות GPS, ולכן האפליקציה תצטרך לבקש מהמשתמש להעניק גישה לנתוני המיקום המדויקים. מוסיפים את הרשאת הגישה למיקום המדויק כצאצא של הרכיב <manifest>
בקובץ AndroidManifest.xml.
<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" />
הוספת פעילות הפעלה עם ממשק משתמש בסיסי
כשהאפליקציה שלך פועלת, צריך קוד שמופעל במהלך ההפעלה כדי לבדוק אם המשתמש העניק הרשאה לגשת למיקום שלו, ולטפל בכל תרחיש אפשרי, בבקשת הרשאה אם היא עדיין לא הוענקה. כדי לעשות את זה, צריך להוסיף לאפליקציה ממשק משתמש בסיסי. ה-Codelab הזה משתמש בממשק המשתמש שנוצר כשיוצרים פעילות צפיות חדשה וריקה ב-Android Studio. צריך לשנות את ההגדרה הזו כדי לבצע את הבדיקה של הרשאות המיקום לפני שמוסיפים קוד לפעילות של ממשק המשתמש של הניווט.
פותחים את הקובץ MainActivity.kt
בעורך הקוד ובודקים את הקוד, שבו מוצג ממשק משתמש בסיסי.
בקשת הרשאות גישה למיקום בזמן ריצה
האפליקציה תצטרך להפעיל את הבקשה לגישה למיקום המדויק לפני שתתבצע האינטליגנציה של Navigation SDK.
כדי לוודא שהבדיקה הזו מתבצעת כשהאפליקציה מתחילה, מוסיפים קוד לכיתה MainActivity
, בשיטת onCreate()
שהוחלפה ב-Activity.
הקוד הבא בודק אם המשתמש העניק הרשאה למיקום מדויק. אם לא, הוא מבקש הרשאה. מוסיפים את הקוד הזה לתוך השיטה 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
}
יוצרים את הפרויקט. אם יש שגיאות ב-build, צריך לאתר אותן ולתקן אותן.
מפעילים את הפרויקט במכשיר וירטואלי חדש. תיבת הדו-שיח לבקשת הרשאה אמורה להופיע בזמן ההתקנה וההפעלה של האפליקציה.
6. הוספת ממשק משתמש לניווט
יש שתי דרכים להוסיף ממשק משתמש לניווט: SupportNavigationFragment
או NavigationView
.
כדי לשמור על פשטות, ה-Codelab משתמש ב-NavigationView
.
עריכת הפריסה
עורכים את res/layout/activity_main.xml
כדי להוסיף פריסה ל-NavigationView.
- פותחים את הקובץ ומעבירים אותו לתצוגת קוד.
- מחליפים את כל התוכן של הקובץ בפריסה חדשה של
NavigationView
בתוךRelativeLayout
, כמו בדוגמה הבאה. בדיוק כמו שמוסיפים תצוגת ניווט לאפליקציה, אפשר לעשות זאת באמצעות פריסה פשוטה. - יש לתת לניווט את המזהה "
@+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>
הגדרת הפעילות 'ניווט'
ב-Android Studio, פותחים את הקובץ MainActivity.kt בעורך.
צריך להוסיף קוד הגדרה בסיסי כדי להבטיח שחוויית הניווט באפליקציה תפעל בצורה תקינה. בקובץ MainActivity.kt, מבצעים את השינויים הבאים:
- מגדירים משתנה בכיתה
MainActivity
כדי להפנות ל-NavigationView
:
private lateinit var navView: NavigationView
- צריך להוסיף קוד ל-method
onCreate()
כדי לקבל הפניה אלNavigationView
:
navView = findViewById(R.id.navigation_view)
navView.onCreate(savedInstanceState)
- מוסיפים קוד ל-method
onCreate()
כדי להבטיח שהמסך ימשיך לפעול במהלך הנחיות הניווט:
// Ensure the screen stays on during nav.
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
- עורכים את הקוד שמפעיל את
ViewCompat.setOnApplyWindowInsetsListener
כך שיתייחס למזהה שלNavigationView
.
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. אתחול ה-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()
. השיטה הזו מקבלת הפניה לאובייקט Navigator
על ידי קריאה ל-NavigationApi.getNavigator()
ומטמיעה NavigatorListener
כדי לטפל בקריאה החוזרת.
שימו לב שכאשר Navigation API מופעל, תתבצע קריאה ל-method NavigationListener.onNavigatorReady
, עם אובייקט Navigator
שמוענק כפרמטר. הקוד שלמעלה יעדכן את המשתנה mNavigator
שהצהרת עליו קודם, עם האובייקט Navigator
המאתחל שיועבר ל-method הזה.
לבסוף, מוסיפים קריאה ל-method initializeNavigationApi
מ-method onLocationPermissionGranted
.
private fun onLocationPermissionGranted() {
initializeNavigationApi()
}
8. הוספת מאזינים לאירועי ניווט מרכזיים
כשהמשתמשים פועלים לפי ההנחיות, ה-Navigation SDK יפעיל אירועים שיכולים להודיע לאפליקציה על שינויים במצבים של מפתחות בדרך, למשל כשהמשתמש משנה את המסלול או מגיע ליעד. בקובץ MainActivity.kt, יש להוסיף מאזינים כדי לטפל באירועים הבאים:
- במחלקה
MainActivity
, צריך להצהיר על שני משתנים שיפנו לאובייקטים של event listener:
private var arrivalListener: Navigator.ArrivalListener? = null
private var routeChangedListener: Navigator.RouteChangedListener? = null
- יש להוסיף שיטת
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)
}
}
- הוספת קריאה אל
registerNavigationListeners()
מקוד הקריאה החוזרת שלonNavigatorReady
בשיטהinitializeNavigationApi
:
override fun onNavigatorReady(navigator: Navigator) {
// store a reference to the Navigator object
mNavigator = navigator
//listen for events en route
registerNavigationListeners()
}
- מגדירים את ממשק המשתמש. אתם יכולים לשלוט בהיבטים שונים של ממשק המשתמש של הניווט כשההוראות פועלות. אחת מההתאמות האישיות החשובות היא מיקום המצלמה. מוסיפים קריאה ל-method
setTaskRemovedBehaviour
של ההחזרה של האובייקטnavigator
ב-onNavigatorReady
באופן הבא. הפעולה הזו תגרום להפסקת ההנחיות וההתראות במקרה של החלקה הצידה:
// 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
באמצעות ה-methodNavigatorView.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, מבצעים את השינויים הבאים:
- מוסיפים שיטה חדשה
navigateToPlace()
שמגדירה את יעד הניווט ומקבלת פרמטרplaceId
.
/**
* 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()
כדי ליצורWaypoint
ממזהה המקום שמועבר ל-method. מטפלים ב-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
}
- כדי להגדיר יעד באמצעות נקודת ה-Waypoint, צריך להוסיף את הקוד הבא ל-method
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
יש method setDestinations()
שיכולה לקבל מגוון פרמטרים. האפשרות הבסיסית ביותר היא לספק Waypoint
. הגדרת ברירת המחדל היא מצב נסיעה של DRIVING
, שמתאים לרכבים עם 4 גלגלים. השיטה setDestinations()
מחזירה אובייקט ListenableResultFuture
שמכיל אובייקט RouteStatus
. הערך של 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)
)
}
השינויים האלה כוללים את השיפורים הבאים:
- הסתרת סרגל הפעולות כדי להגדיל את המקום בממשק המשתמש של הניווט.
- הפעלת הנחיות אודיו להשמעת התראות והוראות ניווט.
- הגדרת הסימולטור לניפוי באגים על ידי ציון מכפיל מהירות.
- מחפשים מזהה מקום שישמש כיעד. במצב אידיאלי, המיקום לא יהיה רחוק מדי ממיקום המשתמש. אפשר להשתמש בכלי לחיפוש מזהי מקומות בפלטפורמת מפות Google או לקבל מזהה מקום מקריאה ל-Places API.
אם אתם מבצעים סימולציה של ניווט, אתם יכולים להגדיר את מיקום המשתמש בקוד או לבחור אותו מהמכשיר המחובר. ההנחה ב-Codelab היא שאתם מדמים מיקום בלונדון, בריטניה.
- מוסיפים אובייקט נלווה לכיתה
MainActivity
כדי לאחסן מיקום התחלה ומזהה מקום. ה-Codelab ישתמש במיקום התחלה בלונדון ובמזהה המקום של כיכר טרפלגר:
companion object{
const val TRAFALGAR_SQUARE ="ChIJH-tBOc4EdkgRJ8aJ8P1CUxo" //London, UK
val startLocation = LatLng(51.345678, -0.1234456)
}
- מוסיפים קריאה ל-method
navigateToPlace()
מה-methodonNavigatorReady
בתוך ה-methodinitializeNavigationApi
, ומוסיפים ענף לוגיקה שיופעל במצב ניפוי באגים, שמגדיר את מיקום המשתמש:
// 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 במאונטיין ויו שבקליפורניה, אלא אם הגדרתם מיקום בקוד או באמצעות תיבת הדו-שיח של מאפייני המהדר.
אם כן, ייתכן שלא תגלו שהאפליקציה לא מוצאת נתיב למזהה המקום שהגדרתם (כברירת מחדל, בית האופרה של סידני, סידני, אוסטרליה). אם בוחרים באפשרות הזו, מקבלים הודעה עם הכיתוב "לא נמצא מסלול", שמוצגת בשיטה showToast()
.
כתיבה קבועה של מיקום ההתחלה
כדי להגדיר מיקום שונה בקוד, צריך להוסיף את השורה הבאה בשיטת navigateToPlace()
ב-MainActivity.kt, לפני הקריאה ל-mNavigator.startGuidance()
:
mNavigator?.simulator?.setUserLocation(startLocation)
הפעלת הסימולטור במיקום ברירת המחדל שבחרתם
כדי להגדיר מיקום אחר באמולטור המכשיר, מפעילים את האמולטור אם הוא עדיין לא פועל ולוחצים על סמל התפריט (3 נקודות) עם ההסבר הקצר 'פקדים מורחבים'. בתיבת הדו-שיח שנפתחת מופיעה אפשרות תפריט 'מיקום'.
לדוגמה, אם היעד הוא מזהה המקום של בית האופרה של סידני, צריך לבחור מיקום בסידני שבאוסטרליה. לדוגמה, מחפשים את 'חוף תל אביב', בוחרים הצעה ולוחצים על 'שמירה של המיקום' בפינה השמאלית התחתונה של תיבת הדו-שיח. אפשר גם ללחוץ על "שמירת נקודה" כדי להוסיף את המיקום לרשימה שמורה לשימוש עתידי.
אם מגדירים מזהה מקום אחר כיעד, בוחרים מיקום בקרבת מקום כדי שהמסלול המדומה יהיה ריאליסטי ולא ארוך מדי, כדי שיהיה קל לנפות באגים.
מפעילים מחדש את האפליקציה, והיא אמורה לנווט ליעד.
11. מעולה!
סיימתם את הקודלאב הזה. כל הכבוד – הגעת ליעד! שיהיה בהצלחה :-)
12. עוד צעד אחד קדימה
אם אתם רוצים להמשיך לפתח אפליקציות, כדאי לעיין בנושאים הבאים כדי לקבל השראה.
- הקשבה לאירועי ניווט נוספים אפשר להוסיף קוד כדי להציג הודעה אם הנהג משנה את המסלול או כשהוא מגיע.
- להתאים אישית את ממשק הניווט.
- אם אתם רוצים להתנסות באתגר גדול יותר, תוכלו לנסות להוסיף רכיב של בורר מקומות ב-Places API כדי לאפשר למשתמש להגדיר את היעד. טיפ: באפליקציות הדגמה של Navigation SDK ב-GitHub יש הטמעה לדוגמה.
- אפשר למנוע בעיות פוטנציאליות בקריאה לאובייקטים של Navigator ו-GoogleMap באופן אסינכרוני, על ידי שימוש בגישה שמשמשת באפליקציות להדגמה של Navigation SDK ב-GitHub. בתרחישים מורכבים יותר של אפליקציות, יכול להיות שההפעלה של האובייקטים האלה לא תסתיים כשהקוד יפעל. טיפ: כדי להטמעה מהירה מאוד, אפשר להוסיף את המחלקה InitializedNavScope בסוף הקובץ MainActivity.kt.