1. ก่อนเริ่มต้น
การสร้างแอปด้วย Google Maps ช่วยให้คุณเพิ่มฟีเจอร์ต่างๆ ลงในแอปได้ เช่น ภาพถ่ายดาวเทียม การควบคุม UI ที่มีประสิทธิภาพสำหรับแผนที่ การติดตามตำแหน่ง และเครื่องหมายตำแหน่ง คุณเพิ่มคุณค่าให้กับ Google Maps มาตรฐานได้โดยการแสดงข้อมูลจากชุดข้อมูลของคุณเอง เช่น สถานที่ตั้งของพื้นที่ตกปลาหรือปีนเขาที่มีชื่อเสียง นอกจากนี้ คุณยังสร้างเกมที่ผู้เล่นสำรวจโลกจริงได้ด้วย เช่น เกมล่าขุมทรัพย์หรือแม้แต่เกมความจริงเสริม
ในบทเรียนนี้ คุณจะได้สร้างแอป Google Maps ชื่อ Wander ซึ่งจะแสดงแผนที่ที่ปรับแต่งแล้วและแสดงตำแหน่งของผู้ใช้
ข้อกำหนดเบื้องต้น
ความรู้เกี่ยวกับสิ่งต่อไปนี้
- วิธีสร้างแอป Android พื้นฐานและเรียกใช้โดยใช้ Android Studio
- วิธีสร้างและจัดการทรัพยากร เช่น สตริง
- วิธีปรับโครงสร้างโค้ดและเปลี่ยนชื่อตัวแปรโดยใช้ Android Studio
- วิธีใช้แผนที่ Google ในฐานะผู้ใช้
- วิธีตั้งค่าสิทธิ์รันไทม์
สิ่งที่คุณจะได้เรียนรู้
- วิธีรับคีย์ API จาก Google API Console และลงทะเบียนคีย์กับแอป
- วิธีผสานรวม Google Maps ในแอป
- วิธีแสดงแผนที่ประเภทต่างๆ
- วิธีจัดรูปแบบ Google Map
- วิธีเพิ่มเครื่องหมายลงในแผนที่
- วิธีเปิดใช้เพื่อให้ผู้ใช้ปักหมุดที่จุดที่น่าสนใจ (POI)
- วิธีเปิดใช้การติดตามตำแหน่ง
- วิธีสร้างแอป
Wanderซึ่งมี Google Maps แบบฝัง - วิธีสร้างฟีเจอร์ที่กำหนดเองสำหรับแอป เช่น เครื่องหมายและการจัดรูปแบบ
- วิธีเปิดใช้การติดตามตำแหน่งในแอป
2. ภาพรวมของแอป
ในโค้ดแล็บนี้ คุณจะสร้างแอป Wander ซึ่งแสดงแผนที่ Google ที่มีการจัดรูปแบบที่กำหนดเอง แอป Wander ช่วยให้คุณวางเครื่องหมายบนสถานที่ เพิ่มภาพซ้อนทับ และดูตำแหน่งของคุณแบบเรียลไทม์ได้

3. งาน: ตั้งค่าโปรเจ็กต์และรับคีย์ API
Maps SDK สำหรับ Android ต้องใช้คีย์ API หากต้องการรับคีย์ API ให้ลงทะเบียนโปรเจ็กต์ในหน้า API และบริการ คีย์ API จะเชื่อมโยงกับใบรับรองดิจิทัลที่ลิงก์แอปกับผู้เขียน ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ใบรับรองดิจิทัลและการลงนามแอปได้ที่ลงนามแอป
ในโค้ดแล็บนี้ คุณจะใช้คีย์ API สำหรับใบรับรองการแก้ไขข้อบกพร่อง ใบรับรองการแก้ไขข้อบกพร่องไม่ปลอดภัยตามการออกแบบ ดังที่อธิบายไว้ในลงนามในบิลด์การแก้ไขข้อบกพร่อง แอป Android ที่เผยแพร่แล้วซึ่งใช้ Maps SDK สำหรับ Android ต้องใช้คีย์ API ที่ 2 ซึ่งเป็นคีย์สำหรับใบรับรองการเผยแพร่ ดูข้อมูลเพิ่มเติมเกี่ยวกับการขอรับใบรับรองรุ่นได้ที่รับคีย์ API
Android Studio มีเทมเพลตกิจกรรม Google Maps ซึ่งสร้างโค้ดเทมเพลตที่เป็นประโยชน์ โค้ดเทมเพลตมีไฟล์ google_maps_api.xml ซึ่งมีลิงก์ที่ช่วยให้รับคีย์ API ได้ง่ายขึ้น
ขั้นตอนที่ 1: สร้างโปรเจ็กต์ Wander ด้วยเทมเพลตแผนที่
- สร้างโปรเจ็กต์ Android Studio ใหม่
- เลือกเทมเพลตกิจกรรมใน Google Maps

