با Google Maps Platform Navigation SDK یک برنامه ناوبری ساده اندروید بسازید

1. قبل از شروع

این کد لبه به شما می آموزد که یک برنامه اندروید ساده ایجاد کنید که از Google Maps Platform Navigation SDK برای پیمایش به یک مقصد از پیش پیکربندی شده استفاده می کند.

پس از اتمام برنامه شما به این شکل خواهد بود.

b6c535afde7abd20.png

پیش نیازها

  • آشنایی با توسعه اولیه اپلیکیشن اندروید در Kotlin
  • آشنایی با مفاهیم اولیه Google Maps SDK مانند نقشه ها، مکان ها، مختصات.

چیزی که یاد خواهید گرفت

  • چگونه یک برنامه اندروید ساده بسازیم که از Navigation SDK برای پیمایش به مقصد استفاده کند.
  • نحوه ادغام Navigation SDK از مخزن راه دور Google Maven
  • نحوه مدیریت مجوزهای مکان و قرارداد کاربر با شرایط کاربر نهایی Navigation SDK
  • چگونه SDK را مقداردهی اولیه کنیم
  • نحوه تعیین مقصد و شروع راهنمای ناوبری.

آنچه شما نیاز دارید

  • آخرین نسخه پایدار اندروید استودیو نصب شده است. این کد لبه با استفاده از Android Studio Jellyfish ایجاد شده است. اگر از نسخه دیگری استفاده می کنید، ظاهر و چیدمان رابط و اجزا ممکن است متفاوت باشد.
  • یک حساب Google و پروژه با فعال بودن صورتحساب.
  • یک دستگاه Android در حالت برنامه‌نویس با اشکال‌زدایی USB فعال یا شبیه‌ساز Android. هر کدام را که انتخاب کنید باید حداقل شرایط لازم برای Navigation SDK را داشته باشد

2. راه اندازی شوید

اگر قبلاً یک حساب Google Cloud Platform و پروژه‌ای با صورت‌حساب فعال ندارید، پروژه Google Cloud خود را طبق دستورالعمل‌های شروع با Google Maps Platform راه‌اندازی کنید https://developers.google.com/maps/gmp-get-started

پروژه Google Cloud خود را در کنسول انتخاب کنید

در Cloud Console ، روی منوی کشویی پروژه کلیک کنید و پروژه ای را که می خواهید برای این کد لبه استفاده کنید انتخاب کنید.

منوی کشویی انتخابگر پروژه در کنسول Google Cloud.

Navigation SDK را در پروژه خود فعال کنید

APIها و SDKهای پلتفرم Google Maps مورد نیاز برای این لبه کد را در Google Cloud Marketplace فعال کنید.

به APIs & Services > Library در Google Cloud Console بروید و «Navigation SDK» را جستجو کنید.

شما باید یک نتیجه جستجو را ببینید.

صفحه کتابخانه API در کنسول Google Cloud که صفحه Navigation SDK را نشان می دهد.

روی نتیجه Navigation SDK کلیک کنید تا صفحه جزئیات محصول باز شود. روی دکمه Enable کلیک کنید تا SDK در پروژه شما فعال شود.

این فرآیند را برای Google Maps SDK برای Android تکرار کنید.

یک کلید API ایجاد کنید

یک کلید API در صفحه Credentials در Cloud Console ایجاد کنید. می‌توانید مراحل مرحله 3 از بخش شروع سریع را در شروع به کار با پلتفرم Google Maps دنبال کنید. همه درخواست‌ها به پلتفرم Google Maps به یک کلید API نیاز دارند.

3. نمونه فایل های پروژه را دریافت کنید

این بخش نحوه راه‌اندازی یک پروژه خالی پایه اندروید استودیو را با شبیه‌سازی فایل‌ها از مخزن GitHub برای این کد لبه توضیح می‌دهد. مخزن Github شامل نسخه های قبل و بعد از کد لبه کد است. کد لبه با یک الگوی پروژه خالی شروع می شود و تا حالت تمام شده ساخته می شود. در صورت گیر افتادن می توانید از پروژه تمام شده در مخزن به عنوان مرجع استفاده کنید.

این مخزن Github را کلون کنید تا کد این کد لبه را دریافت کنید.

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

اگر git را نصب نکرده اید، روی این دکمه کلیک کنید تا کد را دریافت کنید:

برای شروع هر چه سریع‌تر، مخزن حاوی مقداری کد شروع در پوشه Starter است تا به شما کمک کند این کد را دنبال کنید. پروژه شروع کننده یک رابط کاربری اولیه برنامه و پیکربندی ساخت را ارائه می دهد، اما SDK ناوبری به آن اضافه نشده است. همچنین یک پروژه Solution تمام شده وجود دارد در صورتی که بخواهید در هر زمان به جلو بپرید یا پیشرفت خود را بررسی کنید.

مخزن کلون شده را در اندروید استودیو باز کنید

هنگامی که مخزن را به صورت محلی کلون کردید، از Android Studio برای باز کردن پوشه Starter به عنوان یک پروژه موجود استفاده کنید.

  1. از گفتگوی Welcome to Android Studio، روی دکمه Open کلیک کنید.
  2. به پوشه ای که مخزن کلون شده را در آن ذخیره کرده اید بروید و پوشه Starter را در داخل پوشه سطح بالا " codelab-navigation-101-android-kotlin " انتخاب کنید.
  3. بررسی کنید که پروژه ساخته و اجرا شود.

یک دستگاه مجازی اضافه کنید یا یک دستگاه سخت افزاری را وصل کنید

برای اتصال یک دستگاه Android به رایانه خود، دستورالعمل های Android Studio را در مورد نحوه اجرای برنامه ها در دستگاه سخت افزاری دنبال کنید. همچنین، می‌توانید یک دستگاه مجازی را با استفاده از مدیر دستگاه مجازی Android (AVD) پیکربندی کنید. هنگام انتخاب یک شبیه ساز، مطمئن شوید که تصویری را انتخاب کرده اید که شامل API های Google باشد.

در اندروید استودیو، روی گزینه منوی Run یا نماد دکمه پخش کلیک کنید. همانطور که از شما خواسته شده یک دستگاه را انتخاب کنید.

4. Navigation SDK را به برنامه خود اضافه کنید

کتابخانه Navigation SDK و کلید API خود را به پروژه خود اضافه کنید

برای افزودن کتابخانه Navigation SDK به برنامه خود، باید build.gradle.kts در سطح برنامه خود را تغییر دهید تا Navigation SDK را از مخزن Google Maven واکشی کرده و شماره نسخه را پیکربندی کنید.

یک متغیر در پیکربندی ساخت خود ایجاد کنید تا شماره نسخه Navigation SDK ذخیره شود.

متغیری را در build.gradle.kts سطح برنامه خود تنظیم کنید تا حاوی مقدار نسخه Navigation SDK مورد استفاده در برنامه شما باشد، بنابراین تغییر آن به آخرین نسخه در آینده آسان است.

یادداشت‌های انتشار SDK ناوبری را برای آخرین شماره نسخه بررسی کنید.

val navSdkVersion by extra("6.0.0")

همچنین می توانید مقادیر این متغیر و سایر متغیرها را با استفاده از گفتگوی موجود در File > Project Structure > Variables تغییر دهید:

668332736b67dc82.png

یک وابستگی به پیکربندی ساخت اضافه کنید

اکنون وابستگی 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 را در دایرکتوری سطح بالای خود باز کنید و سپس کلید API خود را جایگزین YOUR_API_KEY کنید. کلید خود را در این فایل ذخیره کنید زیرا 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 به پروژه اضافه نشود وجود دارد تا بیلدها شکست نخورند. نیازی به ویرایش این فایل نیست. اگر تعریف 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. مجوزهای برنامه را پیکربندی کنید و یک رابط کاربری اولیه اضافه کنید

درخواست مجوز مکان دقیق

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 زیر در همان مکان مجوز دسترسی دقیق به موقعیت مکانی، مجوز Foreground Service Location را درخواست کنید:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />

یک فعالیت راه‌اندازی را با یک رابط کاربری پایه اضافه کنید

وقتی برنامه شما اجرا می‌شود، به کدی نیاز دارد که در حین راه‌اندازی اجرا شود تا بررسی کند که آیا کاربر اجازه دسترسی به موقعیت مکانی خود را داده است یا خیر، و هر سناریوی احتمالی را مدیریت می‌کند و در صورتی که هنوز اعطا نشده است، مجوز درخواست می‌کند. برای انجام این کار، یک رابط کاربری اولیه به برنامه خود اضافه کنید. این کد لبه از رابط کاربری استفاده می کند که هنگام ایجاد یک فعالیت Views جدید و خالی در Android Studio ایجاد می شود. شما این را برای انجام بررسی مجوز موقعیت مکانی قبل از افزودن کد به فعالیت برای رابط کاربری ناوبری تنظیم خواهید کرد.

