1. ก่อนที่คุณจะเริ่มต้น
โค้ดแล็บนี้จะสอนวิธีผสานรวม Places SDK สำหรับ Android กับแอป และวิธีใช้ฟีเจอร์แต่ละอย่างของ Places SDK
ข้อกำหนดเบื้องต้น
- ความรู้พื้นฐานเกี่ยวกับการพัฒนา Kotlin และ Android
สิ่งที่คุณจะได้เรียนรู้
- วิธีติดตั้ง Places SDK สำหรับ Android ด้วยส่วนขยาย Kotlin
- วิธีโหลดรายละเอียดสถานที่สำหรับสถานที่ที่เฉพาะเจาะจง
- วิธีเพิ่มวิดเจ็ตการเติมข้อความอัตโนมัติของสถานที่ลงในแอป
- วิธีโหลดสถานที่ปัจจุบันตามตำแหน่งที่อุปกรณ์รายงานในปัจจุบัน
สิ่งที่คุณต้องมี
หากต้องการทำ Codelab นี้ให้เสร็จสมบูรณ์ คุณจะต้องมีบัญชี บริการ และเครื่องมือต่อไปนี้
- บัญชี Google ที่เปิดใช้การเรียกเก็บเงิน
- Android Studio Bumblebee ขึ้นไป
- บริการ Google Play ที่ติดตั้งใน Android Studio
- อุปกรณ์ Android หรือโปรแกรมจำลอง Android ที่เรียกใช้แพลตฟอร์ม Google APIs ที่อิงตาม Android 8 ขึ้นไป (ดูขั้นตอนการติดตั้งได้ที่เรียกใช้แอปในโปรแกรมจำลอง Android)
2. ตั้งค่า
สำหรับขั้นตอนการเปิดใช้ด้านล่าง ให้เปิดใช้ Places API และ Maps SDK สำหรับ Android
ตั้งค่า Google Maps Platform
หากยังไม่มีบัญชี Google Cloud Platform และโปรเจ็กต์ที่เปิดใช้การเรียกเก็บเงิน โปรดดูคู่มือเริ่มต้นใช้งาน Google Maps Platform เพื่อสร้างบัญชีสำหรับการเรียกเก็บเงินและโปรเจ็กต์
- ใน Cloud Console ให้คลิกเมนูแบบเลื่อนลงของโปรเจ็กต์ แล้วเลือกโปรเจ็กต์ที่ต้องการใช้สำหรับ Codelab นี้
- เปิดใช้ Google Maps Platform APIs และ SDK ที่จำเป็นสำหรับ Codelab นี้ใน Google Cloud Marketplace โดยทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้
- สร้างคีย์ API ในหน้าข้อมูลเข้าสู่ระบบของ Cloud Console คุณสามารถทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้ คำขอทั้งหมดไปยัง Google Maps Platform ต้องใช้คีย์ API
3. การเริ่มใช้งานอย่างง่าย
หากต้องการให้คุณเริ่มต้นใช้งานได้โดยเร็วที่สุด ให้ดาวน์โหลดโค้ดเริ่มต้นเพื่อช่วยให้คุณทำตาม Codelab นี้ได้ คุณสามารถข้ามไปยังวิธีแก้ปัญหาได้ แต่หากต้องการทำตามขั้นตอนทั้งหมดเพื่อสร้างด้วยตนเอง โปรดอ่านต่อ
- โคลนที่เก็บหากคุณติดตั้ง
git
ไว้
git clone https://github.com/googlemaps/codelab-places-101-android-kotlin.git
หรือคลิกปุ่มนี้เพื่อดาวน์โหลดซอร์สโค้ด
- หลังจากดาวน์โหลดโค้ดแล้ว ให้เปิดโปรเจ็กต์ที่อยู่ในไดเรกทอรี
/starter
ใน Android Studio โปรเจ็กต์นี้มีโครงสร้างไฟล์พื้นฐานที่คุณจะต้องใช้เพื่อทำ Codelab ให้เสร็จสมบูรณ์ ทุกอย่างที่คุณต้องใช้ในการทำงานจะอยู่ในไดเรกทอรี/starter
หากต้องการดูโค้ดโซลูชันทั้งหมดที่ทำงานอยู่ คุณสามารถดูโค้ดที่เสร็จสมบูรณ์แล้วในไดเรกทอรี /solution
4. เพิ่มคีย์ API ลงในโปรเจ็กต์
ส่วนนี้อธิบายวิธีจัดเก็บคีย์ API เพื่อให้แอปอ้างอิงได้อย่างปลอดภัย คุณไม่ควรเช็คอินคีย์ API ในระบบควบคุมเวอร์ชัน ดังนั้นเราขอแนะนำให้จัดเก็บคีย์ในไฟล์ secrets.properties
ซึ่งจะอยู่ในสำเนาในเครื่องของไดเรกทอรีรากของโปรเจ็กต์ ดูข้อมูลเพิ่มเติมเกี่ยวกับไฟล์ secrets.properties
ได้ที่ไฟล์พร็อพเพอร์ตี้ Gradle
เราขอแนะนำให้ใช้ปลั๊กอินข้อมูลลับ Gradle สำหรับ Android เพื่อให้งานนี้มีประสิทธิภาพมากขึ้น
วิธีติดตั้งปลั๊กอินข้อมูลลับ Gradle สำหรับ Android ในโปรเจ็กต์ Google Maps
- ใน Android Studio ให้เปิดไฟล์
build.gradle.kts
หรือbuild.gradle
ระดับบนสุด แล้วเพิ่มโค้ดต่อไปนี้ลงในองค์ประกอบdependencies
ภายในbuildscript
หากใช้ build.gradle.kts
ให้เพิ่มข้อมูลต่อไปนี้
buildscript {
dependencies {
classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1")
}
}
หากใช้ build.gradle
ให้เพิ่มข้อมูลต่อไปนี้
buildscript {
dependencies {
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
}
}
- เปิดไฟล์
build.gradle.kts
หรือbuild.gradle
ระดับโมดูล แล้วเพิ่มโค้ดต่อไปนี้ลงในองค์ประกอบplugins
หากใช้ build.gradle.kts
ให้เพิ่มข้อมูลต่อไปนี้
plugins {
// ...
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
}
หากใช้ build.gradle
ให้เพิ่มข้อมูลต่อไปนี้
plugins {
// ...
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
- ในไฟล์
build.gradle.kts
หรือbuild.gradle
ระดับโมดูล ให้ตรวจสอบว่าได้ตั้งค่าtargetSdk
และcompileSdk
เป็น 34 - บันทึกไฟล์และซิงค์โปรเจ็กต์กับ Gradle
- เปิดไฟล์
secrets.properties
ในไดเรกทอรีระดับบนสุด แล้วเพิ่มโค้ดต่อไปนี้ แทนที่YOUR_API_KEY
ด้วยคีย์ API ของคุณ จัดเก็บคีย์ไว้ในไฟล์นี้เนื่องจากระบบจะไม่ตรวจสอบsecrets.properties
ในระบบควบคุมเวอร์ชัน
PLACES_API_KEY=YOUR_API_KEY
- บันทึกไฟล์
- สร้างไฟล์
local.defaults.properties
ในไดเรกทอรีระดับบนสุด ซึ่งเป็นโฟลเดอร์เดียวกับไฟล์secrets.properties
แล้วเพิ่มโค้ดต่อไปนี้
PLACES_API_KEY=DEFAULT_API_KEY
จุดประสงค์ของไฟล์นี้คือการระบุตำแหน่งสำรองสำหรับคีย์ API ในกรณีที่ไม่พบไฟล์ secrets.properties
เพื่อให้การสร้างไม่ล้มเหลว ปัญหานี้อาจเกิดขึ้นหากคุณโคลนแอปจากระบบควบคุมเวอร์ชันที่ละเว้น secrets.properties
และคุณยังไม่ได้สร้างไฟล์ secrets.properties
ในเครื่องเพื่อระบุคีย์ API
- บันทึกไฟล์
- ใน Android Studio ให้เปิดไฟล์
build.gradle.kts
หรือbuild.gradle
ระดับโมดูล แล้วแก้ไขพร็อพเพอร์ตี้secrets
หากไม่มีพร็อพเพอร์ตี้secrets
ให้เพิ่ม
แก้ไขพร็อพเพอร์ตี้ของปลั๊กอินเพื่อตั้งค่า propertiesFileName
เป็น secrets.properties
ตั้งค่า defaultPropertiesFileName
เป็น local.defaults.properties
และตั้งค่าพร็อพเพอร์ตี้อื่นๆ
secrets {
// Optionally specify a different file name containing your secrets.
// The plugin defaults to "local.properties"
propertiesFileName = "secrets.properties"
// A properties file containing default secret values. This file can be
// checked in version control.
defaultPropertiesFileName = "local.defaults.properties"
}
5. ติดตั้ง Places SDK สำหรับ Android
ในส่วนนี้ คุณจะเพิ่ม Places SDK สำหรับ Android ลงในการขึ้นต่อกันของแอป
- ตอนนี้คุณเข้าถึงคีย์ API ภายในแอปได้แล้ว ให้เพิ่มการอ้างอิง Places SDK สำหรับ Android ลงในไฟล์
build.gradle
ของแอป
แก้ไขไฟล์ build.gradle
ระดับแอปเพื่อเพิ่มทรัพยากร Dependency สำหรับ Places SDK สำหรับ Android ดังนี้
build.gradle ระดับแอป
dependencies {
// Dependency to include Places SDK for Android
implementation 'com.google.android.libraries.places:places:3.4.0'
}
- เรียกใช้แอป
ตอนนี้คุณควรเห็นแอปที่มีหน้าจอว่างเปล่า ดำเนินการป้อนข้อมูลในหน้าจอนี้ด้วยการสาธิต 3 รายการต่อไป
6. ติดตั้ง Places Android KTX
สำหรับแอป Kotlin ที่ใช้ Google Maps Platform Android SDK อย่างน้อย 1 รายการ ไลบรารีส่วนขยาย Kotlin (KTX) จะช่วยให้คุณใช้ประโยชน์จากฟีเจอร์ภาษา Kotlin ได้ เช่น Coroutine, พร็อพเพอร์ตี้/ฟังก์ชันส่วนขยาย และอื่นๆ Google Maps SDK แต่ละรายการมีไลบรารี KTX ที่เกี่ยวข้องดังที่แสดงด้านล่าง
ในงานนี้ ให้ใช้ไลบรารี Places Android KTX เพื่อใช้ฟีเจอร์ภาษาเฉพาะของ Kotlin ในแอป
เพิ่มการอ้างอิง Places Android KTX
หากต้องการใช้ประโยชน์จากฟีเจอร์เฉพาะของ Kotlin ให้รวมไลบรารี KTX ที่เกี่ยวข้องสำหรับ SDK นี้ไว้ในไฟล์ build.gradle
ระดับแอป
build.gradle
dependencies {
// ...
// Places SDK for Android KTX Library
implementation 'com.google.maps.android:places-ktx:3.1.1'
}
7. เริ่มต้นไคลเอ็นต์ Places
เริ่มต้น Places SDK สำหรับขอบเขตแอปพลิเคชัน
ในไฟล์ DemoApplication.kt
ของโฟลเดอร์ app/src/main/java/com/google/codelabs/maps/placesdemo
ให้เริ่มต้นใช้งาน Places SDK สำหรับ Android วางบรรทัดด้านล่างที่ส่วนท้ายของฟังก์ชัน onCreate
// Initialize the SDK with the Google Maps Platform API key
Places.initialize(this, BuildConfig.PLACES_API_KEY)
เมื่อคุณสร้างแอป ปลั๊กอินข้อมูลลับ Gradle สำหรับ Android จะทำให้คีย์ API ในไฟล์ secrets.properties
พร้อมใช้งานเป็น BuildConfig.PLACES_API_KEY
เพิ่มไฟล์แอปพลิเคชันลงในไฟล์ Manifest
เนื่องจากคุณได้ขยายเวลา Application
ด้วย DemoApplication
คุณจึงต้องอัปเดตไฟล์ Manifest เพิ่มพร็อพเพอร์ตี้ android:name
ลงในองค์ประกอบ application
ในไฟล์ AndroidManifest.xml
ซึ่งอยู่ใน app/src/main
<application
android:name=".DemoApplication"
...
</application>
โค้ดนี้จะชี้ Manifest ของแอปพลิเคชันไปยังคลาส DemoApplication
ในโฟลเดอร์ src/main/java/com/google/codelabs/maps/placesdemo/
8. ดึงข้อมูลรายละเอียดสถานที่
สร้างหน้าจอรายละเอียด
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/
แล้วเชื่อมโยงกับเลย์เอาต์ที่คุณเพิ่งสร้าง วางโค้ดนี้ลงในไฟล์
@ExperimentalCoroutinesApi
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)
val apiKey = BuildConfig.PLACES_API_KEY
// Log an error if apiKey is not set.
if (apiKey.isEmpty() || apiKey == "DEFAULT_API_KEY") {
Log.e(TAG, "No api key")
finish()
return
}
}
}
- สร้างไคลเอ็นต์ Places เพื่อใช้กับกิจกรรมนี้ วางโค้ดนี้หลังโค้ดเพื่อตรวจสอบคีย์ API ในฟังก์ชัน
onCreate
// Retrieve a PlacesClient (previously initialized - see DemoApplication)
placesClient = Places.createClient(this)
- หลังจากตั้งค่าไคลเอ็นต์ Places แล้ว ให้แนบเครื่องมือฟังการคลิกกับปุ่ม วางโค้ดนี้หลังจากการสร้างไคลเอ็นต์ Places ในฟังก์ชัน
onCreate
// Upon button click, fetch and display the Place Details
detailsButton.setOnClickListener { button ->
button.isEnabled = false
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
}
button.isEnabled = true
}
}
โค้ดนี้จะดึงข้อมูลรหัสสถานที่ที่ป้อนในช่องป้อนข้อมูล กำหนดช่องที่จะขอสำหรับสถานที่ สร้าง FetchPlaceRequest
เริ่มต้นงาน และรอฟังผลสำเร็จหรือล้มเหลว หากคำขอสำเร็จ ฟังก์ชันจะป้อนรายละเอียดที่ขอลงใน TextView
เพิ่มกิจกรรม Details ลงในไฟล์ Manifest
เพิ่มองค์ประกอบ <activity>
สำหรับ DetailsActivity
เป็นองค์ประกอบย่อยขององค์ประกอบ <application>
ในไฟล์ AndroidManifest.xml
ซึ่งอยู่ใน app/src/main
<activity android:name=".DetailsActivity" android:label="@string/details_demo_title" />
เพิ่มกิจกรรมรายละเอียดลงในเมนูการสาธิต
เรามีโมดูล 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
หากผู้ใช้แตะรายการในลิสต์ Listener การคลิกจะเปิดกิจกรรมที่เกี่ยวข้อง
เรียกใช้แอป
- เรียกใช้แอป คราวนี้คุณควรเห็นรายการเดียวในรายการที่แสดงการสาธิตรายละเอียดสถานที่
- แตะข้อความรายละเอียดสถานที่ คุณควรเห็นมุมมองที่สร้างขึ้นพร้อมช่องป้อนข้อมูลและปุ่ม
- แตะปุ่ม "ดูรายละเอียด" หากใช้รหัสสถานที่เริ่มต้น คุณควรเห็นชื่อสถานที่ ที่อยู่ และพิกัดแผนที่ที่แสดง ดังที่แสดงในรูปที่ 1
รูปที่ 1 กิจกรรมรายละเอียดสถานที่พร้อมคำตอบที่แสดง
9. เพิ่ม Place Autocomplete
สร้างหน้าจอเติมข้อความอัตโนมัติ
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/
แล้วกำหนดด้วยโค้ดนี้
@ExperimentalCoroutinesApi
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
val placeFields: List<Place.Field> =
listOf(Place.Field.NAME, Place.Field.ID, Place.Field.ADDRESS, Place.Field.LAT_LNG)
autocompleteFragment.setPlaceFields(placeFields)
// Listen to place selection events
lifecycleScope.launchWhenCreated {
autocompleteFragment.placeSelectionEvents().collect { event ->
when (event) {
is PlaceSelectionSuccess -> {
val place = event.place
responseView.text = prettyPrintAutocompleteWidget(place, false)
}
is PlaceSelectionError -> Toast.makeText(
this@AutocompleteActivity,
"Failed to get place '${event.status.statusMessage}'",
Toast.LENGTH_SHORT
).show()
}
}
}
โค้ดนี้จะกำหนดช่องที่จะขอสำหรับสถานที่ ฟังเหตุการณ์การเลือกสถานที่ และฟังความสำเร็จหรือความล้มเหลว หากคำขอสำเร็จ ฟังก์ชันจะป้อนรายละเอียดสถานที่ลงใน TextView โปรดทราบว่าการเติมข้อความอัตโนมัติของสถานที่จะแสดงออบเจ็กต์ Place คุณจึงไม่จำเป็นต้องส่งคำขอรายละเอียดสถานที่แยกต่างหากเมื่อใช้เครื่องมือการเติมข้อความอัตโนมัติของสถานที่
เพิ่มกิจกรรมการเติมข้อความอัตโนมัติลงในไฟล์ Manifest
เพิ่มองค์ประกอบ <activity>
สำหรับ AutocompleteActivity
เป็นองค์ประกอบย่อยขององค์ประกอบ <application>
ในไฟล์ AndroidManifest.xml
ซึ่งอยู่ใน app/src/main
<activity android:name=".AutocompleteActivity" android:label="@string/autocomplete_fragment_demo_title" />
เพิ่มกิจกรรมการเติมข้อความอัตโนมัติลงในเมนูการสาธิต
เช่นเดียวกับก่อนหน้านี้ ให้เพิ่มการสาธิตการเติมข้อความอัตโนมัติของสถานที่ลงในหน้าจอหลักโดยต่อท้ายรายการในโมดูล 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 รายการในรายการหน้าจอหลัก
- แตะแถวการเติมข้อความอัตโนมัติของสถานที่ คุณควรเห็นอินพุตการเติมข้อความอัตโนมัติของสถานที่ปรากฏขึ้นตามที่แสดงในรูปที่ 2
- เริ่มพิมพ์ชื่อสถานที่ ซึ่งอาจเป็นชื่อสถานประกอบการ ที่อยู่ หรือภูมิภาคทางภูมิศาสตร์ การคาดคะเนควรแสดงขึ้นขณะที่คุณพิมพ์
- เลือกการคาดการณ์รายการใดรายการหนึ่ง การคาดคะเนควรหายไป และตอนนี้ TextView ควรแสดงรายละเอียดเกี่ยวกับสถานที่ที่เลือกตามที่แสดงในรูปที่ 3
รูปที่ 2 กิจกรรมการเติมข้อความอัตโนมัติหลังจากที่ผู้ใช้แตะช่องป้อนข้อมูล
รูปที่ 3 กิจกรรมการเติมข้อความอัตโนมัติที่แสดงรายละเอียดสถานที่หลังจากที่ผู้ใช้พิมพ์และเลือก "น้ำตกไนแอการา"
10. รับสถานที่ปัจจุบันของอุปกรณ์
สร้างหน้าจอสถานที่ปัจจุบัน
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" />
สร้างกิจกรรมสถานที่ปัจจุบัน
- สร้างไฟล์
CurrentPlaceActivity.kt
ในโฟลเดอร์src/main/java/com/google/codelabs/maps/placesdemo/
แล้วกำหนดด้วยโค้ดนี้
@ExperimentalCoroutinesApi
class CurrentPlaceActivity : AppCompatActivity(), OnMapReadyCallback {
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
เมื่อมีการคลิกปุ่ม
- กำหนด
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(
ACCESS_FINE_LOCATION,
ACCESS_COARSE_LOCATION
),
PERMISSION_REQUEST_CODE
)
}
}
}
companion object {
private const val TAG = "CurrentPlaceActivity"
private const val PERMISSION_REQUEST_CODE = 9
}
- เมื่อสาขา
else
ของฟังก์ชันcheckPermissionThenFindCurrentPlace
เรียกใช้requestPermissions
แอปจะแสดงกล่องโต้ตอบคำขอสิทธิ์ต่อผู้ใช้ หากผู้ใช้ใช้อุปกรณ์ที่ใช้ระบบปฏิบัติการต่ำกว่า Android 12 ผู้ใช้จะให้สิทธิ์เข้าถึงตำแหน่งที่แน่นอน (ละเอียด) ได้เท่านั้น หากผู้ใช้ใช้อุปกรณ์ที่ใช้ Android 12 ขึ้นไป ผู้ใช้จะมีตัวเลือกในการระบุตำแหน่งโดยประมาณ (หยาบ) แทนตำแหน่งที่แน่นอน (ละเอียด) ดังที่แสดงในรูปที่ 4
รูปที่ 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()
}
- เมื่อได้รับสิทธิ์แล้ว ฟังก์ชัน
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)
// 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
currentButton.isEnabled = false
lifecycleScope.launch {
val response = placesClient.awaitFindCurrentPlace(placeFields)
responseView.text = response.prettyPrint()
// Enable scrolling on the long list of likely places
val movementMethod = ScrollingMovementMethod()
responseView.movementMethod = movementMethod
}
} else {
Log.d(TAG, "LOCATION permission not granted")
checkPermissionThenFindCurrentPlace()
}
}
โค้ดนี้จะกำหนดช่องที่จะขอสำหรับสถานที่ที่มีแนวโน้มว่าจะใช่ สร้าง FindCurrentPlaceRequest
เริ่มงาน และป้อนข้อมูล TextView ด้วยรายละเอียดที่ขอ
เพิ่มกิจกรรมสถานที่ปัจจุบันลงในไฟล์ Manifest
เพิ่มองค์ประกอบ <activity>
สำหรับ CurrentPlaceActivity
เป็นองค์ประกอบย่อยขององค์ประกอบ <application>
ในไฟล์ AndroidManifest.xml
ซึ่งอยู่ใน app/src/main
<activity android:name=".CurrentPlaceActivity" android:label="@string/current_demo_title" />
เพิ่มกิจกรรมสถานที่ปัจจุบันลงในเมนูการสาธิต
เช่นเดียวกับก่อนหน้านี้ ให้เพิ่มเดโมสถานที่ปัจจุบันลงในหน้าจอหลักโดยต่อท้ายรายการในโมดูล 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
เรียกใช้แอป
- เรียกใช้แอป คราวนี้คุณควรเห็น 3 รายการในรายการหน้าจอหลัก
- แตะแถวสถานที่ปัจจุบัน คุณควรเห็นปุ่มบนหน้าจอ
- แตะปุ่ม หากคุณไม่เคยให้สิทธิ์เข้าถึงตำแหน่งแก่แอปนี้มาก่อน คำขอสิทธิ์ควรปรากฏขึ้น
- ให้สิทธิ์แอปในการเข้าถึงตำแหน่งของอุปกรณ์
- แตะปุ่มอีกครั้ง คราวนี้ รายการสถานที่ใกล้เคียงสูงสุด 20 แห่งและความน่าจะเป็นของแต่ละแห่งควรปรากฏขึ้น ดังที่แสดงในรูปที่ 5
รูปที่ 5 แสดงสถานที่ปัจจุบันที่น่าจะเป็นไปได้สำหรับตำแหน่งที่รายงานของอุปกรณ์
11. แสดงสถานที่ปัจจุบันบนแผนที่
เพิ่มการอ้างอิง Maps
ในไฟล์ build.gradle
ระดับโมดูล ให้เพิ่มทรัพยากร Dependency ของบริการ Google Play สำหรับ Maps SDK สำหรับ Android
app/build.gradle
dependencies {
// ...
implementation 'com.google.android.gms:play-services-maps:18.2.0'
}
อัปเดตไฟล์ Manifest ของ Android เพื่อรองรับแผนที่
เพิ่มองค์ประกอบ meta-data
ต่อไปนี้ภายในองค์ประกอบ application
ซึ่งจะฝังเวอร์ชันของบริการ Google Play ที่ใช้คอมไพล์แอปและระบุคีย์ API ของคุณ
AndroidManifest.xml
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
เพิ่มคีย์ API ลงใน secrets.properties
เปิดไฟล์ secrets.properties
ในไดเรกทอรีระดับบนสุด แล้วเพิ่มโค้ดต่อไปนี้ แทนที่ YOUR_API_KEY
ด้วยคีย์ API ของคุณ
MAPS_API_KEY=YOUR_API_KEY
เปิดไฟล์ local.defaults.properties
ในไดเรกทอรีระดับบนสุด ซึ่งเป็นโฟลเดอร์เดียวกับไฟล์ secrets.properties
แล้วเพิ่มโค้ดต่อไปนี้
MAPS_API_KEY=DEFAULT_API_KEY
ตรวจสอบคีย์ API
ใน onCreate()
แอปจะตรวจสอบคีย์ API ของ Maps และเริ่มต้น Fragment การรองรับแผนที่ getMapAsync()
ใช้เพื่อลงทะเบียนการโทรกลับของแผนที่
เพิ่มโค้ดต่อไปนี้เพื่อดำเนินการนี้
CurrentPlaceActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_current)
val apiKey = BuildConfig.MAPS_API_KEY
// Log an error if apiKey is not set.
if (apiKey.isEmpty() || apiKey == "DEFAULT_API_KEY") {
Log.e("Places test", "No api key")
finish()
return
}
// Retrieve a PlacesClient (previously initialized - see DemoApplication)
placesClient = Places.createClient(this)
(supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment?)?.getMapAsync(this)
// ...
}
สร้างเลย์เอาต์แผนที่
- ในโฟลเดอร์
app/src/main/res/layout/
ให้สร้างไฟล์เลย์เอาต์fragment_map.xml
แล้วป้อนโค้ดต่อไปนี้ลงในเลย์เอาต์
res/layout/fragment_map.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.google.codelabs.maps.placesdemo.CurrentPlaceActivity" />
ซึ่งจะกำหนดให้ SupportMapFragment
ทำหน้าที่เป็นคอนเทนเนอร์สำหรับแผนที่และให้สิทธิ์เข้าถึงออบเจ็กต์ GoogleMap
- ในเลย์เอาต์
activity_current.xml
ที่อยู่ในโฟลเดอร์app/src/main/res/layout/
ให้เพิ่มโค้ดต่อไปนี้ที่ด้านล่างของเลย์เอาต์เชิงเส้น
res/layout/activity_current.xml
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:text="@string/showing_most_likely_place"
style="@style/TextAppearance.AppCompat.Title"/>
<include layout="@layout/fragment_map"/>
TextView
ที่เพิ่มเข้ามาอ้างอิงถึงทรัพยากรสตริงใหม่ที่ต้องสร้าง
- ใน
app/src/main/res/values/strings.xml
ให้เพิ่มทรัพยากรสตริงต่อไปนี้
res/values/strings.xml
<string name="showing_most_likely_place">Showing most likely place</string>
เนื่องจากมีการเพิ่มมุมมองเพิ่มเติมสำหรับแผนที่ TextView
ที่แสดงรายการสถานที่จึงต้องตั้งค่าความสูงเพื่อให้มุมมองเหล่านี้ยังคงมองเห็นได้
- เพิ่มแอตทริบิวต์
maxHeight
ลงในTextView
ที่มีรหัสcurrent_response_content
res/layout/activity_current.xml
android:maxHeight="200dp"
ใช้ OnMapReadyCallback
ใช้OnMapReadyCallback
อินเทอร์เฟซโดยเพิ่มลงในการประกาศคลาส และแทนที่เมธอด onMapReady()
เพื่อตั้งค่าแผนที่เมื่อมีออบเจ็กต์ GoogleMap
CurrentPlaceActivity.kt
class CurrentPlaceActivity : AppCompatActivity(), OnMapReadyCallback {
ที่ส่วนท้ายของคลาส ให้เพิ่มโค้ดต่อไปนี้
CurrentPlaceActivity.kt
override fun onMapReady(map: GoogleMap) {
this.map = map
lastKnownLocation?.let { location ->
map.moveCamera(
CameraUpdateFactory.newLatLngZoom(
location,
DEFAULT_ZOOM
)
)
}
}
Callback ต้องใช้ตัวแปรคลาสบางรายการจึงจะทำงานได้อย่างถูกต้อง เพิ่มข้อมูลต่อไปนี้ทันทีหลังจากส่วนหัวของคลาส
CurrentPlaceActivity.kt
private var map: GoogleMap? = null
private var lastKnownLocation: LatLng? = null
เพิ่มโค้ดต่อไปนี้ลงในออบเจ็กต์คู่ของคลาส
CurrentPlaceActivity.kt
private const val DEFAULT_ZOOM = 15f
เรียกใช้แอป
- เรียกใช้แอป
- แตะแถวสถานที่ปัจจุบัน คุณควรเห็นปุ่มบนหน้าจอ
- แตะปุ่ม หากคุณไม่เคยให้สิทธิ์เข้าถึงตำแหน่งแก่แอปนี้มาก่อน คำขอสิทธิ์ควรปรากฏขึ้น
- ให้สิทธิ์แอปในการเข้าถึงตำแหน่งของอุปกรณ์
- แตะปุ่มอีกครั้ง แผนที่จะแสดงขึ้น
รูปที่ 6 กิจกรรมสถานที่ปัจจุบันที่แสดงแผนที่
อัปเดตแผนที่ด้วยสถานที่
ที่ส่วนท้ายของคลาส ให้เพิ่มโค้ดต่อไปนี้
CurrentPlaceActivity.kt
private data class LikelyPlace(
val name: String,
val address: String,
val attribution: List<String>,
val latLng: LatLng
)
private fun PlaceLikelihood.toLikelyPlace(): LikelyPlace? {
val name = this.place.name
val address = this.place.address
val latLng = this.place.latLng
val attributions = this.place.attributions ?: emptyList()
return if (name != null && address != null && latLng != null) {
LikelyPlace(name, address, attributions, latLng)
} else {
null
}
}
ซึ่งใช้เพื่อจัดเก็บและจัดรูปแบบข้อมูลของสถานที่
ที่จุดเริ่มต้นของคลาส ให้เพิ่มโค้ดต่อไปนี้เพื่อสร้างตัวแปรที่ใช้จัดเก็บข้อมูลของสถานที่ที่ส่งคืน
CurrentPlaceActivity.kt
private val likelyPlaces = mutableListOf<LikelyPlace>()
ในขั้นตอนนี้ ระบบจะเปลี่ยนโค้ดเพื่อให้ผู้ใช้เห็นรายการสถานที่และเลือกสถานที่ที่จะแสดงบนแผนที่ ข้อมูลสถานที่ทั้งหมดจะแสดงในรายการบนหน้าจอ
ในฟังก์ชัน findCurrentPlace
ในบล็อก lifecycleScope.launch
ก่อนบรรทัดโค้ดนี้
CurrentPlaceActivity.kt
responseView.text = response.prettyPrint()
เพิ่มโค้ดต่อไปนี้
CurrentPlaceActivity.kt
likelyPlaces.clear()
likelyPlaces.addAll(
response.placeLikelihoods.take(M_MAX_ENTRIES).mapNotNull { placeLikelihood ->
placeLikelihood.toLikelyPlace()
}
)
openPlacesDialog()
โค้ดนี้ต้องใช้ค่าคงที่สำหรับจำนวนสถานที่สูงสุดที่จะแสดง
เพิ่มโค้ดสำหรับค่าคงที่นั้นในออบเจ็กต์คู่
CurrentPlaceActivity.kt
private const val M_MAX_ENTRIES = 5
เพิ่มโค้ดต่อไปนี้ซึ่งจะสร้างกล่องโต้ตอบที่อนุญาตให้ผู้ใช้เลือกสถานที่
CurrentPlaceActivity.kt
/**
* Displays a form allowing the user to select a place from a list of likely places.
*/
private fun openPlacesDialog() {
// Ask the user to choose the place where they are now.
val listener =
DialogInterface.OnClickListener { _, which -> // The "which" argument contains the position of the selected item.
val likelyPlace = likelyPlaces[which]
lastKnownLocation = likelyPlace.latLng
val snippet = buildString {
append(likelyPlace.address)
if (likelyPlace.attribution.isNotEmpty()) {
append("\n")
append(likelyPlace.attribution.joinToString(", "))
}
}
val place = Place.builder().apply {
name = likelyPlace.name
latLng = likelyPlace.latLng
}.build()
map?.clear()
setPlaceOnMap(place, snippet)
}
// Display the dialog.
AlertDialog.Builder(this)
.setTitle(R.string.pick_place)
.setItems(likelyPlaces.map { it.name }.toTypedArray(), listener)
.setOnDismissListener {
currentButton.isEnabled = true
}
.show()
}
ตามแนวทางปฏิบัติแนะนำของ Android กล่องโต้ตอบจะอ้างอิงทรัพยากรสตริงซึ่งต้องเพิ่มลงในstrings.xml
ไฟล์ทรัพยากรที่อยู่ในโฟลเดอร์ app/src/main/res/values/
เพิ่มรายการต่อไปนี้ไปยัง strings.xml
res/values/strings.xml
<string name="pick_place">Choose a place</string>
จากนั้นฟังก์ชันเหล่านี้จะเรียกใช้ฟังก์ชัน setPlaceOnMap
ซึ่งจะย้ายกล้องและวางเครื่องหมายไว้ที่ตำแหน่งที่เลือก
เพิ่มโค้ดต่อไปนี้
CurrentPlaceActivity.kt
private fun setPlaceOnMap(place: Place?, markerSnippet: String?) {
val latLng = place?.latLng ?: defaultLocation
map?.moveCamera(
CameraUpdateFactory.newLatLngZoom(
latLng,
DEFAULT_ZOOM
)
)
map?.addMarker(
MarkerOptions()
.position(latLng)
.title(place?.name)
.snippet(markerSnippet)
)
}
นอกจากนี้ เราขอแนะนำให้บันทึกและกู้คืนสถานะของแผนที่ด้วย
หากต้องการบันทึกสถานะ ให้ลบล้างฟังก์ชัน onSaveInstanceState
แล้วเพิ่มโค้ดต่อไปนี้
CurrentPlaceActivity.kt
/**
* Saves the state of the map when the activity is paused.
*/
override fun onSaveInstanceState(outState: Bundle) {
outState.putParcelable(KEY_LOCATION, lastKnownLocation)
super.onSaveInstanceState(outState)
}
หากต้องการกู้คืนสถานะ ให้onCreate
เพิ่มโค้ดต่อไปนี้หลังการเรียกใช้ setContentView
CurrentPlaceActivity.kt
if (savedInstanceState != null) {
lastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION)
}
การบันทึกและกู้คืนต้องใช้คีย์ ซึ่งเป็นค่าคงที่จากออบเจ็กต์เสริม
ในบล็อกออบเจ็กต์เสริม ให้เพิ่มข้อมูลต่อไปนี้
CurrentPlaceActivity.kt
// Key for storing activity state.
private const val KEY_LOCATION = "location"
เรียกใช้แอป
- เรียกใช้แอป
- แตะแถวสถานที่ปัจจุบัน คุณควรเห็นปุ่มบนหน้าจอ
- แตะปุ่ม หากคุณไม่เคยให้สิทธิ์เข้าถึงตำแหน่งแก่แอปนี้มาก่อน คำขอสิทธิ์ควรปรากฏขึ้น
- ให้สิทธิ์แอปในการเข้าถึงตำแหน่งของอุปกรณ์
- แตะปุ่มอีกครั้ง
- เลือกสถานที่โดยแตะสถานที่นั้น ระบบจะซูมแผนที่และจัดกึ่งกลางโดยมีเครื่องหมายวางอยู่ที่ตำแหน่งที่เลือก
รูปที่ 7 แผนที่ที่มีเครื่องหมายที่ตำแหน่งที่เลือก
12. ขอแสดงความยินดี
คุณสร้างแอป Android ด้วย Places SDK สำหรับ Android ได้สำเร็จแล้ว
สิ่งที่คุณได้เรียนรู้
- การติดตั้งและกำหนดค่า Places SDK สำหรับ Android
- การติดตั้งส่วนขยาย Kotlin สำหรับ Places SDK สำหรับ Android
- กำลังโหลดรายละเอียดสถานที่
- การเพิ่ม Place Autocomplete
- การรับสถานที่ปัจจุบัน
ขั้นตอนถัดไปคือ
- สำรวจหรือ Fork ที่เก็บ GitHub ของตัวอย่างและเดโม
android-places-demos
เพื่อหาแรงบันดาลใจเพิ่มเติม - ดูKotlin Codelab เพิ่มเติมสำหรับการสร้างแอป Android ด้วย Google Maps Platform
- ช่วยเราสร้างเนื้อหาที่เป็นประโยชน์ต่อคุณมากที่สุดโดยตอบคำถามต่อไปนี้
คุณอยากเห็น Codelab อื่นๆ แบบไหน
หากไม่พบ Codelab ที่ต้องการ ขอได้โดยแจ้งปัญหาใหม่ที่นี่