- ตั้งชื่อโปรเจ็กต์
Wander - ตั้งค่าระดับ API ขั้นต่ำเป็น API 19 ตรวจสอบว่าภาษาเป็น Kotlin
- คลิกเสร็จสิ้น
- เมื่อสร้างแอปเสร็จแล้ว ให้ดูโปรเจ็กต์และไฟล์ที่เกี่ยวข้องกับ Maps ต่อไปนี้ที่ Android Studio สร้างให้คุณ
google_maps_api.xml - คุณใช้ไฟล์การกำหนดค่านี้เพื่อจัดเก็บคีย์ API เทมเพลตจะสร้างไฟล์ google_maps_api.xml 2 ไฟล์ ได้แก่ ไฟล์สําหรับการแก้ไขข้อบกพร่องและไฟล์สําหรับการเผยแพร่ ไฟล์สำหรับคีย์ API ของใบรับรองการแก้ไขข้อบกพร่องจะอยู่ใน src/debug/res/values ไฟล์สำหรับคีย์ API สำหรับใบรับรองการเผยแพร่อยู่ใน src/release/res/values ใน Codelab นี้ คุณจะใช้เฉพาะใบรับรองการแก้ไขข้อบกพร่อง
activity_maps.xml - ไฟล์เลย์เอาต์นี้มี Fragment เดียวที่ครอบคลุมทั้งหน้าจอ คลาส SupportMapFragment เป็นคลาสย่อยของคลาส Fragment SupportMapFragment เป็นวิธีที่ง่ายที่สุดในการวางแผนที่ในแอป ซึ่งเป็น Wrapper รอบมุมมองของแผนที่เพื่อจัดการความต้องการด้านวงจรที่จำเป็นโดยอัตโนมัติ
คุณใส่ SupportMapFragment ในไฟล์เลย์เอาต์ได้โดยใช้แท็ก <fragment> ใน ViewGroup ใดก็ได้ พร้อมด้วยแอตทริบิวต์ name เพิ่มเติม
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.java - ไฟล์ MapsActivity.kt จะสร้างอินสแตนซ์ SupportMapFragment ในเมธอด onCreate() และใช้ getMapAsync() ของคลาสเพื่อเริ่มต้นระบบแผนที่และมุมมองโดยอัตโนมัติ กิจกรรมที่มี SupportMapFragment ต้องใช้การเชื่อมต่อ OnMapReadyCallback และเมธอด onMapReady() ของการเชื่อมต่อดังกล่าว ระบบจะเรียกใช้เมธอด onMapReady() เมื่อโหลดแผนที่
ขั้นตอนที่ 2: รับคีย์ API
- เปิดไฟล์ google_maps_api.xml เวอร์ชันแก้ไขข้อบกพร่อง
- ในไฟล์ ให้มองหาความคิดเห็นที่มี URL ยาว พารามิเตอร์ของ URL มีข้อมูลเฉพาะเกี่ยวกับแอปของคุณ
- คัดลอกและวาง URL ลงในเบราว์เซอร์
- ทำตามข้อความแจ้งเพื่อสร้างโปรเจ็กต์ในหน้า API และบริการ เนื่องจากพารามิเตอร์ใน URL ที่ระบุ หน้าเว็บจึงทราบว่าต้องเปิดใช้ Maps SDK สำหรับ Android โดยอัตโนมัติ
- คลิกสร้างคีย์ API
- ในหน้าถัดไป ให้ไปที่ส่วนคีย์ API แล้วคลิกคีย์ที่คุณเพิ่งสร้าง
- คลิกจำกัดคีย์ แล้วเลือก Maps SDK สำหรับ Android เพื่อจำกัดการใช้คีย์ไว้เฉพาะแอป Android
- คัดลอกคีย์ API ที่สร้างขึ้น โดยจะขึ้นต้นด้วย "
AIza" - ใน
google_maps_api.xmlไฟล์ ให้วางคีย์ลงในสตริงgoogle_maps_keyที่มีข้อความYOUR_KEY_HERE - เรียกใช้แอป คุณควรเห็นแผนที่ฝังในกิจกรรมโดยมีเครื่องหมายที่ตั้งอยู่ในซิดนีย์ ออสเตรเลีย (เครื่องหมายซิดนีย์เป็นส่วนหนึ่งของเทมเพลตและคุณจะเปลี่ยนได้ในภายหลัง)

ขั้นตอนที่ 3: เปลี่ยนชื่อ mMap
MapsActivity มี lateinit var แบบส่วนตัวชื่อ mMap ซึ่งเป็นประเภท GoogleMap หากต้องการทำตามรูปแบบการตั้งชื่อของ Kotlin ให้เปลี่ยนชื่อ mMap เป็น map
- ใน
MapsActivityให้คลิกขวาที่mMapแล้วคลิกปรับโครงสร้าง > เปลี่ยนชื่อ...

