1. قبل البدء
يتيح لك إنشاء تطبيقات باستخدام "خرائط Google" إضافة ميزات إلى تطبيقك، مثل صور الأقمار الصناعية وعناصر تحكّم قوية في واجهة المستخدم للخرائط وتتبُّع الموقع الجغرافي وعلامات الموقع الجغرافي. يمكنك إضافة قيمة إلى "خرائط Google" العادية من خلال عرض معلومات من مجموعة البيانات الخاصة بك، مثل مواقع مناطق الصيد أو التسلق المعروفة. يمكنك أيضًا إنشاء ألعاب يستكشف فيها اللاعب العالم المادي، مثل البحث عن الكنز أو حتى ألعاب الواقع المعزّز.
في هذا الدرس، ستنشئ تطبيقًا على "خرائط Google" باسم Wander يعرض خرائط مخصّصة ويُظهر الموقع الجغرافي للمستخدم.
المتطلبات الأساسية
المعرفة بما يلي:
- كيفية إنشاء تطبيق Android أساسي وتشغيله باستخدام "استوديو Android"
- كيفية إنشاء الموارد وإدارتها، مثل السلاسل
- كيفية إعادة تصميم الرمز البرمجي وإعادة تسمية المتغيرات باستخدام "استوديو Android"
- كيفية استخدام خريطة Google كمستخدم
- كيفية ضبط أذونات وقت التشغيل
أهداف الدورة التعليمية
- كيفية الحصول على مفتاح واجهة برمجة تطبيقات من "وحدة تحكّم Google API" وتسجيل المفتاح في تطبيقك
- كيفية دمج "خريطة Google" في تطبيقك
- كيفية عرض أنواع مختلفة من الخرائط
- كيفية تصميم "خريطة Google"
- كيفية إضافة علامات إلى خريطتك
- كيفية السماح للمستخدم بوضع علامة على نقطة اهتمام
- كيفية تفعيل ميزة "تتبُّع الموقع الجغرافي"
- كيفية إنشاء تطبيق
Wanderيتضمّن "خريطة Google" - كيفية إنشاء ميزات مخصّصة لتطبيقك، مثل العلامات والأنماط
- كيفية تفعيل ميزة "تتبُّع الموقع الجغرافي" في تطبيقك
2. نظرة عامة على التطبيق
في هذا الدرس التطبيقي حول الترميز، ستنشئ تطبيق Wander الذي يعرض خريطة Google بتصميم مخصّص. يتيح لك تطبيق Wander إمكانية وضع علامات على المواقع الجغرافية وإضافة تراكبات وعرض موقعك الجغرافي في الوقت الفعلي.

3- المهمة: إعداد المشروع والحصول على مفتاح واجهة برمجة التطبيقات
تتطلّب حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" للتطبيقات المتوافقة مع Android مفتاح واجهة برمجة تطبيقات. للحصول على مفتاح واجهة برمجة التطبيقات، سجِّل مشروعك في صفحة "واجهات برمجة التطبيقات والخدمات". يرتبط مفتاح واجهة برمجة التطبيقات بشهادة رقمية تربط التطبيق بمؤلفه. لمزيد من المعلومات حول استخدام الشهادات الرقمية وتوقيع تطبيقك، يُرجى الاطّلاع على مقالة توقيع تطبيقك.
في هذا الدرس التطبيقي، ستستخدم مفتاح واجهة برمجة التطبيقات لشهادة تصحيح الأخطاء. شهادة تصحيح الأخطاء غير آمنة بطبيعتها، كما هو موضّح في مقالة توقيع إصدار مخصص لتصحيح الأخطاء. تتطلّب تطبيقات Android المنشورة التي تستخدم حزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android مفتاح واجهة برمجة تطبيقات ثانيًا، وهو مفتاح شهادة الإصدار. لمزيد من المعلومات حول الحصول على شهادة إصدار، يُرجى الاطّلاع على الحصول على مفتاح API.
يتضمّن "استوديو Android" نموذج "نشاط خرائط Google" الذي ينشئ رمز نموذج مفيدًا. يتضمّن رمز النموذج ملف google_maps_api.xml يحتوي على رابط يسهّل الحصول على مفتاح واجهة برمجة التطبيقات.
الخطوة 1: إنشاء مشروع Wander باستخدام نموذج الخرائط
- أنشِئ مشروعًا جديدًا في "استوديو Android".
- اختَر نموذج نشاط "خرائط Google".

