ميزات Android المتقدمة في Kotlin 04.1: خرائط Google لنظام التشغيل Android

1. قبل البدء

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

في هذا الدرس، يمكنك إنشاء تطبيق خرائط Google يسمى Wander يعرض خرائط مخصصة ويعرض موقع المستخدم.

المتطلبات الأساسية

معرفة ما يلي:

  • كيفية إنشاء تطبيق Android أساسي وتشغيله باستخدام "استوديو Android"
  • كيفية إنشاء الموارد وإدارتها، مثل السلاسل
  • كيفية إعادة ضبط الإعدادات البرمجية للرموز وإعادة تسمية المتغيّرات باستخدام "استوديو Android"
  • كيفية استخدام خريطة Google كمستخدم.
  • كيفية ضبط أذونات وقت التشغيل

ما ستتعرَّف عليه

  • كيفية الحصول على مفتاح واجهة برمجة التطبيقات من وحدة تحكم Google API وتسجيل المفتاح في تطبيقك
  • كيفية دمج "خرائط Google" في تطبيقك
  • كيفية عرض أنواع الخرائط المختلفة
  • كيفية تصميم "خرائط Google"
  • كيفية إضافة علامات إلى خريطتك
  • كيفية تمكين المستخدم من وضع علامة على نقطة اهتمام (POI)
  • كيفية تفعيل ميزة تتبُّع الموقع الجغرافي
  • كيفية إنشاء تطبيق Wander، الذي يحتوي على خريطة Google مضمّنة
  • كيفية إنشاء ميزات مخصّصة لتطبيقك، مثل محدّدات المواقع والتصميم
  • كيفية تفعيل تتبُّع الموقع الجغرافي في تطبيقك

2. نظرة عامة على التطبيق

يمكنك في هذا الدرس التطبيقي إنشاء تطبيق "Wander" الذي يعرض خريطة Google بنمط مخصّص. يسمح لك تطبيق Wander بإسقاط محددات على المواقع وإضافة عناصر مركّبة ومشاهدة موقعك الجغرافي في الوقت الفعلي.

5b12eda7f467bc2f.png

3- المهمة: إعداد المشروع والحصول على مفتاح واجهة برمجة التطبيقات

تتطلب حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" لنظام التشغيل Android مفتاح واجهة برمجة التطبيقات. للحصول على مفتاح واجهة برمجة التطبيقات، سجِّل مشروعك في واجهة برمجة التطبيقات صفحة الخدمات. يرتبط مفتاح واجهة برمجة التطبيقات بشهادة رقمية تربط التطبيق بمؤلفه. لمزيد من المعلومات حول استخدام الشهادات الرقمية وتوقيع تطبيقك، يُرجى الاطّلاع على توقيع تطبيقك.

في هذا الدرس التطبيقي حول الترميز، يمكنك استخدام مفتاح واجهة برمجة التطبيقات لشهادة تصحيح الأخطاء. شهادة تصحيح الأخطاء غير آمنة في الأساس، كما هو موضّح في التوقيع على إصدار تصحيح الأخطاء. تتطلّب تطبيقات Android المنشورة التي تستخدم حزمة تطوير البرامج (SDK) لـ "خرائط Google" لنظام التشغيل Android مفتاح واجهة برمجة تطبيقات ثانٍ: وهو مفتاح شهادة الإصدار. لمزيد من المعلومات حول الحصول على شهادة إصدار، يمكنك الاطّلاع على الحصول على مفتاح واجهة برمجة تطبيقات.

يتضمن "استوديو Android" نموذج "نشاط خرائط Google" الذي ينشئ رمز نموذج مفيدًا. يتضمن رمز النموذج ملف google_maps_api.xml يحتوي على رابط يبسّط الحصول على مفتاح واجهة برمجة التطبيقات.

الخطوة 1: إنشاء مشروع Wander باستخدام نموذج الخرائط

  1. أنشِئ مشروعًا جديدًا على "استوديو Android".
  2. اختَر نموذج نشاط "خرائط Google".

d6b874bb19ea68cd.png

  1. أدخِل اسمًا للمشروع "Wander".
  2. اضبط الحدّ الأدنى لمستوى واجهة برمجة التطبيقات على واجهة برمجة التطبيقات 19. تأكَّد من أنّ اللغة هي Kotlin.
  3. انقر على إنهاء.
  4. بعد الانتهاء من إنشاء التطبيق، يمكنك إلقاء نظرة على مشروعك والملفات التالية المتعلقة بالخرائط التي ينشئها "استوديو 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.java مثيلاً لـ SupportMapFragment بطريقة onCreate() ويستخدم الفئة getMapAsync() لإعداد نظام الخرائط والعرض تلقائيًا. يجب أن ينفِّذ النشاط الذي يحتوي على SupportMapFragment واجهة OnMapReadyCallback وطريقة onMapReady() لتلك الواجهة. يتم استدعاء طريقة onMapReady() عند تحميل الخريطة.