- เปลี่ยนชื่อตัวแปรเป็น
map
โปรดสังเกตว่าการอ้างอิงทั้งหมดถึง mMap ในฟังก์ชัน onMapReady() จะเปลี่ยนเป็น map ด้วย
4. งาน: เพิ่มประเภทแผนที่
Google Maps มีแผนที่หลายประเภท ได้แก่ ปกติ ไฮบริด ดาวเทียม ภูมิประเทศ และ "ไม่มี" (สำหรับไม่มีแผนที่เลย)
|
|
|
|
แผนที่ปกติ | แผนที่ดาวเทียม | แผนที่ไฮบริด | แผนที่ภูมิประเทศ |
แผนที่แต่ละประเภทจะให้ข้อมูลที่แตกต่างกัน เช่น เมื่อใช้ Maps เพื่อการนำทางในรถยนต์ การเห็นชื่อถนนจะเป็นประโยชน์ ดังนั้นคุณจึงอาจใช้ตัวเลือกปกติ เมื่อเดินป่า แผนที่ภูมิประเทศอาจช่วยให้คุณตัดสินใจได้ว่าต้องปีนขึ้นไปอีกเท่าใดจึงจะถึงยอดเขา
ในงานนี้ คุณจะต้องทำสิ่งต่อไปนี้
- เพิ่มแถบแอปที่มีเมนูตัวเลือกซึ่งช่วยให้ผู้ใช้เปลี่ยนประเภทแผนที่ได้
- ย้ายตำแหน่งเริ่มต้นของแผนที่ไปยังตำแหน่งบ้านของคุณ
- เพิ่มการรองรับเครื่องหมาย ซึ่งระบุตำแหน่งเดียวบนแผนที่และอาจมีป้ายกำกับ
เพิ่มเมนูสำหรับประเภทแผนที่
ในขั้นตอนนี้ คุณจะเพิ่มแถบแอปที่มีเมนูตัวเลือกซึ่งช่วยให้ผู้ใช้เปลี่ยนประเภทแผนที่ได้
- หากต้องการสร้างไฟล์ XML ของเมนูใหม่ ให้คลิกขวาที่ไดเรกทอรี res แล้วเลือกใหม่ > ไฟล์ทรัพยากร Android
- ในกล่องโต้ตอบ ให้ตั้งชื่อไฟล์
map_options - เลือก Menu เป็นประเภททรัพยากร
- คลิกตกลง
- ในแท็บโค้ด ให้แทนที่โค้ดในไฟล์ใหม่ด้วยโค้ดต่อไปนี้เพื่อสร้างตัวเลือกเมนูแผนที่ ระบบจะละเว้นประเภทแผนที่ "ไม่มี" เนื่องจาก "ไม่มี" จะส่งผลให้ไม่มีแผนที่เลย ขั้นตอนนี้จะทำให้เกิดข้อผิดพลาด แต่คุณจะแก้ไขได้ในขั้นตอนถัดไป
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/normal_map"
android:title="@string/normal_map"
app:showAsAction="never" />
<item
android:id="@+id/hybrid_map"
android:title="@string/hybrid_map"
app:showAsAction="never" />
<item
android:id="@+id/satellite_map"
android:title="@string/satellite_map"
app:showAsAction="never" />
<item
android:id="@+id/terrain_map"
android:title="@string/terrain_map"
app:showAsAction="never" />
</menu>
- ใน
strings.xmlให้เพิ่มแหล่งข้อมูลสำหรับแอตทริบิวต์titleเพื่อแก้ไขข้อผิดพลาด
<resources>
...
<string name="normal_map">Normal Map</string>
<string name="hybrid_map">Hybrid Map</string>
<string name="satellite_map">Satellite Map</string>
<string name="terrain_map">Terrain Map</string>
<string name="lat_long_snippet">Lat: %1$.5f, Long: %2$.5f</string>
<string name="dropped_pin">Dropped Pin</string>
<string name="poi">poi</string>
</resources>
- ใน
MapsActivityให้ลบล้างเมธอดonCreateOptionsMenu()และขยายเมนูจากไฟล์ทรัพยากรmap_options
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.map_options, menu)
return true
}
- ใน
MapsActivity.ktให้ลบล้างเมธอดonOptionsItemSelected()เปลี่ยนประเภทแผนที่โดยใช้ค่าคงที่ของประเภทแผนที่เพื่อให้สอดคล้องกับการเลือกของผู้ใช้
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
// Change the map type based on the user's selection.
R.id.normal_map -> {
map.mapType = GoogleMap.MAP_TYPE_NORMAL
true
}
R.id.hybrid_map -> {
map.mapType = GoogleMap.MAP_TYPE_HYBRID
true
}
R.id.satellite_map -> {
map.mapType = GoogleMap.MAP_TYPE_SATELLITE
true
}
R.id.terrain_map -> {
map.mapType = GoogleMap.MAP_TYPE_TERRAIN
true
}
else -> super.onOptionsItemSelected(item)
}
- เรียกใช้แอป
- คลิก
เพื่อเปลี่ยนประเภทแผนที่ สังเกตว่าลักษณะที่ปรากฏของแผนที่เปลี่ยนแปลงไปอย่างไรในโหมดต่างๆ

