תחילת העבודה עם SDK של מקומות ל-Android (קוטלין)

1. לפני שתתחיל

ב-Codelab הזה אתם יכולים ללמוד איך לשלב עם האפליקציה את ה-SDK של מקומות ל-Android ולהשתמש בכל אחת מהתכונות של SDK SDK.

אפליקציית ההדגמה 'מקומות'

דרישות מוקדמות

  • ידע בסיסי בפיתוח של Kotlin ו-Android

מה תלמדו

  • איך להתקין את SDK של מקומות ל-Android עם תוספי Kotlin.
  • איך לטעון את פרטי המקום של מקום ספציפי.
  • איך להוסיף ווידג'ט של השלמה אוטומטית של מקום לאפליקציה.
  • איך לטעון את המקום הנוכחי על סמך המיקום המדווח של המכשיר כעת.

מה תצטרך להכין

כדי להשלים את קוד הקוד הזה, תצטרכו את החשבונות, השירותים והכלים הבאים:

2. להגדרה

עבור שלב ההפעלה שבהמשך, מפעילים את API של מקומות Google.

הגדרת מפות Google

אם עדיין אין לכם חשבון Google Cloud Platform ופרויקט שבו מופעל חיוב, כדאי לעיין במדריך תחילת העבודה עם הפלטפורמה של מפות Google ליצירת חשבון לחיוב ופרויקט.

  1. ב-Cloud Console, לוחצים על התפריט הנפתח של הפרויקט ובוחרים את הפרויקט שבו רוצים להשתמש ב-Codelab הזה.

  1. מפעילים את ממשקי ה-API ואת ערכות ה-SDK של מפות Google הנדרשים למעבדת קוד זו ב-Google Cloud Marketplace. כדי לעשות זאת, יש לבצע את השלבים המפורטים בסרטון הזה או בתיעוד הזה.
  2. יוצרים מפתח API בדף פרטי הכניסה ב-Cloud Console. ניתן לבצע את השלבים המפורטים בסרטון הזה או בתיעוד הזה. לכל הבקשות שנשלחות לפלטפורמה של מפות Google נדרש מפתח API.

3. התחלה מהירה

כדי להתחיל במהירות האפשרית, כדאי להוריד את הקוד למתחילים כדי לעקוב אחרי שיעור ה-Lab הזה. אתם מוזמנים לקפוץ לפתרון, אבל אם אתם רוצים להמשיך בכל השלבים, תצטרכו להמשיך לקרוא.

  1. משכפלים את המאגר אם git מותקן.
git clone https://github.com/googlemaps/codelab-places-101-android.git

לחלופין, לוחצים על הלחצן הזה כדי להוריד את קוד המקור.

  1. לאחר הורדת הקוד, יש לפתוח את הפרויקט שנמצא בתוך הספרייה של /starter ב-Android Studio. הפרויקט כולל את מבנה הקובץ הבסיסי הנדרש כדי להשלים את Lablab. כל מה שצריך לעבוד נמצא בספרייה של /starter.

אם ברצונך לראות את קוד הפתרון המלא, תוכל להציג את הקוד המלא בספרייה /solution.

4. התקנת SDK של מקומות ל-Android

בקטע הזה, אתה מוסיף את ה-SDK של מקומות ל-Android לתלויות באפליקציה שלך.

הוספת מפתח API

עליך לספק את מפתח ה-API שיצרת בעבר לאפליקציה, כדי שה-SDK של מקומות ל-Android יוכל לשייך את המפתח לאפליקציה שלך.

  1. פותחים את הקובץ שנקרא local.properties בספריית הבסיס של הפרויקט (ברמה שבה נמצאים gradle.properties ו-settings.gradle).
  2. עליך להגדיר מפתח חדש, GOOGLE_MAPS_API_KEY, ולהגדיר את הערך שלו למפתח ה-API שיצרת.

local.properties

GOOGLE_MAPS_API_KEY=YOUR_KEY_HERE

הערה: local.properties רשום בקובץ .gitignore במאגר של Git. הסיבה לכך היא שמפתח ה-API נחשב למידע רגיש, ואין לבדוק אותו כדי לשלוט במקור, אם הדבר אפשרי.

  1. לאחר מכן, כדי לחשוף את מפתח ה-API כך שניתן יהיה להשתמש בו בכל האפליקציה, צריך לכלול את הפלאגין Secrets Gradle 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 כמשתני build בקובץ המניפסט של Android, וכמשתנים בקורס BuildConfig שנוצר על ידי Gradle בזמן היצירה. שימוש בפלאגין הזה מסיר את הקוד המבודד שלפיהם ניתן היה לקרוא נכסים מ-local.properties כדי שניתן יהיה לגשת אליהם מהאפליקציה.

