Android 09.1 nâng cao: Google Maps

1. Chào mừng bạn

Lớp học lập trình này nằm trong khoá học đào tạo Phát triển Android nâng cao do Nhóm đào tạo Google Developers xây dựng. Bạn sẽ nhận được nhiều giá trị nhất qua 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 thông tin chi tiết đầy đủ về khoá học, hãy xem phần Tổng quan về khoá học Phát triển Android nâng cao.

Giới thiệu

Khi tạo ứng dụng bằng Google Maps, bạn có thể thêm các 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 chế độ kiểm soát giao diện người dùng mạnh mẽ, tính năng theo dõi vị trí và điểm đánh dấu vị trí. Bạn có thể tăng 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 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 các trò chơi gắn liền với thế giới thực, chẳng hạn như Pokemon Go.

Trong bài thực hà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 vào ứng dụng của bạn.
  • Hiển thị nhiều loại bản đồ.
  • Tạo kiểu cho Google Maps.
  • Thêm điểm đánh dấu vào bản đồ.
  • Cho phép người dùng đặt một điểm đánh dấu trên một đị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 có Google Maps được nhúng.
  • 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, kiểu và tính năng 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 bài thực hành này, bạn sẽ tạo ứng dụng Wander, đây là một Google Maps có kiểu. Ứ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ố.

Bản đồ Google có phong cách riêng

Chế độ xem đường phố của Google trong một ứng dụng Android

3. Nhiệm vụ 1. Thiết lập dự án và lấy khoá API

API Google Maps (chẳng hạn như Places API) yêu cầu phải có khoá API. Để lấy khoá API, bạn phải đăng ký dự án của mình trong Google API Console. Khoá API được liên kết với một chứng chỉ kỹ thuật số, chứng chỉ này 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 bài viết Ký ứng dụng.

Trong bài thực hành này, bạn sẽ sử dụng khoá API cho chứng chỉ gỡ lỗi. Theo thiết kế, chứng chỉ gỡ lỗi không an toàn, như mô tả trong phần Ký bản gỡ lỗi. Các ứng dụng Android đã xuất bản sử dụng API Google Maps cần có 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 có một mẫu Google Maps Activity (Hoạt động trên Google Maps) giúp tạo mã mẫu hữu ích. Mã mẫu bao gồm một tệp google_maps_api.xml chứa một đườ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

  1. Tạo một dự án Android Studio mới.
  2. Đặt tên cho ứng dụng mới là "Wander". Chấp nhận các giá trị mặc định cho đến khi bạn chuyển đến trang Thêm một hoạt động.
  3. Chọn mẫu Hoạt động trên Google Maps.
  4. Giữ nguyên Tên hoạt độngTên bố cục mặc định.
  5. Thay đổi Tiêu đề thành "Khám phá" rồi nhấp vào 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 dùng tệp cấu hình này để lưu giữ khoá API. Mẫu này tạo ra hai tệp google_maps_api.xml: một cho gỡ lỗi và một cho phát hành. Tệp cho khoá API của chứng chỉ gỡ lỗi nằm trong src/debug/res/values. Tệp cho khoá API của chứng chỉ phát hành nằm trong src/release/res/values. Trong bài thực hà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 fragment 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ể thêm SupportMapFragment vào tệp bố cục bằng cách sử dụng thẻ <fragment> trong bất kỳ ViewGroup nào, với một thuộc tính bổ sung:

android:name="com.google.android.gms.maps.SupportMapFragment"

MapsActivity.java

Tệp MapsActivity.java sẽ 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 Maps. 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, cho biết rằng bản đồ đã được tải.

1.2 Lấy khoá API

  1. Mở phiên bản gỡ lỗi của tệp google_maps_api.xml.

Tệp này có chứa một bình luận 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.

  1. Sao chép và dán URL vào trình duyệt.
  2. Làm theo lời nhắc để tạo một dự án trong Bảng điều khiển API của Google. Do các tham số trong URL được cung cấp, API Console biết cách tự động bật Google Maps Android API
  3. Tạo một khoá API rồi nhấp vào Hạn chế khoá để hạn chế việc sử dụng khoá cho các ứng dụng Android. Khoá API được tạo phải bắt đầu bằng AIza.
  4. Trong tệp google_maps_api.xml, hãy dán khoá vào chuỗi google_maps_key tại vị trí có nội dung YOUR_KEY_HERE.
  5. Chạy ứng dụng. Bạn sẽ 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 được đặt ở Sydney, Úc. (Điểm đánh dấu Sydney là một phần của mẫu và bạn sẽ thay đổi điểm đánh dấu này sau.)

