۱. قبل از شروع
ساخت اپلیکیشن با نقشههای گوگل به شما این امکان را میدهد که ویژگیهایی مانند تصاویر ماهوارهای، کنترلهای رابط کاربری قوی برای نقشهها، ردیابی موقعیت مکانی و نشانگرهای موقعیت مکانی را به اپلیکیشن خود اضافه کنید. میتوانید با نمایش اطلاعات از مجموعه دادههای خود، مانند مکانهای مناطق ماهیگیری یا کوهنوردی شناخته شده، به نقشههای استاندارد گوگل ارزش ببخشید. همچنین میتوانید بازیهایی بسازید که در آنها بازیکن دنیای فیزیکی را کاوش میکند، مانند یک بازی گنجیابی یا حتی بازیهای واقعیت افزوده.
در این درس، شما یک برنامه Google Maps به نام Wander ایجاد میکنید که نقشههای سفارشیسازی شده و موقعیت مکانی کاربر را نمایش میدهد.
پیشنیازها
آشنایی با موارد زیر:
- چگونه یک برنامه اندروید ساده بسازیم و با استفاده از اندروید استودیو آن را اجرا کنیم؟
- نحوه ایجاد و مدیریت منابع، مانند رشتهها.
- نحوهی ریفکتور کردن کد و تغییر نام متغیرها با استفاده از اندروید استودیو
- نحوه استفاده از نقشه گوگل به عنوان کاربر.
- نحوه تنظیم مجوزهای زمان اجرا
آنچه یاد خواهید گرفت
- نحوه دریافت کلید API از کنسول API گوگل و ثبت کلید در برنامه شما
- نحوه ادغام نقشه گوگل در برنامه شما
- نحوه نمایش انواع مختلف نقشه
- نحوه استایل دادن به نقشه گوگل
- نحوه اضافه کردن نشانگر به نقشه شما
- چگونه به کاربر امکان دهیم که روی یک نقطه مورد نظر (POI) علامتگذاری کند؟
- نحوه فعال کردن ردیابی موقعیت مکانی
- نحوه ایجاد برنامه The
Wanderکه دارای نقشه گوگل جاسازی شده است - نحوه ایجاد ویژگیهای سفارشی برای برنامه شما، مانند نشانگرها و استایلبندی
- نحوه فعال کردن ردیابی موقعیت مکانی در برنامه شما
۲. مرور کلی برنامه
در این آزمایشگاه کد، شما برنامه Wander را ایجاد میکنید که یک نقشه گوگل را با سبک سفارشی نمایش میدهد. برنامه Wander به شما امکان میدهد نشانگرها را روی مکانها قرار دهید، پوششها را اضافه کنید و مکان خود را به صورت بلادرنگ مشاهده کنید.

۳. وظیفه: راهاندازی پروژه و دریافت کلید API
کیت توسعه نرمافزار نقشهها برای اندروید به یک کلید API نیاز دارد. برای دریافت کلید API، پروژه خود را در صفحه API & Services ثبت کنید. کلید API به یک گواهی دیجیتال متصل است که برنامه را به نویسنده آن پیوند میدهد. برای اطلاعات بیشتر در مورد استفاده از گواهیهای دیجیتال و امضای برنامه، به بخش امضای برنامه مراجعه کنید.
در این آزمایشگاه کد، شما از کلید API برای گواهی اشکالزدایی استفاده میکنید. گواهی اشکالزدایی، همانطور که در بخش امضای نسخه اشکالزدایی توضیح داده شده است، از نظر طراحی ناامن است. برنامههای اندروید منتشر شده که از Maps SDK برای اندروید استفاده میکنند، به یک کلید API دوم نیاز دارند: کلید گواهی انتشار. برای اطلاعات بیشتر در مورد دریافت گواهی انتشار، به دریافت کلید API مراجعه کنید.
اندروید استودیو شامل یک الگوی فعالیت نقشههای گوگل است که کد الگوی مفیدی تولید میکند. کد الگو شامل یک فایل google_maps_api.xml است که حاوی لینکی است که دریافت کلید API را ساده میکند.
مرحله ۱: ایجاد پروژه Wander با استفاده از الگوی نقشهها
- یک پروژه جدید اندروید استودیو ایجاد کنید.
- الگوی فعالیت نقشههای گوگل را انتخاب کنید.

