لمحة عن هذا الدرس التطبيقي حول الترميز
1. قبل البدء
يعلّمك هذا الدرس التطبيقي حول الترميز كيفية دمج حزمة تطوير البرامج (SDK) للأماكن في نظام التشغيل Android مع تطبيقك واستخدام كل ميزة من ميزات حزمة تطوير البرامج (SDK) للأماكن.
المتطلّبات الأساسية
- معرفة أساسية بالتطوير بلغة Kotlin وAndroid
ما ستتعرَّف عليه
- كيفية تثبيت حزمة تطوير البرامج (SDK) للأماكن التي تعمل بنظام التشغيل Android باستخدام إضافات Kotlin.
- كيفية تحميل تفاصيل المكان لمكان معين.
- كيفية إضافة أداة الإكمال التلقائي للأماكن إلى تطبيقك.
- كيفية تحميل المكان الحالي استنادًا إلى الموقع الذي تم الإبلاغ عنه حاليًا للجهاز
الأشياء التي تحتاج إليها
لإكمال هذا الدرس التطبيقي حول الترميز، ستحتاج إلى الحسابات والخدمات والأدوات التالية:
- حساب Google تم تفعيل الفوترة به.
- Android Studio Bumblebee أو إصدار أحدث.
- خدمات Google Play المثبّتة في "استوديو Android"
- أن يكون لديك جهاز يعمل بنظام التشغيل Android أو محاكي Android يشغّل نظام Google APIs الأساسي استنادًا إلى نظام التشغيل Android 8 أو الإصدارات الأحدث (راجِع تشغيل التطبيقات على محاكي Android لمعرفة خطوات التثبيت).
2. الإعداد
عند تنفيذ خطوة التفعيل، عليك تفعيل أماكن واجهة برمجة التطبيقات.
إعداد "منصة خرائط Google"
إذا لم يكن لديك حساب على Google Cloud Platform ومشروع تم تفعيل الفوترة فيه، يُرجى الاطّلاع على دليل بدء استخدام "منصة خرائط Google" لإنشاء حساب فوترة ومشروع.
- في Cloud Console، انقر على القائمة المنسدلة للمشروع واختَر المشروع الذي تريد استخدامه لهذا الدرس التطبيقي.
- فعِّل واجهات برمجة تطبيقات ومنصة SDK لمنصة "خرائط Google" المطلوبة لهذا الدرس التطبيقي في Google Cloud Marketplace. ولإجراء ذلك، اتّبِع الخطوات الواردة في هذا الفيديو أو هذه المستندات.
- يمكنك إنشاء مفتاح واجهة برمجة تطبيقات في صفحة بيانات الاعتماد في Cloud Console. يمكنك اتّباع الخطوات الواردة في هذا الفيديو أو هذه المستندات. تتطلب جميع الطلبات إلى "منصة خرائط Google" مفتاح واجهة برمجة تطبيقات.
3. البدء بسرعة
للبدء في أسرع وقت ممكن، نزِّل رمز التفعيل لمساعدتك على متابعة هذا الدرس التطبيقي حول الترميز. يمكنك بدء استخدام الحل، ولكن إذا كنت تريد متابعة كل خطوات إنشاء النص بنفسك، تابع القراءة.
- إنشاء نسخة طبق الأصل من المستودع في حال تثبيت
git
.
git clone https://github.com/googlemaps/codelab-places-101-android.git
أو انقر على هذا الزر لتنزيل رمز المصدر.
- بعد تنزيل الرمز، افتح المشروع المتوفّر في دليل
/starter
في"استوديو Android". يتضمّن هذا المشروع البنية الأساسية للملف والتي ستحتاج إلى إكمال الدرس التطبيقي حول الترميز. ستجد كل ما تحتاج إليه للعمل في دليل/starter
.
وإذا كنت تريد عرض رمز الحل الكامل قيد التشغيل، يمكنك عرض الرمز المكتمل في الدليل /solution
.
4. تثبيت الأماكن SDK لنظام التشغيل Android
في هذا القسم، يجب إضافة حزمة تطوير البرامج (SDK) للأماكن في Android إلى تبعيات تطبيقك.
إضافة مفتاح واجهة برمجة التطبيقات
يُرجى تقديم مفتاح واجهة برمجة التطبيقات الذي أنشأته مسبقًا للتطبيق حتى تتمكّن حزمة تطوير البرامج (SDK) لخدمة "أماكن Google" لنظام التشغيل Android من ربط مفتاحك بتطبيقك.
- افتح الملف باسم
local.properties
في الدليل الجذري لمشروعك (المستوى نفسه حيث يوجدgradle.properties
وsettings.gradle
). - تحديد مفتاح جديد
GOOGLE_MAPS_API_KEY
، وضبط قيمته على مفتاح واجهة برمجة التطبيقات الذي أنشأته.
local.properties
GOOGLE_MAPS_API_KEY=YOUR_KEY_HERE
لاحِظ أن local.properties
مدرَج في ملف .gitignore
في مستودع Git. ويرجع ذلك إلى أن مفتاح واجهة برمجة التطبيقات يُعتبر معلومات حساسة ويجب عدم تسجيله للوصول إلى عنصر التحكم في المصدر، إن أمكن.
- بعد ذلك، لعرض مفتاح واجهة برمجة التطبيقات الخاص بك حتى يمكن استخدامه في تطبيقك، أضِف المكوّن الإضافي Secrets Gradle Plugin for Android في ملف
build.gradle
الخاص بتطبيقك المتوفّر في دليلapp/
، وأضِف السطر التالي ضمن كتلةplugins
:
build.gradle على مستوى التطبيق
plugins {
// ...
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
- يمكنك تعديل ملف
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
- الآن ويمكن الوصول إلى مفتاح واجهة برمجة التطبيقات داخل التطبيق، يمكنك إضافة تبعية حزمة تطوير البرامج (SDK) للأماكن في Android إلى ملف
build.gradle
لتطبيقك.
في مشروع المبتدئين الذي يتضمن هذا الدرس التطبيقي حول الترميز، تمت إضافة هذه الاعتمادية لك من قبل.
build.gradle على مستوى التطبيق
dependencies {
// Dependency to include Places SDK for Android
implementation 'com.google.android.libraries.places:places:2.6.0'
}
- شغِّل التطبيق.
من المفترض أن يظهر لك الآن تطبيق يحتوي على شاشة فارغة. مواصلة تعبئة هذه الشاشة بثلاثة إصدارات تجريبية.
5. تثبيت أماكن Android KTX
بالنسبة إلى تطبيقات Kotlin التي تستخدم حزمة تطوير برامج واحدة أو أكثر لمنصة "خرائط Google" لنظام التشغيل Android، تتيح لك مكتبات لغة Kotlin (KTX) الاستفادة من ميزات لغة Kotlin، مثل الكوروتينات وخصائص الإضافات ووظائفها والمزيد. لكل حِزمة تطوير برامج (SDK) في "خرائط Google" مكتبة KTX مطابقة كما هو موضّح أدناه:
في هذه المهمة، استخدم مكتبة 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
.
إنشاء نشاط على التفاصيل
- أنشِئ ملف
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)
}
}
- يمكنك إنشاء عميل للأماكن لاستخدامه مع هذا النشاط. يمكنك لصق هذا الرمز بعد إعداد كائن الملف الشخصي في دالة
onCreate
.
// Retrieve a PlacesClient (previously initialized - see DemoApplication)
placesClient = Places.createClient(this)
- بعد إعداد برنامج الأماكن، يمكنك إرفاق أداة معالجة نقرة بالزر. الصق هذا الرمز بعد إنشاء برنامج الأماكن في دالة
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 بالتفاصيل المطلوبة.
- يمكنك تحويل
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.
الشكل 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
.
إنشاء نشاط الإكمال التلقائي
- أنشئ ملف
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
التي حدّدتها في ملف التنسيق.
- بعد ذلك، حدّد ما يحدث عندما يختار المستخدم أحد التوقعات المقدمة من خلال الإكمال التلقائي للأماكن. أضِف هذا الرمز إلى نهاية دالة
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
.
تشغيل التطبيق
- شغِّل التطبيق. تظهر هذه المرة عنصرين في قائمة الشاشة الرئيسية.
- انقر على صف الإكمال التلقائي للأماكن. من المفترض أن يظهر لك إدخال منبثق لإضافة المكان كما هو موضح في الشكل 2.
- ابدأ في كتابة اسم مكان. يمكن أن يكون اسم المؤسسة أو العنوان أو المنطقة الجغرافية. يجب عرض التوقعات أثناء الكتابة.
- اختَر أحد التوقعات. من المفترض أن تختفي التوقّعات، ويجب أن تعرض أداة TextView الآن تفاصيل عن المكان المحدّد كما هو موضّح في الشكل 3.
الشكل 2. الإكمال التلقائي للنشاط بعد نقر المستخدم على حقل الإدخال.
الشكل 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" />
إنشاء نشاط مكان حالي
- أنشئ ملف
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
عند النقر على الزر.
- حدِّد
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
}
- عندما يستدعي فرع
else
لدالةcheckPermissionThenFindCurrentPlace
الرقمrequestPermissions
، سيقدِّم التطبيق مربّع حوار طلب الإذن للمستخدم. إذا كان المستخدم يعمل بنظام تشغيل يعمل بإصدار نظام تشغيل أقدم من Android 12، يمكن للمستخدم منح إذن الموقع الجغرافي الدقيق (الدقيق) فقط. إذا كان المستخدم يستخدم جهازًا يعمل بالإصدار 12 من نظام التشغيل Android أو إصدار أحدث، سيتم منحه خيار توفير موقع جغرافي تقريبي (تقريبي) بدلاً من الموقع الجغرافي الدقيق (الناعم)، كما هو موضّح في الشكل 4.
الشكل 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()
}
- بعد منح الإذن، سيتم تشغيل الدالة
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 بالتفاصيل المطلوبة.
- يمكنك تحويل
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
.
تشغيل التطبيق
- شغِّل التطبيق. تظهر هذه المرة ثلاثة عناصر في قائمة الشاشة الرئيسية.
- انقر على صف المكان الحالي. من المفترَض أن يظهر لك زر على الشاشة.
- انقر على الزر. في حال عدم منح إذن تحديد الموقع الجغرافي لهذا التطبيق من قبل، من المفترض أن يظهر طلب إذن.
- يجب منح التطبيق إذن الوصول إلى الموقع الجغرافي للجهاز.
- انقر على الزر مرة أخرى. هذه المرة، يجب أن تظهر قائمة تضم ما يصل إلى 20 مكانًا قريبًا واحتمالاته، كما هو موضح في الشكل 5.
الشكل 5. تقديم اقتراحات "المكان الحالي" المحتمل للجهاز الذي تم الإبلاغ عنه في "الموقع الجغرافي"
10. تهانينا
لقد أنشأت تطبيق Android بنجاح باستخدام حزمة تطوير البرامج (SDK) للأماكن لنظام التشغيل Android.
ما تعلّمته
- تثبيت وتهيئة حزمة SDK للأماكن لنظام التشغيل Android.
- تثبيت إضافات Kotlin لحزمة تطوير البرامج (SDK) للأماكن لنظام التشغيل Android.
- جارٍ تحميل تفاصيل المكان.
- إضافة الإكمال التلقائي للأماكن.
- الحصول على المكان الحالي.
ما الخطوات التالية؟
- استكشِف مستودع GitHub الذي يتضمن عيّنات تجريبية وعروضًا توضيحية لها أو اضغط على مستودع منها في
android-places-demos
للحصول على مزيد من الأفكار. - تعلَّم من المزيد من الدروس التطبيقية حول ترميز Kotlin لإنشاء تطبيقات متوافقة مع Android باستخدام "منصة خرائط Google".
- ساعدنا في إنشاء المحتوى الذي قد تجده أكثر فائدة من خلال الإجابة عن السؤال التالي:
ما هي الدروس التطبيقية الأخرى حول الترميز التي تريد الاطّلاع عليها؟
هل الدرس التطبيقي حول الترميز الذي تريد إدراجه في البرنامج غير متوفّر؟ طلب حلول للمشكلة الجديدة هنا