4. Nhiệm vụ 2. Thêm các loại bản đồ và điểm đánh dấu

Google Maps có nhiều 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 đồ đến vị trí nhà riêng của mình. Sau đó, bạn thêm chế độ hỗ trợ cho các điểm đánh dấu. Các điểm đánh dấu này cho biết vị trí duy nhất trên bản đồ và có thể có nhãn.

2.1 Thêm các loại bản đồ

Loại bản đồ mà người dùng muốn xem phụ thuộc vào loại thông tin họ cần. Khi sử dụng bản đồ để tìm đường trong ô tô, bạn nên xem rõ tên đường phố. Khi đi bộ đường dài, có lẽ bạn quan tâm hơn đến việc bạn phải leo bao nhiêu để lên đến đỉnh núi. Trong bước 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 đồ.

  1. Để tạo một 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 > Android Resource File (Mới > Tệp tài nguyên Android).
  2. 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.
  3. Thay thế mã trong tệp mới bằng đoạn mã sau để tạo các lựa chọn về bản đồ. Loại bản đồ "none" (không có) bị bỏ qua, vì "none" dẫn đến việc không có bản đồ nào.
<?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>
  1. Tạo tài nguyên chuỗi cho các thuộc tính title.
  2. Trong tệp MapsActivity, hãy thay đổi lớp để mở rộng lớp AppCompatActivity thay vì mở rộng lớp FragmentActivity. Việc sử dụng AppCompatActivity sẽ hiện thanh ứng dụng và do đó, trình đơn sẽ xuất hiện.
  3. Trong MapsActivity, hãy ghi đè phương thức onCreateOptionsMenu() và tăng cường tệp map_options:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.map_options, menu);
   return true;
}
  1. Để thay đổi loại bản đồ, hãy dùng phương thức setMapType() trên đối tượng GoogleMap, truyền vào một trong các hằng số loại bản đồ.

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 mục trong 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);
       }
    }
  1. Chạy ứng dụng. Sử dụng trình đơn trong thanh ứng dụng để thay đổi loại bản đồ. 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 ra. Lệnh gọi lại mặc định cũng tạo hiệu ứng cho bản đồ để di chuyển đến Sydney. Trong bước này, bạn sẽ di chuyển bản đồ đến vị trí nhà riêng mà không cần đặt điểm đánh dấu, sau đó phóng to đến cấp độ mà bạn chỉ định.

  1. Trong phương thức onMapReady(), hãy xoá mã đặt điểm đánh dấu ở Sydney và di chuyển camera.
  2. Truy cập vào www.google.com/maps trong trình duyệt rồi tìm nhà riêng của bạn.
  3. 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ỏ sẽ bật lên kèm theo thông tin vị trí, bao gồm cả vĩ độ và kinh độ.

  1. Tạo một đối tượng LatLng mới có tên là home. Trong đối tượng LatLng, hãy sử dụng toạ độ mà bạn tìm thấy trên Google Maps trong trình duyệt.
  2. Tạo một biến float có tên là zoom rồi đặt biến đó thành mức thu phóng ban đầu mà bạn muốn. Danh sách sau đây giúp bạn hình dung được mức độ chi tiết mà mỗi cấp độ thu phóng hiển thị:
  • 1: Thế giới
  • 5: Khối đất/lục địa
  • 10: Thành phố
  • 15: Đường phố
  • 20: Toà nhà
  1. Tạo đối tượng CameraUpdate bằng CameraUpdateFactory.newLatLngZoom(), truyền vào đối tượng LatLng và biến zoom. Xoay và thu phóng camera bằng cách gọi moveCamera() trên đối tượng GoogleMap, truyền vào đối tượng CameraUpdate mới:
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
  1. Chạy ứng dụng. Bản đồ sẽ chuyển đến nhà của bạn và phóng to đến mức mong muốn.

2.3 Thêm điểm đánh dấu trên bản đồ

