اندروید پیشرفته در Kotlin 04.1: Android Google Maps

این کد لبه بخشی از دوره آموزشی Advanced Android in Kotlin است. اگر از طریق کدها به صورت متوالی کار کنید، بیشترین ارزش را از این دوره خواهید گرفت، اما اجباری نیست. همه کدهای دوره در صفحه فرود Android Advanced in Kotlin Codelabs فهرست شده اند.

ساختن برنامه‌ها با Google Maps به شما امکان می‌دهد ویژگی‌هایی مانند تصاویر ماهواره‌ای، کنترل‌های رابط کاربری قوی برای نقشه‌ها، ردیابی موقعیت مکانی و نشانگرهای مکان را به برنامه خود اضافه کنید. می‌توانید با نشان دادن اطلاعات از مجموعه داده‌های خود، مانند مکان‌های ماهیگیری یا مناطق کوهنوردی معروف، ارزشی به نقشه استاندارد Google اضافه کنید. همچنین می‌توانید بازی‌هایی بسازید که در آن بازیکن دنیای فیزیکی را کشف کند، مانند شکار گنج یا حتی بازی‌های واقعیت افزوده.

در این درس، شما یک اپلیکیشن Google Maps به نام Wander ایجاد می کنید که نقشه های سفارشی شده را نمایش می دهد و موقعیت مکانی کاربر را نشان می دهد.

پیش نیازها

آگاهی از موارد زیر:

  • چگونه یک برنامه اندروید پایه بسازیم و آن را با استفاده از اندروید استودیو اجرا کنیم.
  • نحوه ایجاد و مدیریت منابع، مانند رشته ها.
  • نحوه تغییر کد و تغییر نام متغیرها با استفاده از اندروید استودیو.
  • نحوه استفاده از نقشه گوگل به عنوان کاربر
  • نحوه تنظیم مجوزهای زمان اجرا

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

  • چگونه یک کلید API را از کنسول API Google دریافت کنید و کلید برنامه خود را ثبت کنید
  • چگونه یک نقشه گوگل را در برنامه خود ادغام کنیم
  • نحوه نمایش انواع مختلف نقشه
  • نحوه استایل دادن به نقشه گوگل
  • چگونه نشانگرها را به نقشه خود اضافه کنید
  • نحوه فعال کردن کاربر برای قرار دادن نشانگر در یک نقطه مورد علاقه (POI)
  • نحوه فعال کردن ردیابی موقعیت مکانی
  • نحوه ایجاد اپلیکیشن The Wander که دارای نقشه گوگل تعبیه شده است
  • نحوه ایجاد ویژگی های سفارشی برای برنامه خود، مانند نشانگرها و استایل
  • چگونه ردیابی موقعیت مکانی را در برنامه خود فعال کنیم

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

Maps SDK برای Android به یک کلید API نیاز دارد. برای دریافت کلید API، پروژه خود را در صفحه API & Services ثبت کنید. کلید API به یک گواهی دیجیتال گره خورده است که برنامه را به نویسنده آن پیوند می دهد. برای اطلاعات بیشتر درباره استفاده از گواهی‌های دیجیتال و امضای برنامه، به امضای برنامه خود مراجعه کنید .

در این کد لبه، شما از کلید API برای گواهی اشکال زدایی استفاده می کنید. گواهی اشکال زدایی از نظر طراحی ناامن است، همانطور که در Sign your debug build توضیح داده شده است. برنامه‌های منتشرشده Android که از Maps SDK برای Android استفاده می‌کنند به یک کلید API دوم نیاز دارند: کلید گواهی انتشار. برای اطلاعات بیشتر در مورد دریافت گواهی انتشار، به دریافت کلید API مراجعه کنید.

Android Studio شامل یک الگوی Google Maps Activity است که کد قالب مفیدی را تولید می کند. کد الگو شامل یک فایل google_maps_api.xml حاوی پیوندی است که به دست آوردن یک کلید API را ساده می کند.

مرحله 1: پروژه Wander را با الگوی نقشه ها ایجاد کنید

  1. یک پروژه Android Studio جدید ایجاد کنید.
  2. الگوی Google Maps Activity را انتخاب کنید.

  1. نام پروژه را Wander .
  2. حداقل سطح API را روی API 19 تنظیم کنید. مطمئن شوید که زبان کاتلین است.
  3. روی Finish کلیک کنید.
  4. پس از اتمام ساخت برنامه، به پروژه خود و فایل های مرتبط با نقشه های زیر که Android Studio برای شما ایجاد می کند نگاهی بیندازید:

google_maps_api.xml — شما از این فایل پیکربندی برای نگه داشتن کلید API خود استفاده می کنید. این الگو دو فایل google_maps_api.xml ایجاد می کند: یکی برای اشکال زدایی و دیگری برای انتشار. فایل کلید API برای گواهی اشکال زدایی در src/debug/res/values ​​قرار دارد. فایل کلید API برای گواهی انتشار در src/release/res/values ​​قرار دارد. در این کد لبه، شما فقط از گواهی اشکال زدایی استفاده می کنید.

activity_maps.xml — این فایل طرح بندی شامل یک قطعه واحد است که کل صفحه را پر می کند. کلاس SupportMapFragment یک زیر کلاس از کلاس Fragment است. SupportMapFragment ساده ترین راه برای قرار دادن نقشه در یک برنامه است. این یک بسته بندی در اطراف یک نمای نقشه است تا به طور خودکار نیازهای چرخه حیات لازم را برطرف کند.

می‌توانید SupportMapFragment در یک فایل طرح‌بندی با استفاده از تگ <fragment> در هر ViewGroup ، با ویژگی name اضافی اضافه کنید.

android:name="com.google.android.gms.maps.SupportMapFragment"

MapsActivity.java — فایل MapsActivity.kt از SupportMapFragment در onCreate() استفاده می کند و از getMapAsync () کلاس برای مقداردهی اولیه سیستم نقشه ها و نمای استفاده می کند. فعالیتی که حاوی SupportMapFragment باید رابط OnMapReadyCallback و onMapReady() آن رابط را پیاده سازی کند. onMapReady() زمانی فراخوانی می شود که نقشه بارگذاری شود.

مرحله 2: کلید API را دریافت کنید

  1. نسخه اشکال زدایی فایل google_maps_api.xml را باز کنید.
  2. در فایل به دنبال نظری با URL طولانی باشید. پارامترهای URL شامل اطلاعات خاصی در مورد برنامه شما هستند.
  3. URL را کپی و در مرورگر پیست کنید.
  4. برای ایجاد پروژه در صفحه APIs & Services ، دستورات را دنبال کنید. به دلیل پارامترهای موجود در URL ارائه شده، صفحه می داند که Maps SDK برای Android به طور خودکار فعال می شود.
  5. روی ایجاد کلید API کلیک کنید.
  6. در صفحه بعد به بخش API Keys رفته و روی کلیدی که ایجاد کردید کلیک کنید.
  7. روی Restrict Key کلیک کنید و Maps SDK for Android را انتخاب کنید تا استفاده از کلید به برنامه‌های Android محدود شود.
  8. کلید API تولید شده را کپی کنید. با " AIza" شروع می شود.
  9. در فایل google_maps_api.xml ، کلید را در رشته google_maps_key جایی که YOUR_KEY_HERE را نشان می دهد، قرار دهید.
  10. برنامه خود را اجرا کنید شما باید یک نقشه جاسازی شده در فعالیت خود با یک نشانگر در سیدنی، استرالیا ببینید. (نشانگر سیدنی بخشی از الگو است و بعداً آن را تغییر می دهید.)

مرحله 3: تغییر نام mMap

MapsActivity یک lateinit var خصوصی به نام mMap دارد که از نوع GoogleMap است. برای پیروی از قراردادهای نامگذاری Kotlin، نام mMap را به map تغییر دهید.

  1. در MapsActivity ، روی mMap راست کلیک کنید و روی Refactor > Rename...

  1. نام متغیر را به map تغییر دهید.

توجه کنید که چگونه تمام ارجاعات به mMap در تابع onMapReady() نیز به map تغییر می کند.

نقشه های گوگل شامل چندین نوع نقشه است: معمولی، ترکیبی، ماهواره ای، زمینی، و "هیچ" (به هیچ وجه بدون نقشه).

نقشه معمولی

نقشه ماهواره ای

نقشه ترکیبی

نقشه زمین

هر نوع نقشه انواع مختلفی از اطلاعات را ارائه می دهد. به عنوان مثال، هنگام استفاده از نقشه ها برای پیمایش در ماشین، دیدن نام خیابان ها مفید است، بنابراین می توانید از گزینه عادی استفاده کنید. هنگامی که در حال پیاده روی هستید، نقشه زمین می تواند برای تصمیم گیری در مورد اینکه چقدر بیشتر باید صعود کنید تا به قله بروید، مفید باشد.