- نام پروژه را
Wander. - حداقل سطح API را روی API 19 تنظیم کنید. مطمئن شوید که زبان Kotlin است.
- روی پایان کلیک کنید.
- پس از اتمام ساخت برنامه، به پروژه خود و فایلهای مربوط به نقشههای زیر که اندروید استودیو برای شما ایجاد میکند، نگاهی بیندازید:
google_maps_api.xml — شما از این فایل پیکربندی برای نگهداری کلید API خود استفاده میکنید. این الگو دو فایل google_maps_api.xml تولید میکند: یکی برای اشکالزدایی و دیگری برای انتشار. فایل مربوط به کلید API برای گواهی اشکالزدایی در src/debug/res/values قرار دارد. فایل مربوط به کلید API برای گواهی انتشار در src/release/res/values قرار دارد. در این codelab، شما فقط از گواهی اشکالزدایی استفاده میکنید.
activity_maps.xml — این فایل طرحبندی شامل یک قطعه کد واحد است که کل صفحه را پر میکند. کلاس SupportMapFragment یک زیرکلاس از کلاس Fragment است. یک SupportMapFragment سادهترین راه برای قرار دادن یک نقشه در یک برنامه است. این یک پوشش در اطراف نمای یک نقشه است تا به طور خودکار نیازهای چرخه عمر لازم را مدیریت کند.
شما میتوانید SupportMapFragment با استفاده از یک تگ <fragment> در هر ViewGroup و با یک ویژگی name اضافی، در یک فایل layout قرار دهید.
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.java — فایل MapsActivity.kt ، SupportMapFragment را در متد onCreate() نمونهسازی میکند و از کلاس getMapAsync () برای مقداردهی اولیه خودکار سیستم نقشهها و نما استفاده میکند. اکتیویتی که شامل SupportMapFragment است، باید رابط OnMapReadyCallback و متد onMapReady() آن رابط را پیادهسازی کند. متد onMapReady() هنگام بارگذاری نقشه فراخوانی میشود.
مرحله ۲: دریافت کلید API
- نسخه اشکالزدایی فایل google_maps_api.xml را باز کنید.
- در فایل، به دنبال کامنتی با آدرس اینترنتی (URL) طولانی باشید. پارامترهای این آدرس اینترنتی شامل اطلاعات خاصی در مورد برنامه شما هستند.
- آدرس اینترنتی (URL) را کپی کرده و در مرورگر جایگذاری کنید.
- برای ایجاد یک پروژه در صفحه APIها و خدمات ، دستورالعملها را دنبال کنید. به دلیل پارامترهای موجود در URL ارائه شده، صفحه میداند که به طور خودکار Maps SDK را برای اندروید فعال کند.
- روی ایجاد کلید API کلیک کنید.
- در صفحه بعد، به بخش کلیدهای API بروید و روی کلیدی که ایجاد کردهاید کلیک کنید.
- روی Restrict Key کلیک کنید و Maps SDK for Android را انتخاب کنید تا استفاده از کلید به برنامههای اندروید محدود شود.
- کلید API تولید شده را کپی کنید. با "
AIza"شروع میشود. - در فایل
google_maps_api.xml، کلید را در رشتهgoogle_maps_keyجایی کهYOUR_KEY_HEREنوشته شده است، جایگذاری کنید. - برنامه خود را اجرا کنید. باید یک نقشه جاسازی شده در activity خود با نشانگری که در سیدنی، استرالیا تنظیم شده است، ببینید. (نشانگر سیدنی بخشی از الگو است و بعداً آن را تغییر میدهید.)