5. งาน: เพิ่มเครื่องหมาย
โดยค่าเริ่มต้น onMapReady() การเรียกกลับจะมีโค้ดที่วางเครื่องหมายในซิดนีย์ ประเทศออสเตรเลีย ซึ่งเป็นที่ที่สร้าง Google Maps การเรียกกลับเริ่มต้นจะทำให้แผนที่เคลื่อนไหวเพื่อเลื่อนไปยังซิดนีย์ด้วย
ในงานนี้ คุณจะทำให้กล้องของแผนที่เคลื่อนไปยังบ้าน ซูมไปยังระดับที่คุณระบุ และวางเครื่องหมายไว้ที่นั่น
ขั้นตอนที่ 1: ซูมไปที่บ้านและเพิ่มเครื่องหมาย
- ในไฟล์
MapsActivity.ktให้ค้นหาวิธีonMapReady()นำโค้ดที่วางเครื่องหมายในซิดนีย์และย้ายกล้องออก ตอนนี้เมธอดของคุณควรมีลักษณะดังนี้
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
}
- ค้นหาละติจูดและลองจิจูดของบ้านโดยทำตามวิธีการเหล่านี้
- สร้างค่าสำหรับละติจูดและค่าสำหรับลองจิจูด แล้วป้อนค่าลอยตัวของค่าเหล่านั้น
val latitude = 37.422160
val longitude = -122.084270
- สร้างออบเจ็กต์
LatLngใหม่ชื่อhomeLatLngในออบเจ็กต์homeLatLngให้ส่งค่าที่คุณเพิ่งสร้าง
val homeLatLng = LatLng(latitude, longitude)
- สร้าง
valสำหรับระดับการซูมที่คุณต้องการในแผนที่ ใช้ระดับการซูม 15f
val zoomLevel = 15f
ระดับการซูมจะควบคุมระดับการซูมเข้าบนแผนที่ รายการต่อไปนี้จะช่วยให้คุณทราบถึงระดับรายละเอียดที่แต่ละระดับการซูมแสดง
1: โลก5: ผืนดินขนาดใหญ่/ทวีป10: เมือง15: ถนน20: อาคาร
- ย้ายกล้องไปที่
homeLatLngโดยเรียกฟังก์ชันmoveCamera()ในออบเจ็กต์mapและส่งออบเจ็กต์CameraUpdateโดยใช้CameraUpdateFactory.newLatLngZoom()ส่งออบเจ็กต์homeLatLngและzoomLevel
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
- เพิ่มเครื่องหมายลงในแผนที่ที่
homeLatLng
map.addMarker(MarkerOptions().position(homeLatLng))
วิธีสุดท้ายควรมีลักษณะดังนี้
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
//These coordinates represent the latitude and longitude of the Googleplex.
val latitude = 37.422160
val longitude = -122.084270
val zoomLevel = 15f
val homeLatLng = LatLng(latitude, longitude)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
map.addMarker(MarkerOptions().position(homeLatLng))
}
- เรียกใช้แอป แผนที่ควรเลื่อนไปยังบ้าน ซูมไปยังระดับที่ต้องการ และวางเครื่องหมายบนบ้าน

ขั้นตอนที่ 2: อนุญาตให้ผู้ใช้เพิ่มเครื่องหมายโดยใช้การคลิกแบบยาว
ในขั้นตอนนี้ คุณจะเพิ่มเครื่องหมายเมื่อผู้ใช้แตะตำแหน่งบนแผนที่ค้างไว้
- สร้าง Stub ของเมธอดใน
MapsActivityชื่อsetMapLongClick()ซึ่งรับGoogleMapเป็นอาร์กิวเมนต์ - แนบเครื่องฟัง
setOnMapLongClickListenerกับออบเจ็กต์แผนที่
private fun setMapLongClick(map:GoogleMap) {
map.setOnMapLongClickListener { }
}
- ใน
setOnMapLongClickListener()ให้เรียกใช้เมธอดaddMarker()ส่งออบเจ็กต์MarkerOptionsใหม่โดยตั้งค่าตำแหน่งเป็นLatLngที่ส่งเข้ามา
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
map.addMarker(
MarkerOptions()
.position(latLng)
)
}
}
- ที่ส่วนท้ายของเมธอด
onMapReady()ให้เรียกใช้setMapLongClick()ด้วยmap
override fun onMapReady(googleMap: GoogleMap) {
...
setMapLongClick(map)
}
- เรียกใช้แอป
- แตะแผนที่ค้างไว้เพื่อวางเครื่องหมายที่ตำแหน่ง
- แตะเครื่องหมายเพื่อจัดกึ่งกลางบนหน้าจอ