در این وظیفه شما:

  1. یک نوار برنامه با منوی گزینه‌ها اضافه کنید که به کاربر امکان می‌دهد نوع نقشه را تغییر دهد.
  2. مکان شروع نقشه را به مکان خانه خود منتقل کنید.
  3. برای نشانگرها پشتیبانی اضافه کنید، که مکان‌های منفرد را روی نقشه نشان می‌دهند و می‌توانند شامل یک برچسب باشند.

اضافه کردن منو برای انواع نقشه

در این مرحله یک نوار برنامه با منوی گزینه ها اضافه می کنید که به کاربر اجازه می دهد نوع نقشه را تغییر دهد.

  1. برای ایجاد یک فایل XML منوی جدید، روی دایرکتوری res خود کلیک راست کرده و New > Android Resource File را انتخاب کنید.
  2. در گفتگو، نام فایل map_options را بگذارید.
  3. منو را برای نوع منبع انتخاب کنید.
  4. روی OK کلیک کنید.
  5. در سربرگ Code ، کد موجود در فایل جدید را با کد زیر جایگزین کنید تا گزینه های منوی نقشه ایجاد شود. نوع نقشه "هیچ" حذف شده است زیرا "هیچ" منجر به فقدان نقشه می شود. این مرحله باعث ایجاد خطا می شود، اما در مرحله بعد آن را برطرف می کنید.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
   <item
       android:id="@+id/normal_map"
       android:title="@string/normal_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/hybrid_map"
       android:title="@string/hybrid_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/satellite_map"
       android:title="@string/satellite_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/terrain_map"
       android:title="@string/terrain_map"
       app:showAsAction="never" />
</menu>
  1. در strings.xml ، منابعی را برای صفات title اضافه کنید تا خطاها را برطرف کنید.
<resources>
   ...
   <string name="normal_map">Normal Map</string>
   <string name="hybrid_map">Hybrid Map</string>
   <string name="satellite_map">Satellite Map</string>
   <string name="terrain_map">Terrain Map</string>
   <string name="lat_long_snippet">Lat: %1$.5f, Long: %2$.5f</string>
   <string name="dropped_pin">Dropped Pin</string>
   <string name="poi">poi</string>
</resources>
  1. در MapsActivity ، روش onCreateOptionsMenu() را لغو کنید و منو را از فایل منبع map_options باز کنید.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. در MapsActivity.kt ، روش onOptionsItemSelected() را لغو کنید. نوع نقشه را با استفاده از ثابت های نوع نقشه تغییر دهید تا انتخاب کاربر را منعکس کند.
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
   // Change the map type based on the user's selection.
   R.id.normal_map -> {
       map.mapType = GoogleMap.MAP_TYPE_NORMAL
       true
   }
   R.id.hybrid_map -> {
       map.mapType = GoogleMap.MAP_TYPE_HYBRID
       true
   }
   R.id.satellite_map -> {
       map.mapType = GoogleMap.MAP_TYPE_SATELLITE
       true
   }
   R.id.terrain_map -> {
       map.mapType = GoogleMap.MAP_TYPE_TERRAIN
       true
   }
   else -> super.onOptionsItemSelected(item)
}
  1. برنامه را اجرا کنید.
  2. کلیک برای تغییر نوع نقشه توجه کنید که چگونه ظاهر نقشه بین حالت های مختلف تغییر می کند.

به‌طور پیش‌فرض، onMapReady() شامل کدی است که نشانگری را در سیدنی، استرالیا، جایی که Google Maps ایجاد شده، قرار می‌دهد. تماس پیش‌فرض نیز نقشه را متحرک می‌کند تا به سیدنی حرکت کند.

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

مرحله 1: خانه خود را بزرگنمایی کنید و یک نشانگر اضافه کنید

  1. در فایل MapsActivity.kt ، onMapReady() را پیدا کنید. کد موجود در آن را که نشانگر را در سیدنی قرار می دهد و دوربین را حرکت می دهد حذف کنید. این همان چیزی است که روش شما اکنون باید شبیه باشد.
override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

}
  1. با دنبال کردن این دستورالعمل ها طول و عرض جغرافیایی خانه خود را بیابید.
  2. یک مقدار برای عرض جغرافیایی و یک مقدار برای طول جغرافیایی ایجاد کنید و مقادیر شناور آنها را وارد کنید.
val latitude = 37.422160
val longitude = -122.084270
  1. یک شی LatLng جدید به نام homeLatLng کنید. در شی homeLatLng ، مقادیری را که ایجاد کردید وارد کنید.
val homeLatLng = LatLng(latitude, longitude)
  1. یک val برای میزان بزرگنمایی که می خواهید روی نقشه داشته باشید ایجاد کنید. از سطح زوم 15f استفاده کنید.
