بدء استخدام حزمة تطوير البرامج (SDK) للأماكن في Android (Kotlin)

بدء استخدام حزمة تطوير البرامج (SDK) للأماكن في Android (Kotlin)

لمحة عن هذا الدرس التطبيقي حول الترميز

subjectتاريخ التعديل الأخير: يونيو 22, 2022
account_circleتأليف: Angela Yu

1. قبل البدء

يعلّمك هذا الدرس التطبيقي حول الترميز كيفية دمج حزمة تطوير البرامج (SDK) للأماكن في نظام التشغيل Android مع تطبيقك واستخدام كل ميزة من ميزات حزمة تطوير البرامج (SDK) للأماكن.

تطبيق تجريبي حول الأماكن

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

  • معرفة أساسية بالتطوير بلغة Kotlin وAndroid

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

  • كيفية تثبيت حزمة تطوير البرامج (SDK) للأماكن التي تعمل بنظام التشغيل Android باستخدام إضافات Kotlin.
  • كيفية تحميل تفاصيل المكان لمكان معين.
  • كيفية إضافة أداة الإكمال التلقائي للأماكن إلى تطبيقك.
  • كيفية تحميل المكان الحالي استنادًا إلى الموقع الذي تم الإبلاغ عنه حاليًا للجهاز

الأشياء التي تحتاج إليها

لإكمال هذا الدرس التطبيقي حول الترميز، ستحتاج إلى الحسابات والخدمات والأدوات التالية:

2. الإعداد

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

إعداد "منصة خرائط Google"

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

  1. في Cloud Console، انقر على القائمة المنسدلة للمشروع واختَر المشروع الذي تريد استخدامه لهذا الدرس التطبيقي.

  1. فعِّل واجهات برمجة تطبيقات ومنصة SDK لمنصة "خرائط Google" المطلوبة لهذا الدرس التطبيقي في Google Cloud Marketplace. ولإجراء ذلك، اتّبِع الخطوات الواردة في هذا الفيديو أو هذه المستندات.
  2. يمكنك إنشاء مفتاح واجهة برمجة تطبيقات في صفحة بيانات الاعتماد في Cloud Console. يمكنك اتّباع الخطوات الواردة في هذا الفيديو أو هذه المستندات. تتطلب جميع الطلبات إلى "منصة خرائط Google" مفتاح واجهة برمجة تطبيقات.

3. البدء بسرعة

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

  1. إنشاء نسخة طبق الأصل من المستودع في حال تثبيت git.
git clone https://github.com/googlemaps/codelab-places-101-android.git

أو انقر على هذا الزر لتنزيل رمز المصدر.

  1. بعد تنزيل الرمز، افتح المشروع المتوفّر في دليل /starter في"استوديو Android". يتضمّن هذا المشروع البنية الأساسية للملف والتي ستحتاج إلى إكمال الدرس التطبيقي حول الترميز. ستجد كل ما تحتاج إليه للعمل في دليل /starter.

وإذا كنت تريد عرض رمز الحل الكامل قيد التشغيل، يمكنك عرض الرمز المكتمل في الدليل /solution.

4. تثبيت الأماكن SDK لنظام التشغيل Android

في هذا القسم، يجب إضافة حزمة تطوير البرامج (SDK) للأماكن في Android إلى تبعيات تطبيقك.

إضافة مفتاح واجهة برمجة التطبيقات

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

  1. افتح الملف باسم local.properties في الدليل الجذري لمشروعك (المستوى نفسه حيث يوجد gradle.properties وsettings.gradle).
  2. تحديد مفتاح جديد GOOGLE_MAPS_API_KEY، وضبط قيمته على مفتاح واجهة برمجة التطبيقات الذي أنشأته.

local.properties

GOOGLE_MAPS_API_KEY=YOUR_KEY_HERE

