الإصدار 09.1 من نظام التشغيل Android: خرائط Google

1. مرحبًا

هذا الدرس التطبيقي حول الترميز هو جزء من الدورة التدريبية المتقدّمة لتطوير تطبيقات Android التي طوّرها فريق التدريب في Google Developers. ستستفيد إلى أقصى حدّ من هذه الدورة التدريبية إذا عملت على إكمال دروس الترميز بالتسلسل.

للاطّلاع على التفاصيل الكاملة حول الدورة التدريبية، يُرجى الانتقال إلى نظرة عامة على دورة "تطوير تطبيقات Android المتقدّم".

مقدّمة

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

في هذا التمرين العملي، ستنشئ تطبيقًا على "خرائط Google" باسم Wander.

ما يجب معرفته

يجب أن تكون على دراية بما يلي:

  • الوظائف الأساسية في "خرائط Google"
  • أذونات التشغيل
  • إنشاء التطبيقات وتصميمها وتشغيلها في "استوديو Android"
  • تضمين مكتبات خارجية في ملف build.gradle

أهداف الدورة التعليمية

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

الإجراءات التي ستنفذّها

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

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

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

خريطة Google ذات تصميم خاص

"التجوّل الافتراضي من Google" في تطبيق Android

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

تتطلّب واجهة Google Maps API، مثل Places API، مفتاح واجهة برمجة تطبيقات. للحصول على مفتاح واجهة برمجة التطبيقات، عليك تسجيل مشروعك في "وحدة تحكّم Google API". يرتبط مفتاح واجهة برمجة التطبيقات بشهادة رقمية تربط التطبيق بمؤلفه. لمزيد من المعلومات حول استخدام الشهادات الرقمية وتوقيع تطبيقك، يُرجى الاطّلاع على مقالة توقيع تطبيقك.

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

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

‫1.1 إنشاء مشروع Wander باستخدام نموذج "خرائط Google"

  1. أنشِئ مشروعًا جديدًا في "استوديو Android".
  2. أدخِل اسم التطبيق الجديد "Wander". اقبل الإعدادات التلقائية إلى أن تصل إلى صفحة إضافة نشاط.
  3. اختَر نموذج نشاط "خرائط Google".
  4. اترك اسم النشاط واسم التصميم التلقائيَين.
  5. غيِّر العنوان إلى "رحلة" وانقر على إنهاء.

ينشئ "استوديو Android" عدة ملفات إضافية ذات صلة بالخرائط:

google_maps_api**.xml**

يمكنك استخدام ملف الإعداد هذا لتخزين مفتاح واجهة برمجة التطبيقات. ينشئ النموذج ملفَي google_maps_api.xml: أحدهما لتصحيح الأخطاء والآخر للإصدار. يقع ملف مفتاح واجهة برمجة التطبيقات لشهادة تصحيح الأخطاء في src/debug/res/values. يقع ملف مفتاح واجهة برمجة التطبيقات لشهادة الإصدار في src/release/res/values. في هذا التمرين العملي، سنستخدم شهادة تصحيح الأخطاء فقط.

activity_maps.xml

يحتوي ملف التصميم هذا على جزء واحد يملأ الشاشة بأكملها. الفئة SupportMapFragment هي فئة فرعية من الفئة Fragment. يمكنك تضمين SupportMapFragment في ملف تصميم باستخدام العلامة <fragment> في أي ViewGroup، مع إضافة سمة:

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

MapsActivity.java

ينشئ ملف MapsActivity.java مثيلاً لفئة SupportMapFragment ويستخدم طريقة getMapAsync() الخاصة بالفئة لإعداد "خرائط Google". يجب أن ينفّذ النشاط الذي يحتوي على SupportMapFragment الواجهة OnMapReadyCallback والطريقة onMapReady() الخاصة بهذه الواجهة. يعرض الإجراء getMapAsync() عنصر GoogleMap، ما يشير إلى أنّه تم تحميل الخريطة.

‫1.2 الحصول على مفتاح واجهة برمجة التطبيقات

  1. افتح إصدار تصحيح الأخطاء من ملف google_maps_api.xml.