Google Maps có thể chọn một vị trí bằng điểm đánh dấu mà 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 tiêu chuẩn: Điểm đánh dấu trên Google Maps

Bạn có thể mở rộng các điểm đánh dấu để hiển thị thông tin theo bối cảnh trong cửa sổ thông tin.

Ở bước này, bạn sẽ 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 thêm một InfoWindow để hiển thị toạ độ của điểm đánh dấu khi người dùng nhấn vào điểm đánh dấu.

Cửa sổ thông tin cho một ghim được thả

  1. Tạo một phương thức sơ khai trong MapsActivity có tên là setMapLongClick(). Phương thức này nhận final GoogleMap làm đối số và trả về void:
private void setMapLongClick(final GoogleMap map) {}
  1. Sử dụng phương thức setOnMapLongClickListener() của đối tượng GoogleMap để đặt một điểm đánh dấu tại vị trí người dùng chạm và giữ. Truyền vào một thực thể mới của OnMapLongClickListener ghi đè phương thức onMapLongClick(). Đối số đến là một đối tượng LatLng 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) {
       }
   });
}
  1. Trong onMapLongClick(), hãy gọi phương thức addMarker(). Truyền vào một đối tượng MarkerOptions mới có vị trí được đặt thành LatLng đã truyền vào:
map.addMarker(new MarkerOptions().position(latLng));
  1. Gọi setMapLongClick() ở cuối phương thức onMapReady(). Truyền trong mMap.
  2. 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í.
  3. Nhấn vào điểm đánh dấu để đưa đ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 của 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.

Cách thêm cửa sổ thông tin cho điểm đánh dấu:

  1. Trong đối tượng MarkerOptions, hãy đặt trường title và trường snippet.
  2. Trong onMapLongClick(), hãy đặt trường title thành "Ghim đã thả". Đặt trường snippet thành toạ độ vị trí bên trong phương thức addMarker().
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));
   }
});
  1. Chạy ứng dụng. Chạm và giữ trên 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.

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 biểu tượng tương ứng. POI bao gồm công viên, trường học, toà nhà chính phủ và nhiều đị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 đồ. POI 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.

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 sẽ đặt ngay một điểm đánh dấu trên bản đồ, thay vì chờ một thao tác chạm và giữ. Trình nghe lượt nhấp cũng hiển thị cửa sổ thông tin chứa tên của địa điểm yêu thích.

Điểm đánh dấu địa điểm yêu thích

  1. Tạo một phương thức sơ khai trong MapsActivity có tên là setPoiClick(). Phương thức này nhận final GoogleMap làm đối số và trả về void:
private void setPoiClick(final GoogleMap map) {}
  1. Trong phương thức setPoiClick(), hãy đặt một OnPoiClickListener trên GoogleMap đã truyền vào:
map.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
   @Override
   public void onPoiClick(PointOfInterest poi) {
   }
});
  1. Trong phương thức onPoiClick(), hãy đặt một điểm đánh dấu tại vị trí của POI. Đặt tiêu đề thành tên của địa điểm yêu thích. 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);
}
  1. Gọi showInfoWindow() trên poiMarker để hiển thị ngay cửa sổ thông tin.
poiMarker.showInfoWindow();
  1. Gọi setPoiClick() ở cuối onMapReady(). Truyền trong mMap.
  2. Chạy ứng dụng của bạn 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 một đị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 một cửa sổ thông tin.

5. Nhiệm vụ 3. Tạo kiểu cho bản đồ

Bạn có thể tuỳ chỉnh Google Maps theo nhiều cách để bản đồ có diện mạo độc đáo.

Bạn có thể tuỳ chỉnh đố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 tuỳ chỉnh mọi mảnh khác. Tuy nhiên, trong bước này, bạn sẽ tuỳ chỉnh giao diện của 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à tuỳ chỉnh các điểm đánh dấu. Bạn cũng có thể thêm một GroundOverlay vào vị trí nhà riêng. Biểu tượng này sẽ điều chỉnh kích thước và xoay theo bản đồ.

3.1 Thêm kiểu vào bản đồ