ขั้นตอนที่ 3: เพิ่มหน้าต่างข้อมูลสำหรับเครื่องหมาย
ในขั้นตอนนี้ คุณจะเพิ่ม InfoWindow ที่แสดงพิกัดของเครื่องหมายเมื่อมีการแตะเครื่องหมาย
- ใน
setMapLongClick()setOnMapLongClickListener()ให้สร้างvalสำหรับsnippetข้อมูลโค้ดคือข้อความเพิ่มเติมที่แสดงหลังชื่อ ข้อมูลโค้ดจะแสดงละติจูดและลองจิจูดของเครื่องหมาย
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
// A snippet is additional text that's displayed after the title.
val snippet = String.format(
Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude
)
map.addMarker(
MarkerOptions()
.position(latLng)
)
}
}
- ใน
addMarker()ให้ตั้งค่าtitleของเครื่องหมายเป็นหมุดที่วางโดยใช้แหล่งข้อมูลสตริงR.string.dropped_pin - ตั้งค่า
snippetของเครื่องหมายเป็นsnippet
ฟังก์ชันที่เสร็จสมบูรณ์แล้วจะมีลักษณะดังนี้
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
// A Snippet is Additional text that's displayed below the title.
val snippet = String.format(
Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude
)
map.addMarker(
MarkerOptions()
.position(latLng)
.title(getString(R.string.dropped_pin))
.snippet(snippet)
)
}
}
- เรียกใช้แอป
- แตะแผนที่ค้างไว้เพื่อวางเครื่องหมายระบุตำแหน่ง
- แตะเครื่องหมายเพื่อแสดงหน้าต่างข้อมูล

ขั้นตอนที่ 4: เพิ่มเครื่องมือฟัง POI
โดยค่าเริ่มต้น จุดที่น่าสนใจ (POI) จะปรากฏบนแผนที่พร้อมกับไอคอนที่เกี่ยวข้อง POI ได้แก่ สวนสาธารณะ โรงเรียน อาคารรัฐบาล และอื่นๆ เมื่อตั้งค่าประเภทแผนที่เป็น normal จุดที่น่าสนใจของธุรกิจจะปรากฏบนแผนที่ด้วย POI ของธุรกิจแสดงถึงธุรกิจต่างๆ เช่น ร้านค้า ร้านอาหาร และโรงแรม
ในขั้นตอนนี้ คุณจะเพิ่ม GoogleMap.OnPoiClickListener ลงในแผนที่ เครื่องมือฟังการคลิกนี้จะวางเครื่องหมายบนแผนที่ทันทีเมื่อผู้ใช้คลิกจุดที่น่าสนใจ ตัวตรวจจับการคลิกจะแสดงหน้าต่างข้อมูลที่มีชื่อจุดที่น่าสนใจด้วย
- สร้าง Stub ของเมธอดใน
MapsActivityชื่อsetPoiClick()ซึ่งรับGoogleMapเป็นอาร์กิวเมนต์ - ในเมธอด
setPoiClick()ให้ตั้งค่าOnPoiClickListenerในGoogleMapที่ส่งเข้ามา
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
}
}
- ใน
setOnPoiClickListener()ให้สร้างval poiMarkerสำหรับเครื่องหมาย - ตั้งค่าเป็นเครื่องหมายโดยใช้
map.addMarker()กับMarkerOptionsโดยตั้งค่าtitleเป็นชื่อของจุดที่น่าสนใจ
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
}
}
- ในฟังก์ชัน
setOnPoiClickListener()ให้เรียกใช้showInfoWindow()ในpoiMarkerเพื่อแสดงหน้าต่างข้อมูลทันที
poiMarker.showInfoWindow()
โค้ดสุดท้ายสำหรับฟังก์ชัน setPoiClick() ควรมีลักษณะดังนี้
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
poiMarker.showInfoWindow()
}
}
- เมื่อสิ้นสุด
onMapReady()ให้โทรหาsetPoiClick()และส่งmap
override fun onMapReady(googleMap: GoogleMap) {
...
setPoiClick(map)
}
- เรียกใช้แอปและค้นหาสถานที่น่าสนใจ เช่น สวนสาธารณะหรือร้านกาแฟ
- แตะจุดที่น่าสนใจเพื่อวางเครื่องหมายและแสดงชื่อของจุดที่น่าสนใจในหน้าต่างข้อมูล

6. งาน: จัดรูปแบบแผนที่
คุณปรับแต่ง Google Maps ได้หลายวิธีเพื่อให้แผนที่มีรูปลักษณ์และให้ความรู้สึกที่ไม่ซ้ำใคร
คุณปรับแต่งออบเจ็กต์ MapFragment ได้โดยใช้แอตทริบิวต์ XML ที่มีอยู่ เช่นเดียวกับการปรับแต่ง Fragment อื่นๆ อย่างไรก็ตาม ในขั้นตอนนี้ คุณจะปรับแต่งรูปลักษณ์ของเนื้อหาของ MapFragment โดยใช้วิธีการในออบเจ็กต์ GoogleMap
หากต้องการสร้างสไตล์ที่กำหนดเองสำหรับแผนที่ ให้สร้างไฟล์ JSON ที่ระบุวิธีแสดงองค์ประกอบในแผนที่ คุณไม่จำเป็นต้องสร้างไฟล์ JSON นี้ด้วยตนเอง Google มีวิซาร์ดการจัดรูปแบบ Maps Platform ซึ่งจะสร้าง JSON ให้คุณหลังจากจัดรูปแบบแผนที่ด้วยภาพ ในงานนี้ คุณจะจัดรูปแบบแผนที่ด้วยธีมย้อนยุค ซึ่งหมายความว่าแผนที่จะใช้สีแบบวินเทจและคุณจะเพิ่มถนนที่มีสี
ขั้นตอนที่ 1: สร้างสไตล์สำหรับแผนที่
- ไปที่ https://mapstyle.withgoogle.com/ ในเบราว์เซอร์
- เลือกสร้างสไตล์
- เลือก Retro