val zoomLevel = 15f

سطح بزرگنمایی میزان بزرگنمایی شما روی نقشه را کنترل می کند. لیست زیر به شما ایده می دهد که هر سطح از زوم چه سطحی از جزئیات را نشان می دهد:

  • 1 : جهان
  • 5 : خشکی/قاره
  • 10 : شهر
  • 15 : خیابان ها
  • 20 : ساختمان ها
  1. با فراخوانی تابع moveCamera() روی شی map ، دوربین را به homeLatLng منتقل کنید و با استفاده از CameraUpdateFactory.newLatLngZoom() یک شی CameraUpdate را ارسال کنید. از شی homeLatLng و zoomLevel .
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. یک نشانگر به نقشه در homeLatLng کنید.
map.addMarker(MarkerOptions().position(homeLatLng))

روش نهایی شما باید به این صورت باشد:

override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

   //These coordinates represent the latitude and longitude of the Googleplex.
   val latitude = 37.422160
   val longitude = -122.084270
   val zoomLevel = 15f

   val homeLatLng = LatLng(latitude, longitude)
   map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
   map.addMarker(MarkerOptions().position(homeLatLng))
}
  1. برنامه خود را اجرا کنید نقشه باید به خانه شما حرکت کند، تا سطح مورد نظر زوم کند و یک نشانگر روی خانه شما قرار دهد.

مرحله 2: به کاربران اجازه دهید با یک کلیک طولانی یک نشانگر اضافه کنند

در این مرحله، زمانی که کاربر مکانی را روی نقشه لمس کرده و نگه می دارد، یک نشانگر اضافه می کنید.

  1. یک روش خرد در MapsActivity به نام setMapLongClick() ایجاد کنید که یک GoogleMap را به عنوان آرگومان می گیرد.
  2. شنونده setOnMapLongClickListener را به شی نقشه متصل کنید.
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. در setOnMapLongClickListener() متد addMarker() را فراخوانی کنید. یک شی MarkerOptions جدید با موقعیتی که روی LatLng تصویب شده تنظیم شده است، ارسال کنید.
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. در پایان onMapReady() onMapReady، setMapLongClick() را با map فراخوانی کنید.
override fun onMapReady(googleMap: GoogleMap) {
   ...
  
   setMapLongClick(map)
}
  1. برنامه خود را اجرا کنید
  2. برای قرار دادن نشانگر در یک مکان، نقشه را لمس کنید و نگه دارید.
  3. روی نشانگر ضربه بزنید، که آن را در مرکز صفحه نمایش قرار می دهد.

مرحله 3: یک پنجره اطلاعات برای نشانگر اضافه کنید

در این مرحله یک InfoWindow اضافه می‌کنید که مختصات نشانگر را با ضربه زدن روی نشانگر نمایش می‌دهد.

  1. در setMapLongClick()setOnMapLongClickListener() یک val برای snippet ایجاد کنید. یک قطعه متن اضافی است که بعد از عنوان نمایش داده می شود. قطعه شما طول و عرض جغرافیایی یک نشانگر را نشان می دهد.
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       // A snippet is additional text that's displayed after the title.
       val snippet = String.format(
           Locale.getDefault(),
           "Lat: %1$.5f, Long: %2$.5f",
           latLng.latitude,
           latLng.longitude
       )
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. در addMarker() title نشانگر را با استفاده از R.string روی R.string. منبع رشته dropped_pin .
  2. snippet نشانگر را روی snippet تنظیم کنید.

تابع تکمیل شده به صورت زیر است:

private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       // A Snippet is Additional text that's displayed below the title.
       val snippet = String.format(
           Locale.getDefault(),
           "Lat: %1$.5f, Long: %2$.5f",
           latLng.latitude,
           latLng.longitude
       )
       map.addMarker(
           MarkerOptions()
               .position(latLng)
               .title(getString(R.string.dropped_pin))
               .snippet(snippet)
              
       )
   }
}
  1. برنامه خود را اجرا کنید
  2. برای رها کردن نشانگر موقعیت، نقشه را لمس کرده و نگه دارید.
  3. روی نشانگر ضربه بزنید تا پنجره اطلاعات نمایش داده شود.

مرحله 4: شنونده POI را اضافه کنید

