Lớp học lập trình này nằm trong khóa học Nâng cao về Android trong Kotlin. Bạn sẽ nhận được nhiều giá trị nhất từ khóa học này nếu bạn làm việc qua các lớp học lập trình theo trình tự, nhưng bạn không bắt buộc phải làm vậy. Tất cả các lớp học lập trình đều có trên trang đích của các lớp học lập trình Android nâng cao trong Kotlin.
Việc xây dựng các ứng dụng bằng Google Maps cho phép bạn thêm các tính năng vào ứng dụng, chẳng hạn như hình ảnh vệ tinh, các tùy chọn kiểm soát giao diện người dùng mạnh mẽ cho bản đồ, tính năng theo dõi vị trí và điểm đánh dấu vị trí. Bạn có thể thêm giá trị cho Google Maps chuẩn bằng cách hiển thị thông tin từ tập dữ liệu của riêng mình, chẳng hạn như vị trí của các khu vực câu cá hoặc leo núi nổi tiếng. Bạn cũng có thể tạo ra các trò chơi trong đó người chơi khám phá thế giới thực, chẳng hạn như trong trò chơi săn kho báu hoặc thậm chí là trò chơi thực tế tăng cường.
Trong bài học này, bạn tạo một ứng dụng Google Maps có tên là Wander. Ứng dụng này hiển thị bản đồ tùy chỉnh và hiển thị vị trí của người dùng.
Điều kiện tiên quyết
Hiểu được những điều sau:
- Cách tạo một ứng dụng Android cơ bản rồi chạy ứng dụng đó bằng Android Studio.
- Cách tạo và quản lý các tài nguyên, chẳng hạn như chuỗi.
- Cách tái cấu trúc mã và đổi tên các biến bằng Android Studio.
- Cách sử dụng Google Maps với tư cách là người dùng.
- Cách đặt quyền trong thời gian chạy.
Kiến thức bạn sẽ học được
- Cách lấy khóa API từ Google API Console và đăng ký khóa đó vào ứng dụng của bạn
- Cách tích hợp Google Maps trong ứng dụng của bạn
- Cách hiển thị các loại bản đồ khác nhau
- Cách tạo kiểu cho Google Maps
- Cách thêm điểm đánh dấu vào bản đồ của bạn
- Cách cho phép người dùng đặt điểm đánh dấu về địa điểm yêu thích (CUE)
- Cách bật tính năng theo dõi vị trí
- Cách tạo ứng dụng
Wander
có ứng dụng Google Maps đã nhúng - Cách tạo các tính năng tùy chỉnh cho ứng dụng của bạn, chẳng hạn như điểm đánh dấu và kiểu
- Cách bật tính năng theo dõi vị trí trong ứng dụng
Trong lớp học lập trình này, bạn tạo ứng dụng Wander
để hiển thị bản đồ Google với kiểu tùy chỉnh. Ứng dụng Wander cho phép bạn thả điểm đánh dấu vào các vị trí, thêm lớp phủ và xem vị trí của bạn theo thời gian thực.
SDK Maps dành cho Android yêu cầu khóa API. Để có được khóa API, hãy đăng ký dự án của bạn trong trang API & Dịch vụ. Khóa API được liên kết với một chứng chỉ kỹ thuật số liên kết ứng dụng với tác giả của ứng dụng. Để biết thêm thông tin về cách sử dụng chứng chỉ kỹ thuật số và ký ứng dụng, hãy xem phần Ký ứng dụng của bạn.
Trong lớp học lập trình này, bạn sử dụng khóa API cho chứng chỉ gỡ lỗi. Thiết kế của chứng chỉ gỡ lỗi là không an toàn, như mô tả trong phần Ký bản dựng gỡ lỗi của bạn. Các ứng dụng Android được xuất bản có sử dụng SDK Maps dành cho Android cần có khóa API thứ hai: khóa cho chứng chỉ phát hành. Để biết thêm thông tin về cách lấy chứng chỉ phát hành, hãy xem phần Nhận khóa API.
Android Studio bao gồm mẫu Hoạt động trên Google Maps. Mã này tạo ra mã mẫu hữu ích. Mã mẫu bao gồm một tệp google_maps_api.xml chứa đường liên kết giúp đơn giản hóa việc nhận khóa API.
Bước 1: Tạo dự án Wander bằng mẫu bản đồ
- Tạo dự án Android Studio mới.
- Chọn mẫu Hoạt động trên Google Maps.
- Đặt tên cho dự án là
Wander
. - Đặt cấp độ API tối thiểu thành API 19. Đảm bảo ngôn ngữ là Kotlin.
- Nhấp vào Finish (Hoàn tất).
- Sau khi ứng dụng hoàn tất, hãy xem dự án của bạn và những tệp liên quan đến bản đồ sau đây mà Android Studio tạo cho bạn:
google_maps_api.xml – Bạn dùng tệp cấu hình này để giữ khóa API của mình. Mẫu tạo hai tệp google_maps_api.xml: một để gỡ lỗi và một để phát hành. Tệp cho khóa API cho chứng chỉ gỡ lỗi nằm trong src/debug/res/values. Tệp cho khóa API cho chứng chỉ phát hành nằm trong src/release/res/values. Trong lớp học lập trình này, bạn chỉ sử dụng chứng chỉ gỡ lỗi.
activity_maps.xml—Tệp bố cục này chứa một mảnh duy nhất lấp đầy toàn bộ màn hình. Lớp SupportMapFragment
là một lớp con của lớp Fragment
. SupportMapFragment
là cách đơn giản nhất để đặt bản đồ vào ứng dụng. Đó là trình bao bọc xung quanh một chế độ xem bản đồ để tự động xử lý các nhu cầu cần thiết trong vòng đời.
Bạn có thể đưa SupportMapFragment
vào tệp bố cục bằng thẻ <fragment>
trong bất kỳ ViewGroup
nào, với thuộc tính name
bổ sung.
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.java – Tệp MapsActivity.kt sẽ tạo thực thể cho SupportMapFragment
trong phương thức onCreate()
, đồng thời sử dụng lớp#39; getMapAsync
()
để tự động khởi tạo hệ thống bản đồ và chế độ xem. Hoạt động chứa SupportMapFragment
phải triển khai giao diện OnMapReadyCallback
và phương thức onMapReady()
của giao diện đó. Phương thức onMapReady()
được gọi khi bản đồ được tải.
Bước 2: Lấy khóa API
- Mở phiên bản gỡ lỗi của tệp google_maps_api.xml.
- Trong tệp, hãy tìm nhận xét có URL dài. Các thông số về URL bao gồm thông tin cụ thể về ứng dụng của bạn.
- Sao chép và dán URL vào một trình duyệt.
- Làm theo lời nhắc để tạo dự án trên trang API & Dịch vụ. Vì các thông số trong URL đã cung cấp nên trang biết tự động bật SDK Maps cho Android.
- Nhấp vào Tạo khóa API.
- Trên trang tiếp theo, hãy chuyển đến phần Khóa API rồi nhấp vào khóa bạn vừa tạo.
- Nhấp vào Hạn chế khóa và chọn SDK Maps dành cho Android để hạn chế việc sử dụng khóa cho các ứng dụng Android.
- Sao chép khóa API đã tạo. Bắt đầu bằng "
AIza"
. - Trong tệp
google_maps_api.xml
, hãy dán khóa này vào chuỗigoogle_maps_key
có dòngYOUR_KEY_HERE
. - Chạy ứng dụng của bạn. Bạn sẽ thấy một bản đồ được nhúng trong hoạt động của mình với một điểm đánh dấu được đặt tại Sydney, Úc. (Điểm đánh dấu Sydney là một phần của mẫu và bạn thay đổi sau này.)
Bước 3: Đổi tên mMap
MapsActivity
có một lateinit
var
riêng tư tên là mMap
, thuộc loại GoogleMap
. Để tuân thủ quy ước đặt tên của Kotlin, hãy đổi tên của mMap
thành map
.
- Trong
MapsActivity
, hãy nhấp chuột phải vàomMap
rồi nhấp vào Tái cấu trúc > Đổi tên...
- Đổi tên biến thành
map
.
Xin lưu ý rằng tất cả các thông tin tham chiếu đến mMap
trong hàm onMapReady()
cũng thay đổi thành map
.
Google Maps bao gồm một số loại bản đồ: bình thường, kết hợp, vệ tinh, địa hình và "none" (không sử dụng bản đồ).
Bản đồ thông thường | Bản đồ vệ tinh | Bản đồ kết hợp | Bản đồ địa hình |
Mỗi loại bản đồ cung cấp các loại thông tin khác nhau. Ví dụ: khi sử dụng bản đồ điều hướng trong ô tô, bạn nên xem tên đường phố để có thể sử dụng tùy chọn thông thường. Khi bạn đi bộ, bản đồ địa hình có thể giúp bạn quyết định bạn phải leo thêm bao nhiêu nữa để lên được đỉnh.
Trong nhiệm vụ này, bạn:
- Thêm thanh ứng dụng với trình đơn tùy chọn cho phép người dùng thay đổi loại bản đồ.
- Di chuyển bản đồ vị trí bắt đầu đến vị trí nhà riêng của bạn.
- Thêm tùy chọn hỗ trợ cho điểm đánh dấu, cho biết các vị trí riêng lẻ trên bản đồ và có thể bao gồm nhãn.
Thêm trình đơn cho các loại bản đồ
Trong bước này, bạn thêm một thanh ứng dụng có một trình đơn tùy chọn cho phép người dùng thay đổi loại bản đồ.
- Để tạo tệp XML mới cho trình đơn, hãy nhấp chuột phải vào thư mục res rồi chọn Mới > Tệp tài nguyên Android.
- Trong hộp thoại, hãy đặt tên tệp là
map_options
. - Chọn Trình đơn cho loại tài nguyên.
- Nhấp vào OK.
- Trong thẻ Mã, hãy thay mã trong tệp mới bằng mã sau để tạo tùy chọn trình đơn bản đồ. Loại "none" loại bản đồ bị bỏ qua vì "none" dẫn đến việc thiếu bất kỳ bản đồ nào. Bước này gây ra lỗi, nhưng bạn giải quyết lỗi trong bước tiếp theo.
<?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>
- Trong
strings.xml
, hãy thêm tài nguyên cho các thuộc tínhtitle
để khắc phục lỗi.
<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>
- Trong
MapsActivity
, hãy ghi đè phương thứconCreateOptionsMenu()
và tăng cường trình đơn từ tệp tài nguyênmap_options
.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.map_options, menu)
return true
}
- Trong
MapsActivity.kt
, hãy ghi đè phương thứconOptionsItemSelected()
. Thay đổi loại bản đồ bằng cách sử dụng hằng số loại bản đồ để phản ánh lựa chọn của người dùng.
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)
}
- Chạy ứng dụng.
- Nhấp vào để thay đổi loại bản đồ. Hãy chú ý tới sự thay đổi trong giao diện của bản đồ.
Theo mặc định, lệnh gọi lại onMapReady()
bao gồm mã đặt điểm đánh dấu ở Sydney, Úc, nơi Google Maps được tạo. Lệnh gọi lại mặc định cũng tạo hiệu ứng bản đồ để xoay đến Sydney.
Trong nhiệm vụ này, bạn cần chuyển máy ảnh của bản đồ về nhà mình, thu phóng đến cấp độ bạn chỉ định và đặt điểm đánh dấu tại đó.
Bước 1: Thu phóng về nhà và thêm điểm đánh dấu
- Trong tệp
MapsActivity.kt
, hãy tìm phương thứconMapReady()
. Xóa mã ở vị trí đó để đặt điểm đánh dấu ở Sydney và di chuyển máy ảnh. Đây là giao diện của phương thức.
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
}
- Tìm vĩ độ và kinh độ trong nhà của bạn bằng cách làm theo các hướng dẫn này.
- Tạo một giá trị cho vĩ độ và một giá trị cho kinh độ, đồng thời nhập các giá trị số thực của chúng.
val latitude = 37.422160
val longitude = -122.084270
- Tạo đối tượng
LatLng
mới có tên làhomeLatLng
. Trong đối tượnghomeLatLng
, hãy chuyển các giá trị mà bạn vừa tạo.
val homeLatLng = LatLng(latitude, longitude)
- Tạo
val
cho mức độ phóng to mà bạn muốn hiển thị trên bản đồ. Sử dụng mức thu phóng 15f.
val zoomLevel = 15f
Mức thu phóng kiểm soát mức độ phóng to của bạn trên bản đồ. Danh sách sau đây giúp bạn biết được mức độ chi tiết của từng mức thu phóng:
1
: Thế giới5
: Vùng đất/l lục địa10
: Thành phố15
: Đường phố20
: Tòa nhà
- Di chuyển máy ảnh vào
homeLatLng
bằng cách gọi hàmmoveCamera()
trên đối tượngmap
và chuyển trong đối tượngCameraUpdate
sử dụngCameraUpdateFactory.newLatLngZoom()
. Chuyển vào đối tượnghomeLatLng
vàzoomLevel
.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
- Thêm điểm đánh dấu vào bản đồ tại
homeLatLng
.
map.addMarker(MarkerOptions().position(homeLatLng))
Phương pháp cuối cùng của bạn sẽ có dạng như sau:
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))
}
- Chạy ứng dụng. Bản đồ sẽ xoay về nhà bạn, thu phóng đến mức mong muốn và đặt điểm đánh dấu trên nhà của bạn.
Bước 2: Cho phép người dùng thêm điểm đánh dấu bằng cách nhấp chuột dài
Trong bước này, bạn thêm một điểm đánh dấu khi người dùng chạm và giữ một vị trí trên bản đồ.
- Tạo một phương thức mã trong
MapsActivity
có tên làsetMapLongClick()
. Phương thức này sẽ lấyGoogleMap
làm đối số. - Đính kèm một trình xử lý
setOnMapLongClickListener
vào đối tượng bản đồ.
private fun setMapLongClick(map:GoogleMap) {
map.setOnMapLongClickListener { }
}
- Trong
setOnMapLongClickListener()
, hãy gọi phương thứcaddMarker()
. Chuyển đối tượngMarkerOptions
mới vào vị trí được đặt thànhLatLng
đã chuyển.
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
map.addMarker(
MarkerOptions()
.position(latLng)
)
}
}
- Ở cuối phương thức
onMapReady()
, hãy gọisetMapLongClick()
bằngmap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapLongClick(map)
}
- Chạy ứng dụng của bạn.
- Chạm và giữ bản đồ để đặt điểm đánh dấu tại một vị trí.
- Hãy nhấn vào điểm đánh dấu đó để tâm điểm vào màn hình.
Bước 3: Thêm cửa sổ thông tin cho điểm đánh dấu
Trong bước này, bạn thêm một InfoWindow
để hiển thị tọa độ của điểm đánh dấu khi điểm đánh dấu được nhấn vào.
- Trong
setMapLongClick()setOnMapLongClickListener()
, hãy tạo mộtval
chosnippet
. Đoạn trích là văn bản bổ sung được hiển thị sau tiêu đề. Đoạn mã của bạn hiển thị vĩ độ và kinh độ của một điểm đánh dấu.
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)
)
}
}
- Trong
addMarker()
, hãy đặttitle
của điểm đánh dấu thành Ghim đã thả bằng tài nguyên chuỗiR.string.
dropped_pin
. - Đặt điểm đánh dấu
snippet
thànhsnippet
.
Hàm hoàn chỉnh sẽ có dạng như sau:
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)
)
}
}
- Chạy ứng dụng của bạn.
- Chạm và giữ bản đồ để thả điểm đánh dấu vị trí.
- Nhấn vào điểm đánh dấu để hiển thị cửa sổ thông tin.
Bước 4: Thêm trình xử lý địa điểm yêu thích
Theo mặc định, các địa điểm yêu thích (CUE) xuất hiện trên bản đồ cùng với các biểu tượng tương ứng. Các điểm yêu thích có thể bao gồm công viên, trường học, tòa nhà chính phủ và các địa điểm khác. Khi loại bản đồ được đặt thành normal
, điểm yêu thích của doanh nghiệp cũng xuất hiện trên bản đồ. Địa điểm yêu thích của doanh nghiệp đại diện cho các doanh nghiệp, chẳng hạn như cửa hàng, nhà hàng và khách sạn.
Trong bước này, bạn sẽ thêm một GoogleMap.OnPoiClickListener
vào bản đồ. Trình nghe lượt nhấp này đặt một điểm đánh dấu trên bản đồ ngay khi người dùng nhấp vào một điểm yêu thích. Trình nghe lượt nhấp cũng hiển thị một cửa sổ thông tin chứa tên địa điểm yêu thích.
- Tạo một phương thức mã trong
MapsActivity
có tên làsetPoiClick()
. Phương thức này sẽ lấyGoogleMap
làm đối số. - Trong phương thức
setPoiClick()
, hãy đặtOnPoiClickListener
trênGoogleMap
đã chuyển.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
}
}
- Trong
setOnPoiClickListener()
, hãy tạo mộtval poiMarker
cho điểm đánh dấu . - Đặt điểm đánh dấu thành điểm đánh dấu bằng cách sử dụng
map.addMarker()
vớiMarkerOptions
, đặttitle
thành tên của điểm yêu thích.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
}
}
- Trong hàm
setOnPoiClickListener()
, hãy gọishowInfoWindow()
trênpoiMarker
để hiển thị ngay cửa sổ thông tin.
poiMarker.showInfoWindow()
Mã cuối cùng của hàm setPoiClick()
phải có dạng như sau.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
poiMarker.showInfoWindow()
}
}
- Vào cuối
onMapReady()
, hãy gọisetPoiClick()
và chuyển vàomap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setPoiClick(map)
}
- Chạy ứng dụng của bạn và tìm địa điểm yêu thích, chẳng hạn như công viên hoặc quán cà phê.
- Nhấn vào điểm yêu thích để đặt điểm đánh dấu vào đó và hiển thị tên điểm yêu thích trong cửa sổ thông tin.
Bạn có thể tùy chỉnh Google Maps theo nhiều cách, mang đến cho bản đồ của bạn một giao diện độc đáo.
Bạn có thể tùy chỉnh một đối tượng MapFragment
bằng cách sử dụng các thuộc tính XML có sẵn, giống như cách bạn tùy chỉnh mọi mảnh khác. Tuy nhiên, trong bước này, bạn tùy chỉnh giao diện nội dung của MapFragment
bằng cách sử dụng các phương thức trên đối tượng GoogleMap
.
Để tạo kiểu tùy chỉnh cho bản đồ của bạn, hãy tạo một tệp JSON chỉ định cách hiển thị các đối tượng trong bản đồ. Bạn không phải tạo tệp JSON này theo cách thủ công. Google cung cấp Trình hướng dẫn tạo kiểu cho Maps – trình tạo này tạo ra JSON cho bạn sau khi bạn tạo kiểu cho bản đồ của mình bằng hình ảnh. Trong nhiệm vụ này, bạn tạo kiểu cho bản đồ theo chủ đề hoài cổ, nghĩa là bản đồ sẽ sử dụng màu cổ điển và bạn thêm các đường màu.
Bước 1: Tạo kiểu cho bản đồ của bạn
- Truy cập vào https://mapstyle.withgoogle.com/ trong trình duyệt của bạn.
- Chọn Tạo kiểu.
- Chọn Retro.
- Nhấp vào Tùy chọn khác.
- Trong danh sách Loại tính năng, hãy chọn Đường > Điền.
- Thay đổi màu của đường thành bất kỳ màu nào bạn chọn (chẳng hạn như màu hồng).
- Nhấp vào Finish (Hoàn tất).
- Sao chép mã JSON từ hộp thoại hiện ra và nếu bạn muốn, hãy ẩn mã đó vào một ghi chú văn bản thuần túy để sử dụng trong bước tiếp theo.
Bước 2: Thêm kiểu vào bản đồ
- Trong Android Studio, trong thư mục
res
, hãy tạo một thư mục tài nguyên và đặt tên làraw
. Bạn sử dụng tài nguyên thư mụcraw
như mã JSON. - Tạo một tệp trong
res/raw
có tên làmap_style.json
. - Dán mã JSON đã lưu trữ vào tệp tài nguyên mới.
- Trong
MapsActivity
, hãy tạo một biến lớpTAG
phía trên phương thứconCreate()
. Thuộc tính này dùng cho mục đích ghi nhật ký.
private val TAG = MapsActivity::class.java.simpleName
- Cũng trong
MapsActivity
, hãy tạo một hàmsetMapStyle()
nhậnGoogleMap
. - Trong
setMapStyle()
, hãy thêm một khốitry{}
. - Trong khối
try{}
, hãy tạoval success
để tạo kiểu thành công. (Bạn thêm khối chặn sau.) - Trong khối
try{}
, hãy đặt kiểu JSON thành bản đồ, hãy gọisetMapStyle()
trên đối tượngGoogleMap
. Chuyển vào đối tượngMapStyleOptions
, sẽ tải tệp JSON. - Chỉ định kết quả cho
success
. Phương thứcsetMapStyle()
trả về boolean cho biết trạng thái thành công của việc phân tích cú pháp tệp định kiểu và đặt kiểu.
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
)
)
}
}
- Thêm câu lệnh if cho
success
là false. Nếu kiểu đó không thành công, hãy in nhật ký mà việc phân tích cú pháp không thành công.
private fun setMapStyle(map: GoogleMap) {
try {
...
if (!success) {
Log.e(TAG, "Style parsing failed.")
}
}
}
- Thêm một khối
catch{}
để xử lý trường hợp thiếu tệp kiểu. Trong khốicatch
, nếu tệp không thể tải, hãy gửiResources.NotFoundException
.
private fun setMapStyle(map: GoogleMap) {
try {
...
} catch (e: Resources.NotFoundException) {
Log.e(TAG, "Can't find style. Error: ", e)
}
}
Phương thức hoàn thành sẽ có dạng như đoạn mã sau:
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)
}
}
- Cuối cùng, hãy gọi phương thức
setMapStyle()
trong phương thứconMapReady()
chuyển trong đối tượngGoogleMap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapStyle(map)
}
- Chạy ứng dụng của bạn.
- Đặt bản đồ thành chế độ
normal
và kiểu mới sẽ hiển thị với giao diện cũ và đường của màu bạn đã chọn.
Bước 3: Tạo kiểu cho điểm đánh dấu của bạn
Bạn có thể cá nhân hóa bản đồ của mình hơn nữa bằng cách tạo kiểu cho điểm đánh dấu bản đồ. Trong bước này, bạn sẽ thay đổi những điểm đánh dấu màu đỏ mặc định thành nội dung hấp dẫn hơn.
- Trong phương thức
onMapLongClick()
, hãy thêm dòng mã sau vàoMarkerOptions()
của hàm dựng để sử dụng điểm đánh dấu mặc định, nhưng đổi màu thành màu xanh lam.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
Giờ đây, onMapLongClickListener()
sẽ có dạng như sau:
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))
)
}
- Chạy ứng dụng. Các điểm đánh dấu xuất hiện sau khi bạn nhấp và giữ hiện có màu xanh dương. Lưu ý rằng các điểm đánh dấu điểm yêu thích vẫn có màu đỏ vì bạn chưa thêm kiểu vào phương thức
onPoiClick()
.
Bạn có thể tuỳ chỉnh bản đồ Google bằng cách vẽ lên trên bản đồ. Kỹ thuật này rất hữu ích nếu bạn muốn làm nổi bật một loại vị trí cụ thể, chẳng hạn như những điểm câu cá phổ biến.
- Hình dạng: Bạn có thể thêm nhiều đường, đa giác và vòng tròn vào bản đồ.
- Đối tượng
GroundOverlay
: Lớp phủ mặt đất là một hình ảnh cố định cho một bản đồ. Không giống như điểm đánh dấu, lớp phủ mặt đất được hướng đến bề mặt Trái đất thay vì màn hình. Xoay, nghiêng hoặc thu phóng bản đồ sẽ thay đổi hướng của hình ảnh. Lớp phủ mặt đất rất hữu ích khi bạn muốn chỉnh sửa một hình ảnh ở một khu vực trên bản đồ.
Bước: Thêm lớp phủ mặt đất
Trong nhiệm vụ này, bạn thêm lớp phủ mặt đất có hình dạng Android vào vị trí nhà riêng.
- Hãy tải hình ảnh Android này xuống rồi lưu vào thư mục
res/drawable
của bạn. (Đảm bảo tên tệp làandroid.png
.)
- Sau
onMapReady()
, sau khi cuộc gọi chuyển máy ảnh đến vị trí nhà riêng của bạn, hãy tạo một đối tượngGroundOverlayOptions
. - Chỉ định đối tượng này cho một biến có tên là
androidOverlay
.
val androidOverlay = GroundOverlayOptions()
- Sử dụng phương thức
BitmapDescriptorFactory.fromResource()
để tạo đối tượngBitmapDescriptor
từ tài nguyên hình ảnh đã tải xuống. - Chuyển đối tượng
BitmapDescriptor
kết quả vào phương thứcimage()
của đối tượngGroundOverlayOptions
.
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
- Tạo
float overlaySize
cho chiều rộng tính bằng mét của lớp phủ mong muốn. Trong ví dụ này, chiều rộng100f
sẽ hoạt động tốt.
Đặt thuộc tính position
cho đối tượng GroundOverlayOptions
bằng cách gọi phương thức position()
và chuyển trong đối tượng homeLatLng
và overlaySize
.
val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
.position(homeLatLng, overlaySize)
- Gọi
addGroundOverlay()
trên đối tượngGoogleMap
và chuyển vào đối tượngGroundOverlayOptions
.
map.addGroundOverlay(androidOverlay)
- Chạy ứng dụng.
- Hãy thay đổi giá trị của
zoomLevel
thành 18f để xem hình ảnh Android dưới dạng một lớp phủ.
Người dùng thường sử dụng Google Maps để xem vị trí hiện tại của họ. Để hiển thị vị trí của thiết bị trên bản đồ của bạn, bạn có thể sử dụng lớp dữ liệu vị trí.
Lớp dữ liệu vị trí sẽ thêm Vị trí của tôi vào bản đồ. Khi người dùng nhấn vào nút, bản đồ sẽ căn giữa vị trí của thiết bị. Vị trí được hiển thị dưới dạng chấm màu xanh dương nếu thiết bị đứng yên và dưới dạng sọc màu xanh dương nếu thiết bị đang di chuyển.
Trong tác vụ này, bạn sẽ bật lớp dữ liệu vị trí.
Bước: Yêu cầu quyền truy cập thông tin vị trí
Để bật tính năng theo dõi vị trí trong Google Maps, bạn phải có một dòng mã duy nhất. Tuy nhiên, bạn phải đảm bảo rằng người dùng đã cấp quyền truy cập thông tin vị trí (bằng cách sử dụng mô hình quyền truy cập thời gian chạy).
Trong bước này, bạn yêu cầu quyền truy cập thông tin vị trí và bật tính năng theo dõi vị trí.
- Trong tệp
AndroidManifest.xml
, hãy xác minh rằng bạn có quyềnFINE_LOCATION
. Android Studio đã chèn quyền này khi bạn chọn mẫu Google Maps.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- Trong
MapsActivity
, hãy tạo một biến lớpREQUEST_LOCATION_PERMISSION
.
private val REQUEST_LOCATION_PERMISSION = 1
- Để kiểm tra xem có được cấp quyền hay không, hãy tạo một phương thức trong
MapsActivity
có tên làisPermissionGranted()
. Trong phương thức này, hãy kiểm tra xem người dùng đã cấp quyền hay chưa.
private fun isPermissionGranted() : Boolean {
return ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
- Để bật tính năng theo dõi vị trí trong ứng dụng, hãy tạo một phương thức trong
MapsActivity
có tên làenableMyLocation()
. Phương thức này không nhận đối số nào và không trả về bất kỳ giá trị nào. Bên trong, hãy kiểm tra quyềnACCESS_FINE_LOCATION
. Nếu quyền đó được cấp, hãy bật lớp vị trí. Nếu không, hãy yêu cầu quyền.
private fun enableMyLocation() {
if (isPermissionGranted()) {
map.isMyLocationEnabled = true
}
else {
ActivityCompat.requestPermissions(
this,
arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_LOCATION_PERMISSION
)
}
}
- Gọi
enableMyLocation()
từ lệnh gọi lạionMapReady()
để bật lớp vị trí.
override fun onMapReady(googleMap: GoogleMap) {
...
enableMyLocation()
}
- Ghi đè phương thức
onRequestPermissionsResult()
. Nếu quyềnrequestCode
bằngREQUEST_LOCATION_PERMISSION
được cấp và nếu mảnggrantResults
không trống vớiPackageManager.PERMISSION_GRANTED
ở vị trí đầu tiên, hãy gọienableMyLocation()
.
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray) {
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
enableMyLocation()
}
}
}
- Chạy ứng dụng của bạn. Bạn sẽ thấy một hộp thoại yêu cầu quyền truy cập vào thông tin vị trí của thiết bị. Hãy tiếp tục và cho phép.
Bản đồ hiện hiển thị vị trí hiện tại của thiết bị bằng chấm màu xanh dương. Xin lưu ý rằng có một nút vị trí. Nếu bạn di chuyển bản đồ ra khỏi vị trí của bạn và nhấp vào nút này, nó sẽ căn giữa bản đồ về vị trí của thiết bị.
Tải mã xuống cho lớp học lập trình đã hoàn thành.
$ git clone https://github.com/googlecodelabs/android-kotlin-geo-maps
Hoặc bạn có thể tải tệp lưu trữ xuống dưới dạng tệp zip, giải nén và mở tệp đó trong Android Studio.
- Để sử dụng API Maps, bạn cần có khóa API từ Google API Console.
- Trong Android Studio, việc sử dụng mẫu Hoạt động trên Google Maps tạo một
Activity
chỉ với mộtSupportMapFragment
trong bố cục của ứng dụng. Mẫu cũng thêmACCESS_FINE_PERMISSION
vào tệp kê khai ứng dụng và triển khaiOnMapReadyCallback
trong hoạt động của bạn và ghi đè phương thứconMapReady()
bắt buộc.
Để thay đổi loại bản đồ của GoogleMap
vào thời gian chạy, hãy dùng phương thức GoogleMap.setMapType()
. Bản đồ của Google có thể là một trong các loại bản đồ sau:
- Thông thường: Bản đồ đường thông thường. Hiển thị đường, một số tính năng do con người tạo ra và các đặc điểm tự nhiên quan trọng như sông. Ngoài ra, nhãn đường và tính năng cũng hiển thị.
- Kết hợp: Dữ liệu ảnh vệ tinh và bản đồ đường được thêm vào. Ngoài ra, nhãn đường và tính năng cũng hiển thị.
- Vệ tinh: Dữ liệu ảnh. Các nhãn đường và tính năng không hiển thị.
- Địa hình: Dữ liệu địa hình. Bản đồ bao gồm màu, đường kẻ và nhãn, cũng như tính năng tô bóng phối cảnh. Một số đường và nhãn cũng hiển thị.
- Không có: Không có ô bản đồ cơ sở nào.
Giới thiệu về Google Maps:
- Điểm đánh dấu là chỉ báo cho một vị trí địa lý cụ thể.
- Khi được nhấn, hoạt động mặc định của điểm đánh dấu là hiển thị cửa sổ thông tin chứa thông tin về vị trí đó.
- Theo mặc định, các địa điểm yêu thích (CUE) xuất hiện trên bản đồ cơ sở cùng với các biểu tượng tương ứng. Các điểm yêu thích có thể bao gồm công viên, trường học, tòa nhà chính phủ và các địa điểm khác.
- Ngoài ra, điểm yêu thích dành cho doanh nghiệp (cửa hàng, nhà hàng, khách sạn và các địa điểm khác) sẽ xuất hiện theo mặc định trên bản đồ khi loại bản đồ là
normal
. - Bạn có thể nắm bắt lượt nhấp vào điểm yêu thích bằng cách sử dụng
OnPoiClickListener
. - Bạn có thể thay đổi giao diện hình ảnh của hầu hết mọi thành phần trong Google Maps bằng Trình hướng dẫn tạo kiểu. Trình hướng dẫn tạo kiểu tạo tệp JSON mà bạn chuyển vào Google Maps bằng phương thức
setMapStyle()
. - Bạn có thể tùy chỉnh các điểm đánh dấu bằng cách thay đổi màu mặc định hoặc thay thế biểu tượng điểm đánh dấu mặc định bằng một hình ảnh tùy chỉnh.
Các thông tin quan trọng khác:
- Sử dụng lớp phủ mặt đất để cố định hình ảnh cho một vị trí địa lý.
- Sử dụng đối tượng
GroundOverlayOptions
để chỉ định hình ảnh, kích thước của hình ảnh tính bằng mét và vị trí của hình ảnh. Chuyển đối tượng này vào phương thứcGoogleMap.addGroundOverlay()
để đặt lớp phủ lên bản đồ. - Miễn là ứng dụng của bạn có quyền
ACCESS_FINE_LOCATION
, bạn có thể bật theo dõi vị trí bằng cách đặtmap.isMyLocationEnabled = true
. - Lớp học này không được bao gồm trong lớp học lập trình này, nhưng bạn có thể cung cấp thêm thông tin về một vị trí bằng cách sử dụng Chế độ xem phố của Google. Đây là ảnh toàn cảnh có thể di chuyển đến một vị trí nhất định.
Tài liệu dành cho nhà phát triển Android:
- Bắt đầu
- Thêm bản đồ bằng điểm đánh dấu
- Đối tượng ánh xạ
- Thêm bản đồ được tạo kiểu
- Chế độ xem phố
- Lớp phủ mặt đất
Tài liệu tham khảo:
Để biết đường liên kết đến các lớp học lập trình khác trong khóa học này, hãy xem trang đích của Lớp học nâng cao cho Android trong Kotlin.