- คลิกตัวเลือกเพิ่มเติม

- เลือกถนน > เติม
- เปลี่ยนสีถนนเป็นสีใดก็ได้ที่คุณเลือก (เช่น สีชมพู)

- คลิกเสร็จสิ้น

- คัดลอกโค้ด JSON จากกล่องโต้ตอบที่ได้ และหากต้องการ ให้เก็บโค้ดไว้ในโน้ตข้อความธรรมดาเพื่อใช้ในขั้นตอนถัดไป

ขั้นตอนที่ 2: เพิ่มสไตล์ลงในแผนที่
- ใน Android Studio ให้สร้างไดเรกทอรีทรัพยากรในไดเรกทอรี
resแล้วตั้งชื่อเป็นrawคุณใช้ทรัพยากรไดเรกทอรีrawเช่น โค้ด JSON - สร้างไฟล์ใน
res/rawชื่อmap_style.json - วางโค้ด JSON ที่ซ่อนไว้ลงในไฟล์ทรัพยากรใหม่
- ใน
MapsActivityให้สร้างตัวแปรคลาสTAGเหนือเมธอดonCreate()ซึ่งใช้เพื่อวัตถุประสงค์ในการบันทึก
private val TAG = MapsActivity::class.java.simpleName
- นอกจากนี้ ใน
MapsActivityให้สร้างฟังก์ชันsetMapStyle()ที่รับGoogleMap - ใน
setMapStyle()ให้เพิ่มบล็อกtry{} - ใน
try{}ให้สร้างval successเพื่อให้การจัดรูปแบบสำเร็จ (คุณเพิ่มบล็อก catch ต่อไปนี้) - ใน
try{}ให้ตั้งค่ารูปแบบ JSON เป็นแผนที่ เรียกใช้setMapStyle()ในออบเจ็กต์GoogleMapส่งออบเจ็กต์MapStyleOptionsซึ่งจะโหลดไฟล์ JSON - มอบหมายผลลัพธ์ให้
successsetMapStyle()เมธอดจะแสดงผลบูลีนที่ระบุสถานะความสำเร็จของการแยกวิเคราะห์ไฟล์การจัดรูปแบบและการตั้งค่ารูปแบบ
private fun setMapStyle(map: GoogleMap) {
try {
// Customize the styling of the base map using a JSON object defined
// in a raw resource file.
val success = map.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this,
R.raw.map_style
)
)
}
}
- เพิ่มคำสั่ง if สำหรับ
successที่เป็นเท็จ หากจัดรูปแบบไม่สำเร็จ ให้พิมพ์บันทึกว่าการแยกวิเคราะห์ล้มเหลว
private fun setMapStyle(map: GoogleMap) {
try {
...
if (!success) {
Log.e(TAG, "Style parsing failed.")
}
}
}
- เพิ่ม
catch{}บล็อกเพื่อจัดการกรณีที่ไม่มีไฟล์สไตล์ ในบล็อกcatchหากโหลดไฟล์ไม่ได้ ให้ส่งResources.NotFoundException
private fun setMapStyle(map: GoogleMap) {
try {
...
} catch (e: Resources.NotFoundException) {
Log.e(TAG, "Can't find style. Error: ", e)
}
}
เมธอดที่เสร็จสมบูรณ์แล้วควรมีลักษณะเหมือนข้อมูลโค้ดต่อไปนี้
private fun setMapStyle(map: GoogleMap) {
try {
// Customize the styling of the base map using a JSON object defined
// in a raw resource file.
val success = map.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this,
R.raw.map_style
)
)
if (!success) {
Log.e(TAG, "Style parsing failed.")
}
} catch (e: Resources.NotFoundException) {
Log.e(TAG, "Can't find style. Error: ", e)
}
}
- สุดท้าย ให้เรียกใช้เมธอด
setMapStyle()ในเมธอดonMapReady()โดยส่งออบเจ็กต์GoogleMap
override fun onMapReady(googleMap: GoogleMap) {
...
setMapStyle(map)
}
- เรียกใช้แอป
- ตั้งค่าแผนที่เป็นโหมด
normalแล้วคุณจะเห็นการจัดรูปแบบใหม่พร้อมธีมย้อนยุคและถนนในสีที่คุณเลือก