يتضمّن الملف تعليقًا يحتوي على عنوان URL طويل. تتضمّن مَعلمات عنوان URL معلومات محدّدة حول تطبيقك.

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

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

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

‫2.1 إضافة أنواع الخرائط

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

  1. لإنشاء ملف XML جديد للقائمة، انقر بزر الماوس الأيمن على دليل res واختَر جديد (New) > ملف موارد Android (Android Resource File).
  2. في مربّع الحوار، اكتب اسمًا للملف map_options. اختَر القائمة لنوع المرجع. انقر على حسنًا.
  3. استبدِل الرمز البرمجي في الملف الجديد بالرمز التالي لإنشاء خيارات الخريطة. يتم حذف نوع الخريطة "بدون"، لأنّ النتيجة "بدون" تؤدي إلى عدم توفّر أي خريطة على الإطلاق.
<?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. أنشئ موارد السلسلة لسمات title.
  2. في ملف MapsActivity، غيِّر الفئة لتوسيع الفئة AppCompatActivity بدلاً من توسيع الفئة FragmentActivity. سيؤدي استخدام AppCompatActivity إلى عرض شريط التطبيق، وبالتالي سيتم عرض القائمة.
  3. في MapsActivity، يمكنك إلغاء طريقة onCreateOptionsMenu() وتوسيع الملف map_options:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.map_options, menu);
   return true;
}
  1. لتغيير نوع الخريطة، استخدِم طريقة setMapType() على العنصر GoogleMap، مع تمرير أحد الثوابت الخاصة بنوع الخريطة.

تجاوز طريقة onOptionsItemSelected() ألصِق الرمز التالي لتغيير نوع الخريطة عندما يختار المستخدم أحد خيارات القائمة:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
       // Change the map type based on the user's selection.
       switch (item.getItemId()) {
           case R.id.normal_map:
               mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
               return true;
           case R.id.hybrid_map:
               mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
               return true;
           case R.id.satellite_map:
               mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
               return true;
           case R.id.terrain_map:
               mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
               return true;
           default:
               return super.onOptionsItemSelected(item);
       }
    }
  1. شغِّل التطبيق واستخدِم القائمة في شريط التطبيق لتغيير نوع الخريطة. لاحظ كيف يتغيّر مظهر الخريطة.

‫2.2 تحريك الموقع الجغرافي التلقائي للخريطة

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

  1. في طريقة onMapReady()، أزِل الرمز الذي يضع العلامة في سيدني ويحرّك الكاميرا.
  2. انتقِل إلى www.google.com/maps في المتصفّح وابحث عن منزلك.
  3. انقر بزر الماوس الأيمن على الموقع الجغرافي واختَر ماذا هنا؟

بالقرب من أسفل الشاشة، ستظهر نافذة صغيرة تتضمّن معلومات الموقع الجغرافي، بما في ذلك خط العرض وخط الطول.

  1. أنشئ عنصر LatLng جديدًا باسم home. في العنصر LatLng، استخدِم الإحداثيات التي عثرت عليها من "خرائط Google" في المتصفح.
  2. أنشئ متغيّرًا باسم float وأطلق عليه اسم zoom، ثم اضبط المتغيّر على مستوى التكبير أو التصغير الأوّلي المطلوب. تقدّم لك القائمة التالية فكرة عن مستوى التفاصيل الذي يظهره كل مستوى من مستويات التكبير:
  • 1: العالم
  • 5: كتلة أرضية/قارة
  • 10: المدينة
  • 15: الشوارع
  • 20: المباني
  1. أنشئ عنصر CameraUpdate باستخدام CameraUpdateFactory.newLatLngZoom()، مع تمرير عنصر LatLng ومتغيّر zoom. يمكنك تحريك الكاميرا وتكبيرها/تصغيرها من خلال استدعاء moveCamera() على العنصر GoogleMap، مع تمرير العنصر الجديد CameraUpdate:
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
  1. شغِّل التطبيق. من المفترض أن يتم تحريك الخريطة إلى منزلك وتكبيرها إلى المستوى المطلوب.