- حدِّد اسمًا للمشروع
Wander. - اضبط الحد الأدنى لمستوى واجهة برمجة التطبيقات على المستوى 19. تأكَّد من أنّ اللغة هي Kotlin.
- انقر على إنهاء.
- بعد انتهاء إنشاء التطبيق، ألقِ نظرة على مشروعك والملفات التالية ذات الصلة بالخرائط التي ينشئها "استوديو Android" لك:
google_maps_api.xml: يمكنك استخدام ملف الإعداد هذا لتخزين مفتاح واجهة برمجة التطبيقات. ينشئ النموذج ملفّين باسم google_maps_api.xml: أحدهما للتصحيح والآخر للإصدار. يقع ملف مفتاح واجهة برمجة التطبيقات لشهادة تصحيح الأخطاء في src/debug/res/values. يقع ملف مفتاح واجهة برمجة التطبيقات لشهادة الإصدار في 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: الحصول على مفتاح واجهة برمجة التطبيقات
- افتح إصدار تصحيح الأخطاء من ملف google_maps_api.xml.
- في الملف، ابحث عن تعليق يتضمّن عنوان URL طويلاً. تتضمّن مَعلمات عنوان URL معلومات محدّدة حول تطبيقك.
- انسخ عنوان URL والصقه في المتصفّح.
- اتّبِع التعليمات لإنشاء مشروع في صفحة "واجهات برمجة التطبيقات والخدمات". بسبب المَعلمات الواردة في عنوان URL المقدَّم، تعرف الصفحة أنّه يجب تفعيل حزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android تلقائيًا.
- انقر على إنشاء مفتاح واجهة برمجة تطبيقات.
- في الصفحة التالية، انتقِل إلى قسم "مفاتيح واجهة برمجة التطبيقات" وانقر على المفتاح الذي أنشأته للتو.
- انقر على تقييد المفتاح واختَر حزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android لتقييد استخدام المفتاح على تطبيقات Android.
- انسخ مفتاح واجهة برمجة التطبيقات الذي تم إنشاؤه. يبدأ بـ "
AIza". - في الملف
google_maps_api.xml، الصِق المفتاح في السلسلةgoogle_maps_keyحيث يظهر النصYOUR_KEY_HERE. - شغِّل تطبيقك. من المفترض أن تظهر لك خريطة مضمّنة في نشاطك مع علامة محدّدة في سيدني، أستراليا. (علامة Sydney هي جزء من النموذج ويمكنك تغييرها لاحقًا).

الخطوة 3: إعادة تسمية mMap
يتضمّن MapsActivity lateinit خاصًا var باسم mMap، وهو من النوع GoogleMap. للتوافق مع اصطلاحات التسمية في Kotlin، غيِّر اسم mMap إلى map.
- في
MapsActivity، انقر بزر الماوس الأيمن علىmMapوانقر على إعادة تصميم > إعادة تسمية...