به طور پیش فرض، نقاط مورد علاقه (POI) به همراه نمادهای مربوطه روی نقشه ظاهر می شوند. POI شامل پارک ها، مدارس، ساختمان های دولتی و موارد دیگر می شود. وقتی نوع نقشه روی normal تنظیم می شود، POI های تجاری نیز روی نقشه ظاهر می شوند. کسب و کار POI نشان دهنده مشاغلی مانند مغازه ها، رستوران ها و هتل ها است.

در این مرحله یک GoogleMap.OnPoiClickListener را به نقشه اضافه می کنید. این کلیک شنونده بلافاصله هنگامی که کاربر روی یک POI کلیک می کند یک نشانگر روی نقشه قرار می دهد. شنونده کلیک نیز یک پنجره اطلاعاتی را نشان می دهد که حاوی نام POI است.

  1. یک روش خرد در MapsActivity به نام setPoiClick() ایجاد کنید که GoogleMap را به عنوان آرگومان می گیرد.
  2. در setPoiClick() ، یک OnPoiClickListener را روی GoogleMap تصویب شده تنظیم کنید.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->

   }
}
  1. در setOnPoiClickListener() یک val poiMarker برای نشانگر ایجاد کنید.
  2. با استفاده از map.addMarker() آن را روی یک نشانگر تنظیم کنید و MarkerOptions title را به نام POI تنظیم کند.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
   }
}
  1. در تابع setOnPoiClickListener() ، showInfoWindow() را در poiMarker کنید تا فوراً پنجره اطلاعات نمایش داده شود.
poiMarker.showInfoWindow()

کد نهایی شما برای تابع setPoiClick() باید شبیه این باشد.

private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
       poiMarker.showInfoWindow()
   }
}
  1. در انتهای onMapReady() ، setPoiClick() را فراخوانی کنید و map را ارسال کنید.
override fun onMapReady(googleMap: GoogleMap) {
   ...

   setPoiClick(map)
}
  1. برنامه خود را اجرا کنید و یک POI مانند پارک یا کافی شاپ پیدا کنید.
  2. روی POI ضربه بزنید تا یک نشانگر روی آن قرار دهید و نام POI در یک پنجره اطلاعات نمایش داده شود.

می‌توانید نقشه‌های گوگل را به روش‌های مختلف سفارشی کنید و به نقشه خود ظاهر و احساسی منحصربفرد بدهید.

شما می توانید یک شی MapFragment را با استفاده از ویژگی های XML موجود سفارشی کنید، همانطور که هر قطعه دیگری را سفارشی می کنید. با این حال، در این مرحله، ظاهر و احساس محتوای MapFragment را با استفاده از روش‌هایی روی شی GoogleMap سفارشی می‌کنید.

برای ایجاد یک سبک سفارشی برای نقشه خود، یک فایل JSON ایجاد می کنید که نحوه نمایش ویژگی های نقشه را مشخص می کند. لازم نیست این فایل JSON را به صورت دستی ایجاد کنید. Google Maps Platform Styling Wizard را ارائه می‌کند که پس از استایل بصری نقشه خود، JSON را برای شما تولید می‌کند. در این کار، نقشه را با تم رترو استایل می‌دهید، یعنی نقشه از رنگ‌های قدیمی استفاده می‌کند و جاده‌های رنگی را اضافه می‌کنید.

مرحله 1: یک سبک برای نقشه خود ایجاد کنید

  1. در مرورگر خود به https://mapstyle.withgoogle.com/ بروید .
  2. Create a Style را انتخاب کنید.
  3. Retro را انتخاب کنید.

  1. روی گزینه های بیشتر کلیک کنید.

  1. در لیست نوع ویژگی ، جاده > پر کردن را انتخاب کنید.
  2. رنگ جاده ها را به هر رنگی که انتخاب می کنید (مانند صورتی) تغییر دهید.

  1. روی Finish کلیک کنید.

  1. کد JSON را از دیالوگ به دست آمده کپی کنید و در صورت تمایل، آن را در یک یادداشت متنی ساده ذخیره کنید تا در مرحله بعد از آن استفاده کنید.

مرحله 2: سبک را به نقشه خود اضافه کنید

  1. در اندروید استودیو، در res دایرکتوری، یک دایرکتوری منبع ایجاد کنید و نام آن را raw بگذارید. شما از منابع دایرکتوری raw مانند کد JSON استفاده می کنید.
  2. یک فایل در res/raw به نام map_style.json کنید.
  3. کد JSON مخفی شده خود را در فایل منبع جدید جای‌گذاری کنید.
  4. در MapsActivity ، یک متغیر کلاس TAG بالای onCreate() ایجاد کنید. این برای اهداف ورود به سیستم استفاده می شود.