الخطوة 2: الحصول على مفتاح واجهة برمجة التطبيقات

  1. افتح إصدار تصحيح الأخطاء من ملف google_maps_api.xml.
  2. في الملف، ابحث عن تعليق يحتوي على عنوان URL طويل. وتتضمّن مَعلمات عنوان URL معلومات محدَّدة عن تطبيقك.
  3. انسخ عنوان URL والصقه في متصفّح.
  4. اتّبِع التعليمات لإنشاء مشروع على واجهات برمجة التطبيقات صفحة الخدمات. نظرًا للمعلَمات في عنوان URL المقدَّم، تعرف الصفحة كيفية تفعيل حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" لنظام التشغيل Android تلقائيًا.
  5. انقر على إنشاء مفتاح واجهة برمجة التطبيقات.
  6. في الصفحة التالية، انتقل إلى قسم "مفاتيح واجهة برمجة التطبيقات" وانقر على المفتاح الذي أنشأته للتو.
  7. انقر على تقييد المفتاح واختَر حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" لنظام التشغيل Android لحظر استخدام المفتاح لتطبيقات Android.
  8. انسخ مفتاح واجهة برمجة التطبيقات الذي تم إنشاؤه. ويبدأ بـ "AIza".
  9. في ملف google_maps_api.xml، الصِق المفتاح في سلسلة google_maps_key في الحقل YOUR_KEY_HERE.
  10. شغِّل تطبيقك. يجب أن تظهر لك خريطة مضمّنة في نشاطك مع محدّد موقع تم ضبطه في سيدني، أستراليا. (علامة سيدني جزء من القالب ويمكنك تغييره لاحقًا).

34dc9dd877c90996.png

الخطوة 3: إعادة تسمية خريطة الأجهزة الجوّالة

لدى MapsActivity lateinit خاص var باسم mMap، وهو من النوع GoogleMap. لاتباع اصطلاحات تسمية Kotlin، غيِّر اسم mMap إلى map.

  1. في MapsActivity، انقر بزر الماوس الأيمن على mMap وانقر على إعادة ضبط الإعدادات >. إعادة التسمية...

e713ccb3384450c6.png

  1. غيِّر اسم المتغيّر إلى map.

لاحظ كيف تتغير أيضًا جميع الإشارات إلى mMap في الدالة onMapReady() إلى map.

4. المهمة: إضافة أنواع الخرائط

تشتمل خرائط Google على أنواع خرائط متعددة: عادية، ومختلطة، وقمر صناعي، وتضاريس، و"بدون" (لعدم وجود خريطة على الإطلاق).

الخريطة العادية

خريطة القمر الصناعي

خريطة مختلطة

خريطة التضاريس

يوفر كل نوع من الخرائط أنواعًا مختلفة من المعلومات. على سبيل المثال، عند استخدام الخرائط للتنقل في السيارة، من المفيد رؤية أسماء الشوارع، وبالتالي يمكنك استخدام الخيار العادي. عند المشي لمسافات طويلة، يمكن أن تكون خريطة التضاريس مفيدة لتحديد مقدار ما عليك تسلقه للوصول إلى القمة.

في هذه المهمة، تقوم بما يلي:

  1. أضف شريط تطبيق مع قائمة خيارات تسمح للمستخدم بتغيير نوع الخريطة.
  2. حرِّك موقع بداية الخريطة إلى موقع منزلك.
  3. أضف دعمًا للعلامات التي تشير إلى مواقع فردية على الخريطة ويمكن أن تتضمن تسمية.

إضافة قائمة لأنواع الخرائط

في هذه الخطوة، يمكنك إضافة شريط تطبيق مع قائمة خيارات تسمح للمستخدم بتغيير نوع الخريطة.

  1. لإنشاء ملف XML لقائمة جديد، انقر بزر الماوس الأيمن على الدليل res واختَر جديد >. ملف موارد Android
  2. في مربّع الحوار، أدخِل اسمًا للملف map_options.
  3. اختَر القائمة لنوع المورد.
  4. انقر على موافق.
  5. في علامة التبويب الرمز، استبدِل الرمز في الملف الجديد بالرمز التالي لإنشاء خيارات قائمة الخريطة. استراتيجية "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>
  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. انقر على 428da163b831115b.png لتغيير نوع الخريطة. لاحظ كيف يتغير مظهر الخريطة بين الأوضاع المختلفة.