مرحله ۳: تغییر نام mMap
MapsActivity یک var lateinit خصوصی به نام mMap دارد که از نوع GoogleMap است. برای پیروی از قراردادهای نامگذاری Kotlin، نام mMap را به map تغییر دهید.
- در
MapsActivity، رویmMapکلیک راست کرده و Refactor > Rename... را انتخاب کنید.

- نام متغیر را به
mapتغییر دهید.
توجه کنید که چگونه تمام ارجاعات به mMap در تابع onMapReady() نیز به map تغییر میکنند.
۴. وظیفه: اضافه کردن انواع نقشه
نقشههای گوگل شامل چندین نوع نقشه هستند: معمولی، ترکیبی، ماهوارهای، زمینی و «هیچ» (یعنی اصلاً نقشهای وجود ندارد).
|
|
|
|
نقشه عادی | نقشه ماهوارهای | نقشه ترکیبی | نقشه زمین |
هر نوع نقشه اطلاعات متفاوتی ارائه میدهد. برای مثال، هنگام استفاده از نقشهها برای جهتیابی در ماشین، دیدن نام خیابانها مفید است، بنابراین میتوانید از گزینه معمولی استفاده کنید. هنگام پیادهروی، نقشه عوارض زمین میتواند برای تصمیمگیری در مورد اینکه چقدر دیگر باید صعود کنید تا به قله برسید، مفید باشد.
در این وظیفه شما:
- یک نوار برنامه با منوی گزینهها اضافه کنید که به کاربر اجازه میدهد نوع نقشه را تغییر دهد.
- محل شروع نقشه را به محل خانه خودتان منتقل کنید.
- پشتیبانی از نشانگرها را اضافه کنید، که مکانهای تکی را روی نقشه نشان میدهند و میتوانند شامل یک برچسب باشند.
اضافه کردن منو برای انواع نقشه
در این مرحله، یک نوار برنامه با منوی گزینهها اضافه میکنید که به کاربر اجازه میدهد نوع نقشه را تغییر دهد.
- برای ایجاد یک فایل XML منوی جدید، روی دایرکتوری res خود راست کلیک کرده و New > Android Resource File را انتخاب کنید.
- در کادر محاورهای، نام فایل را
map_optionsبگذارید. - برای نوع منبع، منو را انتخاب کنید.
- روی تأیید کلیک کنید.
- در تب Code ، کد موجود در فایل جدید را با کد زیر جایگزین کنید تا گزینههای منوی نقشه ایجاد شود. نوع نقشه "none" حذف شده است زیرا "none" منجر به عدم وجود هیچ نقشهای میشود. این مرحله باعث ایجاد خطا میشود، اما شما آن را در مرحله بعدی برطرف میکنید.
<?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>
- در
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>
- در
MapsActivity، متدonCreateOptionsMenu()را بازنویسی کنید و منو را از فایل منبعmap_optionsایجاد کنید.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.map_options, menu)
return true
}
- در
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)
}
- برنامه را اجرا کنید.
- کلیک
برای تغییر نوع نقشه. توجه کنید که ظاهر نقشه چگونه بین حالتهای مختلف تغییر میکند.