‫2.3 إضافة علامات على الخريطة

يمكن لـ "خرائط Google" تحديد موقع جغرافي باستخدام علامة تنشئها باستخدام الفئة Marker. يستخدم العلامة التلقائية رمز "خرائط Google" العادي: محدِّد موقع في &quot;خرائط Google&quot;

يمكنك توسيع العلامات لعرض معلومات سياقية في نوافذ المعلومات.

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

نافذة معلومات حول دبوس تم إسقاطه

  1. أنشئ رمزًا أوليًا للطريقة في MapsActivity باسم setMapLongClick() يأخذ final GoogleMap كوسيطة ويعرض void:
private void setMapLongClick(final GoogleMap map) {}
  1. استخدِم طريقة setOnMapLongClickListener() الخاصة بالكائن GoogleMap لوضع علامة في المكان الذي يلمسه المستخدم ويضغط عليه مع الاستمرار. مرِّر مثيلاً جديدًا من OnMapLongClickListener يتجاوز طريقة onMapLongClick(). الوسيط الوارد هو عنصر LatLng يحتوي على إحداثيات الموقع الجغرافي الذي ضغط عليه المستخدم:
private void setMapLongClick(final GoogleMap map) {
   map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
       @Override
       public void onMapLongClick(LatLng latLng) {
       }
   });
}
  1. داخل onMapLongClick()، استدعِ الطريقة addMarker(). مرِّر كائن MarkerOptions جديدًا مع ضبط الموضع على LatLng الذي تم تمريره:
map.addMarker(new MarkerOptions().position(latLng));
  1. استدعِ setMapLongClick() في نهاية طريقة onMapReady(). المرور في mMap
  2. شغِّل التطبيق. انقر مع الاستمرار على الخريطة لوضع محدّد موقع في مكان ما.
  3. انقر على العلامة، ما يؤدي إلى توسيطها على الشاشة.

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

لإضافة نافذة معلومات إلى العلامة، اتّبِع الخطوات التالية:

  1. في العنصر MarkerOptions، اضبط الحقل title والحقل snippet.
  2. في onMapLongClick()، اضبط الحقل title على "دبوس تم إسقاطه". اضبط الحقل snippet على إحداثيات الموقع الجغرافي داخل الطريقة addMarker().
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
   @Override
   public void onMapLongClick(LatLng latLng) {
       String snippet = String.format(Locale.getDefault(),
               "Lat: %1$.5f, Long: %2$.5f",
               latLng.latitude,
               latLng.longitude);

       map.addMarker(new MarkerOptions()
               .position(latLng)
               .title(getString(R.string.dropped_pin))
               .snippet(snippet));
   }
});
  1. شغِّل التطبيق. انقر مع الاستمرار على الخريطة لإضافة علامة موقع جغرافي. انقر على محدّد الموقع لعرض نافذة المعلومات.

‫2.4 إضافة متتبِّع لنقاط الاهتمام

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

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

علامة نقطة الاهتمام

  1. أنشئ رمزًا بديلًا للطريقة في MapsActivity باسم setPoiClick() يأخذ final GoogleMap كوسيطة ويعرض void:
private void setPoiClick(final GoogleMap map) {}
  1. في طريقة setPoiClick()، اضبط OnPoiClickListener على GoogleMap الذي تم تمريره:
map.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
   @Override
   public void onPoiClick(PointOfInterest poi) {
   }
});
  1. في الطريقة onPoiClick()، ضَع علامة في موقع نقطة الاهتمام. اضبط العنوان على اسم النقطة المهمة. احفظ النتيجة في متغيّر باسم poiMarker.