הוספת ה-SDK של 'מקומות' ל-Android

  1. עכשיו, כשניתן לגשת למפתח ה-API שלך בתוך האפליקציה, יש להוסיף את תלות של 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. התקנת מקומות KTX ב-Android

באפליקציות של Kotlin הכוללות SDK אחד או יותר של Android Maps Platform, ספריות תוספים של Kotlin מאפשרות להשתמש בתכונות השפה של Kotlin, כמו שגרות, פונקציות/מאפיינים של תוספים ועוד. לכל SDK של מפות Google יש ספריית KTX תואמת, כפי שמוצג בהמשך:

תרשים KTX של מפות Google

במשימה הזו, השתמש בספרייה של מקומות Google ל-Android KTX כדי להשתמש בתכונות שפה ספציפיות ל-Kotlin באפליקציה שלך.

הוספת תלות של 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)

כשאתם בונים את האפליקציה, הפלאגין Secret Gradle ל-Android הופך את מפתח ה-API שבקובץ 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" />

קוד זה מוסיף שדה קלט טקסט שבו המשתמש יכול להזין כל מזהה מקום או להשתמש בברירת המחדל שסופקה, לחצן להפעלת הבקשה לפרטי מקום ותצוגת טקסט כדי להציג את המידע מהתגובה. המחרוזות המשויכות מוגדרות עבורך בקובץ 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 ומוודאים שהוא יוצר ה-ListView שמאוכלס על ידי חזרה על התוכן של המודול Demo. אם המשתמש מקיש על פריט ברשימה, הכלי להאזנה על קליקים פותח את הפעילות המשויכת.

הפעלת האפליקציה

  1. מריצים את האפליקציה. הפעם אמור להופיע פריט אחד ברשימה שמציג את ההדגמה של 'פרטי מקום'.
  2. מקישים על הטקסט 'פרטי מקום'. אתם אמורים לראות את התצוגה שיצרתם עם שדה קלט ולחצן.
  3. מקישים על הלחצן "GET Details" . אם השתמשתם בברירת המחדל של מזהה המקום, השם, הכתובת וקואורדינטות המפה של המקום אמורים להופיע באיור 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 ותצוגת טקסט כדי להציג את המידע מהתגובה. המחרוזות המשויכות מוגדרות בקובץ 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; NiagaraWaterfall&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()
        }
    }
}

קוד זה משייך את הפעילות לתצוגות המפורטות שהגדרת בקובץ הפריסה. הוא גם מוסיף פונקציות מסוג listener של קליק ללחצן כדי להפעיל את הפונקציה 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, הוא יוכל להעניק הרשאת מיקום מדויקת (עדינה). אם המשתמש משתמש במכשיר עם Android מגרסה 12 ואילך, תהיה לו אפשרות לציין מיקום משוער (גס) במקום מיקום מדויק (מצוין), כפי שמתואר באיור 4.

בקשה להרשאת משתמש במכשיר עם Android מגרסה 12 ואילך

איור 4. בקשת הרשאת משתמש במכשיר עם Android 12 ומעלה מציגה את האפשרות להעניק מיקום מדויק או משוער.

לאחר שהמשתמש מגיב לתיבת הדו-שיח של הרשאות המערכת, המערכת מפעילה את האפליקציה של 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.

הצגת התאמות פוטנציאליות ל&#39;מיקום נוכחי&#39; עבור המיקום המדווח של המכשיר

איור 5. הצגת התאמות קיימות עבור המיקום הנוכחי של המכשיר המדווח.

10. מזל טוב

יצרת בהצלחה אפליקציה ל-Android עם SDK של מקומות ל-Android.

מה למדת

מה עכשיו?

  • תוכלו לעיין במאגר android-places-demos GitHub כדי לקבל השראה ודוגמאות.
  • הוראות נוספות ליצירת קוד ב-Kotlin יעזרו לכם ליצור אפליקציות ל-Android בעזרת הפלטפורמה של מפות Google.
  • כדי לעזור לנו ליצור את התוכן המועיל ביותר, נשמח לקבל ממך תשובות לשאלות הבאות:

אילו מעבדי קוד אחרים היית רוצה לראות?

תצוגה חזותית של נתונים במפות מידע נוסף על התאמה אישית של סגנון המפות שלי יצירת אינטראקציות בתלת-ממד במפות

ה-lablab לא מופיע ברשימה? אפשר לבקש אותו באמצעות בעיה חדשה כאן.