private val TAG = MapsActivity::class.java.simpleName
  1. همچنین در MapsActivity ، یک setMapStyle() ایجاد کنید که GoogleMap را می گیرد.
  2. در setMapStyle() یک بلوک try{} اضافه کنید.
  3. در بلوک try{} ، یک val success برای موفقیت در استایل ایجاد کنید. (شما بلوک catch زیر را اضافه می کنید.)
  4. در بلوک try{} ، سبک JSON را روی نقشه تنظیم کنید، setMapStyle() را در شیء GoogleMap فراخوانی کنید. یک شی MapStyleOptions را ارسال کنید، که فایل JSON را بارگیری می کند.
  5. نتیجه را به success اختصاص دهید. setMapStyle() یک بولی برمی گرداند که نشان دهنده وضعیت موفقیت آمیز تجزیه فایل استایل و تنظیم سبک است.
private fun setMapStyle(map: GoogleMap) {
   try {
       // Customize the styling of the base map using a JSON object defined
       // in a raw resource file.
       val success = map.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
               this,
               R.raw.map_style
           )
       )
   }
}
  1. برای false بودن success یک عبارت if اضافه کنید. اگر یک ظاهر طراحی ناموفق بود، گزارشی را چاپ کنید که تجزیه ناموفق است.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   }
}
  1. یک بلوک catch{} برای رسیدگی به وضعیت یک فایل سبک از دست رفته اضافه کنید. در بلوک catch ، اگر فایل قابل بارگیری نیست، یک Resources.NotFoundException را پرتاب کنید.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

متد تمام شده باید شبیه قطعه کد زیر باشد:

private fun setMapStyle(map: GoogleMap) {
   try {
       // Customize the styling of the base map using a JSON object defined
       // in a raw resource file.
       val success = map.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
               this,
               R.raw.map_style
           )
       )

       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}
  1. در نهایت، متد GoogleMap setMapStyle() را در متد onMapReady() فراخوانی کنید.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. برنامه خود را اجرا کنید
  2. نقشه را روی حالت normal تنظیم کنید و یک ظاهر طراحی جدید باید با طرح زمینه و جاده های رنگ انتخابی شما قابل مشاهده باشد.

مرحله 3: به نشانگر خود سبک دهید

شما می توانید نقشه خود را بیشتر با طراحی نشانگرهای نقشه شخصی سازی کنید. در این مرحله، نشانگرهای قرمز پیش‌فرض را به چیزی شیاردارتر تغییر می‌دهید.

  1. در onMapLongClick() خط کد زیر را به MarkerOptions() سازنده اضافه کنید تا از نشانگر پیش فرض استفاده کنید، اما رنگ را به آبی تغییر دهید.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))

اکنون onMapLongClickListener() شکل زیر است:

map.setOnMapLongClickListener { latLng ->
   // A snippet is additional text that's displayed after the title.
   val snippet = String.format(
       Locale.getDefault(),
       "Lat: %1$.5f, Long: %2$.5f",
       latLng.latitude,
       latLng.longitude
   )
   map.addMarker(
       MarkerOptions()
           .position(latLng)
           .title(getString(R.string.dropped_pin))
           .snippet(snippet)
         .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
   )
}
  1. برنامه را اجرا کنید. نشانگرهایی که پس از کلیک طولانی شما ظاهر می شوند اکنون به رنگ آبی در می آیند. توجه داشته باشید که نشانگرهای POI همچنان قرمز هستند زیرا استایلی را به onPoiClick() اضافه نکردید.

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

  • شکل ها: می توانید چند خط، چند ضلعی و دایره را به نقشه اضافه کنید .
  • اشیاء GroundOverlay : روکش زمین تصویری است که روی نقشه ثابت می شود. بر خلاف نشانگرها، روکش‌های زمین به جای صفحه نمایش، به سطح زمین می‌روند. چرخش، کج کردن، یا بزرگنمایی نقشه، جهت تصویر را تغییر می دهد. پوشش های زمین زمانی مفید هستند که می خواهید یک تصویر واحد را در یک منطقه روی نقشه ثابت کنید.

مرحله: یک روکش زمین اضافه کنید

در این کار، یک روکش زمین به شکل اندروید به محل خانه خود اضافه می کنید.

  1. این تصویر اندروید را دانلود کنید و در پوشه res/drawable ذخیره کنید. (مطمئن شوید که نام فایل android.png باشد.)

  1. در onMapReady() ، پس از تماس برای انتقال دوربین به موقعیت خانه خود، یک شی GroundOverlayOptions ایجاد کنید.
  2. شی را به متغیری به نام androidOverlay اختصاص دهید.