public void onPoiClick(PointOfInterest poi) {
   Marker poiMarker = mMap.addMarker(new MarkerOptions()
       .position(poi.latLng)
       .title(poi.name);
}
  1. اتّصِل بـ showInfoWindow() على poiMarker لعرض نافذة المعلومات على الفور.
poiMarker.showInfoWindow();
  1. اتّصِل بالرقم setPoiClick() في نهاية onMapReady(). المرور في mMap
  2. شغِّل تطبيقك وابحث عن نقطة اهتمام، مثل منتزه. انقر على نقطة الاهتمام لوضع علامة عليها وعرض اسمها في نافذة معلومات.

5- المهمة رقم 3 اختيار نمط خريطتك

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

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

‫3.1 إضافة نمط إلى خريطتك

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

  1. انتقِل إلى https://mapstyle.withgoogle.com/ في المتصفّح.
  2. انقر على إنشاء نمط.
  3. اختَر المظهر ليلي.
  4. انقر على خيارات إضافية في أسفل القائمة.
  5. في أسفل قائمة نوع العنصر، اختَر المياه > التعبئة. غيِّر لون الماء إلى الأزرق الداكن (على سبيل المثال، ‎#160064).
  6. انقر على إنهاء. انسخ رمز JSON من النافذة المنبثقة الناتجة.
  7. في "استوديو Android"، أنشِئ دليل موارد باسم raw في الدليل res. أنشئ ملفًا في res/raw باسم map_style.json.
  8. الصِق رمز JSON في ملف الموارد الجديد.
  9. لضبط نمط JSON على الخريطة، استدعِ setMapStyle() على العنصر GoogleMap. مرِّر عنصر MapStyleOptions الذي يحمّل ملف JSON. تعرض الطريقة setMapStyle() قيمة منطقية تشير إلى نجاح عملية تطبيق الأنماط. إذا تعذّر تحميل الملف، ستعرض الطريقة Resources.NotFoundException.

انسخ الرمز التالي إلى طريقة onMapReady() لتصميم الخريطة. قد تحتاج إلى إنشاء سلسلة TAG لعبارات السجلّ:

     try {
        // Customize the styling of the base map using a JSON object defined
        // in a raw resource file.
        boolean success = googleMap.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
                   this, R.raw.map_style));

        if (!success) {
            Log.e(TAG, "Style parsing failed.");
        }
     } catch (Resources.NotFoundException e) {
        Log.e(TAG, "Can't find style. Error: ", e);
     }
  1. شغِّل تطبيقك. من المفترض أن يظهر التصميم الجديد عندما تكون الخريطة في وضع normal.

خريطة Google بنمط &quot;الوضع الليلي&quot;

‫3.2 تصميم محدّد الموقع

يمكنك تخصيص خريطتك بشكل أكبر من خلال تصميم علامات الخريطة. في هذه الخطوة، يمكنك تغيير العلامات الحمراء التلقائية لتتطابق مع نظام ألوان الوضع الليلي.

  1. في طريقة onMapLongClick()، أضِف سطر الرمز البرمجي التالي إلى طريقة وضع التصميم MarkerOptions() لاستخدام العلامة التلقائية ولكن مع تغيير اللون إلى الأزرق:
.icon(BitmapDescriptorFactory.defaultMarker
       (BitmapDescriptorFactory.HUE_BLUE))
  1. شغِّل التطبيق. ستظهر العلامات التي تضعها الآن باللون الأزرق الداكن، ما يتوافق بشكل أكبر مع مظهر وضع الليل في التطبيق.

يُرجى العِلم أنّ علامات نقاط الاهتمام لا تزال حمراء لأنّك لم تُضِف نمطًا إلى طريقة onPoiClick().

‫3.3 إضافة تراكب

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

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

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

  1. نزِّل صورة Android هذه واحفظها في مجلد res/drawable.
  2. في onMapReady()، بعد طلب نقل الكاميرا إلى الوضع الأساسي، أنشئ عنصر GroundOverlayOptions. عيِّن العنصر إلى متغيّر باسم homeOverlay:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions();
  1. استخدِم طريقة BitmapDescriptorFactory.fromResource() لإنشاء عنصر BitmapDescriptor من الصورة أعلاه. مرِّر العنصر إلى الإجراء image() الخاص بالعنصر GroundOverlayOptions:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
    .image(BitmapDescriptorFactory.fromResource(R.drawable.android));
  1. اضبط السمة position للعنصر GroundOverlayOptions من خلال استدعاء الطريقة position(). مرِّر الكائن home LatLng وfloat للعرض بالأمتار للتراكب المطلوب. في هذا المثال، يكون العرض 100 متر مناسبًا:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
     .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
       .position(home, 100);
  1. استدعِ الدالة addGroundOverlay() على العنصر GoogleMap. مرِّر عنصر GroundOverlayOptions:
mMap.addGroundOverlay(homeOverlay);
  1. شغِّل التطبيق. كبِّر موقع منزلك، وستظهر لك صورة Android كصورة متراكبة.

6. المهمة رقم 4 تفعيل ميزة "تتبُّع الموقع الجغرافي" و"التجوّل الافتراضي"

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

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

خريطة Google منمّقة تتضمّن ميزة تتبُّع الموقع الجغرافي

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

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

‫4.1 تفعيل ميزة "تتبُّع الموقع الجغرافي"

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

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

  1. في الملف AndroidManifest.xml، تأكَّد من أنّ الإذن FINE_LOCATION متوفّر. أضاف "استوديو Android" هذا الإذن عند اختيار نموذج "خرائط Google".
  2. لتفعيل ميزة تتبُّع الموقع الجغرافي في تطبيقك، أنشئ طريقة في MapsActivity باسم enableMyLocation() لا تأخذ أي وسيطات ولا تعرض أي نتائج.
  3. حدِّد طريقة enableMyLocation(). ابحث عن الإذن ACCESS_FINE_LOCATION. في حال منح الإذن، فعِّل طبقة الموقع الجغرافي. بخلاف ذلك، اطلب الإذن باتّباع الخطوات التالية:
private void enableMyLocation() {
   if (ContextCompat.checkSelfPermission(this,
           Manifest.permission.ACCESS_FINE_LOCATION)
           == PackageManager.PERMISSION_GRANTED) {
       mMap.setMyLocationEnabled(true);
   } else {
       ActivityCompat.requestPermissions(this, new String[]
                       {Manifest.permission.ACCESS_FINE_LOCATION},
               REQUEST_LOCATION_PERMISSION);
   }
}
  1. استخدِم الدالة enableMyLocation() من onMapReady() callback لتفعيل طبقة الموقع الجغرافي.
  2. تجاوز طريقة onRequestPermissionsResult() في حال منح الإذن، اتّصِل بـ enableMyLocation():
@Override
public void onRequestPermissionsResult(int requestCode,
       @NonNull String[] permissions,
       @NonNull int[] grantResults) {
   // Check if location permissions are granted and if so enable the
   // location data layer.
   switch (requestCode) {
       case REQUEST_LOCATION_PERMISSION:
           if (grantResults.length > 0
                   && grantResults[0]
                   == PackageManager.PERMISSION_GRANTED) {
               enableMyLocation();
               break;
           }
   }
}
  1. شغِّل التطبيق. ستظهر الآن في أعلى يسار الشاشة الزر موقعي الجغرافي الذي يعرض الموقع الجغرافي الحالي للجهاز.

‫4.2 تفعيل ميزة "التجوّل الافتراضي"

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

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

  1. ميِّز علامات نقاط الاهتمام عن العلامات الأخرى، لأنّك تريد أن تعمل وظيفة تطبيقك فقط على علامات نقاط الاهتمام. بهذه الطريقة، يمكنك بدء "التجوّل الافتراضي" عندما ينقر المستخدم على نافذة معلومات نقطة الاهتمام، ولكن ليس عندما ينقر على أي نوع آخر من العلامات.

تتضمّن الفئة Marker طريقة setTag() تتيح لك إرفاق البيانات. (يمكن أن تكون البيانات أي شيء يمتد من Object). عليك ضبط علامة على العلامات التي يتم إنشاؤها عندما ينقر المستخدمون على نقاط الاهتمام.

  1. عندما ينقر المستخدم على نافذة معلومات موسومة في OnInfoWindowClickListener، استبدِل MapFragment بـ StreetViewPanoramaFragment. (يستخدم الرمز البرمجي أدناه SupportMapFragment وSupportStreetViewPanoramaFragment للتوافق مع إصدارات Android الأقدم من المستوى 12 لواجهة برمجة التطبيقات).