- غيِّر اسم المتغيّر إلى
map.
لاحظ كيف تتغيّر أيضًا جميع المراجع إلى mMap في الدالة onMapReady() إلى map.
4. المهمة: إضافة أنواع الخرائط
تتضمّن "خرائط Google" عدة أنواع من الخرائط: عادية ومختلطة وقمر صناعي وتضاريس و"بلا خريطة" (لعدم عرض أي خريطة على الإطلاق).
|
|
|
|
خريطة النواظم | خريطة القمر الصناعي | خريطة هجينة | خريطة التضاريس |
يقدّم كل نوع من الخرائط أنواعًا مختلفة من المعلومات. على سبيل المثال، عند استخدام الخرائط للتنقّل في السيارة، من المفيد رؤية أسماء الشوارع، لذا يمكنك استخدام الخيار العادي. عند المشي لمسافات طويلة، قد تكون خريطة التضاريس مفيدة لتحديد المسافة المتبقية للوصول إلى القمة.
في هذه المهمة، عليك إجراء ما يلي:
- أضِف شريط تطبيقات يتضمّن قائمة خيارات تتيح للمستخدم تغيير نوع الخريطة.
- حرِّك الموقع الجغرافي الأوّلي للخريطة إلى الموقع الجغرافي لمنزلك.
- إضافة دعم للعلامات التي تشير إلى مواقع جغرافية فردية على الخريطة ويمكن أن تتضمّن تصنيفًا
إضافة قائمة لأنواع الخرائط
في هذه الخطوة، ستضيف شريط تطبيقات يتضمّن قائمة خيارات تتيح للمستخدم تغيير نوع الخريطة.
- لإنشاء ملف XML جديد للقائمة، انقر بزر الماوس الأيمن على دليل res واختَر جديد (New) > ملف موارد Android (Android Resource File).
- في مربّع الحوار، اكتب اسمًا للملف
map_options. - اختَر القائمة لنوع المرجع.
- انقر على موافق.
- في علامة التبويب الرمز، استبدِل الرمز في الملف الجديد بالرمز التالي لإنشاء خيارات قائمة الخريطة. تم حذف نوع الخريطة "بلا" لأنّ اختيار "بلا" يؤدي إلى عدم ظهور أي خريطة على الإطلاق. تتسبّب هذه الخطوة في حدوث خطأ، ولكنك ستعمل على حلّه في الخطوة التالية.
<?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)
}
- شغِّل التطبيق.
- انقر على
لتغيير نوع الخريطة. لاحظ كيف يتغيّر مظهر الخريطة بين الأوضاع المختلفة.

5- المهمة: إضافة علامات
يتضمّن الإجراء onMapReady() بشكلٍ تلقائي رمزًا برمجيًا يضع علامة في سيدني، أستراليا، حيث تم إنشاء "خرائط Google". تعمل دالة معاودة الاتصال التلقائية أيضًا على تحريك الخريطة لتوسيطها على "سيدني".
في هذه المهمة، ستجعل كاميرا الخريطة تنتقل إلى منزلك، وتكبّر الخريطة إلى المستوى الذي تحدّده، وتضع علامة في ذلك الموقع الجغرافي.
الخطوة 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: المباني
- حرِّك الكاميرا إلى
homeLatLngمن خلال استدعاء الدالةmoveCamera()على العنصرmapوتمرير العنصرCameraUpdateباستخدامCameraUpdateFactory.newLatLngZoom(). مرِّر العنصر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()، استدعِ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.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: إضافة متتبِّع لنقاط الاهتمام
تظهر تلقائيًا نقاط الاهتمام على الخريطة مع الرموز المقابلة لها. تشمل نقاط الاهتمام المتنزّهات والمدارس والمباني الحكومية وغيرها. عند ضبط نوع الخريطة على normal، تظهر أيضًا نقاط الاهتمام الخاصة بالأنشطة التجارية على الخريطة. تمثّل نقاط الاهتمام الخاصة بالأنشطة التجارية المؤسسات، مثل المتاجر والمطاعم والفنادق.
في هذه الخطوة، ستضيف GoogleMap.OnPoiClickListener إلى الخريطة. يضع برنامج معالجة النقرات هذا علامة على الخريطة فورًا عندما ينقر المستخدم على نقطة اهتمام. يعرض متتبِّع النقر أيضًا نافذة معلومات تحتوي على اسم نقطة الاهتمام.
- أنشئ رمزًا أوليًا للدالة في
MapsActivityباسمsetPoiClick()يأخذGoogleMapكوسيطة. - في الطريقة
setPoiClick()، اضبط قيمةOnPoiClickListenerعلىGoogleMapالذي تم تمريره.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
}
}
- في
setOnPoiClickListener()، أنشئval poiMarkerللعلامة . - اضبطها على علامة باستخدام
map.addMarker()معMarkerOptions، مع ضبطtitleعلى اسم نقطة الاهتمام.
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)
}
- شغِّل تطبيقك وابحث عن نقطة اهتمام، مثل حديقة أو مقهى.
- انقر على "نقطة الاهتمام" لوضع علامة عليها وعرض اسمها في نافذة معلومات.