۵. وظیفه: اضافه کردن نشانگرها
به طور پیشفرض، تابع فراخوانی onMapReady() شامل کدی است که یک نشانگر را در سیدنی، استرالیا، جایی که نقشههای گوگل ایجاد شدهاند، قرار میدهد. این تابع فراخوانی پیشفرض همچنین نقشه را برای حرکت به سمت سیدنی متحرک میکند.
در این تکلیف، شما دوربین نقشه را به سمت خانه خود حرکت میدهید، تا سطحی که مشخص میکنید زوم میکنید و یک نشانگر در آنجا قرار میدهید.
مرحله ۱: روی خانه خود زوم کنید و یک نشانگر اضافه کنید
- در فایل
MapsActivity.kt، متدonMapReady()را پیدا کنید. کدی که نشانگر را در سیدنی قرار میدهد و دوربین را حرکت میدهد را از آن حذف کنید. اکنون متد شما باید به این شکل باشد.
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
}
- با دنبال کردن این دستورالعملها، طول و عرض جغرافیایی خانه خود را پیدا کنید.
- یک مقدار برای عرض جغرافیایی و یک مقدار برای طول جغرافیایی ایجاد کنید و مقادیر اعشاری آنها را وارد کنید.
val latitude = 37.422160
val longitude = -122.084270
- یک شیء
LatLngجدید به نامhomeLatLngایجاد کنید. در شیءhomeLatLng، مقادیری را که ایجاد کردهاید، وارد کنید.
val homeLatLng = LatLng(latitude, longitude)
- برای میزان بزرگنمایی مورد نظر خود روی نقشه، یک
valایجاد کنید. از سطح بزرگنمایی 15f استفاده کنید.
val zoomLevel = 15f
سطح بزرگنمایی، میزان بزرگنمایی شما روی نقشه را کنترل میکند. لیست زیر به شما نشان میدهد که هر سطح بزرگنمایی چه سطحی از جزئیات را نشان میدهد:
-
1: جهان -
5: خشکی/قاره -
10: شهر -
15: خیابانها -
20: ساختمانها
- با فراخوانی تابع
moveCamera()روی شیءmap، دوربین را بهhomeLatLngمنتقل کنید و با استفاده ازCameraUpdateFactory.newLatLngZoom()یک شیءCameraUpdateبه آن ارسال کنید. شیءhomeLatLngوzoomLevelنیز ارسال کنید.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
- یک نشانگر به نقشه در
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))
}
- برنامه خود را اجرا کنید. نقشه باید به خانه شما حرکت کند، تا سطح مورد نظر بزرگنمایی کند و یک نشانگر روی خانه شما قرار دهد.

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

مرحله ۳: یک پنجره اطلاعات برای نشانگر اضافه کنید
در این مرحله، یک InfoWindow اضافه میکنید که مختصات نشانگر را هنگام ضربه زدن به نشانگر نمایش میدهد.
- در
setMapLongClick()setOnMapLongClickListener()، یکvalبرایsnippetایجاد کنید. snippet متن اضافی است که بعد از عنوان نمایش داده میشود. 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)
)
}
}
- در
addMarker()،titleنشانگر را با استفاده از منبع رشتهایR.string.بهdropped_pinPin تنظیم کنید. -
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)
)
}
}
- برنامه خود را اجرا کنید.
- برای نمایش نشانگر مکان، نقشه را لمس کرده و نگه دارید.
- برای نمایش پنجره اطلاعات، روی نشانگر ضربه بزنید.

مرحله ۴: اضافه کردن شنونده POI
به طور پیشفرض، نقاط مورد علاقه (POI) به همراه نمادهای مربوطهشان روی نقشه ظاهر میشوند. POIها شامل پارکها، مدارس، ساختمانهای دولتی و موارد دیگر میشوند. وقتی نوع نقشه روی normal تنظیم شود، POIهای تجاری نیز روی نقشه ظاهر میشوند. POIهای تجاری نشاندهنده مشاغلی مانند مغازهها، رستورانها و هتلها هستند.
در این مرحله، یک GoogleMap.OnPoiClickListener به نقشه اضافه میکنید. این شنونده کلیک، بلافاصله پس از کلیک کاربر روی یک POI، یک نشانگر روی نقشه قرار میدهد. شنونده کلیک همچنین یک پنجره اطلاعات که شامل نام POI است را نمایش میدهد.
- یک متد stub در
MapsActivityبه نامsetPoiClick()ایجاد کنید که یکGoogleMapبه عنوان آرگومان دریافت کند. - در متد
setPoiClick()، یکOnPoiClickListenerرویGoogleMapارسالی تنظیم کنید.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
}
}
- در تابع
setOnPoiClickListener()، یکval poiMarkerبرای نشانگر ایجاد کنید. - با استفاده از
map.addMarker()و با تنظیمtitleبه نام POI توسطMarkerOptions، آن را روی یک نشانگر تنظیم کنید.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
}
}
- در تابع
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()
}
}
- در انتهای
onMapReady()، تابعsetPoiClick()را فراخوانی کرده وmapرا به آن ارسال کنید.
override fun onMapReady(googleMap: GoogleMap) {
...
setPoiClick(map)
}
- برنامه خود را اجرا کنید و یک POI (نقطه مورد نظر) مانند پارک یا کافیشاپ پیدا کنید.
- روی نقطه مورد نظر (POI) ضربه بزنید تا یک نشانگر روی آن قرار گیرد و نام آن در یک پنجره اطلاعات نمایش داده شود.