فایل MainActivity.kt را در ویرایشگر کد باز کنید و کد را که یک UI اصلی را نشان می دهد، بررسی کنید.

درخواست مجوز دسترسی به مکان در زمان اجرا

قبل از اینکه 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
}

پروژه خود را بسازید اگر هر گونه خطای ساخت دارید، آنها را پیدا و رفع کنید.

پروژه خود را روی یک دستگاه مجازی جدید اجرا کنید. هنگام نصب و راه‌اندازی برنامه، پنجره درخواست مجوز ظاهر می‌شود.

6. یک رابط کاربری ناوبری اضافه کنید

دو راه برای افزودن رابط کاربری ناوبری وجود دارد: SupportNavigationFragment یا NavigationView .

برای سادگی، Codelab از NavigationView استفاده می کند.

طرح بندی را ویرایش کنید

برای افزودن طرح‌بندی برای NavigationView، res/layout/activity_main.xml ویرایش کنید.

  1. فایل را باز کنید و به نمای کد بروید.
  2. کل محتویات فایل را با یک طرح جدید از NavigationView در داخل یک RelativeLayout مانند مثال زیر جایگزین کنید. همانطور که شما فقط یک نمای ناوبری به برنامه اضافه می کنید، یک طرح بندی ساده انجام می شود.
  3. به NavigationView خود شناسه " @+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 تغییرات زیر را اعمال کنید:

  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 خود ارجاع دهید.
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 را راه اندازی کنید

اکنون که تنظیمات اولیه فعالیت ناوبری را تکمیل کرده اید، می توانید 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 برای رسیدگی به callback پیاده سازی می کند.

توجه داشته باشید که هنگامی که Navigation API مقداردهی اولیه می شود، متد NavigationListener.onNavigatorReady فراخوانی می شود که یک شی Navigator به عنوان پارامتر ارسال می شود. کد بالا متغیر mNavigator را که قبلاً اعلام کرده‌اید با شی Navigator اولیه که به این متد ارسال می‌شود، به‌روزرسانی می‌کند.