val androidOverlay = GroundOverlayOptions()
  1. از BitmapDescriptorFactory.fromResource() برای ایجاد یک شی BitmapDescriptor از منبع تصویر دانلود شده استفاده کنید.
  2. شی BitmapDescriptor حاصل را به متد image() شی GroundOverlayOptions کنید.
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. یک float overlaySize برای عرض بر حسب متر از پوشش مورد نظر ایجاد کنید. برای این مثال، عرض 100f به خوبی کار می کند.

ویژگی position را برای شی GroundOverlayOptions با فراخوانی متد position() تنظیم کنید و شی homeLatLng و overlaySize را ارسال کنید.

val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
   .position(homeLatLng, overlaySize)
  1. addGroundOverlay() را روی شی GoogleMap فراخوانی کنید و شی GroundOverlayOptions خود را ارسال کنید.
map.addGroundOverlay(androidOverlay)
  1. برنامه را اجرا کنید.
  2. مقدار zoomLevel را به 18f تغییر دهید تا تصویر اندروید را به صورت همپوشانی ببینید.

کاربران اغلب از نقشه های گوگل برای دیدن مکان فعلی خود استفاده می کنند. برای نمایش مکان دستگاه روی نقشه، می‌توانید از لایه مکان-داده استفاده کنید.

لایه مکان-داده موقعیت مکانی من را به نقشه اضافه می کند. هنگامی که کاربر روی دکمه ضربه می زند، نقشه بر روی مکان دستگاه متمرکز می شود. اگر دستگاه ثابت است، مکان به صورت یک نقطه آبی و اگر دستگاه در حال حرکت است به صورت یک شورون آبی نشان داده می شود.

در این کار، لایه مکان-داده را فعال می کنید.

مرحله: درخواست مجوزهای مکان

فعال کردن ردیابی موقعیت مکانی در Google Maps به یک خط کد نیاز دارد. با این حال، باید مطمئن شوید که کاربر مجوزهای موقعیت مکانی را داده است (با استفاده از مدل مجوز زمان اجرا).

در این مرحله شما مجوزهای موقعیت مکانی را درخواست می کنید و ردیابی موقعیت مکانی را فعال می کنید.

  1. در فایل AndroidManifest.xml ، بررسی کنید که مجوز FINE_LOCATION از قبل وجود داشته باشد. زمانی که شما الگوی Google Maps را انتخاب کردید، Android Studio این مجوز را وارد کرد.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. در MapsActivity ، یک متغیر کلاس REQUEST_LOCATION_PERMISSION ایجاد کنید.
private val REQUEST_LOCATION_PERMISSION = 1
  1. برای بررسی اینکه آیا مجوزها اعطا شده اند یا خیر، روشی به نام MapsActivity isPermissionGranted() در MapsActivity ایجاد کنید. در این روش بررسی کنید که آیا کاربر مجوز را داده است یا خیر.