۶. وظیفه: نقشه خود را سبکبندی کنید
شما میتوانید نقشههای گوگل را از بسیاری جهات سفارشی کنید و به نقشه خود ظاهر و حس منحصر به فردی ببخشید.
شما میتوانید یک شیء MapFragment را با استفاده از ویژگیهای XML موجود، همانطور که هر قطعه کد دیگری را سفارشی میکنید، سفارشی کنید. با این حال، در این مرحله، ظاهر و حس محتوای MapFragment را با استفاده از متدهای شیء GoogleMap سفارشی میکنید.
برای ایجاد یک سبک سفارشی برای نقشه خود، یک فایل JSON ایجاد میکنید که نحوه نمایش ویژگیهای نقشه را مشخص میکند. لازم نیست این فایل JSON را به صورت دستی ایجاد کنید. گوگل ابزار سبکدهی پلتفرم نقشهها را ارائه میدهد که پس از اینکه نقشه خود را به صورت بصری سبکدهی کردید، JSON را برای شما تولید میکند. در این کار، نقشه را با یک تم رترو سبکدهی میکنید، به این معنی که نقشه از رنگهای قدیمی استفاده میکند و جادههای رنگی اضافه میکنید.
مرحله ۱: یک سبک برای نقشه خود ایجاد کنید
- در مرورگر خود به آدرس https://mapstyle.withgoogle.com/ بروید.
- ایجاد یک سبک را انتخاب کنید.
- رترو را انتخاب کنید.

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

- جاده > پر کردن را انتخاب کنید.
- رنگ جادهها را به هر رنگی که انتخاب میکنید (مثلاً صورتی) تغییر دهید.

- روی پایان کلیک کنید.

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

مرحله ۲: سبک را به نقشه خود اضافه کنید
- در اندروید استودیو، در پوشه
res، یک پوشه منابع ایجاد کنید و نام آن راrawبگذارید. شما از منابع پوشهrawمانند کد JSON استفاده میکنید. - یک فایل در
res/rawبا نامmap_style.jsonایجاد کنید. - کد JSON ذخیره شده خود را در فایل منبع جدید جایگذاری کنید.
- در
MapsActivity، یک متغیر کلاسTAGبالای متدonCreate()ایجاد کنید. این برای اهداف ثبت وقایع (logging) استفاده میشود.
private val TAG = MapsActivity::class.java.simpleName
- همچنین در
MapsActivity، یک تابعsetMapStyle()ایجاد کنید که یکGoogleMapرا دریافت کند. - در
setMapStyle()، یک بلوکtry{}اضافه کنید. - در بلوک
try{}، یکval successبرای موفقیت استایلبندی ایجاد کنید. (شما بلوک catch زیر را اضافه میکنید.) - در بلوک
try{}، سبک JSON را روی نقشه تنظیم کنید، تابعsetMapStyle()را روی شیءGoogleMapفراخوانی کنید. یک شیءMapStyleOptionsرا به آن ارسال کنید که فایل JSON را بارگذاری میکند. - نتیجه را به
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
)
)
}
}
- اگر تابع
successدر حالت false قرار داشت، یک دستور if اضافه کنید. اگر استایلبندی ناموفق بود، گزارشی مبنی بر ناموفق بودن تجزیه چاپ کند.
private fun setMapStyle(map: GoogleMap) {
try {
...
if (!success) {
Log.e(TAG, "Style parsing failed.")
}
}
}
- یک بلوک
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)
}
}
- در نهایت، متد
setMapStyle()را در متدonMapReady()که شیءGoogleMapخود را به آن ارسال میکنید، فراخوانی کنید.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapStyle(map)
}
- برنامه خود را اجرا کنید.
- نقشه را روی حالت
normalتنظیم کنید و ظاهر جدید باید با تم رترو و جادههایی با رنگ انتخابی شما قابل مشاهده باشد.