ขั้นตอนที่ 3: จัดรูปแบบเครื่องหมาย
คุณปรับแต่งแผนที่เพิ่มเติมได้โดยการจัดรูปแบบเครื่องหมายแผนที่ ในขั้นตอนนี้ คุณจะเปลี่ยนเครื่องหมายสีแดงเริ่มต้นให้เป็นเครื่องหมายที่ดูดีขึ้น
- ในเมธอด
onMapLongClick()ให้เพิ่มบรรทัดโค้ดต่อไปนี้ลงในMarkerOptions()ของตัวสร้างเพื่อใช้เครื่องหมายเริ่มต้น แต่เปลี่ยนสีเป็นสีน้ำเงิน
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
ตอนนี้ onMapLongClickListener() มีลักษณะดังนี้
map.setOnMapLongClickListener { latLng ->
// A snippet is additional text that's displayed after the title.
val snippet = String.format(
Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude
)
map.addMarker(
MarkerOptions()
.position(latLng)
.title(getString(R.string.dropped_pin))
.snippet(snippet)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
)
}
- เรียกใช้แอป ตอนนี้เครื่องหมายที่ปรากฏหลังจากที่คุณคลิกค้างไว้จะเป็นสีน้ำเงิน โปรดทราบว่าเครื่องหมาย POI ยังคงเป็นสีแดงเนื่องจากคุณไม่ได้เพิ่มรูปแบบให้กับเมธอด
onPoiClick()

7. งาน: เพิ่มการวางซ้อน
วิธีหนึ่งในการปรับแต่งแผนที่ Google คือการวาดทับแผนที่ เทคนิคนี้มีประโยชน์หากคุณต้องการไฮไลต์สถานที่ประเภทใดประเภทหนึ่ง เช่น จุดตกปลายอดนิยม
- รูปร่าง: คุณสามารถเพิ่มเส้นหลายเส้น รูปหลายเหลี่ยม และวงกลมลงในแผนที่ได้
GroundOverlayออบเจ็กต์: การวางซ้อนพื้นคือรูปภาพที่ตรึงไว้กับแผนที่ การวางซ้อนพื้นดินจะวางแนวให้สอดคล้องกับพื้นผิวโลก ไม่ใช่หน้าจอ การหมุน เอียง หรือซูมแผนที่จะเปลี่ยนการวางแนวของรูปภาพ การวางซ้อนพื้นมีประโยชน์เมื่อคุณต้องการแก้ไขรูปภาพเดียวในพื้นที่หนึ่งบนแผนที่
ขั้นตอน: เพิ่มภาพซ้อนทับพื้น
ในงานนี้ คุณจะได้เพิ่มภาพซ้อนทับพื้นในรูปของหุ่นยนต์ Android ลงในตำแหน่งบ้าน
- ดาวน์โหลด รูปภาพ Android นี้และบันทึกลงในโฟลเดอร์
res/drawable(ตรวจสอบว่าชื่อไฟล์คือandroid.png)

- ใน
onMapReady()หลังจากเรียกให้ย้ายกล้องไปยังตำแหน่งของบ้านแล้ว ให้สร้างออบเจ็กต์GroundOverlayOptions - กำหนดออบเจ็กต์ให้กับตัวแปรที่ชื่อ
androidOverlay
val androidOverlay = GroundOverlayOptions()
- ใช้เมธอด
BitmapDescriptorFactory.fromResource()เพื่อสร้างออบเจ็กต์BitmapDescriptorจากแหล่งข้อมูลรูปภาพที่ดาวน์โหลด - ส่งออบเจ็กต์
BitmapDescriptorที่ได้ไปยังเมธอดimage()ของออบเจ็กต์GroundOverlayOptions
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
- สร้าง
float overlaySizeสำหรับความกว้างเป็นเมตรของภาพซ้อนทับที่ต้องการ ในตัวอย่างนี้ ความกว้าง100fจะใช้งานได้ดี
ตั้งค่าพร็อพเพอร์ตี้ position สำหรับออบเจ็กต์ GroundOverlayOptions โดยเรียกใช้เมธอด position() และส่งออบเจ็กต์ homeLatLng และ overlaySize
val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
.position(homeLatLng, overlaySize)
- เรียกใช้
addGroundOverlay()ในออบเจ็กต์GoogleMapแล้วส่งออบเจ็กต์GroundOverlayOptions
map.addGroundOverlay(androidOverlay)
- เรียกใช้แอป
- เปลี่ยนค่าของ
zoomLevelเป็น 18f เพื่อดูรูปภาพ Android เป็นภาพซ้อนทับ

8. งาน: เปิดใช้การติดตามตำแหน่ง
ผู้ใช้มักใช้ Google Maps เพื่อดูตำแหน่งปัจจุบันของตน หากต้องการแสดงตำแหน่งอุปกรณ์บนแผนที่ คุณสามารถใช้เลเยอร์ข้อมูลตำแหน่ง
เลเยอร์ข้อมูลตำแหน่งจะเพิ่มไอคอนตำแหน่งของฉันลงในแผนที่