لاحِظ أن local.properties مدرَج في ملف .gitignore في مستودع Git. ويرجع ذلك إلى أن مفتاح واجهة برمجة التطبيقات يُعتبر معلومات حساسة ويجب عدم تسجيله للوصول إلى عنصر التحكم في المصدر، إن أمكن.

  1. بعد ذلك، لعرض مفتاح واجهة برمجة التطبيقات الخاص بك حتى يمكن استخدامه في تطبيقك، أضِف المكوّن الإضافي Secrets Gradle Plugin for Android في ملف build.gradle الخاص بتطبيقك المتوفّر في دليل app/، وأضِف السطر التالي ضمن كتلة plugins:

build.gradle على مستوى التطبيق

plugins {
   
// ...
    id
'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
  1. يمكنك تعديل ملف build.gradle على مستوى المشروع ليتضمن مسار الصف التالي:

build.gradle على مستوى المشروع

buildscript {
    dependencies
{
       
// ...
        classpath
"com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
   
}
}

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

إضافة حِزمة تطوير البرامج (SDK) للأماكن في نظام التشغيل Android

  1. الآن ويمكن الوصول إلى مفتاح واجهة برمجة التطبيقات داخل التطبيق، يمكنك إضافة تبعية حزمة تطوير البرامج (SDK) للأماكن في Android إلى ملف build.gradle لتطبيقك.

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

build.gradle على مستوى التطبيق

dependencies {
   
// Dependency to include Places SDK for Android
   implementation
'com.google.android.libraries.places:places:2.6.0'
}
  1. شغِّل التطبيق.

من المفترض أن يظهر لك الآن تطبيق يحتوي على شاشة فارغة. مواصلة تعبئة هذه الشاشة بثلاثة إصدارات تجريبية.

5. تثبيت أماكن Android KTX

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

مخطط KTX لمنصّة "خرائط Google"

في هذه المهمة، استخدم مكتبة Places Android KTX لاستخدام ميزات اللغة بلغة Kotlin في تطبيقك.

إضافة تبعية الأماكن في نظام التشغيل Android KTX

للاستفادة من الميزات الخاصة بلغة Kotlin، يمكنك تضمين مكتبة KTX المقابلة لها في حزمة تطوير البرامج (SDK) هذه في ملف build.gradle على مستوى التطبيق.

build.gradle

dependencies {
   
// ...

   
// Places SDK for Android KTX Library
    implementation
'com.google.maps.android:places-ktx:2.0.0'
}

6. إعداد عميل الأماكن

إعداد حزمة تطوير البرامج (SDK) للأماكن لنطاق التطبيق

في ملف DemoApplication.kt من مجلد app/src/main/java/com/google/codelabs/maps/placesdemo، يجب إعداد حزمة تطوير البرامج (SDK) للأماكن في نظام التشغيل Android. الصق الأسطر الواردة في نهاية دالة onCreate:

        // Initialize the SDK with the Google Maps Platform API key
       
Places.initialize(this, BuildConfig.GOOGLE_MAPS_API_KEY)

عند إنشاء تطبيقك، يجعل مكوّن Secrets Gradle Plugin for Android مفتاح واجهة برمجة التطبيقات في ملف local.properties متاحًا بتنسيق BuildConfig.GOOGLE_MAPS_API_KEY.

إضافة ملف التطبيق إلى البيان

بما أنك قد وسّعت نطاق Application باستخدام DemoApplication، عليك تعديل البيان. أضِف السمة android:name إلى العنصر application في الملف AndroidManifest.xml المتوفّر في app/src/main:

    <application
        android:name=".DemoApplication"
        ...
   
</application>

يشير هذا الرمز إلى بيان التطبيق إلى الفئة DemoApplication في المجلد src/main/java/com/google/codelabs/maps/placesdemo/.

7. استرجاع تفاصيل المكان

إنشاء شاشة التفاصيل

يتوفر تنسيق activity_details.xml مع LinearLayout فارغ في المجلد app/src/main/res/layout/. عليك ملء التنسيق الخطي بإضافة الرمز التالي بين قوسَي <LinearLayout>.

    <com.google.android.material.textfield.TextInputLayout
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content">

       
<com.google.android.material.textfield.TextInputEditText
           
android:id="@+id/details_input"
           
android:layout_width="match_parent"
           
android:layout_height="wrap_content"
           
android:hint="@string/details_input_hint"
           
android:text="@string/details_input_default" />

   
</com.google.android.material.textfield.TextInputLayout>

   
<Button
       
android:id="@+id/details_button"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:text="@string/button_details" />

   
<TextView
       
android:id="@+id/details_response_content"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:paddingTop="16dp"
       
android:textIsSelectable="true" />

يضيف هذا الرمز حقل إدخال نص يمكن للمستخدم من خلاله إدخال أي رقم تعريف مكان أو استخدام الإعداد التلقائي المقدم، وزر لبدء طلب تفاصيل المكان، وTextView لعرض المعلومات من الاستجابة. يتم تحديد السلاسل المرتبطة في ملف src/main/res/values/strings.xml.

إنشاء نشاط على التفاصيل

  1. أنشِئ ملف DetailsActivity.kt في مجلد src/main/java/com/google/codelabs/maps/placesdemo/ واربطه بالتنسيق الذي أنشأته للتو. ألصِق هذا الرمز في الملف:
class DetailsActivity : AppCompatActivity() {
   
private lateinit var placesClient: PlacesClient
   
private lateinit var detailsButton: Button
   
private lateinit var detailsInput: TextInputEditText
   
private lateinit var responseView: TextView

   
override fun onCreate(savedInstanceState: Bundle?) {
       
super.onCreate(savedInstanceState)
        setContentView
(R.layout.activity_details)

       
// Set up view objects
        detailsInput
= findViewById(R.id.details_input)
        detailsButton
= findViewById(R.id.details_button)
        responseView
= findViewById(R.id.details_response_content)

   
}
}
  1. يمكنك إنشاء عميل للأماكن لاستخدامه مع هذا النشاط. يمكنك لصق هذا الرمز بعد إعداد كائن الملف الشخصي في دالة onCreate.
        // Retrieve a PlacesClient (previously initialized - see DemoApplication)
        placesClient
= Places.createClient(this)
  1. بعد إعداد برنامج الأماكن، يمكنك إرفاق أداة معالجة نقرة بالزر. الصق هذا الرمز بعد إنشاء برنامج الأماكن في دالة onCreate.
        // Upon button click, fetch and display the Place Details
        detailsButton
.setOnClickListener {
            val placeId
= detailsInput.text.toString()
            val placeFields
= listOf(
               
Place.Field.NAME,
               
Place.Field.ID,
               
Place.Field.LAT_LNG,
               
Place.Field.ADDRESS
           
)
            lifecycleScope
.launch {
               
try {
                    val response
= placesClient.awaitFetchPlace(placeId, placeFields)
                    responseView
.text = response.prettyPrint()
               
} catch (e: Exception) {
                    e
.printStackTrace()
                    responseView
.text = e.message
               
}
           
}
       
}

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

  1. يمكنك تحويل FetchPlaceResponse إلى نص عن طريق تحديد دالة إضافة. يتم توفير ملف StringUtil.kt لتبسيط تحويل استجابات SDK للمكان إلى سلاسل مقروءة.

في نهاية ملف DetailsActivity.kt، حدِّد دالة لتحويل كائن الرد "جلب المكان" إلى سلسلة.

fun FetchPlaceResponse.prettyPrint(): String {
   
return StringUtil.stringify(this, false)
}

إضافة نشاط التفاصيل إلى البيان

أضِف عنصر <activity> للعنصر DetailsActivity كعنصر ثانوي للعنصر <application> في الملف AndroidManifest.xml، المتوفّر في app/src/main:

        <activity android:name=".DetailsActivity" />

إضافة نشاط التفاصيل إلى القائمة التجريبية

يتم توفير وحدة Demo فارغة لإدراج العروض التوضيحية المتاحة على الشاشة الرئيسية. الآن وبعد أن أنشأت نشاط تفاصيل المكان، يمكنك إضافته إلى ملف Demo.kt في مجلد src/main/java/com/google/codelabs/maps/placesdemo/ باستخدام هذا الرمز:

    DETAILS_FRAGMENT_DEMO(
        R
.string.details_demo_title,
        R
.string.details_demo_description,
       
DetailsActivity::class.java
   
),

يتم تحديد السلاسل المرتبطة في ملف src/main/res/values/strings.xml.

افحص MainActivity.kt ولاحظ أنّه يُنشئ طريقة عرض قائمة تتم تعبئتها من خلال تكرار محتوى وحدة Demo. وإذا نقر المستخدم على عنصر في القائمة، يفتح مستمع النقر النشاط المرتبط به.

تشغيل التطبيق

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

النشاط المتعلّق بتفاصيل المكان من خلال الرد

الشكل 1. نشاط المكان الذي تم تحديده مع عرض الرد.

8. إضافة الإكمال التلقائي للأماكن

إنشاء شاشة الإكمال التلقائي

تنسيق activity_autocomplete.xml بدون LinearLayout فارغ في المجلد app/src/main/res/layout/. عليك ملء التنسيق الخطي بإضافة هذا الرمز بين أقواس <LinearLayout>.

    <androidx.fragment.app.FragmentContainerView
       
android:id="@+id/autocomplete_fragment"
       
android:background="@android:color/white"
       
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content" />

   
<TextView
       
android:id="@+id/autocomplete_response_content"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:paddingTop="16dp"
       
android:textIsSelectable="true" />

يضيف هذا الرمز أداة AutocompleteSupportFragment وTextView لعرض المعلومات من الرد. يتم تحديد السلاسل المرتبطة في ملف src/main/res/values/strings.xml.

إنشاء نشاط الإكمال التلقائي

  1. أنشئ ملف AutocompleteActivity.kt في مجلد src/main/java/com/google/codelabs/maps/placesdemo/ وحدِّده باستخدام هذا الرمز:
class AutocompleteActivity : AppCompatActivity() {
   
private lateinit var responseView: TextView

   
override fun onCreate(savedInstanceState: Bundle?) {
       
super.onCreate(savedInstanceState)
        setContentView
(R.layout.activity_autocomplete)

       
// Set up view objects
        responseView
= findViewById(R.id.autocomplete_response_content)
        val autocompleteFragment
=
            supportFragmentManager
.findFragmentById(R.id.autocomplete_fragment)
                   
as AutocompleteSupportFragment
   
}
}

يعمل هذا الرمز على ربط النشاط بالملفات الشخصية وAutocompleteSupportFramgent التي حدّدتها في ملف التنسيق.

  1. بعد ذلك، حدّد ما يحدث عندما يختار المستخدم أحد التوقعات المقدمة من خلال الإكمال التلقائي للأماكن. أضِف هذا الرمز إلى نهاية دالة onCreate:
        // Specify the types of place data to return.
        autocompleteFragment
.setPlaceFields(listOf(Place.Field.NAME, Place.Field.ID, Place.Field.LAT_LNG, Place.Field.ADDRESS))

       
// Listen to place selection events
        lifecycleScope
.launchWhenCreated {
            autocompleteFragment
.placeSelectionEvents().collect { event ->
               
when (event) {
                   
is PlaceSelectionSuccess -> {
                        val place
= event.place
                        responseView
.text = StringUtil.stringifyAutocompleteWidget(place, false)
                   
}
                   
is PlaceSelectionError -> Toast.makeText(
                       
this@AutocompleteActivity,
                       
"Failed to get place '${event.status.statusMessage}'",
                       
Toast.LENGTH_SHORT
                   
).show()
               
}
           
}

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

إضافة نشاط الإكمال التلقائي إلى البيان

أضِف عنصر <activity> للعنصر AutocompleteActivity كعنصر ثانوي للعنصر <application> في الملف AndroidManifest.xml، المتوفّر في app/src/main:

        <activity android:name=".AutocompleteActivity" />

إضافة نشاط الإكمال التلقائي إلى قائمة الإصدار التجريبي

مثلما كانت الحال في السابق، أضِف العرض التوضيحي للإكمال التلقائي للأماكن إلى الشاشة الرئيسية من خلال إلحاقه بالقائمة في وحدة Demo. الآن وبعد أن أنشأت نشاطًا للإكمال التلقائي للأماكن، يمكنك إضافته إلى ملف Demo.kt في المجلد src/main/java/com/google/codelabs/maps/placesdemo/. لصق هذا الرمز بعد عنصر DETAILS_FRAGMENT_DEMO مباشرةً:

    AUTOCOMPLETE_FRAGMENT_DEMO(
        R
.string.autocomplete_fragment_demo_title,
        R
.string.autocomplete_fragment_demo_description,
       
AutocompleteActivity::class.java
   
),

يتم تحديد السلاسل المرتبطة في ملف src/main/res/values/strings.xml.

تشغيل التطبيق

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

الإكمال التلقائي للنشاط بعد نقر المستخدم على حقل الإدخال

الشكل 2. الإكمال التلقائي للنشاط بعد نقر المستخدم على حقل الإدخال.

نشاط الإكمال التلقائي بعد أن يكتب المستخدم ويختار &ldquo;Niagara Falls&rdquo;

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

9. الحصول على مكان الجهاز الحالي

إنشاء شاشة مكان حالي

تم توفير تنسيق activity_current.xml بدون LinearLayout فارغ في المجلد app/src/main/res/layout/. عليك ملء التنسيق الخطي بإضافة الرمز التالي بين أقواس <LinearLayout>.

    <Button
       
android:id="@+id/current_button"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:text="@string/current_button" />

   
<TextView
       
android:id="@+id/current_response_content"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:paddingTop="16dp"
       
android:scrollbars = "vertical"
       
android:textIsSelectable="true" />

إنشاء نشاط مكان حالي

  1. أنشئ ملف CurrentActivity.kt في المجلد src/main/java/com/google/codelabs/maps/placesdemo/ وحدِّده باستخدام هذا الرمز:
class CurrentPlaceActivity : AppCompatActivity() {
   
private lateinit var placesClient: PlacesClient
   
private lateinit var currentButton: Button
   
private lateinit var responseView: TextView

   
override fun onCreate(savedInstanceState: Bundle?) {
       
super.onCreate(savedInstanceState)
        setContentView
(R.layout.activity_current)

       
// Retrieve a PlacesClient (previously initialized - see DemoApplication)
        placesClient
= Places.createClient(this)

       
// Set view objects
        currentButton
= findViewById(R.id.current_button)
        responseView
= findViewById(R.id.current_response_content)


       
// Set listener for initiating Current Place
        currentButton
.setOnClickListener {
            checkPermissionThenFindCurrentPlace
()
       
}
   
}
}

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

  1. حدِّد checkPermissionThenFindCurrentPlace() للتحقق من وجود إذن تحديد الموقع الجغرافي الدقيق وطلب الإذن إذا لم يتم منحه بعد. ألصِق هذا الرمز بعد الدالة onCreate.
    /**
     * Checks that the user has granted permission for fine or coarse location.
     * If granted, finds current Place.
     * If not yet granted, launches the permission request.
     * See https://developer.android.com/training/permissions/requesting
     */

   
private fun checkPermissionThenFindCurrentPlace() {
       
when {
           
(ContextCompat.checkSelfPermission(
               
this,
                ACCESS_FINE_LOCATION
           
) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
               
this,
                ACCESS_COARSE_LOCATION
           
) == PackageManager.PERMISSION_GRANTED) -> {
               
// You can use the API that requires the permission.
                findCurrentPlace
()
           
}
            shouldShowRequestPermissionRationale
(ACCESS_FINE_LOCATION)
           
-> {
               
Log.d(TAG, "Showing permission rationale dialog")
               
// TODO: In an educational UI, explain to the user why your app requires this
               
// permission for a specific feature to behave as expected. In this UI,
               
// include a "cancel" or "no thanks" button that allows the user to
               
// continue using your app without granting the permission.
           
}
           
else -> {
               
// Ask for both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.
               
ActivityCompat.requestPermissions(
                   
this,
                    arrayOf
(
                       
Manifest.permission.ACCESS_FINE_LOCATION,
                       
Manifest.permission.ACCESS_COARSE_LOCATION
                   
),
                    PERMISSION_REQUEST_CODE
               
)
           
}
       
}
   
}

    companion
object {
       
private val TAG = "CurrentPlaceActivity"
       
private const val PERMISSION_REQUEST_CODE = 9
   
}
  1. عندما يستدعي فرع else لدالة checkPermissionThenFindCurrentPlace الرقم requestPermissions، سيقدِّم التطبيق مربّع حوار طلب الإذن للمستخدم. إذا كان المستخدم يعمل بنظام تشغيل يعمل بإصدار نظام تشغيل أقدم من Android 12، يمكن للمستخدم منح إذن الموقع الجغرافي الدقيق (الدقيق) فقط. إذا كان المستخدم يستخدم جهازًا يعمل بالإصدار 12 من نظام التشغيل Android أو إصدار أحدث، سيتم منحه خيار توفير موقع جغرافي تقريبي (تقريبي) بدلاً من الموقع الجغرافي الدقيق (الناعم)، كما هو موضّح في الشكل 4.

طلب إذن المستخدم على جهاز يعمل بالإصدار 12 من نظام التشغيل Android أو إصدار أحدث

الشكل 4. إنّ طلب إذن المستخدم على جهاز يعمل بالإصدار 12 من نظام التشغيل Android أو إصدار أحدث يتيح لك خيار منح الموقع الجغرافي الدقيق أو التقريبي.

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

    @SuppressLint("MissingPermission")
   
override fun onRequestPermissionsResult(
        requestCode
: Int,
        permissions
: Array<String>, grantResults: IntArray
   
) {
       
if (requestCode != PERMISSION_REQUEST_CODE) {
           
super.onRequestPermissionsResult(
                requestCode
,
                permissions
,
                grantResults
           
)
           
return
       
} else if (permissions.toList().zip(grantResults.toList())
               
.firstOrNull { (permission, grantResult) ->
                    grantResult
== PackageManager.PERMISSION_GRANTED && (permission == ACCESS_FINE_LOCATION || permission == ACCESS_COARSE_LOCATION)
               
} != null
       
)
           
// At least one location permission has been granted, so proceed with Find Current Place
            findCurrentPlace
()
   
}
  1. بعد منح الإذن، سيتم تشغيل الدالة findCurrentPlace. حدِّد الدالة باستخدام هذا الرمز بعد الدالة onRequestPermissionsResult.
    /**
     * Fetches a list of [PlaceLikelihood] instances that represent the Places the user is
     * most
     * likely to be at currently.
     */

   
@RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])
   