إذا تغيّرت أي من الأجزاء في وقت التشغيل، يجب إضافتها في فئة Activity الحاوية، وليس بشكل ثابت في XML.

وضع علامة على محدّد موقع نقطة الاهتمام

  1. في دالة معاودة الاتصال onPoiClick()، اتّصِل بالرقم setTag() على poiMarker. مرِّر أي سلسلة عشوائية:
poiMarker.setTag("poi");

استبدال SupportMapFragment الثابت بمثيل وقت التشغيل

  1. افتح activity_maps.xml وغيِّر العنصر إلى تخطيط إطار سيعمل كحاوية للقطاعات:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/fragment_container"
   android:layout_width="match_parent"
   android:layout_height="match_parent" />
  1. في onCreate() في MapsActivity، أزِل الرمز الذي يعثر على SupportMapFragment حسب رقم التعريف، لأنّه لم يعُد هناك SupportMapFragment ثابت في ملف XML. بدلاً من ذلك، أنشِئ مثيلاً جديدًا لوقت التشغيل من SupportMapFragment عن طريق استدعاء SupportMapFragment.newInstance():
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
  1. أضِف الجزء إلى FrameLayout باستخدام معاملة جزء مع FragmentManager:
getSupportFragmentManager().beginTransaction()
       .add(R.id.fragment_container, mapFragment).commit();
  1. احتفِظ بسطر الرمز الذي يؤدي إلى التحميل غير المتزامن للخريطة:
mapFragment.getMapAsync(this);

ضبط OnInfoWindowClickListener والتحقّق من علامة العلامة

  1. أنشئ رمزًا أوليًا للطريقة في MapsActivity باسم setInfoWindowClickToPanorama() يأخذ GoogleMap كوسيطة ويعرض void:
private void setInfoWindowClickToPanorama(GoogleMap map) {}
  1. ضبط OnInfoWindowClickListener على GoogleMap:
map.setOnInfoWindowClickListener(
       new GoogleMap.OnInfoWindowClickListener() {
           @Override
           public void onInfoWindowClick(Marker marker) {
           }
       });
  1. في الطريقة onInfoWindowClick()، تحقَّق ممّا إذا كان العلامة تحتوي على علامة السلسلة التي ضبطتها في الطريقة onPoiClick():
if (marker.getTag() == "poi") {}

استبدِل SupportMapFragment بـ SupportStreetViewPanoramaFragment

  1. في حال احتواء العلامة على العلامة، حدِّد الموقع الجغرافي لصورة بانورامية في "التجوّل الافتراضي" باستخدام عنصر StreetViewPanoramaOptions. اضبط السمة position للعنصر على موضع العلامة التي تم تمريرها:
StreetViewPanoramaOptions options =
       new StreetViewPanoramaOptions().position(
               marker.getPosition());
  1. أنشئ مثيلاً جديدًا من SupportStreetViewPanoramaFragment، مع تمرير العنصر options الذي أنشأته:
SupportStreetViewPanoramaFragment streetViewFragment
       = SupportStreetViewPanoramaFragment
       .newInstance(options);
  1. بدء معاملة جزء استبدِل محتوى حاوية الجزء بالجزء الجديد، streetViewFragment. أضِف المعاملة إلى حزمة الأنشطة السابقة، حتى يؤدي الضغط على "رجوع" إلى الانتقال إلى SupportMapFragment وليس الخروج من التطبيق:
getSupportFragmentManager().beginTransaction()
       .replace(R.id.fragment_container,
               streetViewFragment)
       .addToBackStack(null).commit();
  1. الاتصال بالرقم setInfoWindowClickToPanorama(mMap) في onMapReady() بعد الاتصال بالرقم setPoiClick().
  2. شغِّل التطبيق. كبِّر مدينة تتوفّر فيها تغطية "التجوّل الافتراضي"، مثل ماونتن فيو (مقرّ Google الرئيسي)، وابحث عن نقطة اهتمام، مثل متنزّه. انقر على نقطة الاهتمام لوضع علامة وعرض نافذة المعلومات. انقر على نافذة المعلومات للدخول إلى وضع "التجوّل الافتراضي" الخاص بموقع محدّد الموقع. اضغط على زر الرجوع للعودة إلى جزء الخريطة.