Để tạo kiểu tuỳ chỉnh cho bản đồ, bạn tạo một tệp JSON chỉ định cách hiển thị các đối tượng trên bản đồ.Bạn không cần 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 đồ. Trong bài tập thực hành này, bạn sẽ tạo kiểu cho bản đồ ở "chế độ ban đêm", tức là bản đồ sẽ sử dụng màu sắc mờ và độ tương phản thấp để sử dụng vào ban đêm.

  1. Truy cập vào https://mapstyle.withgoogle.com/ trong trình duyệt.
  2. Chọn Tạo kiểu.
  3. Chọn giao diện Ban đêm.
  4. Nhấp vào Tuỳ chọn khác ở cuối trình đơn.
  5. Ở cuối danh sách Loại đối tượng, hãy chọn Nước > Tô màu. Thay đổi màu nước thành màu xanh dương đậm (ví dụ: #160064).
  6. Nhấp vào Hoàn tất. Sao chép mã JSON trong cửa sổ bật lên xuất hiện.
  7. Trong Android Studio, hãy tạo một thư mục tài nguyên có tên là raw trong thư mục res. Tạo một tệp trong res/raw có tên là map_style.json.
  8. Dán mã JSON vào tệp tài nguyên mới.
  9. Để đặt kiểu JSON cho bản đồ, hãy gọi setMapStyle() trên đối tượng GoogleMap. Truyền vào một đối tượng MapStyleOptions, đối tượng này sẽ tải tệp JSON. Phương thức setMapStyle() trả về một giá trị boolean cho biết việc tạo kiểu có thành công hay không. Nếu không tải được tệp, phương thức này sẽ gửi một Resources.NotFoundException.

Sao chép mã sau vào phương thức onMapReady() để tạo kiểu cho bản đồ. Bạn có thể cần tạo một 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);
     }
  1. Chạy ứng dụng của bạn. Kiểu mới sẽ xuất hiện khi bản đồ ở chế độ normal.

Google Maps ở chế độ ban đêm

3.2 Tạo kiểu cho điểm đánh dấu

Bạn có thể cá nhân hoá bản đồ hơn nữa bằng cách tạo kiểu cho các điểm đánh dấu trên bản đồ. Trong bước này, bạn sẽ thay đổi các điểm đánh dấu màu đỏ mặc định cho phù hợp với bảng phối màu ở chế độ ban đêm.

  1. Trong phương thức onMapLongClick(), hãy thêm dòng mã sau vào hàm khởi tạo MarkerOptions() để sử dụng điểm đánh dấu mặc định nhưng thay đổi màu thành xanh dương:
.icon(BitmapDescriptorFactory.defaultMarker
       (BitmapDescriptorFactory.HUE_BLUE))
  1. 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.

Xin lưu ý rằng các điểm đánh dấu địa đ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().

3.3 Thêm lớp phủ

Một cách để tuỳ chỉnh Google Maps là vẽ lên trên bản đồ. Kỹ thuật này 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ư các điểm câu cá nổi tiếng. Chúng tôi hỗ trợ 3 loại lớp phủ:

  • Hình dạng: Bạn có thể thêm đường nhiều đoạn, đa giácvòng tròn vào bản đồ.
  • Các đối tượng TileOverlay: Lớp phủ xếp kề xác định một tập hợp hình ảnh được thêm vào đầu các ô bản đồ cơ sở. Lớp phủ ô rất hữu ích khi bạn muốn thêm nhiều hình ảnh vào bản đồ. Một lớp phủ xếp kề điển hình bao phủ một khu vực địa lý rộng lớn.
  • Đối tượng GroundOverlay: Lớp phủ trên mặt đất là một hình ảnh được cố định vào bản đồ. Không giống như điểm đánh dấu, lớp phủ mặt đất được định hướng theo bề mặt Trái Đất chứ không phải theo màn hình. Khi bạn xoay, nghiêng hoặc thu phóng bản đồ, hướng của hình ảnh sẽ thay đổi. Lớp phủ mặt đất rất hữu ích khi bạn muốn cố định một hình ảnh tại một khu vực trên bản đồ