مرحله ۳: به ماژیک خود استایل بدهید
شما میتوانید با تغییر استایل نشانگرهای نقشه، نقشه خود را بیشتر شخصیسازی کنید. در این مرحله، نشانگرهای قرمز پیشفرض را به چیزی جذابتر تغییر میدهید.
- در متد
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))
)
}
- برنامه را اجرا کنید. نشانگرهایی که پس از کلیک طولانی شما ظاهر میشوند، اکنون به رنگ آبی سایهدار هستند. توجه داشته باشید که نشانگرهای POI هنوز قرمز هستند زیرا شما به متد
onPoiClick()استایل اضافه نکردهاید.

۷. وظیفه: اضافه کردن یک پوشش
یکی از راههایی که میتوانید نقشه گوگل را سفارشی کنید، کشیدن نقاشی روی آن است. این تکنیک زمانی مفید است که میخواهید نوع خاصی از مکان، مانند مکانهای ماهیگیری محبوب، را برجسته کنید.
- اشکال: میتوانید چندخطیها ، چندضلعیها و دایرهها را به نقشه اضافه کنید.
- اشیاء
GroundOverlay: یک پوشش زمینی، تصویری است که روی نقشه ثابت میشود. برخلاف نشانگرها، پوششهای زمینی به جای صفحه نمایش، به سمت سطح زمین جهتگیری میشوند. چرخاندن، کج کردن یا بزرگنمایی نقشه، جهت تصویر را تغییر میدهد. پوششهای زمینی زمانی مفید هستند که میخواهید یک تصویر واحد را در یک ناحیه روی نقشه ثابت کنید.
مرحله: یک پوشش زمینی اضافه کنید
در این تکلیف، شما یک پوشش زمینی به شکل یک اندروید به محل خانه خود اضافه میکنید.
- این تصویر اندروید را دانلود کنید و آن را در پوشه
res/drawableخود ذخیره کنید. (مطمئن شوید که نام فایلandroid.pngاست.)

- در
onMapReady()، پس از فراخوانی برای انتقال دوربین به موقعیت خانه، یک شیءGroundOverlayOptionsایجاد کنید. - شیء را به متغیری به نام
androidOverlayاختصاص دهید.
val androidOverlay = GroundOverlayOptions()
- از متد
BitmapDescriptorFactory.fromResource()برای ایجاد یک شیءBitmapDescriptorاز منبع تصویر دانلود شده استفاده کنید. - شیء
BitmapDescriptorحاصل را به متدimage()از شیءGroundOverlayOptionsارسال کنید.
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
- یک
float overlaySizeبرای عرض پوشش مورد نظر بر حسب متر ایجاد کنید. برای این مثال، عرض100fخوب جواب میدهد.
با فراخوانی متد position() ، ویژگی position (position) را برای شیء GroundOverlayOptions تنظیم کنید و شیء homeLatLng و overlaySize به آن ارسال کنید.
val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
.position(homeLatLng, overlaySize)
- تابع
addGroundOverlay()را روی شیءGoogleMapفراخوانی کنید و شیءGroundOverlayOptionsخود را به آن ارسال کنید.
map.addGroundOverlay(androidOverlay)
- برنامه را اجرا کنید.
- برای دیدن تصویر اندروید به صورت یک لایه رویی، مقدار
zoomLevelرا به 18f تغییر دهید.