&quot;التجوّل الافتراضي من Google&quot; في تطبيق Android

7. رمز الحلّ

Wander رمز الحلّ

8. تحدّي البرمجة

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

  • للتحقّق مما إذا كانت ميزة "التجوّل الافتراضي" متاحة في منطقة معيّنة، نفِّذ وظيفة الاستدعاء OnStreetViewPanomaraReady مع StreetViewPanorama.OnStreetViewPanoramaChangeListener.
  • إذا لم تكن ميزة "التجوّل الافتراضي" متاحة في منطقة محدّدة، ارجع إلى جزء الخريطة واعرض رسالة خطأ.

9- ملخّص

  • لاستخدام Maps API، يجب الحصول على مفتاح API من وحدة تحكّم Google API.
  • في استوديو Android، يؤدي استخدام نموذج "نشاط خرائط Google" إلى إنشاء Activity مع SupportMapFragment واحد في تصميم التطبيق. يضيف النموذج أيضًا ACCESS_FINE_PERMISSION إلى بيان التطبيق، وينفّذ OnMapReadyCallback في نشاطك، ويتجاهل طريقة onMapReady() المطلوبة.

لتغيير نوع خريطة GoogleMap في وقت التشغيل، استخدِم طريقة GoogleMap.setMapType(). يمكن أن تكون "خريطة Google" أحد أنواع الخرائط التالية:

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

لمحة عن "خرائط Google":

  • العلامة هي مؤشر لموقع جغرافي محدّد.
  • عند النقر على العلامة، يكون السلوك التلقائي لها هو عرض نافذة معلومات تتضمّن معلومات عن الموقع الجغرافي.
  • تظهر تلقائيًا نقاط الاهتمام على الخريطة الأساسية مع الرموز المقابلة لها. تشمل نقاط الاهتمام المتنزّهات والمدارس والمباني الحكومية وغيرها.
  • بالإضافة إلى ذلك، تظهر تلقائيًا نقاط الاهتمام الخاصة بالأنشطة التجارية (المتاجر والمطاعم والفنادق وغيرها) على الخريطة عندما يكون نوع الخريطة normal.
  • يمكنك تسجيل النقرات على "نقاط الاهتمام" باستخدام OnPoiClickListener.
  • يمكنك تغيير المظهر المرئي لجميع عناصر "خريطة Google" تقريبًا باستخدام معالج الأنماط. ينشئ "معالج الأنماط" ملف JSON يمكنك تمريره إلى "خريطة Google" باستخدام الطريقة setMapStyle().
  • يمكنك تخصيص العلامات عن طريق تغيير اللون التلقائي أو استبدال رمز العلامة التلقائي بصورة مخصّصة.

معلومات مهمة أخرى:

  • استخدِم تراكبًا أرضيًا لتثبيت صورة في موقع جغرافي.
  • استخدِم عنصر GroundOverlayOptions لتحديد الصورة وحجمها بالمتر وموضعها. مرِّر هذا العنصر إلى الطريقة GoogleMap.addGroundOverlay() لضبط التراكب على الخريطة.
  • إذا كان تطبيقك لديه إذن ACCESS_FINE_LOCATION، يمكنك تفعيل تتبُّع الموقع الجغرافي باستخدام طريقة mMap.setMyLocationEnabled(true).
  • توفّر ميزة "التجوّل الافتراضي من Google" صورًا بانورامية بزاوية 360 درجة من طرق محدّدة في جميع أنحاء منطقة التغطية.
  • استخدِم الطريقة StreetViewPanoramaFragment.newInstance() لإنشاء جزء جديد من "التجوّل الافتراضي".
  • لتحديد خيارات العرض، استخدِم عنصر StreetViewPanoramaOptions. مرِّر العنصر إلى الطريقة newInstance().

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