در نهایت، یک فراخوانی از متد 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 مقداردهی اولیه می شود تنظیم کنید. این متد Navigator.clearDestinations() را برای بازنشانی NavigationView هنگامی که رویداد Arrival فعال می شود فراخوانی می کند:
/**
* 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. یک تماس به registerNavigationListeners() از کد پاسخ به تماس onNavigatorReady در متد initializeNavigationApi اضافه کنید:
override fun onNavigatorReady(navigator: Navigator) {
   // store a reference to the Navigator object
   mNavigator = navigator

   //listen for events en route
   registerNavigationListeners()


}
  1. رابط کاربری را پیکربندی کنید. شما می توانید جنبه های مختلف رابط کاربری ناوبری را در هنگام اجرا کنترل کنید. یکی از سفارشی سازی های مهم موقعیت دوربین است. یک فراخوانی به متد 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)
  1. برای تعیین CameraPerspective یک تماس به GoogleMap.followMyLocation اضافه کنید. GoogleMap از طریق متد NavigatorView.getMapAsync() به صورت زیر قابل دسترسی است:
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() برای ایجاد یک Waypoint از شناسه مکان ارسال شده به متد استفاده کنید. 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() خود اضافه کنید تا با استفاده از Waypoint یک مقصد تعیین کنید:
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 ، مناسب برای خودروهای 4 چرخ خواهد بود. متد setDestinations() یک شی ListenableResultFuture حاوی یک شی RouteStatus را برمی گرداند. 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)
   )
}

این تغییرات شامل بهبودهای زیر است:

  • پنهان کردن Action Bar برای به حداکثر رساندن فضا برای Navigation UI.
  • فعال کردن راهنمای صوتی برای بیان هشدارها و دستورالعمل‌های ناوبری.
  • راه اندازی شبیه ساز برای اشکال زدایی با تعیین یک ضرب کننده سرعت.
  1. شناسه مکانی را پیدا کنید که به عنوان مقصد شما عمل می کند. در حالت ایده آل، این مکان خیلی دور از مکان کاربر نخواهد بود. از ابزار Google Maps Platform Place ID Finder استفاده کنید یا از تماس API Places یک شناسه مکان دریافت کنید.

اگر پیمایش را شبیه‌سازی می‌کنید، می‌توانید مکان کاربر را در کد تنظیم کنید یا آن را از دستگاه متصل خود بگیرید. نرم افزار Codelab فرض می کند که شما در حال شبیه سازی مکانی در لندن، انگلستان هستید.

  1. یک شیء همراه به کلاس MainActivity خود اضافه کنید تا مکان شروع و شناسه مکان ذخیره شود. Codelab از یک مکان شروع در لندن و شناسه مکان Trafalgar Square استفاده خواهد کرد:
companion object{
   const val TRAFALGAR_SQUARE ="ChIJH-tBOc4EdkgRJ8aJ8P1CUxo" //London, UK
   val startLocation = LatLng(51.345678, -0.1234456)
}
  1. یک فراخوانی به متد navigateToPlace() خود از پاسخ به تماس onNavigatorReady در داخل متد initializeNavigationApi اضافه کنید و شاخه‌ای از منطق را اضافه کنید که در حالت Debug اجرا می‌شود و مکان کاربر را تعیین می‌کند:
// 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() را فراخوانی می‌کند که پس از استفاده از 1000 مقصد اول، هزینه‌ای را متحمل می‌شود. برای اطلاعات بیشتر به استفاده و صورتحساب مراجعه کنید.

93aa433000a14dfc.png

گفتگوی اصطلاحات کاربر نهایی Navigation SDK.

تنظیم مکان

به‌طور پیش‌فرض، ممکن است مکان دستگاه شبیه‌سازی‌شده روی پردیس Google در Mountain View کالیفرنیا تنظیم شود، مگر اینکه مکانی را در کد تنظیم کرده باشید، یا از گفتگوی ویژگی‌های شبیه‌ساز استفاده کنید.

اگر چنین است، ممکن است متوجه شوید که برنامه نمی تواند مسیری به شناسه مکانی که شما پیکربندی کرده اید (به طور پیش فرض، خانه اپرای سیدنی، سیدنی، استرالیا) پیدا کند. این با پیامی مبنی بر "هیچ مسیری یافت نشد" نشان داده می شود که با متد showToast() شما نمایش داده می شود.

نمای نقشه برنامه ناوبری که دفتر Google را در Mountain View، کالیفرنیا نشان می دهد.

کد نویسی سخت محل شروع

برای تنظیم مکان متفاوت در کد، قبل از فراخوانی mNavigator.startGuidance() خط زیر را در متد navigateToPlace() خود در MainActivity.kt اضافه کنید:

mNavigator?.simulator?.setUserLocation(startLocation)

شبیه ساز را در مکان پیش فرض انتخابی خود راه اندازی کنید

برای تنظیم مکان متفاوت در شبیه‌ساز دستگاه، اگر شبیه‌ساز از قبل در حال اجرا نیست، آن را راه‌اندازی کنید و روی منوی 3 نقطه‌ای با راهنمای ابزار «کنترل‌های توسعه‌یافته» کلیک کنید. گفتگوی باز شده دارای یک گزینه منو برای "مکان" است.

به عنوان مثال، اگر از شناسه مکان اپرای سیدنی به عنوان مقصد استفاده می کنید، مکانی را در سیدنی، استرالیا انتخاب کنید. به عنوان مثال، "ساحل Bondi" را جستجو کنید، یک پیشنهاد را انتخاب کنید و روی "ذخیره مکان" در سمت راست پایین کادر گفتگو کلیک کنید. همچنین می‌توانید روی «ذخیره نقطه» کلیک کنید تا مکان را برای استفاده در آینده به فهرست ذخیره‌شده اضافه کنید.

گفتگوی Extended Controls در مدیریت دستگاه Android، انتخابگر مکان و نقشه ای را در مرکز ساحل Bondi در استرالیا نشان می دهد.

اگر شناسه مکان دیگری را به عنوان مقصد تعیین کرده‌اید، مکانی را در نزدیکی آن انتخاب کنید تا مسیر شبیه‌سازی‌شده یک مسیر واقعی باشد و برای اشکال‌زدایی آسان خیلی طولانی نباشد.

برنامه را مجدداً راه اندازی کنید و اکنون باید به مقصد حرکت کند.

تصویری از برنامه ناوبری که مقصد را راهنمایی می کند.

11. تبریک!

شما این کد را تکمیل کرده اید. آفرین - شما به مقصد خود رسیدید! کد نویسی مبارک :-)

55812f33256c0596.png

12. جلوتر بردن

اگر می خواهید توسعه برنامه خود را بیشتر پیش ببرید، برای الهام گرفتن به موضوعات زیر نگاهی بیندازید.