private fun isPermissionGranted() : Boolean {
  return ContextCompat.checkSelfPermission(
       this,
      Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
  1. برای فعال کردن ردیابی موقعیت مکانی در برنامه خود، روشی به نام enableMyLocation() MapsActivity ایجاد کنید که هیچ آرگومانی نمی‌گیرد و چیزی را بر نمی‌گرداند. در داخل، مجوز ACCESS_FINE_LOCATION را بررسی کنید. اگر مجوز داده شده است، لایه مکان را فعال کنید. در غیر این صورت، درخواست مجوز کنید.
private fun enableMyLocation() {
   if (isPermissionGranted()) {
       map.isMyLocationEnabled = true 
   }
   else {
       ActivityCompat.requestPermissions(
           this,
           arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
           REQUEST_LOCATION_PERMISSION
       )
   }
}
  1. برای فعال کردن لایه مکان، از روی ( enableMyLocation() onMapReady() فراخوانی کنید.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. روش onRequestPermissionsResult() را لغو کنید. اگر requestCode برابر با REQUEST_LOCATION_PERMISSION است، اجازه داده می‌شود، و اگر آرایه grantResults با PackageManager.PERMISSION_GRANTED در اولین شکاف خالی نباشد، enableMyLocation() .
override fun onRequestPermissionsResult(
   requestCode: Int,
   permissions: Array<String>,
   grantResults: IntArray) {
   if (requestCode == REQUEST_LOCATION_PERMISSION) {
       if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
           enableMyLocation()
       }
   }
}
  1. برنامه خود را اجرا کنید باید گفتگویی وجود داشته باشد که درخواست دسترسی به مکان دستگاه را می دهد. برو جلو و اجازه بده.

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

کد مربوط به کد لبه تمام شده را دانلود کنید.

$  git clone https://github.com/googlecodelabs/android-kotlin-geo-maps


همچنین، می‌توانید مخزن را به‌صورت یک فایل فشرده دانلود کنید، آن را از حالت فشرده خارج کرده و در اندروید استودیو باز کنید.

فایل فشرده را دانلود کنید

  • برای استفاده از Maps API، به یک کلید API از Google API Console نیاز دارید.
  • در Android Studio، با استفاده از الگوی Google Maps Activity یک Activity با یک SupportMapFragment در طرح‌بندی برنامه ایجاد می‌شود. این الگو همچنین ACCESS_FINE_PERMISSION را به مانیفست برنامه اضافه می‌کند، و OnMapReadyCallback را در فعالیت شما پیاده‌سازی می‌کند، و روش مورد نیاز onMapReady() را لغو می‌کند.

برای تغییر نوع نقشه یک GoogleMap در زمان اجرا، از متد GoogleMap.setMapType() استفاده کنید. نقشه گوگل می تواند یکی از انواع نقشه های زیر باشد:

  • عادی : نقشه راه معمولی. جاده ها، برخی از ویژگی های ساخته شده توسط انسان، و ویژگی های مهم طبیعی مانند رودخانه ها را نشان می دهد. برچسب های جاده و ویژگی نیز قابل مشاهده است.
  • ترکیبی : داده های عکس های ماهواره ای با اضافه شدن نقشه های راه. برچسب های جاده و ویژگی نیز قابل مشاهده است.
  • ماهواره : داده های عکس. برچسب‌های جاده و ویژگی قابل مشاهده نیستند.
  • زمین : داده های توپوگرافی این نقشه شامل رنگ‌ها، خطوط و برچسب‌های کانتور و سایه‌های پرسپکتیو است. برخی از جاده ها و برچسب ها نیز قابل مشاهده هستند.
  • هیچ : بدون کاشی نقشه پایه.

درباره Google Maps:

  • نشانگر یک نشانگر برای یک موقعیت جغرافیایی خاص است.
  • هنگامی که ضربه بزنید، رفتار پیش فرض نشانگر نمایش یک پنجره اطلاعات با اطلاعات مکان است.
  • به طور پیش فرض، نقاط مورد علاقه (POI) به همراه نمادهای مربوطه روی نقشه پایه ظاهر می شوند. POI شامل پارک ها، مدارس، ساختمان های دولتی و موارد دیگر می شود.
  • علاوه بر این، POI های کسب و کار (فروشگاه ها، رستوران ها، هتل ها و موارد دیگر) به طور پیش فرض روی نقشه ظاهر می شوند که نوع نقشه normal باشد.
  • با استفاده از OnPoiClickListener می‌توانید کلیک‌ها را روی POI ثبت کنید.
  • شما می توانید ظاهر بصری تقریباً تمام عناصر یک نقشه گوگل را با استفاده از Styling Wizard تغییر دهید. Styling Wizard یک فایل JSON تولید می کند که شما با استفاده از setMapStyle() به Google Map ارسال می کنید.
  • می‌توانید با تغییر رنگ پیش‌فرض، یا جایگزین کردن نماد نشانگر پیش‌فرض با یک تصویر سفارشی، نشانگرهای خود را سفارشی کنید.

اطلاعات مهم دیگر:

  • از روکش زمین برای تثبیت تصویر در یک مکان جغرافیایی استفاده کنید.
  • از یک شی GroundOverlayOptions برای تعیین تصویر، اندازه تصویر بر حسب متر و موقعیت تصویر استفاده کنید. این شی را به متد GoogleMap.addGroundOverlay() کنید تا همپوشانی روی نقشه تنظیم شود.
  • به شرطی که برنامه شما دارای مجوز ACCESS_FINE_LOCATION باشد، می‌توانید ردیابی موقعیت مکانی را با تنظیم map.isMyLocationEnabled = true فعال کنید.
  • این کد در این کد پوشش داده نمی‌شود، اما می‌توانید با استفاده از نمای خیابان Google ، که یک عکس پانورامای قابل پیمایش از یک مکان معین است، اطلاعات بیشتری درباره یک مکان ارائه کنید.

مستندات توسعه دهنده اندروید:

مستندات مرجع:

برای پیوند به سایر کدهای این دوره، به صفحه فرود Android Advanced in Kotlin codelabs مراجعه کنید.