6fa42970d87f5dc7.png

5- المهمة: إضافة علامات

بشكل تلقائي، تشتمل معاودة الاتصال onMapReady() على رمز يضع علامة في سيدني، أستراليا، حيث تم إنشاء "خرائط Google". يؤدي رد الاتصال الافتراضي أيضًا إلى تحريك الخريطة لتحريك الخريطة إلى سيدني.

في هذه المهمة، يمكنك جعل كاميرا الخريطة تتحرك إلى منزلك، وتكبير إلى المستوى الذي تحدده، ووضع علامة هناك.

الخطوة 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. يمكنك تحريك الكاميرا إلى homeLatLng من خلال استدعاء الوظيفة moveCamera() على العنصر map وتمرير عنصر CameraUpdate باستخدام CameraUpdateFactory.newLatLngZoom(). مرِّر سريعًا في الكائن 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. شغِّل تطبيقك. من المفترض أن يتم تحريك الخريطة باتجاه منزلك، وتكبيرها للوصول إلى المستوى المطلوب، ووضع محدّد موقع على منزلك.

fc939024778ee76.png

الخطوة 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()، يمكنك استدعاء setMapLongClick() مع map.
override fun onMapReady(googleMap: GoogleMap) {
   ...
  
   setMapLongClick(map)
}
  1. شغِّل تطبيقك.
  2. المس الخريطة مع الاستمرار لوضع علامة على أحد المواقع.
  3. انقر على العلامة التي تظهر في وسط الشاشة.

4ff8d1c1db3bca9e.png

الخطوة 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.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. انقر على محدّد الموقع لعرض نافذة المعلومات.

63f210e6e47dfa29.png

الخطوة 4: إضافة أداة معالجة نقاط الاهتمام

بشكل افتراضي، تظهر نقاط الاهتمام على الخريطة مع الرموز المقابلة لها. تشمل نقاط الاهتمام الحدائق والمدارس والمباني الحكومية وغيرها. عند ضبط نوع الخريطة على normal، تظهر أيضًا نقاط الاهتمام على الخريطة. تمثل نقاط اهتمام الأنشطة التجارية الأنشطة التجارية، مثل المتاجر والمطاعم والفنادق.

في هذه الخطوة، يمكنك إضافة GoogleMap.OnPoiClickListener إلى الخريطة. يضع مستمع النقر هذا علامة على الخريطة مباشرةً عندما ينقر المستخدم على نقطة اهتمام. يعرض مستمع النقر أيضًا نافذة معلومات تحتوي على اسم نقطة الاهتمام.

  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 على اسم نقطة الاهتمام.
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. شغِّل تطبيقك وابحث عن نقطة اهتمام، مثل متنزّه أو مقهى.
  2. انقر على نقطة الاهتمام لوضع علامة عليها وعرض اسم نقطة الاهتمام في نافذة المعلومات.

f4b0972c75d5fa5f.png

6- المهمة: تحديد نمط لخريطتك

يمكنك تخصيص خرائط Google بعدة طرق، مما يمنح خريطتك مظهرًا وطابعًا فريدين.

يمكنك تخصيص كائن MapFragment باستخدام سمات XML المتاحة، كما يمكنك تخصيص أي جزء آخر. في المقابل، يمكنك في هذه الخطوة تخصيص مظهر محتوى MapFragment وأسلوبه باستخدام الطرق المتاحة في الكائن GoogleMap.

لإنشاء نمط مخصص لخريطتك، يمكنك إنشاء ملف JSON يحدد كيفية عرض الميزات في الخريطة. وليس عليك إنشاء ملف JSON هذا يدويًا. وتوفّر Google معالج تصميم النظام الأساسي لـ "خرائط Google" الذي ينشئ ملف JSON لك بعد تعديل تصميم الخريطة بشكل مرئي. في هذه المهمة، يمكنك تصميم الخريطة بموضوع قديم، مما يعني أن الخريطة تستخدم ألوانًا قديمة وتضيف طرقًا ملونة.

الخطوة 1: إنشاء نمط لخريطتك

  1. انتقِل إلى https://mapstyle.withgoogle.com/ في المتصفّح.
  2. اختَر إنشاء نمط.
  3. اختَر ريترو.

208b3d3aeab0d9b6.png

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

4a35faaf9535ee82.png

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

92c3293749293a4c.png

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

f1bfe8585eb69480.png

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

3c32168b299d6420.png