private fun findCurrentPlace() {
       
// Use fields to define the data types to return.
        val placeFields
: List<Place.Field> =
            listOf
(Place.Field.NAME, Place.Field.ID, Place.Field.ADDRESS, Place.Field.LAT_LNG)

       
// Use the builder to create a FindCurrentPlaceRequest.
        val request
: FindCurrentPlaceRequest = FindCurrentPlaceRequest.newInstance(placeFields)

       
// Call findCurrentPlace and handle the response (first check that the user has granted permission).
       
if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) ==
           
PackageManager.PERMISSION_GRANTED ||
           
ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) ==
           
PackageManager.PERMISSION_GRANTED
       
) {
           
// Retrieve likely places based on the device's current location
            lifecycleScope
.launch {
               
try {
                    val response
= placesClient.awaitFindCurrentPlace(placeFields)
                    responseView
.text = response.prettyPrint()

                   
// Enable scrolling on the long list of likely places
                    val movementMethod
= ScrollingMovementMethod()
                    responseView
.movementMethod = movementMethod
               
} catch (e: Exception) {
                    e
.printStackTrace()
                    responseView
.text = e.message
               
}
           
}
       
} else {
           
Log.d(TAG, "LOCATION permission not granted")
            checkPermissionThenFindCurrentPlace
()

       
}
   
}