เมื่อผู้ใช้แตะปุ่ม แผนที่จะอยู่ตรงกลางตำแหน่งของอุปกรณ์ ตำแหน่งจะแสดงเป็นจุดสีน้ำเงินหากอุปกรณ์อยู่กับที่ และเป็นเครื่องหมายเชฟรอนสีน้ำเงินหากอุปกรณ์กำลังเคลื่อนที่
ในงานนี้ คุณจะเปิดใช้เลเยอร์ข้อมูลตำแหน่ง
ขั้นตอน: ขอสิทธิ์เข้าถึงตำแหน่ง
การเปิดใช้การติดตามตำแหน่งใน Google Maps ต้องใช้โค้ดเพียงบรรทัดเดียว อย่างไรก็ตาม คุณต้องตรวจสอบว่าผู้ใช้ได้ให้สิทธิ์เข้าถึงตำแหน่ง (โดยใช้โมเดลสิทธิ์รันไทม์)
ในขั้นตอนนี้ คุณจะขอสิทธิ์เข้าถึงตำแหน่งและเปิดใช้การติดตามตำแหน่ง
- ในไฟล์
AndroidManifest.xmlให้ตรวจสอบว่ามีสิทธิ์FINE_LOCATIONอยู่แล้ว Android Studio แทรกสิทธิ์นี้เมื่อคุณเลือกเทมเพลต Google Maps
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- ใน
MapsActivityให้สร้างตัวแปรคลาสREQUEST_LOCATION_PERMISSION
private val REQUEST_LOCATION_PERMISSION = 1
- หากต้องการตรวจสอบว่าได้รับสิทธิ์หรือไม่ ให้สร้างเมธอดใน
MapsActivityที่ชื่อisPermissionGranted()ในวิธีนี้ ให้ตรวจสอบว่าผู้ใช้ได้ให้สิทธิ์แล้วหรือไม่
private fun isPermissionGranted() : Boolean {
return ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
- หากต้องการเปิดใช้การติดตามตำแหน่งในแอป ให้สร้างเมธอดใน
MapsActivityที่ชื่อenableMyLocation()ซึ่งไม่ต้องใช้อาร์กิวเมนต์และไม่แสดงผลใดๆ ภายใน ให้มองหาสิทธิ์ACCESS_FINE_LOCATIONหากได้รับสิทธิ์ ให้เปิดใช้เลเยอร์ตำแหน่ง หรือขอสิทธิ์
private fun enableMyLocation() {
if (isPermissionGranted()) {
map.isMyLocationEnabled = true
}
else {
ActivityCompat.requestPermissions(
this,
arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_LOCATION_PERMISSION
)
}
}
- เรียกใช้
enableMyLocation()จากการเรียกกลับonMapReady()เพื่อเปิดใช้เลเยอร์ตำแหน่ง
override fun onMapReady(googleMap: GoogleMap) {
...
enableMyLocation()
}
- แทนที่เมธอด
onRequestPermissionsResult()ตรวจสอบว่าrequestCodeเท่ากับREQUEST_LOCATION_PERMISSIONหรือไม่ หากเป็นเช่นนั้น แสดงว่าคุณได้รับสิทธิ์แล้ว หากได้รับสิทธิ์ ให้ตรวจสอบด้วยว่าอาร์เรย์grantResultsมีPackageManager.PERMISSION_GRANTEDในช่องแรกหรือไม่ หากเป็นเช่นนั้น โปรดโทรหาenableMyLocation()
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray) {
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
enableMyLocation()
}
}
}
- เรียกใช้แอป ควรมีกล่องโต้ตอบที่ขอสิทธิ์เข้าถึงตำแหน่งของอุปกรณ์ โปรดอนุญาตสิทธิ์

ตอนนี้แผนที่จะแสดงตำแหน่งปัจจุบันของอุปกรณ์โดยใช้จุดสีน้ำเงิน สังเกตว่ามีปุ่มตำแหน่ง หากเลื่อนแผนที่ออกจากตำแหน่งของคุณแล้วคลิกปุ่มนี้ ระบบจะจัดให้แผนที่อยู่ตรงกลางตำแหน่งของอุปกรณ์อีกครั้ง

9. รหัสโซลูชัน
ดาวน์โหลดโค้ดสำหรับ Codelab ที่เสร็จสมบูรณ์
$ git clone https://github.com/googlecodelabs/android-kotlin-geo-maps
หรือจะดาวน์โหลดที่เก็บเป็นไฟล์ ZIP, แตกไฟล์ และเปิดใน Android Studio ก็ได้
10. สรุป
ยินดีด้วย คุณเพิ่มแผนที่ Google ลงในแอป Android Kotlin และจัดรูปแบบแล้ว
11. ดูข้อมูลเพิ่มเติม
เอกสารประกอบสำหรับนักพัฒนาแอป Android:
- เริ่มต้นใช้งาน
- การเพิ่มแผนที่พร้อมเครื่องหมาย
- ออบเจ็กต์แผนที่
- การเพิ่มแผนที่ที่มีการจัดรูปแบบ
- Street View
- การวางซ้อนพื้น
เอกสารอ้างอิง:
12. Codelab ถัดไป
ดูลิงก์ไปยัง Codelab อื่นๆ ในหลักสูตรนี้ได้ที่หน้า Landing Page ของ Codelab Android ขั้นสูงใน Kotlin