Trong bước này, bạn sẽ thêm một lớp phủ mặt đất có hình dạng của Android vào vị trí nhà riêng của mình.

  1. Tải hình ảnh Android này xuống rồi lưu vào thư mục res/drawable.
  2. Trong onMapReady(), sau khi gọi để di chuyển camera về vị trí ban đầu, hãy tạo một đối tượng GroundOverlayOptions. Chỉ định đối tượng cho một biến có tên là homeOverlay:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions();
  1. Sử dụng phương thức BitmapDescriptorFactory.fromResource() để tạo một đối tượng BitmapDescriptor từ hình ảnh ở trên. Truyền đối tượng vào phương thức image() của đối tượng GroundOverlayOptions:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
    .image(BitmapDescriptorFactory.fromResource(R.drawable.android));
  1. Đặt thuộc tính position cho đối tượng GroundOverlayOptions bằng cách gọi phương thức position(). Truyền đối tượng home LatLngfloat 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 sẽ phù hợp:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
     .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
       .position(home, 100);
  1. Gọi addGroundOverlay() trên đối tượng GoogleMap. Truyền vào đối tượng GroundOverlayOptions của bạn:
mMap.addGroundOverlay(homeOverlay);
  1. Chạy ứng dụng. Phóng to vị trí nhà 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 sử dụng Google Maps để xem vị trí hiện tại của họ và 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 đồ mà không cần sử dụng thêm dữ liệu Location, bạn có thể dùng lớp dữ liệu vị trí.

Lớp dữ liệu vị trí sẽ 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í sẽ xuất hiện dưới dạng một chấm màu xanh dương nếu thiết bị đang đứng yên và dưới dạng một dấu nhọn màu xanh dương nếu thiết bị đang di chuyển.

Google Maps được tạo kiểu có tính năng theo dõi vị trí

Bạn có thể cung cấp thêm thông tin về một địa điểm bằng Chế độ xem đường phố của Google. Đây là ảnh toàn cảnh có thể điều hướng của một địa điểm cụ thể.

Trong tác vụ này, bạn sẽ 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ế độ Chế độ xem đường phố.

4.1 Bật tính năng theo dõi vị trí

Bạn chỉ cần một dòng mã để bật tính năng theo dõi vị trí trong Google Maps. Tuy nhiên, bạn phải đảm bảo rằng người dùng đã cấp quyền truy cập vào vị trí (bằng cách sử dụng mô hình quyền khi bắt đầu chạy).

Trong bước này, bạn yêu cầu cấp quyền truy cập thông tin vị trí và bật tính năng theo dõi vị trí.

  1. Trong tệp AndroidManifest.xml, hãy xác minh rằng quyền FINE_LOCATION đã có sẵn. Android Studio đã chèn quyền này khi bạn chọn mẫu Google Maps.
  2. Để 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.
  3. Xác định phương thức enableMyLocation(). Kiểm tra quyền ACCESS_FINE_LOCATION. Nếu được cấp quyền, 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);
   }
}
  1. Gọi enableMyLocation() từ lệnh gọi lại onMapReady() để bật lớp vị trí.
  2. Ghi đè phương thức onRequestPermissionsResult(). Nếu quyền được cấp, hãy gọi enableMyLocation():
@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;
           }
   }
}
  1. Chạy ứng dụng. Giờ đây, góc trên cùng bên phải sẽ có nút Vị trí của tôi. Nút này cho biết 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ố, là chế độ xem toàn cảnh về một địa điểm, có các nút điều khiển để di chuyển dọc theo một đường dẫn được chỉ định. Chế độ xem đường phố không có phạm vi phủ sóng toàn cầu.