يمكنك الاطّلاع على مستندات المفهوم ذي الصلة في ‫9.1: Google Maps API.

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

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

11. الواجبات المنزلية

يسرد هذا القسم مهامًا منزلية محتملة للطلاب الذين يشاركون في هذا الدرس العملي المبرمَج كجزء من دورة تدريبية يقودها مدرّب. على المعلّم تنفيذ ما يلي:

  • حدِّد واجبًا منزليًا إذا لزم الأمر.
  • توضيح كيفية إرسال واجبات منزلية للطلاب
  • ضَع درجة لواجباتك المنزلية.

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

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

إنشاء تطبيق وتشغيله

  1. أنشئ تطبيقًا جديدًا يستخدم نموذج "نشاط خرائط Google" الذي يحمّل "خرائط Google" عند تشغيل التطبيق.
  2. عند تحميل "خريطة Google"، حرِّك الكاميرا إلى موقع مدرستك أو منزلك أو أي موقع جغرافي آخر يهمّك.
  3. أضِف علامتين إلى الخريطة، إحداهما في موقع مؤسستك التعليمية والأخرى في منزلك أو أي موقع جغرافي آخر مهم.
  4. يمكنك تخصيص رموز العلامات من خلال تغيير اللون التلقائي أو استبدال رمز العلامة التلقائي بصورة مخصّصة.

ملاحظة: يمكنك الاطّلاع على مستندات onMapReady (GoogleMap googleMap).

الإجابة عن هذه الأسئلة

السؤال 1

ما هي الطريقة التي يتم استدعاؤها عندما يتم تحميل الخريطة وتكون جاهزة للاستخدام في التطبيق؟

السؤال 2

ما هي مكوّنات Android التي يمكنك استخدامها لتضمين "خرائط Google" في تطبيقك؟

  • MapView وMapFragment
  • MapFragment وMapActivity
  • MapView وMapActivity
  • MapFragment فقط

السؤال 3

ما هي أنواع الخرائط التي توفّرها Google Maps Android API؟

  • عادي ومختلط وتضاريس وقمر صناعي وخريطة طريق
  • عادي ومختلط وتضاريس وقمر صناعي و "بلا قيمة"
  • "هجين" و"تضاريس" و"قمر صناعي" و"خريطة طريق" و"بلا"
  • عادي وتضاريس وقمر صناعي وخريطة صور و "بلا"

السؤال 4

ما هي الواجهة التي تنفّذها لإضافة وظيفة النقر إلى نقطة اهتمام؟

  • GoogleMap.OnPoiListener
  • GoogleMap.OnPoiClickListener
  • GoogleMap.OnPoiClick
  • GoogleMap.OnPoiClicked

إرسال تطبيقك للحصول على تقييم

إرشادات للمصحّحين

تأكَّد من أنّ التطبيق يتضمّن الميزات التالية:

  • عند تشغيل التطبيق، يتم عرض "خريطة Google" بشكلٍ صحيح، ما يشير إلى أنّه تم إنشاء مفتاح واجهة برمجة التطبيقات بشكلٍ سليم.
  • بعد تحميل "خرائط Google"، تنتقل الكاميرا إلى موقع منزل الطالب أو مدرسته. في الرمز، يجب أن تحدث هذه الخطوة في طريقة رد الاتصال onMapReady (GoogleMap googleMap).
  • يتم عرض العلامات في الموقع الجغرافي لمدرسة الطالب وموقع جغرافي آخر، مثل منزل الطالب.
  • تم تخصيص العلامتَين. على سبيل المثال، تستخدِم العلامات لونًا غير اللون الأحمر التلقائي، أو تستخدِم رمزًا مخصّصًا.

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

للاطّلاع على جميع الدروس التطبيقية حول الترميز في دورة "تطوير تطبيقات Android المتقدّم" التدريبية، انتقِل إلى الصفحة المقصودة الخاصة بالدروس التطبيقية حول الترميز في دورة "تطوير تطبيقات Android المتقدّم".