این کد لبه بخشی از دوره آموزشی 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 را با الگوی نقشه ها ایجاد کنید
- یک پروژه Android Studio جدید ایجاد کنید.
- الگوی Google Maps Activity را انتخاب کنید.
- نام پروژه را
Wander
. - حداقل سطح API را روی API 19 تنظیم کنید. مطمئن شوید که زبان کاتلین است.
- روی Finish کلیک کنید.
- پس از اتمام ساخت برنامه، به پروژه خود و فایل های مرتبط با نقشه های زیر که 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 را دریافت کنید
- نسخه اشکال زدایی فایل google_maps_api.xml را باز کنید.
- در فایل به دنبال نظری با URL طولانی باشید. پارامترهای URL شامل اطلاعات خاصی در مورد برنامه شما هستند.
- URL را کپی و در مرورگر پیست کنید.
- برای ایجاد پروژه در صفحه APIs & Services ، دستورات را دنبال کنید. به دلیل پارامترهای موجود در URL ارائه شده، صفحه می داند که Maps SDK برای Android به طور خودکار فعال می شود.
- روی ایجاد کلید API کلیک کنید.
- در صفحه بعد به بخش API Keys رفته و روی کلیدی که ایجاد کردید کلیک کنید.
- روی Restrict Key کلیک کنید و Maps SDK for Android را انتخاب کنید تا استفاده از کلید به برنامههای Android محدود شود.
- کلید API تولید شده را کپی کنید. با "
AIza"
شروع می شود. - در فایل
google_maps_api.xml
، کلید را در رشتهgoogle_maps_key
جایی کهYOUR_KEY_HERE
را نشان می دهد، قرار دهید. - برنامه خود را اجرا کنید شما باید یک نقشه جاسازی شده در فعالیت خود با یک نشانگر در سیدنی، استرالیا ببینید. (نشانگر سیدنی بخشی از الگو است و بعداً آن را تغییر می دهید.)
مرحله 3: تغییر نام mMap
MapsActivity
یک lateinit
var
خصوصی به نام mMap
دارد که از نوع GoogleMap
است. برای پیروی از قراردادهای نامگذاری Kotlin، نام mMap
را به map
تغییر دهید.
- در
MapsActivity
، رویmMap
راست کلیک کنید و روی Refactor > Rename...
- نام متغیر را به
map
تغییر دهید.
توجه کنید که چگونه تمام ارجاعات به mMap
در تابع onMapReady()
نیز به map
تغییر می کند.
نقشه های گوگل شامل چندین نوع نقشه است: معمولی، ترکیبی، ماهواره ای، زمینی، و "هیچ" (به هیچ وجه بدون نقشه).
نقشه معمولی | نقشه ماهواره ای | نقشه ترکیبی | نقشه زمین |
هر نوع نقشه انواع مختلفی از اطلاعات را ارائه می دهد. به عنوان مثال، هنگام استفاده از نقشه ها برای پیمایش در ماشین، دیدن نام خیابان ها مفید است، بنابراین می توانید از گزینه عادی استفاده کنید. هنگامی که در حال پیاده روی هستید، نقشه زمین می تواند برای تصمیم گیری در مورد اینکه چقدر بیشتر باید صعود کنید تا به قله بروید، مفید باشد.
در این وظیفه شما:
- یک نوار برنامه با منوی گزینهها اضافه کنید که به کاربر امکان میدهد نوع نقشه را تغییر دهد.
- مکان شروع نقشه را به مکان خانه خود منتقل کنید.
- برای نشانگرها پشتیبانی اضافه کنید، که مکانهای منفرد را روی نقشه نشان میدهند و میتوانند شامل یک برچسب باشند.
اضافه کردن منو برای انواع نقشه
در این مرحله یک نوار برنامه با منوی گزینه ها اضافه می کنید که به کاربر اجازه می دهد نوع نقشه را تغییر دهد.
- برای ایجاد یک فایل XML منوی جدید، روی دایرکتوری res خود کلیک راست کرده و New > Android Resource File را انتخاب کنید.
- در گفتگو، نام فایل
map_options
را بگذارید. - منو را برای نوع منبع انتخاب کنید.
- روی OK کلیک کنید.
- در سربرگ 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>
- در
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()
شامل کدی است که نشانگری را در سیدنی، استرالیا، جایی که Google Maps ایجاد شده، قرار میدهد. تماس پیشفرض نیز نقشه را متحرک میکند تا به سیدنی حرکت کند.
در این کار، دوربین نقشه را به خانه خود منتقل میکنید، تا سطحی که مشخص میکنید بزرگنمایی میکنید و یک نشانگر در آنجا قرار میدهید.
مرحله 1: خانه خود را بزرگنمایی کنید و یک نشانگر اضافه کنید
- در فایل
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))
}
- برنامه خود را اجرا کنید نقشه باید به خانه شما حرکت کند، تا سطح مورد نظر زوم کند و یک نشانگر روی خانه شما قرار دهد.
مرحله 2: به کاربران اجازه دهید با یک کلیک طولانی یک نشانگر اضافه کنند
در این مرحله، زمانی که کاربر مکانی را روی نقشه لمس کرده و نگه می دارد، یک نشانگر اضافه می کنید.
- یک روش خرد در
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()
onMapReady،setMapLongClick()
را باmap
فراخوانی کنید.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapLongClick(map)
}
- برنامه خود را اجرا کنید
- برای قرار دادن نشانگر در یک مکان، نقشه را لمس کنید و نگه دارید.
- روی نشانگر ضربه بزنید، که آن را در مرکز صفحه نمایش قرار می دهد.
مرحله 3: یک پنجره اطلاعات برای نشانگر اضافه کنید
در این مرحله یک InfoWindow
اضافه میکنید که مختصات نشانگر را با ضربه زدن روی نشانگر نمایش میدهد.
- در
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)
)
}
}
- در
addMarker()
title
نشانگر را با استفاده از R.string رویR.string.
منبع رشتهdropped_pin
. -
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)
)
}
}
- برنامه خود را اجرا کنید
- برای رها کردن نشانگر موقعیت، نقشه را لمس کرده و نگه دارید.
- روی نشانگر ضربه بزنید تا پنجره اطلاعات نمایش داده شود.
مرحله 4: شنونده POI را اضافه کنید
به طور پیش فرض، نقاط مورد علاقه (POI) به همراه نمادهای مربوطه روی نقشه ظاهر می شوند. POI شامل پارک ها، مدارس، ساختمان های دولتی و موارد دیگر می شود. وقتی نوع نقشه روی normal
تنظیم می شود، POI های تجاری نیز روی نقشه ظاهر می شوند. کسب و کار POI نشان دهنده مشاغلی مانند مغازه ها، رستوران ها و هتل ها است.
در این مرحله یک GoogleMap.OnPoiClickListener
را به نقشه اضافه می کنید. این کلیک شنونده بلافاصله هنگامی که کاربر روی یک POI کلیک می کند یک نشانگر روی نقشه قرار می دهد. شنونده کلیک نیز یک پنجره اطلاعاتی را نشان می دهد که حاوی نام POI است.
- یک روش خرد در
MapsActivity
به نامsetPoiClick()
ایجاد کنید کهGoogleMap
را به عنوان آرگومان می گیرد. - در
setPoiClick()
، یکOnPoiClickListener
را رویGoogleMap
تصویب شده تنظیم کنید.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
}
}
- در
setOnPoiClickListener()
یکval poiMarker
برای نشانگر ایجاد کنید. - با استفاده از
map.addMarker()
آن را روی یک نشانگر تنظیم کنید وMarkerOptions
title
را به نام POI تنظیم کند.
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 ضربه بزنید تا یک نشانگر روی آن قرار دهید و نام POI در یک پنجره اطلاعات نمایش داده شود.
میتوانید نقشههای گوگل را به روشهای مختلف سفارشی کنید و به نقشه خود ظاهر و احساسی منحصربفرد بدهید.
شما می توانید یک شی MapFragment
را با استفاده از ویژگی های XML موجود سفارشی کنید، همانطور که هر قطعه دیگری را سفارشی می کنید. با این حال، در این مرحله، ظاهر و احساس محتوای MapFragment
را با استفاده از روشهایی روی شی GoogleMap
سفارشی میکنید.
برای ایجاد یک سبک سفارشی برای نقشه خود، یک فایل JSON ایجاد می کنید که نحوه نمایش ویژگی های نقشه را مشخص می کند. لازم نیست این فایل JSON را به صورت دستی ایجاد کنید. Google Maps Platform Styling Wizard را ارائه میکند که پس از استایل بصری نقشه خود، JSON را برای شما تولید میکند. در این کار، نقشه را با تم رترو استایل میدهید، یعنی نقشه از رنگهای قدیمی استفاده میکند و جادههای رنگی را اضافه میکنید.
مرحله 1: یک سبک برای نقشه خود ایجاد کنید
- در مرورگر خود به https://mapstyle.withgoogle.com/ بروید .
- Create a Style را انتخاب کنید.
- Retro را انتخاب کنید.
- روی گزینه های بیشتر کلیک کنید.
- در لیست نوع ویژگی ، جاده > پر کردن را انتخاب کنید.
- رنگ جاده ها را به هر رنگی که انتخاب می کنید (مانند صورتی) تغییر دهید.
- روی Finish کلیک کنید.
- کد JSON را از دیالوگ به دست آمده کپی کنید و در صورت تمایل، آن را در یک یادداشت متنی ساده ذخیره کنید تا در مرحله بعد از آن استفاده کنید.
مرحله 2: سبک را به نقشه خود اضافه کنید
- در اندروید استودیو، در
res
دایرکتوری، یک دایرکتوری منبع ایجاد کنید و نام آن راraw
بگذارید. شما از منابع دایرکتوریraw
مانند کد JSON استفاده می کنید. - یک فایل در
res/raw
به نامmap_style.json
کنید. - کد JSON مخفی شده خود را در فایل منبع جدید جایگذاری کنید.
- در
MapsActivity
، یک متغیر کلاسTAG
بالایonCreate()
ایجاد کنید. این برای اهداف ورود به سیستم استفاده می شود.
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
)
)
}
}
- برای false بودن
success
یک عبارت 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)
}
}
- در نهایت، متد
GoogleMap
setMapStyle()
را در متدonMapReady()
فراخوانی کنید.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapStyle(map)
}
- برنامه خود را اجرا کنید
- نقشه را روی حالت
normal
تنظیم کنید و یک ظاهر طراحی جدید باید با طرح زمینه و جاده های رنگ انتخابی شما قابل مشاهده باشد.
مرحله 3: به نشانگر خود سبک دهید
شما می توانید نقشه خود را بیشتر با طراحی نشانگرهای نقشه شخصی سازی کنید. در این مرحله، نشانگرهای قرمز پیشفرض را به چیزی شیاردارتر تغییر میدهید.
- در
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
را برای شی GroundOverlayOptions
با فراخوانی متد position()
تنظیم کنید و شی 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 تغییر دهید تا تصویر اندروید را به صورت همپوشانی ببینید.
کاربران اغلب از نقشه های گوگل برای دیدن مکان فعلی خود استفاده می کنند. برای نمایش مکان دستگاه روی نقشه، میتوانید از لایه مکان-داده استفاده کنید.
لایه مکان-داده موقعیت مکانی من را به نقشه اضافه می کند. هنگامی که کاربر روی دکمه ضربه می زند، نقشه بر روی مکان دستگاه متمرکز می شود. اگر دستگاه ثابت است، مکان به صورت یک نقطه آبی و اگر دستگاه در حال حرکت است به صورت یک شورون آبی نشان داده می شود.
در این کار، لایه مکان-داده را فعال می کنید.
مرحله: درخواست مجوزهای مکان
فعال کردن ردیابی موقعیت مکانی در Google Maps به یک خط کد نیاز دارد. با این حال، باید مطمئن شوید که کاربر مجوزهای موقعیت مکانی را داده است (با استفاده از مدل مجوز زمان اجرا).
در این مرحله شما مجوزهای موقعیت مکانی را درخواست می کنید و ردیابی موقعیت مکانی را فعال می کنید.
- در فایل
AndroidManifest.xml
، بررسی کنید که مجوزFINE_LOCATION
از قبل وجود داشته باشد. زمانی که شما الگوی Google Maps را انتخاب کردید، Android Studio این مجوز را وارد کرد.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- در
MapsActivity
، یک متغیر کلاسREQUEST_LOCATION_PERMISSION
ایجاد کنید.
private val REQUEST_LOCATION_PERMISSION = 1
- برای بررسی اینکه آیا مجوزها اعطا شده اند یا خیر، روشی به نام
MapsActivity
isPermissionGranted()
در MapsActivity ایجاد کنید. در این روش بررسی کنید که آیا کاربر مجوز را داده است یا خیر.
private fun isPermissionGranted() : Boolean {
return ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
- برای فعال کردن ردیابی موقعیت مکانی در برنامه خود، روشی به نام
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
)
}
}
- برای فعال کردن لایه مکان، از روی (
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()
}
}
}
- برنامه خود را اجرا کنید باید گفتگویی وجود داشته باشد که درخواست دسترسی به مکان دستگاه را می دهد. برو جلو و اجازه بده.
اکنون نقشه مکان فعلی دستگاه را با استفاده از یک نقطه آبی نشان می دهد. توجه داشته باشید که یک دکمه مکان وجود دارد. اگر نقشه را از موقعیت مکانی خود دور کنید و روی این دکمه کلیک کنید، نقشه را در مرکز مکان دستگاه قرار می دهید.
کد مربوط به کد لبه تمام شده را دانلود کنید.
$ 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 مراجعه کنید.