ويحدّد هذا الرمز الحقول التي يتم طلبها للأماكن المحتملة ويُنشئ FindCurrentPlaceRequest ويبدأ المهمة ويملأ TextView بالتفاصيل المطلوبة.

  1. يمكنك تحويل FindCurrentPlaceResponse إلى نص عن طريق تحديد دالة إضافة. يتم توفير ملف StringUtil.kt لتبسيط تحويل استجابات SDK للمكان إلى سلاسل مقروءة.

في نهاية ملف CurrentPlaceActivity.kt، حدِّد دالة لتحويل كائن استجابة"المكان الحالي"إلى سلسلة.

fun FindCurrentPlaceResponse.prettyPrint(): String {
   
return StringUtil.stringify(this, false)
}

إضافة نشاط المكان الحالي إلى البيان

أضِف عنصر <activity> للعنصر CurrentPlaceActivity كعنصر ثانوي للعنصر <application> في الملف AndroidManifest.xml، المتوفّر في app/src/main:

        <activity android:name=".CurrentPlaceActivity" />

إضافة نشاط المكان الحالي إلى القائمة التجريبية

وكما كانت الحال في السابق، أضِف العرض التوضيحي "المكان الحالي" إلى الشاشة الرئيسية من خلال إلحاقه بالقائمة في وحدة Demo. الآن وبعد أن أنشأت نشاطًا في المكان الحالي، أضفه إلى ملف Demo.kt في مجلد src/main/java/com/google/codelabs/maps/placesdemo/. لصق هذا الرمز بعد عنصر AUTOCOMPLETE_FRAGMENT_DEMO مباشرةً:

    CURRENT_FRAGMENT_DEMO(
        R
.string.current_demo_title,
        R
.string.current_demo_description,
       
CurrentPlaceActivity::class.java
   
),