Ở bước này, bạn sẽ bật một Ảnh toàn cảnh trong Chế độ xem đường phố đượ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 2 việc:

  1. 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ể bắt đầu Chế độ xem đường phố khi người dùng nhấn vào cửa sổ thông tin về một địa điểm yêu thích, nhưng không thể bắt đầu 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 cứ thứ gì mở rộng từ Object). Bạn sẽ đặt thẻ trên các điểm đánh dấu được tạo khi người dùng nhấp vào các địa điểm yêu thích.

  1. 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ằng StreetViewPanoramaFragment. (Đoạn mã dưới đây sử dụng SupportMapFragmentSupportStreetViewPanoramaFragment để 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, bạn phải thêm các mảnh đó vào lớp Activity chứa, chứ không phải tĩnh trong XML.

Gắn thẻ điểm đánh dấu địa điểm yêu thích

  1. Trong lệnh gọi lại onPoiClick(), hãy gọi setTag() trên poiMarker. 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

  1. 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 của bạn:
<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" />
  1. Trong onCreate() trong MapsActivity, hãy xoá mã tìm SupportMapFragment theo mã nhận dạng, vì không còn SupportMapFragment tĩnh nào trong XML. Thay vào đó, hãy tạo một phiên bản thời gian chạy mới của SupportMapFragment bằng cách gọi SupportMapFragment.newInstance():
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
  1. Thêm fragment vào FrameLayout bằng cách sử dụng một giao dịch fragment có FragmentManager:
getSupportFragmentManager().beginTransaction()
       .add(R.id.fragment_container, mapFragment).commit();
  1. Giữ lại dòng mã kích hoạt quá trình tải bản đồ không đồng bộ:
mapFragment.getMapAsync(this);

Đặt OnInfoWindowClickListener và kiểm tra thẻ điểm đánh dấu

  1. Tạo một phương thức sơ khai trong MapsActivity có tên là setInfoWindowClickToPanorama(). Phương thức này nhận GoogleMap làm đối số và trả về void:
private void setInfoWindowClickToPanorama(GoogleMap map) {}
  1. Đặt OnInfoWindowClickListener thành GoogleMap:
map.setOnInfoWindowClickListener(
       new GoogleMap.OnInfoWindowClickListener() {
           @Override
           public void onInfoWindowClick(Marker marker) {
           }
       });
  1. 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ức onPoiClick() hay không:
if (marker.getTag() == "poi") {}

Thay thế SupportMapFragment bằng SupportStreetViewPanoramaFragment

  1. 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 trong Chế độ xem đường phố bằng cách sử dụng đối tượng StreetViewPanoramaOptions. Đặt thuộc tính position của đối tượng thành vị trí của điểm đánh dấu được truyền vào:
StreetViewPanoramaOptions options =
       new StreetViewPanoramaOptions().position(
               marker.getPosition());
  1. Tạo một phiên bản mới của SupportStreetViewPanoramaFragment, truyền vào đối tượng options mà bạn đã tạo:
SupportStreetViewPanoramaFragment streetViewFragment
       = SupportStreetViewPanoramaFragment
       .newInstance(options);
  1. Bắt đầu một giao dịch fragment. Thay thế nội dung của vùng chứa fragment bằng fragment mới, streetViewFragment. Thêm giao dịch vào ngăn xếp lùi để thao tác nhấn nút quay lại sẽ chuyển về SupportMapFragment chứ không thoát khỏi ứng dụng:
getSupportFragmentManager().beginTransaction()
       .replace(R.id.fragment_container,
               streetViewFragment)
       .addToBackStack(null).commit();
  1. Gọi setInfoWindowClickToPanorama(mMap) trong onMapReady() sau khi gọi đến setPoiClick().
  2. Chạy ứng dụng. Phóng to một thành phố có phạm vi phủ sóng của Chế độ xem đường phố, chẳng hạn như Mountain View (trụ sở của Google) 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 POI để đặt điểm đánh dấu và hiện cửa sổ thông tin. Nhấn vào cửa sổ thông tin để chuyển sang chế độ xem đường phố cho vị trí của điểm đánh dấu. Nhấn nút quay lại để quay lại fragment bản đồ.

Chế độ xem đường phố của Google trong một ứng dụng Android

7. Đoạn mã giải pháp

Wander.

8. Thử thách lập trình

Vấn đề: Nếu nhấn vào cửa sổ thông tin của một địa điểm yêu thích ở nơi không có phạm vi phủ sóng của Chế độ xem đường phố, bạn sẽ thấy màn hình đen.

9. Tóm tắt

  • Để sử dụng Maps API, bạn cần có một khoá API từ Google API Console.
  • Trong Android Studio, việc sử dụng mẫu Google Maps Activity sẽ tạo ra một Activity có một SupportMapFragment duy nhất trong bố cục của ứng dụng. Mẫu này cũng thêm ACCESS_FINE_PERMISSION vào tệp kê khai ứng dụng, triển khai OnMapReadyCallback trong hoạt động của bạn và ghi đè phương thức onMapReady() bắt buộc.

Để thay đổi loại bản đồ của một GoogleMap trong thời gian chạy, hãy dùng phương thức GoogleMap.setMapType(). Google Maps có thể là một trong những loại bản đồ sau:

  • Bình thường: Bản đồ đường bộ thông thường. Cho thấy đường, một số công trình do con người xây dựng và các đặc điểm tự nhiên quan trọng như sông. Nhãn đường và nhãn đối tượng cũng xuất hiện.
  • Kết hợp: Dữ liệu ảnh vệ tinh có thêm bản đồ đường. Nhãn đường và đối tượng cũng xuất hiện.
  • Vệ tinh: Dữ liệu ảnh. Nhãn đường và đối tượng không xuất hiện.
  • Địa hình: Dữ liệu địa hình. Bản đồ này có màu sắc, đường viền và nhãn, cũng như hiệu ứng đổ bóng phối cảnh. Một số đường và nhãn cũng xuất hiện.
  • Không có**:** Không có bản đồ.

Giới thiệu về Google Maps:

  • Điểm đánh dấu là một chỉ báo cho một vị trí địa lý cụ thể.
  • Khi được nhấn, hành vi mặc định của điểm đánh dấu là hiển thị một cửa sổ thông tin có thông tin về vị trí.
  • Theo mặc định, các địa điểm yêu thích (POI) sẽ xuất hiện trên bản đồ cơ sở cùng với các biểu tượng tương ứng. POI bao gồm công viên, trường học, toà nhà chính phủ và nhiều địa điểm khác.
  • Ngoài ra, các địa điểm yêu thích của doanh nghiệp (cửa hàng, nhà hàng, khách sạn và nhiều đị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ể ghi lại các lượt nhấp vào các đị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 mọi phần tử trên Google Maps bằng Trình hướng dẫn tạo kiểu. Trình hướng dẫn tạo kiểu sẽ tạo một tệp JSON mà bạn truyền vào Google Maps bằng phương thức setMapStyle().
  • Bạn có thể tuỳ chỉnh đ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 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 đến phương thức GoogleMap.addGroundOverlay() để đặt lớp phủ cho 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ức mMap.setMyLocationEnabled(true).
  • Chế độ xem đường phố của Google cung cấp chế độ xem toàn cảnh 360 độ từ những con đường được chỉ định trong khu vực đưa tin.
  • Sử dụng phương thức StreetViewPanoramaFragment.newInstance() để tạo một fragment Chế độ xem đường phố mới.
  • Để chỉ định các lựa 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ức newInstance().

10. Tìm hiểu thêm

Tài liệu về khái niệm liên quan nằm trong phần 9.1: API Google Maps.

Tài liệu dành cho nhà phát triển Android:

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

  1. Tạo một ứng dụng mới sử dụng mẫu Google Maps Activity (Hoạt động trên Google Maps). Mẫu này sẽ tải Google Maps khi ứng dụng khởi chạy.
  2. Khi Google Maps tải xong, hãy di chuyển camera đến vị trí trường học, vị trí nhà hoặc một vị trí khác có ý nghĩa đối với bạn.
  3. Thêm 2 điểm đánh dấu vào bản đồ, một điểm tại vị trí trường học và một điểm tại nhà riêng hoặc một vị trí có ý nghĩa khác.
  4. 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 một hình ảnh tuỳ chỉnh.

Lưu ý: Hãy 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?

Câu hỏi 2

Bạn có thể sử dụng những thành phần Android nào để thêm Google Maps vào ứng dụng của mình?

  • MapViewMapFragment
  • MapFragmentMapActivity
  • MapViewMapActivity
  • Chỉ có MapFragment

Câu hỏi 3

Google Maps Android API cung cấp những loại bản đồ nào?

  • Bình thường, kết hợp, địa hình, vệ tinh và bản đồ đường đi
  • 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, bản đồ đường đi và "không có"
  • Bình thường, địa hình, vệ tinh, imagemap và "none"

Câu hỏi 4

Bạn triển khai giao diện nào để thêm chức năng khi nhấp vào một đị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 khởi chạy, Google Maps sẽ 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à hoặc trường học của học viên. Trong mã, bước này phải diễn ra trong phương thức gọi lại onMapReady (GoogleMap googleMap).
  • Các điểm đánh dấu xuất hiện tại 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à riêng của học viên.
  • Hai điểm đánh dấu này được tuỳ chỉnh. Ví dụ: các đ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ả cá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.