الخطوة 2: إضافة النمط إلى خريطتك

  1. في "استوديو Android" وفي دليل 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 لنجاح التصميم. (يمكنك إضافة مجموعة الصيد التالية.)
  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. أضِف عبارة if للسمة success خطأ. في حال عدم نجاح التصميم، اطبع سجلّاً تعذّر فيه التحليل.
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. وأخيرًا، استدعِ الطريقة setMapStyle() في طريقة onMapReady() التي يتم فيها تمرير كائن GoogleMap.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. شغِّل تطبيقك.
  2. يمكنك ضبط الخريطة على الوضع "normal"، ويجب أن يظهر التصميم الجديد مع مظاهر قديمة وطرق اللون التي اخترتها.

b59d6cb81f02a14f.png

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

b9916bca3c367e3.png

7. المهمة: إضافة تراكب

إحدى الطرق التي يمكنك من خلالها تخصيص خريطة Google هي الرسم فوقها. هذه التقنية مفيدة إذا كنت تريد إبراز نوع معين من المواقع، مثل أماكن الصيد المشهورة.

  • الأشكال: يمكنك إضافة الخطوط المتعددة والمضلّعات والدوائر إلى الخريطة.
  • كائنات GroundOverlay الكائنات: تراكب الأرض هو صورة ثابتة على خريطة. على عكس العلامات، يتم توجيه طبقات الأرض نحو سطح الأرض بدلاً من الشاشة. يؤدي تدوير الخريطة أو إمالتها أو تكبيرها إلى تغيير اتجاه الصورة. تكون تراكبات الأرض مفيدة عندما تريد إصلاح صورة واحدة في منطقة واحدة على الخريطة.

الخطوة: إضافة تراكب أرضي

في هذه المهمة، تقوم بإضافة تراكب أرضي على شكل Android إلى موقع منزلك.

  1. نزِّل صورة Android هذه واحفظها في مجلد res/drawable. (يُرجى التأكّد من أنّ اسم الملف هو android.png).

61fabd56a0841b44.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 لعرض صورة Android كتراكب.

b1b25b0acd6a9807.png

8. المهمة: تفعيل تتبع الموقع

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

تضيف طبقة بيانات الموقع رمز موقعي إلى الخريطة.

f317f84dcb3ac3a1.png

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

في هذه المهمة، تقوم بتمكين طبقة بيانات الموقع.

الخطوة: طلب أذونات تحديد الموقع الجغرافي

يتطلب تفعيل تتبع الموقع الجغرافي في "خرائط Google" سطرًا واحدًا من الرموز. ومع ذلك، عليك التأكّد من أنّ المستخدم قد منح أذونات تحديد الموقع الجغرافي (باستخدام نموذج الإذن في وقت التشغيل).

في هذه الخطوة، يجب طلب أذونات تحديد الموقع الجغرافي وتفعيل ميزة تتبُّع الموقع الجغرافي.

  1. في ملف AndroidManifest.xml، تأكَّد من أنّ إذن FINE_LOCATION متوفّر حاليًا. أدرج "استوديو Android" هذا الإذن عند اختيار نموذج "خرائط Google".
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. في MapsActivity، أنشئ متغيّر فئة REQUEST_LOCATION_PERMISSION.
private val REQUEST_LOCATION_PERMISSION = 1
  1. للتحقّق مما إذا تم منح الأذونات، يمكنك إنشاء طريقة في MapsActivity باسم isPermissionGranted(). وبهذه الطريقة، تحقّق مما إذا كان المستخدم قد منح الإذن أم لا.
private fun isPermissionGranted() : Boolean {
  return ContextCompat.checkSelfPermission(
       this,
      Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
  1. لتفعيل ميزة تتبُّع الموقع الجغرافي في تطبيقك، أنشِئ طريقة في 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
       )
   }
}
  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. شغِّل تطبيقك. من المفترض أن يظهر مربع حوار يطلب الوصول إلى الموقع الجغرافي للجهاز. امنح الإذن.

da7e23e00ec762c1.png

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

5b12eda7f467bc2f.png

9. رمز الحلّ

نزِّل رمز الدرس التطبيقي المكتمل حول الترميز.

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

ويمكنك بدلاً من ذلك تنزيل المستودع كملف ZIP وفك ضغطه وفتحه في "استوديو Android".

10. ملخّص

تهانينا! أضفت خريطة Google إلى تطبيق Android Kotlin وصممتها.

11. مزيد من المعلومات

مستندات مطوّري برامج Android:

المستندات المرجعية:

12. الدرس التطبيقي التالي حول الترميز

للحصول على روابط إلى الدروس التطبيقية الأخرى حول الترميز في هذه الدورة التدريبية، اطّلِع على الصفحة المقصودة للدروس التطبيقية حول الترميز في لغة Kotlin المتقدمة.