يتم تحديد السلاسل المرتبطة في ملف src/main/res/values/strings.xml.

تشغيل التطبيق

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

تقديم المطابقات المحتملة للمكان الحالي للموقع الذي تم الإبلاغ عنه للجهاز

الشكل 5. تقديم اقتراحات "المكان الحالي" المحتمل للجهاز الذي تم الإبلاغ عنه في "الموقع الجغرافي"

10. تهانينا

لقد أنشأت تطبيق Android بنجاح باستخدام حزمة تطوير البرامج (SDK) للأماكن لنظام التشغيل Android.

ما تعلّمته

ما الخطوات التالية؟

  • استكشِف مستودع GitHub الذي يتضمن عيّنات تجريبية وعروضًا توضيحية لها أو اضغط على مستودع منها في android-places-demos للحصول على مزيد من الأفكار.
  • تعلَّم من المزيد من الدروس التطبيقية حول ترميز Kotlin لإنشاء تطبيقات متوافقة مع Android باستخدام "منصة خرائط Google".
  • ساعدنا في إنشاء المحتوى الذي قد تجده أكثر فائدة من خلال الإجابة عن السؤال التالي:

ما هي الدروس التطبيقية الأخرى حول الترميز التي تريد الاطّلاع عليها؟

هل الدرس التطبيقي حول الترميز الذي تريد إدراجه في البرنامج غير متوفّر؟ طلب حلول للمشكلة الجديدة هنا