1. ก่อนเริ่มต้น
การสร้างแอปด้วย Google Maps จะช่วยให้คุณเพิ่มฟีเจอร์ต่างๆ ลงในแอปได้ เช่น ภาพถ่ายจากดาวเทียม การควบคุม UI ที่มีประสิทธิภาพสำหรับแผนที่ การติดตามตำแหน่ง และเครื่องหมายระบุตำแหน่ง คุณสามารถเพิ่มคุณค่าให้กับ Google Maps มาตรฐานด้วยการแสดงข้อมูลจากชุดข้อมูลของคุณเอง เช่น สถานที่ตกปลาหรือพื้นที่ปีนเขาชื่อดัง คุณยังสร้างเกมที่ผู้เล่นสำรวจโลกจริงได้ด้วย เช่น ในเกมล่าสมบัติหรือแม้กระทั่งเกมเทคโนโลยีความจริงเสริม (AR)
ในบทเรียนนี้ คุณจะได้สร้างแอป Google Maps ชื่อ Wander ซึ่งแสดงแผนที่ที่กำหนดเองและแสดงตำแหน่งของผู้ใช้
ข้อกำหนดเบื้องต้น
ความรู้เกี่ยวกับสิ่งต่อไปนี้
- วิธีสร้างแอป Android พื้นฐานและเรียกใช้โดยใช้ Android Studio
- วิธีสร้างและจัดการทรัพยากร เช่น สตริง
- วิธีเปลี่ยนโครงสร้างโค้ดและเปลี่ยนชื่อตัวแปรโดยใช้ Android Studio
- วิธีใช้ Google Maps ในฐานะผู้ใช้
- วิธีตั้งค่าสิทธิ์รันไทม์
สิ่งที่คุณจะได้เรียนรู้
- วิธีรับคีย์ API จากคอนโซล Google API และลงทะเบียนคีย์กับแอปของคุณ
- วิธีผสานรวม Google Maps ในแอปของคุณ
- วิธีแสดงแผนที่ประเภทต่างๆ
- วิธีจัดรูปแบบ Google Maps
- วิธีเพิ่มเครื่องหมายลงในแผนที่ของคุณ
- วิธีทำให้ผู้ใช้สามารถวางเครื่องหมายบนจุดที่น่าสนใจ (POI) ได้
- วิธีเปิดใช้การติดตามตำแหน่ง
- วิธีสร้างแอป
Wander
ซึ่งมี Google Maps ฝังอยู่ - วิธีสร้างฟีเจอร์ที่กำหนดเองให้กับแอป เช่น เครื่องหมายและการจัดรูปแบบ
- วิธีเปิดใช้การติดตามตำแหน่งในแอปของคุณ
2. ภาพรวมของแอป
ใน Codelab นี้ คุณจะได้สร้างแอป Wander
ซึ่งจะแสดงแผนที่ Google พร้อมการจัดรูปแบบที่กำหนดเอง แอป Wander ให้คุณวางเครื่องหมายลงบนตำแหน่ง เพิ่มการวางซ้อน และดูตำแหน่งของคุณในแบบเรียลไทม์
3. งาน: ตั้งค่าโปรเจ็กต์และรับคีย์ API
Maps SDK สำหรับ Android ต้องใช้คีย์ API หากต้องการรับคีย์ API ให้ลงทะเบียนโปรเจ็กต์ใน API และ หน้าบริการ คีย์ API ผูกกับใบรับรองดิจิทัลที่ลิงก์แอปกับผู้เขียน โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ใบรับรองดิจิทัลและการลงนามแอปที่หัวข้อลงนามแอป
ใน Codelab นี้ คุณใช้คีย์ API สำหรับใบรับรองการแก้ไขข้อบกพร่อง ใบรับรองการแก้ไขข้อบกพร่องออกแบบมาให้ไม่ปลอดภัย ตามที่อธิบายไว้ในลงนามบิลด์การแก้ไขข้อบกพร่อง แอป Android ที่เผยแพร่แล้วที่ใช้ Maps SDK สำหรับ Android ต้องใช้คีย์ API ที่สอง ซึ่งเป็นคีย์สำหรับใบรับรองรุ่น โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับการรับใบรับรองรุ่นที่หัวข้อรับคีย์ API
Android Studio มีเทมเพลตกิจกรรมใน Google Maps ซึ่งจะสร้างโค้ดเทมเพลตที่เป็นประโยชน์ โค้ดเทมเพลตประกอบด้วยไฟล์ google_maps_api.xml ที่มีลิงก์ซึ่งช่วยให้รับคีย์ API ได้ง่ายขึ้น
ขั้นตอนที่ 1: สร้างโปรเจ็กต์ Wander ด้วยเทมเพลตแผนที่
- สร้างโปรเจ็กต์ Android Studio ใหม่
- เลือกเทมเพลตกิจกรรมใน Google Maps
- ตั้งชื่อโปรเจ็กต์
Wander
- ตั้งค่าระดับ API ขั้นต่ำเป็น API 19 ตรวจสอบว่าภาษาคือ Kotlin
- คลิกเสร็จสิ้น
- เมื่อสร้างแอปเสร็จแล้ว ให้ตรวจสอบโปรเจ็กต์และไฟล์ที่เกี่ยวข้องกับแผนที่ต่อไปนี้ซึ่ง 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 - ไฟล์เลย์เอาต์นี้มีส่วนย่อยเดียวที่แสดงเต็มหน้าจอ คลาส SupportMapFragment
เป็นคลาสย่อยของคลาส Fragment
SupportMapFragment
เป็นวิธีที่ง่ายที่สุดในการวางแผนที่ในแอป ซึ่งเป็น Wrapper ในการดูแผนที่เพื่อจัดการกับความต้องการที่จำเป็นในวงจรโดยอัตโนมัติ
คุณรวม SupportMapFragment
ในไฟล์เลย์เอาต์ได้โดยใช้แท็ก <fragment>
ใน ViewGroup
ใดก็ได้โดยมีแอตทริบิวต์ name
เพิ่มเติม
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.java ไฟล์ MapsActivity.java จะสร้าง 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 มีแผนที่หลายประเภท ได้แก่ ปกติ ไฮบริด ดาวเทียม ภูมิประเทศ และ "ไม่มี" (หากไม่มีแผนที่เลย)
แผนที่ปกติ | แผนที่ดาวเทียม | แผนที่แบบผสม | แผนที่ภูมิประเทศ |
แผนที่แต่ละประเภทให้ข้อมูลแตกต่างกัน ตัวอย่างเช่น เมื่อคุณใช้แผนที่สำหรับการนำทางในรถยนต์ การดูชื่อถนนจะมีประโยชน์เพื่อให้สามารถใช้ตัวเลือกปกติได้ เมื่อคุณกำลังเดินป่า แผนที่ภูมิประเทศอาจมีประโยชน์ในการตัดสินใจว่าคุณต้องปีนขึ้นอีกเท่าใดจึงจะถึงจุดสูงสุด
ในงานนี้ คุณจะทำสิ่งต่อไปนี้ได้
- เพิ่มแถบแอปด้วยเมนูตัวเลือกที่ให้ผู้ใช้เปลี่ยนประเภทแผนที่ได้
- ย้ายตำแหน่งเริ่มต้นของแผนที่ไปยังตำแหน่งบ้านของคุณเอง
- เพิ่มการรองรับเครื่องหมายซึ่งระบุสถานที่แห่งเดียวบนแผนที่และใส่ป้ายกำกับได้
เพิ่มเมนูสำหรับประเภทแผนที่
ในขั้นตอนนี้ คุณจะเพิ่มแถบแอปด้วยเมนูตัวเลือกที่ให้ผู้ใช้เปลี่ยนประเภทแผนที่ได้
- หากต้องการสร้างไฟล์ XML ของเมนูใหม่ ให้คลิกขวาที่ไดเรกทอรี res แล้วเลือกใหม่ > ไฟล์ทรัพยากร Android
- ตั้งชื่อไฟล์ในกล่องโต้ตอบว่า
map_options
- เลือกเมนูสำหรับประเภททรัพยากร
- คลิกตกลง
- ในแท็บโค้ด ให้แทนที่โค้ดในไฟล์ใหม่ด้วยโค้ดต่อไปนี้เพื่อสร้างตัวเลือกเมนูแผนที่ คอลัมน์ "none" ไม่แสดงประเภทแผนที่เนื่องจาก "ไม่มี" ทำให้ไม่มีแผนที่ใดเลย การดำเนินการนี้จะทำให้เกิดข้อผิดพลาด แต่คุณจะแก้ไขได้ในขั้นตอนถัดไป
<?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: ซูมไปที่บ้านและเพิ่มเครื่องหมาย
- ค้นหาเมธอด
onMapReady()
ในไฟล์MapsActivity.kt
ลบรหัสที่อยู่ในนั้นซึ่งวางเครื่องหมายไว้ในซิดนีย์แล้วย้ายกล้อง นี่คือหน้าตาวิธีการของคุณในปัจจุบัน
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: อนุญาตให้ผู้ใช้เพิ่มเครื่องหมายโดยการคลิกค้าง
ในขั้นตอนนี้ คุณจะเพิ่มเครื่องหมายเมื่อผู้ใช้แตะและค้างไว้ตำแหน่งบนแผนที่
- สร้างสตับเมธอดใน
MapsActivity
ชื่อsetMapLongClick()
ที่จะนำGoogleMap
เป็นอาร์กิวเมนต์ - แนบ Listener
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: เพิ่ม Listener จุดที่น่าสนใจ
โดยค่าเริ่มต้น จุดที่น่าสนใจ (POI) จะปรากฏบนแผนที่พร้อมกับไอคอนที่สอดคล้องกัน จุดที่น่าสนใจ ได้แก่ สวนสาธารณะ โรงเรียน อาคารหน่วยงานราชการ และอื่นๆ เมื่อตั้งประเภทแผนที่เป็น normal
จุดที่น่าสนใจของธุรกิจก็จะปรากฏในแผนที่ด้วย จุดที่น่าสนใจของธุรกิจแสดงถึงธุรกิจต่างๆ เช่น ร้านค้า ร้านอาหาร และโรงแรม
ในขั้นตอนนี้ คุณต้องเพิ่ม GoogleMap.OnPoiClickListener
ลงในแผนที่ Listener การคลิกนี้จะวางเครื่องหมายบนแผนที่ทันทีเมื่อผู้ใช้คลิกจุดที่น่าสนใจ Listener การคลิกจะแสดงหน้าต่างข้อมูลที่มีชื่อจุดที่น่าสนใจด้วย
- สร้างสตับเมธอดใน
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 ที่มีอยู่ได้ เช่นเดียวกับการปรับแต่งส่วนย่อยอื่นๆ แต่ในขั้นตอนนี้ คุณจะปรับแต่งรูปลักษณ์ของเนื้อหาของ MapFragment
โดยใช้เมธอดในออบเจ็กต์ GoogleMap
หากต้องการสร้างรูปแบบที่กำหนดเองสำหรับแผนที่ คุณต้องสร้างไฟล์ JSON ที่ระบุวิธีแสดงสถานที่ในแผนที่ คุณไม่จำเป็นต้องสร้างไฟล์ JSON นี้ด้วยตนเอง Google มีวิซาร์ดการจัดรูปแบบแพลตฟอร์ม Maps ซึ่งจะสร้าง JSON ให้คุณหลังจากที่คุณจัดรูปแบบแผนที่แล้ว ในงานนี้ คุณได้จัดรูปแบบแผนที่ด้วยธีมย้อนยุค ซึ่งหมายความว่าแผนที่จะใช้สีย้อนยุคและคุณได้เพิ่มถนนสีต่างๆ
ขั้นตอนที่ 1: สร้างรูปแบบสำหรับแผนที่ของคุณ
- ไปที่ https://mapstyle.withgoogle.com/ ในเบราว์เซอร์
- เลือกสร้างรูปแบบ
- เลือกย้อนยุค
- คลิกตัวเลือกเพิ่มเติม
- เลือกถนน > เติม
- เปลี่ยนสีของถนนเป็นสีที่คุณเลือก (เช่น สีชมพู)
- คลิกเสร็จสิ้น
- คัดลอกโค้ด 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
เพื่อให้การจัดรูปแบบสำเร็จ (คุณได้เพิ่มบล็อคคำสั่งต่อไปนี้) - ในบล็อก
try{}
ให้ตั้งค่ารูปแบบ JSON ให้กับแผนที่ เรียกsetMapStyle()
ในออบเจ็กต์GoogleMap
ส่งออบเจ็กต์MapStyleOptions
ซึ่งจะโหลดไฟล์ JSON - กำหนดผลลัพธ์ให้กับ
success
เมธอดsetMapStyle()
จะแสดงค่าบูลีนที่ระบุสถานะสำเร็จในการแยกวิเคราะห์ไฟล์การจัดรูปแบบและการตั้งค่ารูปแบบ
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))
)
}
- เรียกใช้แอป เครื่องหมายที่ปรากฏหลังจากคลิกค้างจะเปลี่ยนเป็นสีน้ำเงิน โปรดทราบว่าเครื่องหมายจุดที่น่าสนใจยังคงเป็นสีแดงเนื่องจากคุณไม่ได้เพิ่มการจัดรูปแบบให้กับเมธอด
onPoiClick()
7. งาน: เพิ่มการวางซ้อน
วิธีหนึ่งที่คุณจะปรับแต่ง Google Maps ได้คือการวาดทับแผนที่นั้น เทคนิคนี้จะเป็นประโยชน์หากคุณต้องการเน้นสถานที่ตั้งประเภทใดประเภทหนึ่ง เช่น จุดตกปลายอดนิยม
- รูปร่าง: คุณสามารถเพิ่มรูปหลายเหลี่ยม รูปหลายเหลี่ยม และวงกลมลงในแผนที่
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 Maps ในแอป Kotlin และจัดรูปแบบแอปแล้ว
11. ดูข้อมูลเพิ่มเติม
เอกสารประกอบสำหรับนักพัฒนาซอฟต์แวร์ Android:
- เริ่มต้นใช้งาน
- การเพิ่มแผนที่ด้วยเครื่องหมาย
- จับคู่ออบเจ็กต์
- การเพิ่มแผนที่ที่มีการจัดรูปแบบ
- Street View
- การวางซ้อนภาคพื้นดิน
เอกสารอ้างอิง:
12. Codelab ถัดไป
สําหรับลิงก์ไปยัง Codelab อื่นๆ ในหลักสูตรนี้ โปรดดูหน้า Landing Page สำหรับ Android ขั้นสูงใน Kotlin