۸. وظیفه: فعال کردن ردیابی موقعیت مکانی
کاربران اغلب از نقشههای گوگل برای دیدن مکان فعلی خود استفاده میکنند. برای نمایش مکان دستگاه روی نقشه، میتوانید از لایه دادههای مکان استفاده کنید.
لایه دادههای مکانی، آیکون «موقعیت مکانی من» را به نقشه اضافه میکند.

وقتی کاربر دکمه را لمس میکند، نقشه روی موقعیت مکانی دستگاه متمرکز میشود. اگر دستگاه ثابت باشد، موقعیت مکانی به صورت نقطه آبی و اگر در حال حرکت باشد، به صورت یک شورون آبی نشان داده میشود.
در این کار، لایه دادههای مکانی را فعال میکنید.
مرحله: درخواست مجوزهای مکان
فعال کردن ردیابی موقعیت مکانی در گوگل مپ به یک خط کد نیاز دارد. با این حال، باید مطمئن شوید که کاربر مجوزهای موقعیت مکانی را اعطا کرده است (با استفاده از مدل runtime-permission).
در این مرحله، مجوزهای موقعیت مکانی را درخواست میکنید و ردیابی موقعیت مکانی را فعال میکنید.
- در فایل
AndroidManifest.xml، تأیید کنید که مجوزFINE_LOCATIONاز قبل وجود دارد. اندروید استودیو این مجوز را هنگام انتخاب الگوی Google Maps وارد کرده است.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- در
MapsActivity، یک متغیر کلاسREQUEST_LOCATION_PERMISSIONایجاد کنید.
private val REQUEST_LOCATION_PERMISSION = 1
- برای بررسی اینکه آیا مجوزها اعطا شدهاند یا خیر، متدی در
MapsActivityبه نامisPermissionGranted()ایجاد کنید. در این متد، بررسی کنید که آیا کاربر مجوز را اعطا کرده است یا خیر.
private fun isPermissionGranted() : Boolean {
return ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
- برای فعال کردن ردیابی موقعیت مکانی در برنامه خود، متدی در
MapsActivityبه نامenableMyLocation()ایجاد کنید که هیچ آرگومانی نمیگیرد و چیزی برنمیگرداند. درون آن، مجوز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
)
}
}
- برای فعال کردن لایه موقعیت مکانی، تابع
enableMyLocation()را از تابعonMapReady()فراخوانی کنید.
override fun onMapReady(googleMap: GoogleMap) {
...
enableMyLocation()
}
- متد
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()
}
}
}
- برنامه خود را اجرا کنید. باید یک پنجره محاورهای وجود داشته باشد که درخواست دسترسی به موقعیت مکانی دستگاه را میدهد. ادامه دهید و اجازه دسترسی را بدهید.

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

۹. کد راهحل
کد مربوط به codelab نهایی را دانلود کنید.
$ git clone https://github.com/googlecodelabs/android-kotlin-geo-maps
روش دیگر این است که مخزن را به صورت یک فایل زیپ دانلود کنید، آن را از حالت فشرده خارج کنید و در اندروید استودیو باز کنید.
۱۰. خلاصه
تبریک! شما یک نقشه گوگل را به یک برنامه اندروید کاتلین اضافه کردید و آن را استایلبندی کردید.
۱۱. بیشتر بدانید
مستندات توسعهدهندگان اندروید:
- شروع کنید
- اضافه کردن نقشه با نشانگر
- اشیاء نقشه
- اضافه کردن یک نقشه استایلدار
- نمای خیابان
- پوششهای زمینی
مستندات مرجع:
۱۲. آزمایشگاه کد بعدی
برای پیوند به سایر آزمایشگاههای کد در این دوره، به صفحه اصلی آزمایشگاههای کد اندروید پیشرفته در کاتلین مراجعه کنید.