6. المهمة: تخصيص مظهر خريطتك
يمكنك تخصيص "خرائط Google" بطرق عديدة، ما يمنح خريطتك مظهرًا فريدًا.
يمكنك تخصيص عنصر MapFragment باستخدام سمات XML المتاحة، كما تفعل عند تخصيص أي جزء آخر. ومع ذلك، في هذه الخطوة، يمكنك تخصيص شكل ومظهر المحتوى الخاص بـ MapFragment باستخدام طرق في العنصر GoogleMap.
لإنشاء نمط مخصّص للخريطة، عليك إنشاء ملف JSON يحدّد كيفية عرض العناصر في الخريطة. لست بحاجة إلى إنشاء ملف JSON هذا يدويًا. توفّر Google أداة تصميم الخرائط لمنصة خرائط Google التي تنشئ رمز JSON لك بعد تصميم خريطتك بشكل مرئي. في هذه المهمة، ستصمّم الخريطة باستخدام مظهر قديم، ما يعني أنّ الخريطة ستستخدم ألوانًا قديمة وستضيف طرقًا ملوّنة.
الخطوة 1: إنشاء نمط للخريطة
- انتقِل إلى https://mapstyle.withgoogle.com/ في المتصفّح.
- انقر على إنشاء نمط.
- اختَر Retro.

- انقر على خيارات إضافية.

- انقر على طريق > تعبئة.
- تغيير لون الطرق إلى أي لون تختاره (مثل الوردي)

- انقر على إنهاء.

- انسخ رمز JSON من مربّع الحوار الناتج، وإذا أردت، يمكنك تخزينه في ملاحظة نصية عادية لاستخدامه في الخطوة التالية.

الخطوة 2: إضافة النمط إلى الخريطة
- في "استوديو Android"، أنشئ دليل موارد في الدليل
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لنجاح عملية التنسيق. (أضِف كتلة الالتقاط التالية). - في الحظر
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
)
)
}
}
- أضِف عبارة if ليكون
successfalse. في حال عدم نجاح عملية التنسيق، اطبع سجلّاً يفيد بتعذّر عملية التحليل.
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، وسيظهر التصميم الجديد مع المظهر القديم والطرق باللون الذي اخترته.

الخطوة 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))
)
}
- شغِّل التطبيق. ستظهر العلامات التي تظهر بعد النقر مع الاستمرار باللون الأزرق. يُرجى العِلم أنّ علامات نقاط الاهتمام لا تزال حمراء لأنّك لم تُضِف نمطًا إلى طريقة
onPoiClick().

