1. Trước khi bắt đầu
Tạo ứng dụng bằng Google Maps cho phép bạn thêm tính năng vào ứng dụng của mình, chẳng hạn như hình ảnh vệ tinh, các tùy chọn kiểm soát mạnh mẽ trên giao diện người dùng dành cho bản đồ, theo dõi vị trí và các điểm đánh dấu vị trí. Bạn có thể thêm giá trị cho Google Maps tiêu chuẩn bằng cách hiển thị thông tin từ tập dữ liệu của riêng bạn, 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 trò chơi trong đó người chơi khám phá thế giới thực, chẳng hạn như trong cuộc săn tìm 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 sẽ tạo một ứng dụng Google Maps có tên là Wander. Ứng dụng này hiển thị bản đồ tuỳ chỉnh và cho biết vị trí của người dùng.
Điều kiện tiên quyết
Kiến thức về:
- Nắm được cách tạo và chạy ứng dụng Android cơ bản bằng Android Studio.
- Cách tạo và quản lý tài nguyên, chẳng hạn như chuỗi.
- Cách tái cấu trúc mã và đổi tên biến bằng Android Studio.
- Cách sử dụng bản đồ Google với tư cách là người dùng.
- Cách đặt quyền khi bắt đầu chạy.
Kiến thức bạn sẽ học được
- Cách lấy khoá API từ Google API Console và đăng ký khoá cho ứng dụng của bạn
- Cách tích hợp Google Maps vào ứ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ào địa điểm yêu thích (POI)
- Cách bật tính năng theo dõi vị trí
- Cách tạo ứng dụng
Wander
, trong đó có một Google Maps được nhúng - Cách tạo tính năng tuỳ chỉnh cho ứng dụng, chẳng hạn như điểm đánh dấu và định kiểu
- Cách bật tính năng theo dõi vị trí trong ứng dụng của bạn
2. Tổng quan về ứng dụng
Trong lớp học lập trình này, bạn sẽ tạo ứng dụng Wander
, ứng dụng này hiển thị bản đồ Google với kiểu tuỳ chỉnh. Ứng dụng Wander cho phép bạn thả điểm đánh dấu vào vị trí, thêm lớp phủ và xem vị trí của bạn theo thời gian thực.
3. Nhiệm vụ: Thiết lập dự án và tải Khoá API
SDK bản đồ dành cho Android yêu cầu khoá API. Để có được khoá API, hãy đăng ký dự án của bạn trong API & Dịch vụ. Khoá API được gắn 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 khoá đó. Để 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 bài viết Ký ứng dụng.
Trong lớp học lập trình này, bạn sẽ sử dụng khoá API cho chứng chỉ gỡ lỗi. Chứng chỉ gỡ lỗi không an toàn theo thiết kế, như mô tả trong bài viết Ký bản gỡ lỗi. Các ứng dụng Android đã phát hành có sử dụng Maps SDK dành cho Android yêu cầu khoá API thứ hai: khoá 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 Lấy khoá API.
Android Studio chứa một mẫu Hoạt động trên Google Maps để tạo mã mẫu hữu ích. Mã mẫu bao gồm tệp google_maps_api.xml chứa đường liên kết giúp đơn giản hoá việc lấy khoá API.
Bước 1: Tạo dự án Wander bằng mẫu bản đồ
- Tạo một 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 Hoàn tất.
- Sau khi tạo xong ứng dụng, hãy xem dự án của bạn và các tệp liên quan đến bản đồ sau đây mà Android Studio tạo cho bạn:
google_maps_api.xml—Bạn sử dụng tệp cấu hình này để lưu khoá API. Mẫu này tạo hai tệp google_maps_api.xml: một tệp để gỡ lỗi và một tệp để phát hành. Tệp cho khoá API cho chứng chỉ gỡ lỗi nằm trong src/debug/res/values. Tệp cho khoá 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 đồ trong ứng dụng. Đó là một trình bao bọc xung quanh chế độ xem của 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, kèm theo thuộc tính name
bổ sung.
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.java – Tệp MapsActivity.java tạo thực thể của SupportMapFragment
trong phương thức onCreate()
và sử dụng lớp này getMapAsync
()
để tự động khởi chạy 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 khoá API
- Mở phiên bản gỡ lỗi của tệp google_maps_api.xml.
- Trong tệp đó, hãy tìm một nhận xét có URL dài. Các tham số của 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 trình duyệt.
- Làm theo lời nhắc để tạo một dự án trên các API và Dịch vụ. Do các tham số trong URL được cung cấp, trang biết để tự động bật SDK bản đồ cho Android.
- Nhấp vào Tạo khoá API.
- Trên trang tiếp theo, chuyển đến phần Khoá API rồi nhấp vào khoá bạn vừa tạo.
- Nhấp vào Hạn chế khoá rồi chọn SDK Maps cho Android để hạn chế việc sử dụng khoá cho các ứng dụng Android.
- Sao chép khoá API đã tạo. Mã này sẽ bắt đầu bằng "
AIza"
. - Trong tệp
google_maps_api.xml
, hãy dán khoá vào chuỗigoogle_maps_key
cho biếtYOUR_KEY_HERE
. - Chạy ứng dụng. Bạn sẽ nhìn thấy một bản đồ được nhúng trong hoạt động của mình cùng với một điểm đánh dấu được thiết lập ở Sydney, Úc. (Điểm đánh dấu Sydney là một phần của mẫu và bạn sẽ thay đổi nó sau.)
Bước 3: Đổi tên mMap
MapsActivity
có một lateinit
var
riêng tư tên là mMap
thuộc kiểu GoogleMap
. Để tuân theo 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 Refactor (Tái cấu trúc) > Đổi tên...
- Hãy thay đổi tên biến thành
map
.
Hãy lưu ý cách mọi tham chiếu đến mMap
trong hàm onMapReady()
cũng thay đổi thành map
.
4. Nhiệm vụ: Thêm loại bản đồ
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à "không có" (không hề có 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 đồ để chỉ đường trong ô tô, bạn nên nhìn thấy tên đường phố, vì vậy, bạn có thể sử dụng lựa chọn thông thường. Khi bạn đi bộ đường dài, bản đồ địa hình có thể hữu ích trong việc quyết định bạn phải leo thêm bao nhiêu nữa để lên đến đỉnh.
Trong nhiệm vụ này, bạn:
- Thêm thanh ứng dụng có trình đơn tuỳ chọn cho phép người dùng thay đổi loại bản đồ.
- Di chuyển vị trí bắt đầu của bản đồ đến vị trí nhà riêng của bạn.
- Thêm hỗ trợ cho các điểm đánh dấu, cho biết các vị trí đơn 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 thanh ứng dụng có 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 trình đơn mới, 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 cho tệp là
map_options
. - Chọn Trình đơn cho loại tài nguyên.
- Nhấp vào OK.
- Trong thẻ Code (Mã), hãy thay thế mã trong tệp mới bằng mã sau để tạo các lựa chọn trên trình đơn bản đồ. Giá trị "không" loại bản đồ bị bỏ qua vì "không có" dẫn đến việc thiếu bản đồ. Bước này gây ra lỗi nhưng bạn sẽ giải quyết được lỗi này 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
để sửa 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 ánh xạ để 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ú ý cách giao diện của bản đồ thay đổi giữa các chế độ.
5. Nhiệm vụ: Thêm điểm đánh dấu
Theo mặc định, lệnh gọi lại onMapReady()
bao gồm mã đặt 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 ảnh động cho bản đồ để xoay sang Sydney.
Trong nhiệm vụ này, bạn sẽ điều chỉnh camera của bản đồ đến nhà riêng, phóng to đến mức bạn chỉ định và đặt điểm đánh dấu ở đó.
Bước 1: Thu phóng tới nhà của bạn và thêm điểm đánh dấu
- Trong tệp
MapsActivity.kt
, hãy tìm phương thứconMapReady()
. Xoá đoạn mã trong đó dùng để đặt điểm đánh dấu ở Sydney và di chuyển camera. Phương thức của bạn bây giờ sẽ có dạng như sau.
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
}
- Tìm vĩ độ và kinh độ của nhà 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 giá trị số thực của chúng.
val latitude = 37.422160
val longitude = -122.084270
- Tạo một đối tượng
LatLng
mới có tên làhomeLatLng
. Trong đối tượnghomeLatLng
, hãy truyền các giá trị bạn vừa tạo vào.
val homeLatLng = LatLng(latitude, longitude)
- Tạo
val
để thể hiện mức độ phóng to mà bạn muốn 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 độ bạn được phóng to trên bản đồ. Danh sách sau đây cho bạn biết mức độ chi tiết mà mỗi mức thu phóng hiển thị:
1
: Thế giới5
: Vùng đất/lục địa10
: Thành phố15
: Đường phố20
: Toà nhà
- Di chuyển camera đến
homeLatLng
bằng cách gọi hàmmoveCamera()
trên đối tượngmap
rồi truyền vào đối tượngCameraUpdate
bằng cách sử dụngCameraUpdateFactory.newLatLngZoom()
. Truyền vào đối tượnghomeLatLng
vàzoomLevel
.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
- Thêm một đ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 tới nhà bạn, phóng to đến mức mong muốn và đặt mộ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 và giữ
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 mã giả lập phương thức trong
MapsActivity
có tên làsetMapLongClick()
. Mã này sẽ lấyGoogleMap
làm đối số. - Đính kèm trình nghe
setOnMapLongClickListener
vào đối tượng ánh xạ.
private fun setMapLongClick(map:GoogleMap) {
map.setOnMapLongClickListener { }
}
- Trong
setOnMapLongClickListener()
, hãy gọi phương thứcaddMarker()
. Truyền vào một đối tượngMarkerOptions
mới có vị trí được đặt thànhLatLng
đã truyền vào.
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í.
- Nhấn vào điểm đánh dấu để đặt điểm đánh dấu vào giữa màn hình.
Bước 3: Thêm cửa sổ thông tin cho điểm đánh dấu
Ở bước này, bạn sẽ thêm một InfoWindow
cho thấy toạ độ 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 xuất hiện sau tiêu đề. Đoạn mã của bạn hiển thị vĩ độ và kinh độ của đ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
snippet
của điểm đánh dấu 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ả một đ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 nghe POI
Theo mặc định, các địa điểm yêu thích (POI) sẽ xuất hiện trên bản đồ cùng với các biểu tượng tương ứng của chúng. Địa điểm yêu thích bao gồm công viên, trường học, toà nhà chính phủ và các địa điểm khác. Khi bạn đặt loại bản đồ thành normal
, các địa điểm yêu thích của doanh nghiệp cũng sẽ xuất hiện trên bản đồ. Địa điểm yêu thích là 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.
Ở bước này, bạn 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 địa điểm yêu thích. Trình nghe lượt nhấp cũng hiển thị cửa sổ thông tin có chứa tên POI.
- Tạo một mã giả lập phương thức trong
MapsActivity
có tên làsetPoiClick()
. Mã này sẽ lấyGoogleMap
làm đối số. - Trong phương thức
setPoiClick()
, hãy đặtOnPoiClickListener
trênGoogleMap
đã truyền vào.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
}
}
- Trong
setOnPoiClickListener()
, tạoval poiMarker
cho điểm đánh dấu . - Đặt thành một điểm đánh dấu bằng cách sử dụng
map.addMarker()
vớiMarkerOptions
, đặttitle
thành tên của đị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ị cửa sổ thông tin ngay lập tức.
poiMarker.showInfoWindow()
Mã hoàn thiện cho hàm setPoiClick()
sẽ 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()
}
}
- Ở cuối
onMapReady()
, hãy gọisetPoiClick()
và truyền vàomap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setPoiClick(map)
}
- Chạy ứng dụng 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 địa điểm yêu thích để đặt một điểm đánh dấu lên địa điểm đó và hiển thị tên của địa điểm yêu thích đó trong cửa sổ thông tin.
6. Nhiệm vụ: Tạo kiểu cho bản đồ của bạn
Bạn có thể tuỳ chỉnh Google Maps theo nhiều cách, tạo ra một giao diện độc đáo cho bản đồ của bạn.
Bạn có thể tuỳ chỉnh đối tượng MapFragment
bằng các thuộc tính XML có sẵn, giống như cách bạn tuỳ chỉnh bất kỳ mảnh nào khác. Tuy nhiên, trong bước này, bạn tuỳ 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, bạn tạo tệp JSON chỉ rõ cách hiển thị các đối tượng trong bản đồ. Bạn không cần 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 trên nền tảng Maps. Trình hướng dẫn này sẽ tạo JSON cho bạn sau khi bạn tạo kiểu trực quan cho bản đồ của mình. Trong nhiệm vụ này, bạn tạo kiểu cho bản đồ bằng chủ đề hoài cổ, nghĩa là bản đồ sử dụng các màu cổ điển và thêm những con đường được tô màu.
Bước 1: Tạo kiểu cho bản đồ
- Hãy 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 Cũ.
- Nhấp vào Tùy chọn khác.
- Chọn Đường > Điền.
- Thay đổi màu đườ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 Hoàn tất.
- Sao chép mã JSON từ hộp thoại hiện ra và nếu muốn, hãy lưu trữ mã đó trong một ghi chú văn bản thuần tuý để sử dụng trong bước tiếp theo.
Bước 2: Thêm kiểu vào bản đồ của bạn
- Trong Android Studio, ở thư mục
res
, hãy tạo một thư mục tài nguyên rồi đặt tên cho thư mục đó làraw
. Bạn sử dụng các 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()
. Dữ liệu này dùng cho mục đích ghi nhật ký.
private val TAG = MapsActivity::class.java.simpleName
- Ngoài ra, trong
MapsActivity
, hãy tạo một hàmsetMapStyle()
chứaGoogleMap
. - Trong
setMapStyle()
, hãy thêm một khốitry{}
. - Trong khối
try{}
, hãy tạo mộtval success
để có thể định kiểu thành công. (Bạn thêm khối tiêu đề sau.) - Trong khối
try{}
, hãy thiết lập kiểu JSON thành bản đồ, gọisetMapStyle()
trên đối tượngGoogleMap
. Truyền vào một đối tượngMapStyleOptions
. Đối tượng này sẽ tải tệp JSON. - Chỉ định kết quả cho
success
. Phương thứcsetMapStyle()
trả về một giá trị 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 việc định kiểu không thành công, hãy xuất nhật ký cho biết quá trình 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 khối
catch{}
để xử lý trường hợp thiếu tệp kiểu. Trong khốicatch
, nếu không thể tải tệp, hãy gửi mộtResources.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 chỉ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()
truyền vào đối tượngGoogleMap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapStyle(map)
}
- Chạy ứng dụng của bạn.
- Đặt bản đồ ở chế độ
normal
và kiểu mới sẽ hiển thị với giao diện và đường màu cổ điển mà 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 hoá 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 thay đổi điểm đánh dấu màu đỏ mặc định thành điểm đánh dấu 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 khởi tạo để sử dụng điểm đánh dấu mặc định nhưng thay đổi màu thành màu xanh dương.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
onMapLongClickListener()
hiện 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. Điểm đánh dấu xuất hiện sau khi bạn nhấp và giữ giờ đây sẽ được tô màu xanh dương. Lưu ý rằng các điểm đánh dấu POI vẫn có màu đỏ vì bạn không thêm kiểu vào phương thức
onPoiClick()
.
7. Nhiệm vụ: Thêm lớp phủ
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 địa điểm cụ thể, chẳng hạn như các điểm câu cá nổi tiếng.
- Hình dạng: Bạn có thể thêm hình nhiều đường, đa giác và hình tròn vào bản đồ.
GroundOverlay
đối tượng: Lớp phủ mặt đất là hình ảnh được cố định với bản đồ. Không giống như điểm đánh dấu, lớp phủ mặt đất được định hướng về bề mặt Trái đất chứ không phải 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 hữu ích khi bạn muốn sửa một hình ảnh trong 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 sẽ thêm một lớp phủ mặt đất theo hình dạng Android vào vị trí nhà riêng của mình.
- Tải hình ảnh Android này xuống rồi lưu vào thư mục
res/drawable
. (Hãy đảm bảo tên tệp làandroid.png
.)
- Trong
onMapReady()
, sau lệnh gọi di chuyển camera đến vị trí nhà bạn, hãy tạo một đối tượngGroundOverlayOptions
. - Chỉ định đối tượng cho 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. - Truyền đối tượng
BitmapDescriptor
thu được 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ộng của100f
là phù hợp.
Đặt thuộc tính position
cho đối tượng GroundOverlayOptions
bằng cách gọi phương thức position()
rồi truyền vào đố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
rồi truyền vào đối tượngGroundOverlayOptions
.
map.addGroundOverlay(androidOverlay)
- Chạy ứng dụng.
- Thay đổi giá trị của
zoomLevel
thành 18f để xem hình ảnh Android dưới dạng lớp phủ.
8. Nhiệm vụ: Bật tính năng theo dõi vị trí
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 đồ, bạn có thể sử dụng lớp dữ liệu vị trí.
Lớp dữ liệu vị trí thêm biểu tượng Vị trí của tôi vào bản đồ.
Khi người dùng nhấn vào nút này, bản đồ sẽ tập trung vào 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ị đang cố định và dưới dạng vạch chữ v màu xanh dương nếu thiết bị đang di chuyển.
Trong nhiệm 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í
Việc bật tính năng theo dõi vị trí trong Google Maps yêu cầu 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 mô hình quản lý quyền khi bắt đầu chạy).
Ở 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 quyềnFINE_LOCATION
đã có. 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 quyền đã được cấp hay chưa, 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ố và không trả về 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 cấp 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()
. Kiểm tra xemrequestCode
có bằngREQUEST_LOCATION_PERMISSION
hay không. Nếu được cấp quyền thì điều đó có nghĩa là quyền đã được cấp. Nếu được cấp quyền, hãy kiểm tra xem mảnggrantResults
có chứaPackageManager.PERMISSION_GRANTED
trong ô đầu tiên hay không. Nếu đúng như vậy, 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. Sẽ có một hộp thoại yêu cầu quyền truy cập vào vị trí của thiết bị. Hãy tiếp tục và cấp quyền.
Bản đồ giờ đây hiển thị vị trí hiện tại của thiết bị bằng một chấm màu xanh dương. Lưu ý rằng có nút vị trí. Nếu bạn di chuyển bản đồ ra xa vị trí của mình và nhấp vào nút này, nút này sẽ căn giữa bản đồ trở về vị trí của thiết bị.
9. Đoạn mã giải pháp
Tải mã nguồn xuống khi lớp học lập trình đã kết thúc.
$ git clone https://github.com/googlecodelabs/android-kotlin-geo-maps
Ngoài ra, bạn có thể tải kho lưu trữ xuống dưới dạng tệp ZIP, sau đó giải nén và mở trong Android Studio.
10. Tóm tắt
Xin chúc mừng! Bạn đã thêm một bản đồ Google vào một ứng dụng Android trên Kotlin và tạo kiểu cho nó.
11. Tìm hiểu thêm
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 bản đồ
- Thêm bản đồ được tạo kiểu
- Chế độ xem đường phố
- Lớp phủ mặt đất
Tài liệu tham khảo:
12. Lớp học lập trình tiếp theo
Để xem đường liên kết đến các lớp học lập trình khác trong khoá học này, hãy xem trang đích của lớp học lập trình Android bằng Kotlin nâng cao.