1. Chào mừng
Lớp học lập trình này nằm trong khoá đào tạo Phát triển Android nâng cao do Nhóm đào tạo nhà phát triển của Google phát triển. Bạn sẽ nhận được nhiều giá trị nhất từ khoá học này nếu thực hiện các lớp học lập trình theo trình tự.
Để biết toàn bộ thông tin chi tiết về khoá học, hãy xem bài viết Tổng quan về Phát triển Android nâng cao.
Giới thiệu
Xây dựng ứ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 của mình như hình ảnh vệ tinh, các chế độ điều khiển trên giao diện người dùng mạnh mẽ, 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 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 các trò chơi gắn liền với thế giới thực, như Pokemon Go.
Trong lớp học lập trình này, bạn sẽ tạo một ứng dụng Google Maps có tên là Wander
.
Kiến thức bạn cần có
Bạn cần thông thạo:
- Chức năng cơ bản của Google Maps.
- Quyền khi bắt đầu chạy.
- Tạo, xây dựng và chạy ứng dụng trong Android Studio.
- Đưa các thư viện bên ngoài vào tệp
build.gradle
.
Kiến thức bạn sẽ học được
- Tích hợp Google Maps trong ứng dụng của bạn.
- Hiển thị các loại bản đồ khác nhau.
- Tạo kiểu cho Bản đồ Google.
- Thêm điểm đánh dấu vào bản đồ của bạn.
- Cho phép người dùng đặt điểm đánh dấu trên địa điểm yêu thích (POI).
- Bật tính năng theo dõi vị trí.
- Bật Chế độ xem đường phố của Google.
Bạn sẽ thực hiện
- Lấy khoá API từ Google API Console và đăng ký khoá cho ứng dụng của bạn.
- Tạo ứng dụng
Wander
, trong đó có nhúng Google Maps. - Thêm các tính năng tuỳ chỉnh vào ứng dụng của bạn, chẳng hạn như điểm đánh dấu, tạo kiểu và theo dõi vị trí.
- Bật tính năng theo dõi vị trí và Chế độ xem đường phố 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
, một ứng dụng được tạo kiểu trên Google Map. Ứng dụng Wander
cho phép bạn thả điểm đánh dấu vào các vị trí, xem vị trí của bạn theo thời gian thực và xem ảnh toàn cảnh trong Chế độ xem đường phố.
3. Nhiệm vụ 1. Thiết lập dự án và nhận Khoá API
API Google Maps, chẳng hạn như API Địa điểm, yêu cầu có khoá API. Để lấy khoá API, bạn cần đăng ký dự án của mình trong Google API Console. 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 API Google Maps 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.
1.1 Tạo dự án Wander bằng mẫu Maps
- Tạo một dự án Android Studio mới.
- Đặt tên cho ứng dụng mới là "Wander". Chấp nhận các chế độ mặc định cho đến khi bạn truy cập vào trang Add an Activity (Thêm hoạt động).
- Chọn mẫu Hoạt động trên Google Maps.
- Giữ nguyên Activity Name (Tên hoạt động) và Layout Name (Tên bố cục) mặc định.
- Thay đổi Tiêu đề thành "Wander" rồi nhấp vào Finish (Hoàn tất).
Android Studio tạo một số tệp bổ sung liên quan đến bản đồ:
google_maps_api**.xml**
Bạn sử dụng tệp cấu hình này để lưu giữ khoá API. Mẫu này sẽ tạo 2 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 của 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, chúng ta 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
. 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 bổ sung:
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.java
Tệp MapsActivity.java
tạo thực thể cho lớp SupportMapFragment
và sử dụng phương thức getMapAsync()
của lớp này để chuẩn bị Google Map. 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 getMapAsync()
trả về một đối tượng GoogleMap
, biểu thị rằng bản đồ đã được tải.
1.2 Lấy khoá API
- Mở phiên bản gỡ lỗi của tệp
google_maps_api.xml
.
Tệp này chứa một nhận xét có một 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 dự án trong Google API Console. Do các tham số trong URL được cung cấp, Bảng điều khiển API biết phải tự động bật API Google Maps dành cho Android
- Tạo một khoá API rồi nhấp vào Hạn chế khoá để hạn chế việc ứng dụng Android sử dụng khoá. Khoá API được tạo phải 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 có một bản đồ được nhúng trong hoạt động của mình, với một điểm đánh dấu ở Sydney, Úc. (Điểm đánh dấu Sydney là một phần của mẫu và bạn sẽ thay đổi lại sau.)
4. Nhiệm vụ 2. Thêm loại bản đồ và điểm đánh dấu
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ó". Trong nhiệm vụ này, bạn sẽ thêm một thanh ứng dụng có trình đơn tuỳ chọn cho phép người dùng thay đổi loại bản đồ. Bạn di chuyển vị trí bắt đầu của bản đồ sang vị trí nhà riêng của mình. Sau đó, 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.
2.1 Thêm loại bản đồ
Loại bản đồ mà người dùng của bạn muốn phụ thuộc vào loại thông tin họ cần. Khi sử dụng bản đồ để đi theo chỉ dẫn trong ô tô, bạn nên nhìn thấy rõ tên đường phố. Khi đi bộ đường dài, có thể bạn sẽ quan tâm nhiều hơn đến việc phải leo núi bao nhiêu quãng đường mới có thể lên đến đỉnh núi. 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 New > (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. - Thay thế mã trong tệp mới bằng mã sau để tạo các tuỳ chọ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 đồ.
<?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>
- Tạo tài nguyên chuỗi cho các thuộc tính
title
. - Trong tệp
MapsActivity
, hãy thay đổi lớp này để mở rộng lớpAppCompatActivity
thay vì mở rộng lớpFragmentActivity
. Việc sử dụngAppCompatActivity
sẽ làm hiện thanh ứng dụng và do đó thanh ứng dụng cũng sẽ hiện trình đơn. - Trong
MapsActivity
, hãy ghi đè phương thứconCreateOptionsMenu()
và tăng cường tệpmap_options
:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.map_options, menu);
return true;
}
- Để thay đổi loại ánh xạ, hãy sử dụng phương thức
setMapType
() trên đối tượngGoogleMap
, truyền vào một trong các hằng số kiểu ánh xạ.
Ghi đè phương thức onOptionsItemSelected()
. Dán mã sau để thay đổi loại bản đồ khi người dùng chọn một trong các tuỳ chọn trình đơn:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Change the map type based on the user's selection.
switch (item.getItemId()) {
case R.id.normal_map:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
case R.id.hybrid_map:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
return true;
case R.id.satellite_map:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
case R.id.terrain_map:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
- Chạy ứng dụng. Sử dụng trình đơn trong thanh ứng dụng để thay đổi loại bản đồ. Hãy lưu ý cách giao diện của bản đồ thay đổi.
2.2 Di chuyển vị trí mặc định trên bản đồ
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. Ở bước này, bạn làm cho bản đồ xoay đến vị trí nhà của bạn mà không đặt điểm đánh dấu, sau đó phóng to đến mức bạn chỉ định.
- Trong phương thức
onMapReady()
, hãy xoá mã đặt điểm đánh dấu ở Sydney và di chuyển camera. - Truy cập vào www.google.com/maps trong trình duyệt và tìm địa chỉ nhà riêng của bạn.
- Nhấp chuột phải vào vị trí rồi chọn Đây là gì?
Gần cuối màn hình, một cửa sổ nhỏ bật lên có thông tin vị trí, bao gồm vĩ độ và kinh độ.
- Tạo một đối tượng
LatLng
mới có tên làhome
. Trong đối tượngLatLng
, hãy dùng toạ độ mà bạn tìm thấy trên Google Maps trong trình duyệt. - Tạo biến
float
có tên làzoom
rồi đặt biến đó về mức thu phóng ban đầu mà bạn muố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à
- Tạo đối tượng
CameraUpdate
bằngCameraUpdateFactory.newLatLngZoom()
, truyền vào đối tượngLatLng
và biếnzoom
. Xoay và thu phóng máy ảnh bằng cách gọimoveCamera()
trên đối tượngGoogleMap
, truyền đối tượngCameraUpdate
mới:
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
- Chạy ứng dụng. Bản đồ sẽ xoay tới nhà bạn và phóng to đến mức mong muốn.
2.3 Thêm điểm đánh dấu bản đồ
Google Maps có thể đánh dấu một vị trí bằng một điểm đánh dấu do bạn tạo bằng lớp Marker
. Điểm đánh dấu mặc định sử dụng biểu tượng Google Maps chuẩn:
Bạn có thể mở rộng điểm đánh dấu để hiển thị thông tin theo ngữ cảnh trong cửa sổ thông tin.
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 đồ. Sau đó, bạn có thể thêm InfoWindow
cho thấy toạ độ của điểm đánh dấu khi người dùng nhấn vào điểm đánh dấu.
- Tạo một mã giả lập phương thức trong
MapsActivity
có tên làsetMapLongClick()
. Mã này sẽ lấyfinal
GoogleMap
làm đối số và trả vềvoid
:
private void setMapLongClick(final GoogleMap map) {}
- Sử dụng phương thức
setOnMapLongClickListener()
của đối tượngGoogleMap
để đặt điểm đánh dấu nơi người dùng chạm và giữ. Truyền vào một thực thể mới củaOnMapLongClickListener
để ghi đè phương thứconMapLongClick()
. Đối số đến là một đối tượngLatLng
chứa toạ độ của vị trí mà người dùng đã nhấn:
private void setMapLongClick(final GoogleMap map) {
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
}
});
}
- Bên trong
onMapLongClick()
, 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:
map.addMarker(new MarkerOptions().position(latLng));
- Gọi
setMapLongClick()
ở cuối phương thứconMapReady()
. TruyềnmMap
vào. - Chạy ứng dụng. Chạm và giữ trên 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.
Các nút điều hướng xuất hiện ở phía dưới cùng bên trái màn hình, cho phép người dùng sử dụng ứng dụng Google Maps để điều hướng đến vị trí được đánh dấu.
Để thêm cửa sổ thông tin cho điểm đánh dấu:
- Trong đối tượng
MarkerOptions
, hãy thiết lập trườngtitle
và trườngsnippet
. - Trong
onMapLongClick()
, hãy đặt trườngtitle
thành "Đã thả ghim". Đặt trườngsnippet
thành toạ độ vị trí bên trong phương thứcaddMarker()
.
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
String snippet = String.format(Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude);
map.addMarker(new MarkerOptions()
.position(latLng)
.title(getString(R.string.dropped_pin))
.snippet(snippet));
}
});
- Chạy ứng dụng. Chạm và giữ trên 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.
2.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 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 nhấp chuột này sẽ đặt một điểm đánh dấu trên bản đồ ngay lập tức, thay vì chờ người dùng chạm & . 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ấyfinal
GoogleMap
làm đối số và trả vềvoid
:
private void setPoiClick(final GoogleMap map) {}
- Trong phương thức
setPoiClick()
, hãy đặtOnPoiClickListener
trênGoogleMap
được truyền vào:
map.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
@Override
public void onPoiClick(PointOfInterest poi) {
}
});
- Trong phương thức
onPoiClick()
, hãy đặt một điểm đánh dấu tại vị trí POI. Đặt tiêu đề thành tên của POI. Lưu kết quả vào một biến có tên làpoiMarker
.
public void onPoiClick(PointOfInterest poi) {
Marker poiMarker = mMap.addMarker(new MarkerOptions()
.position(poi.latLng)
.title(poi.name);
}
- Gọi
showInfoWindow()
trênpoiMarker
để hiển thị cửa sổ thông tin ngay lập tức.
poiMarker.showInfoWindow();
- Gọi
setPoiClick()
vào cuốionMapReady()
. TruyềnmMap
vào. - Chạy ứng dụng và tìm một địa điểm yêu thích, chẳng hạn như công viên. Nhấn vào địa điểm yêu thích để đặt điểm đánh dấu trê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.
5. Nhiệm vụ 3. 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
. Bạn sử dụng Trình hướng dẫn tạo kiểu trực tuyến để thêm kiểu vào bản đồ và tùy chỉnh điểm đánh dấu của mình. Bạn cũng có thể thêm GroundOverlay
vào vị trí nhà riêng của mình. Biểu tượng này sẽ điều chỉnh theo tỷ lệ và xoay theo bản đồ.
3.1 Thêm kiểu cho bản đồ của bạn
Để tạo kiểu tùy chỉnh cho bản đồ của bạn, bạn hãy tạo tệp JSON chỉ rõ cách các đối tượng trong bản đồ được hiển thị.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, công cụ 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 lớp học lập trình này, bạn sẽ tạo kiểu cho bản đồ là "chế độ ban đêm", có nghĩa là bản đồ sử dụng màu tối và độ tương phản thấp để sử dụng vào ban đêm.
- 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 giao diện Ban đêm.
- Nhấp vào Lựa chọn khác ở cuối trình đơn.
- Ở cuối danh sách Loại đối tượng, hãy chọn Nước > Màu nền. Thay đổi màu của nước thành màu xanh dương đậm (ví dụ: #160064).
- Nhấp vào Hoàn tất. Sao chép mã JSON trong cửa sổ bật lên hiện ra.
- Trong Android Studio, hãy tạo một thư mục tài nguyên có tên là
raw
trong thư mụcres
. Tạo một tệp trongres/raw
có tên làmap_style.json
. - Dán mã JSON vào tệp tài nguyên mới.
- Để thiết lập kiểu JSON thành bản đồ, hãy gọi
setMapStyle()
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. Phương thứcsetMapStyle()
trả về một giá trị boolean cho biết việc định kiểu thành công. Nếu không thể tải tệp, phương thức này sẽ gửiResources.NotFoundException
.
Sao chép mã nguồn sau đây vào phương thức onMapReady()
để tạo kiểu cho bản đồ. Bạn có thể cần tạo chuỗi TAG
cho các câu lệnh nhật ký:
try {
// Customize the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this, R.raw.map_style));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style. Error: ", e);
}
- Chạy ứng dụng. Kiểu mới sẽ hiển thị khi bản đồ ở chế độ
normal
.
3.2 Tạo kiểu cho điểm đánh dấu
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 để phù hợp với bảng phối màu của chế độ ban đêm.
- Trong phương thức
onMapLongClick()
, hãy thêm dòng mã sau vào hàm khởi tạoMarkerOptions()
để 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))
- Chạy ứng dụng. Các điểm đánh dấu bạn đặt hiện có màu xanh dương, phù hợp hơn với giao diện chế độ ban đêm của ứng dụng.
Lưu ý các điểm đánh dấu POI vẫn có màu đỏ, vì bạn không thêm kiểu cho phương thức onPoiClick()
.
3.3 Thêm lớp phủ
Bạn có thể tuỳ chỉnh Google Maps bằng cách vẽ lên trê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. Có ba loại lớp phủ được hỗ trợ:
- 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 đồ.
- Đối tượng
TileOverlay
: Lớp phủ thẻ thông tin xác định một tập hợp hình ảnh được thêm vào phía trên các thẻ thông tin bản đồ cơ sở. Lớp phủ xếp kề rất hữu ích khi bạn muốn thêm hình ảnh bao quát vào bản đồ. Lớp phủ ô thông thường bao phủ một khu vực địa lý rộng lớn. - Đối tượng
GroundOverlay
: 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 tại một khu vực trên bản đồ
Trong bước này, bạn 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
. - Trong
onMapReady()
, sau lệnh gọi di chuyển camera về vị trí ban đầu, hãy tạo một đối tượngGroundOverlayOptions
. Chỉ định đối tượng cho biến có tên làhomeOverlay
:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions();
- Sử dụng phương thức
BitmapDescriptorFactory.fromResource()
để tạo đối tượngBitmapDescriptor
từ hình ảnh trên. Truyền đối tượng vào phương thứcimage()
của đối tượngGroundOverlayOptions
:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android));
- Đặt thuộc tính
position
cho đối tượngGroundOverlayOptions
bằng cách gọi phương thứcposition()
. Truyền vào đối tượnghome
LatLng
vàfloat
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 100 m phù hợp:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
.position(home, 100);
- Gọi
addGroundOverlay()
trên đối tượngGoogleMap
. Truyền vào đối tượngGroundOverlayOptions
:
mMap.addGroundOverlay(homeOverlay);
- Chạy ứng dụng. Phóng to vị trí nhà riêng của bạn và bạn sẽ thấy hình ảnh Android dưới dạng lớp phủ.
6. Nhiệm vụ 4. Bật tính năng theo dõi vị trí và Chế độ xem đường phố
Người dùng thường dùng Google Maps để xem vị trí hiện tại của họ, còn bạn có thể lấy thông tin vị trí của thiết bị bằng API Dịch vụ vị trí. Để hiển thị vị trí của thiết bị trên bản đồ của bạn mà không cần sử dụng thêm dữ liệu Location
, bạn có thể sử dụng lớp dữ liệu vị trí.
Lớp dữ liệu vị trí thêm nút Vị trí của tôi vào phía trên cùng bên phải của 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 dấu chữ v màu xanh dương nếu thiết bị đang di chuyển.
Bạn có thể cung cấp thêm thông tin về một vị trí bằng Chế độ xem đường phố của Google, một ảnh toàn cảnh có thể đi theo chỉ dẫn về một vị trí nhất định.
Trong nhiệm vụ này, bạn bật lớp dữ liệu vị trí và Chế độ xem đường phố để khi người dùng nhấn vào cửa sổ thông tin của điểm đánh dấu POI, bản đồ sẽ chuyển sang Chế độ xem đường phố.
4.1 Bật tính năng theo dõi 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. - Để 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. - Xác định phương thức
enableMyLocation()
. 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 void enableMyLocation() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
ActivityCompat.requestPermissions(this, new 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í. - Ghi đè phương thức
onRequestPermissionsResult()
. Nếu quyền đã được cấp, hãy gọienableMyLocation()
:
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
// Check if location permissions are granted and if so enable the
// location data layer.
switch (requestCode) {
case REQUEST_LOCATION_PERMISSION:
if (grantResults.length > 0
&& grantResults[0]
== PackageManager.PERMISSION_GRANTED) {
enableMyLocation();
break;
}
}
}
- Chạy ứng dụng. Góc trên cùng bên phải giờ đây chứa nút Vị trí của tôi, giúp hiển thị vị trí hiện tại của thiết bị.
4.2 Bật Chế độ xem đường phố
Google Maps cung cấp Chế độ xem đường phố, chế độ xem toàn cảnh của một vị trí với các nút điều khiển để điều hướng dọc theo con đường được chỉ định. Chế độ xem đường phố không được phủ sóng trên toàn cầu.
Trong bước này, bạn bật ảnh toàn cảnh trong Chế độ xem đường phố. Ảnh toàn cảnh này sẽ được kích hoạt khi người dùng nhấn vào cửa sổ thông tin của một địa điểm yêu thích. Bạn cần làm hai việc:
- Phân biệt các điểm đánh dấu POI với các điểm đánh dấu khác, vì bạn muốn chức năng của ứng dụng chỉ hoạt động trên các điểm đánh dấu POI. Bằng cách này, bạn có thể khởi động Chế độ xem phố khi người dùng nhấn vào một cửa sổ thông tin POI nhưng không phải khi người dùng nhấn vào bất kỳ loại điểm đánh dấu nào khác.
Lớp Marker
bao gồm một phương thức setTag()
cho phép bạn đính kèm dữ liệu. (Dữ liệu có thể là bất kỳ nội dung nào mở rộng từ Object
). Bạn sẽ đặt một thẻ trên các điểm đánh dấu được tạo khi người dùng nhấp vào POI.
- Khi người dùng nhấn vào một cửa sổ thông tin được gắn thẻ trong
OnInfoWindowClickListener
, hãy thay thếMapFragment
bằngStreetViewPanoramaFragment
. (Mã bên dưới sử dụngSupportMapFragment
vàSupportStreetViewPanoramaFragment
để hỗ trợ các phiên bản Android dưới API 12.)
Nếu bất kỳ mảnh nào thay đổi trong thời gian chạy, thì bạn phải thêm các mảnh đó vào lớp Activity
chứa chứ không phải trong XML.
Gắn thẻ điểm đánh dấu địa điểm yêu thích
- Trong lệnh gọi lại
onPoiClick()
, hãy gọisetTag()
trênpoiMarker
. Truyền vào một chuỗi bất kỳ:
poiMarker.setTag("poi");
Thay thế SupportMapFragment tĩnh bằng một thực thể thời gian chạy
- Mở
activity_maps.xml
rồi thay đổi phần tử thành một bố cục khung sẽ đóng vai trò là vùng chứa cho các mảnh:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- Trong
onCreate()
trongMapsActivity
, hãy xoá mã tìmSupportMapFragment
theo mã nhận dạng vì không cònSupportMapFragment
tĩnh trong XML nữa. Thay vào đó, hãy tạo một thực thể thời gian chạy mới củaSupportMapFragment
bằng cách gọiSupportMapFragment.newInstance()
:
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
- Thêm mảnh vào
FrameLayout
bằng cách sử dụng giao dịch mảnh vớiFragmentManager
:
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, mapFragment).commit();
- Giữ dòng mã kích hoạt quá trình tải không đồng bộ của bản đồ:
mapFragment.getMapAsync(this);
Đặt OnInfoWindowClickListener và kiểm tra thẻ đánh dấu
- Tạo một mã giả lập phương thức trong
MapsActivity
có tên làsetInfoWindowClickToPanorama()
. Mã này sẽ lấyGoogleMap
làm đối số và trả vềvoid
:
private void setInfoWindowClickToPanorama(GoogleMap map) {}
- Đặt
OnInfoWindowClickListener
thànhGoogleMap
:
map.setOnInfoWindowClickListener(
new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
}
});
- Trong phương thức
onInfoWindowClick()
, hãy kiểm tra xem điểm đánh dấu có chứa thẻ chuỗi mà bạn đã đặt trong phương thứconPoiClick()
hay không:
if (marker.getTag() == "poi") {}
Thay thế SupportMapFragment bằng Support StreetViewẢnh toàn cảnh
- Trong trường hợp điểm đánh dấu chứa thẻ, hãy chỉ định vị trí cho ảnh toàn cảnh của Chế độ xem đường phố bằng cách sử dụng đối tượng
StreetViewPanoramaOptions
. Đặt thuộc tínhposition
của đối tượng thành vị trí của điểm đánh dấu đã chuyển sang:
StreetViewPanoramaOptions options =
new StreetViewPanoramaOptions().position(
marker.getPosition());
- Tạo một thực thể mới của
SupportStreetViewPanoramaFragment
, truyền vào đối tượngoptions
mà bạn đã tạo:
SupportStreetViewPanoramaFragment streetViewFragment
= SupportStreetViewPanoramaFragment
.newInstance(options);
- Bắt đầu giao dịch mảnh. Thay thế nội dung của vùng chứa mảnh bằng mảnh mới
streetViewFragment
. Thêm giao dịch vào ngăn xếp lui sao cho thao tác nhấn vào nút quay lại sẽ quay lạiSupportMapFragment
và không thoát khỏi ứng dụng:
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container,
streetViewFragment)
.addToBackStack(null).commit();
- Gọi cho
setInfoWindowClickToPanorama(mMap)
trongonMapReady()
sau cuộc gọi đếnsetPoiClick().
- Chạy ứng dụng. Phóng to một thành phố có phạm vi bao phủ của Chế độ xem phố, như Mountain View (trụ sở chính của Google), và tìm địa điểm yêu thích, chẳng hạn như công viên. Nhấn vào địa điểm yêu thích để đặt điểm đánh dấu và hiển thị cửa sổ thông tin. Nhấn vào cửa sổ thông tin để vào Chế độ xem đường phố cho vị trí của điểm đánh dấu. Nhấn nút quay lại để quay lại mảnh bản đồ.
7. Đoạn mã giải pháp
Mã giải pháp Wander
.
8. Thử thách lập trình
Thử thách: Nếu nhấn vào cửa sổ thông tin cho một địa điểm yêu thích ở một vị trí không có phạm vi bao phủ của Chế độ xem đường phố, bạn sẽ thấy một màn hình đen.
- Để kiểm tra xem Chế độ xem đường phố có ở một khu vực hay không, hãy triển khai lệnh gọi lại
OnStreetViewPanomaraReady
kết hợp vớiStreetViewPanorama.OnStreetViewPanoramaChangeListener
. - Nếu một khu vực đã chọn không thể xem Chế độ xem đường phố, hãy quay lại mảnh bản đồ và hiển thị lỗi.
9. Tóm tắt
- Để sử dụng API Maps, bạn cần có khoá API từ Google API Console.
- Trong Android Studio, việc sử dụng mẫu Hoạt động trên Google Maps sẽ tạo
Activity
với mộtSupportMapFragment
duy nhất trong bố cục của ứng dụng. Mẫu này cũng thêmACCESS_FINE_PERMISSION
vào tệp kê khai ứng dụng, 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
trong thời gian chạy, hãy sử dụng phương thức GoogleMap.setMapType()
. Google Maps có thể là một trong những loại bản đồ sau đây:
- Thông thường: Bản đồ đường thông thường. Hiển thị đường, một số đối tượng địa lý do con người xây dựng và các đối tượng tự nhiên quan trọng như sông. Nhãn đường và đối tượng địa lý cũng xuất hiện.
- Kết hợp: Dữ liệu ảnh chụp vệ tinh có thêm bản đồ đường bộ. Nhãn đường và đối tượng địa lý cũng xuất hiện.
- Vệ tinh: Dữ liệu ảnh chụp. Nhãn đường và đối tượng địa lý không hiển thị.
- Địa hình: Dữ liệu địa hình. Bản đồ bao gồm màu sắc, đường viền, nhãn và 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 đồ.
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 với thông tin về vị trí.
- Theo mặc định, địa điểm ưa thích (POI) xuất hiện trên bản đồ cơ sở 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.
- Ngoài ra, địa điểm yêu thích của doanh nghiệp (cửa hàng, nhà hàng, khách sạn, v.v.) sẽ xuất hiện theo mặc định trên bản đồ khi loại bản đồ là
normal
. - Bạn có thể thu thập lượt nhấp vào địa điểm yêu thích bằng cách sử dụng
OnPoiClickListener
. - Bạn có thể thay đổi giao diện trực quan của hầu hết các thành phần trên Google Maps bằng cách sử dụ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ể tuỳ chỉnh điểm đánh dấu của mình 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 hình ảnh tuỳ 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 vào 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. Truyền đối tượng này vào phương thứcGoogleMap.addGroundOverlay()
để đặt lớp phủ vào bản đồ. - Miễn là ứng dụng của bạn có quyền
ACCESS_FINE_LOCATION
, bạn có thể bật tính năng theo dõi vị trí bằng phương thứcmMap.setMyLocationEnabled(true)
. - Chế độ xem đường phố của Google cung cấp chế độ xem toàn cảnh 360 độ từ các con đường được chỉ định trong toàn bộ khu vực bao phủ của nó.
- Sử dụng phương thức
StreetViewPanoramaFragment.newInstance()
để tạo một mảnh Chế độ xem đường phố mới. - Để chỉ định các tuỳ chọn cho khung hiển thị, hãy sử dụng đối tượng
StreetViewPanoramaOptions
. Truyền đối tượng vào phương thứcnewInstance()
.
10. Tìm hiểu thêm
Tài liệu về khái niệm có liên quan nằm trong 9.1: API Google Maps.
Tài liệu dành cho nhà phát triển Android:
- Bắt đầu sử dụng API Google Maps dành cho Android
- 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:
11. Bài tập về nhà
Phần này liệt kê các bài tập về nhà cho học viên của lớp học lập trình này trong phạm vi khoá học có người hướng dẫn. Người hướng dẫn phải thực hiện các việc sau đây:
- Giao bài tập về nhà nếu cần.
- Trao đổi với học viên về cách nộp bài tập về nhà.
- Chấm điểm bài tập về nhà.
Người hướng dẫn có thể sử dụng các đề xuất này ít hoặc nhiều tuỳ ý và nên giao cho học viên bất kỳ bài tập về nhà nào khác mà họ cảm thấy phù hợp.
Nếu bạn đang tự học các lớp học lập trình, hãy sử dụng những bài tập về nhà này để kiểm tra kiến thức của mình.
Tạo và chạy ứng dụng
- Tạo một ứng dụng mới sử dụng mẫu Hoạt động trên Google Maps để tải Google Maps khi ứng dụng khởi chạy.
- Khi Google Maps được tải, hãy di chuyển camera đến vị trí trường học, vị trí nhà của bạn hoặc một vị trí khác có ý nghĩa đối với bạn.
- Thêm hai điểm đánh dấu vào bản đồ, một điểm đánh dấu tại vị trí trường học của bạn và một điểm đánh dấu tại nhà riêng hoặc một vị trí quan trọng khác.
- Tuỳ chỉnh biểu tượng đ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 hình ảnh tuỳ chỉnh.
Gợi ý: Xem tài liệu về onMapReady (GoogleMap googleMap)
.
Trả lời các câu hỏi sau
Câu hỏi 1
Phương thức nào được gọi khi bản đồ được tải và sẵn sàng để sử dụng trong ứng dụng?
onMapReady (
GoogleMap
googleMap)
onMapLoaded (
GoogleMap
googleMap)
onMapCreate (
GoogleMap
googleMap)
onMapInitialize (
GoogleMap
googleMap)
Câu hỏi 2
Bạn có thể sử dụng thành phần Android nào để đưa Google Maps vào ứng dụng của mình?
MapView
vàMapFragment
MapFragment
vàMapActivity
MapView
vàMapActivity
- Chỉ có
MapFragment
Câu hỏi 3
API Google Maps dành cho Android cung cấp những loại bản đồ nào?
- Thông thường, kết hợp, địa hình, vệ tinh và lộ trình
- Bình thường, kết hợp, địa hình, vệ tinh và "không có"
- Kết hợp, địa hình, vệ tinh, lộ trình và "không có"
- Bình thường, địa hình, vệ tinh, bản đồ hình ảnh và "không có"
Câu hỏi 4
Bạn triển khai giao diện nào để thêm chức năng nhấp vào địa điểm yêu thích (POI)?
GoogleMap.OnPoiListener
GoogleMap.OnPoiClickListener
GoogleMap.OnPoiClick
GoogleMap.OnPoiClicked
Gửi ứng dụng của bạn để được chấm điểm
Hướng dẫn dành cho học viên
Kiểm tra để đảm bảo ứng dụng có các đặc điểm sau:
- Khi ứng dụng được khởi chạy, Google Maps được hiển thị chính xác, cho biết rằng khoá API đã được tạo đúng cách.
- Sau khi Google Maps tải xong, camera sẽ di chuyển đến vị trí nhà riêng hoặc trường học của học sinh. Trong mã, bước này sẽ xảy ra trong phương thức gọi lại
onMapReady (GoogleMap googleMap)
. - Điểm đánh dấu xuất hiện ở vị trí trường học của học viên và một vị trí khác, chẳng hạn như nhà của học viên.
- Hai điểm đánh dấu này được tuỳ chỉnh. Ví dụ: điểm đánh dấu sử dụng màu khác với màu đỏ mặc định hoặc sử dụng biểu tượng tuỳ chỉnh.
12. Lớp học lập trình tiếp theo
Để xem tất cả lớp học lập trình trong khoá đào tạo Phát triển Android nâng cao, hãy truy cập vào trang đích của Lớp học lập trình phát triển Android nâng cao.