7. المهمة: إضافة تراكب
إحدى الطرق التي يمكنك من خلالها تخصيص خريطة Google هي الرسم فوقها. تكون هذه الطريقة مفيدة إذا كنت تريد إبراز نوع معيّن من المواقع الجغرافية، مثل أماكن الصيد الشهيرة.
- الأشكال: يمكنك إضافة خطوط متعددة الأضلاع ومضلّعات ودوائر إلى الخريطة.
GroundOverlayالعناصر: تراكب الأرضية هو صورة ثابتة على الخريطة. على عكس العلامات، يتم توجيه الصور المتراكبة على الأرض إلى سطح الأرض بدلاً من الشاشة. يؤدي تدوير الخريطة أو إمالتها أو تكبيرها إلى تغيير اتجاه الصورة. تكون الصور المتراكبة على الأرض مفيدة عندما تريد تثبيت صورة واحدة في منطقة واحدة على الخريطة.
الخطوة: إضافة طبقة أرضية
في هذه المهمة، ستضيف صورة على الأرض على شكل روبوت Android إلى موقع منزلك.
- نزِّل صورة Android هذه واحفظها في مجلد
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 لعرض صورة Android كتراكب.

8. المهمة: تفعيل ميزة "تتبُّع الموقع الجغرافي"
يستخدم المستخدمون غالبًا "خرائط Google" لمعرفة موقعهم الجغرافي الحالي. لعرض الموقع الجغرافي للجهاز على الخريطة، يمكنك استخدام طبقة بيانات الموقع الجغرافي.
تضيف طبقة بيانات الموقع الجغرافي رمز موقعي الجغرافي إلى الخريطة.

عندما ينقر المستخدم على الزر، تتوسّط الخريطة الموقع الجغرافي للجهاز. يظهر الموقع الجغرافي كنقطة زرقاء إذا كان الجهاز ثابتًا، وكعلامة شيفرون زرقاء إذا كان الجهاز يتحرّك.
في هذه المهمة، عليك تفعيل طبقة بيانات الموقع الجغرافي.
الخطوة: طلب أذونات تحديد الموقع الجغرافي
يتطلّب تفعيل ميزة تتبُّع الموقع الجغرافي في "خرائط Google" سطرًا واحدًا من الرمز. ومع ذلك، يجب التأكّد من أنّ المستخدم قد منح أذونات تحديد الموقع الجغرافي (باستخدام نموذج أذونات التشغيل).
في هذه الخطوة، عليك طلب أذونات تحديد الموقع الجغرافي وتفعيل ميزة تتبُّع الموقع الجغرافي.
- في الملف
AndroidManifest.xml، تأكَّد من أنّ الإذنFINE_LOCATIONمتوفّر. أضاف "استوديو Android" هذا الإذن عند اختيار نموذج "خرائط Google".
<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()callback لتفعيل طبقة الموقع الجغرافي.
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()
}
}
}
- شغِّل تطبيقك. من المفترض أن يظهر مربّع حوار يطلب الوصول إلى الموقع الجغرافي للجهاز. واصِل العملية وامنح الإذن.

تعرض الخريطة الآن الموقع الجغرافي الحالي للجهاز باستخدام نقطة زرقاء. لاحظ أنّه يتضمّن زر مشاركة الموقع الجغرافي. إذا حرّكت الخريطة بعيدًا عن موقعك الجغرافي ونقرت على هذا الزر، ستتم إعادة توسيط الخريطة على الموقع الجغرافي للجهاز.

9- رمز الحلّ
نزِّل الرمز البرمجي لدرس البرمجة المكتمل.
$ git clone https://github.com/googlecodelabs/android-kotlin-geo-maps
بدلاً من ذلك، يمكنك تنزيل المستودع كملف zip وفك ضغطه وفتحه في Android Studio.
10. ملخّص
تهانينا! أضفت خريطة Google إلى تطبيق Android Kotlin وأضفت إليها أنماطًا.
11. مزيد من المعلومات
مستندات مطوّري تطبيقات Android:
المستندات المرجعية:
12. الدرس التطبيقي التالي حول الترميز
للحصول على روابط تؤدي إلى دروس تطبيقية حول الترميز الأخرى في هذه الدورة التدريبية، يمكنك الاطّلاع على الصفحة المقصودة للدروس التطبيقية حول الترميز الخاصة بدورة "تطبيقات متقدّمة متوافقة مع نظام Android باستخدام لغة Kotlin".



