Android 09.1 nâng cao: Google Maps

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ố.

Một bản đồ Google được tạo kiểu

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à 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

  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 chế độ mặc định cho đến khi bạn truy cập vào trang Add an Activity (Thêm hoạt động).
  3. Chọn mẫu Hoạt động trên Google Maps.
  4. Giữ nguyên Activity Name (Tên hoạt động) và Layout Name (Tên bố cục) mặc định.
  5. 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

  1. 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.

  1. Sao chép và dán URL đó vào trình duyệt.
  2. 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
  3. 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.
  4. Trong tệp google_maps_api.xml, hãy dán khoá vào chuỗi google_maps_key cho biết YOUR_KEY_HERE.
  5. 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 đồ.

  1. Để 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.
  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 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>
  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 này để mở rộng lớp AppCompatActivity thay vì mở rộng lớp FragmentActivity. Việc sử dụng AppCompatActivity sẽ làm hiện thanh ứng dụng và do đó thanh ứng dụng cũng sẽ hiện trình đơ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 ánh xạ, hãy sử 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ố 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);
       }
    }
  1. 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.

  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 và tìm địa chỉ 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ỏ bật lên có thông tin vị trí, bao gồm 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 dùng toạ độ mà bạn tìm thấy trên Google Maps trong trình duyệt.
  2. 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ới
  • 5: Vùng đấ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 máy ảnh bằng cách gọi moveCamera() trên đối tượng GoogleMap, truyền đối tượng CameraUpdate mới:
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
  1. 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: Điểm đánh dấu trên Google Maps

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.

Cửa sổ thông tin về ghim được thả

  1. Tạo một mã giả lập phương thức trong MapsActivity có tên là setMapLongClick(). Mã này sẽ lấy 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 đ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ủ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. Bên 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 mMap vào.
  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 để đặ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:

  1. Trong đối tượng MarkerOptions, hãy thiết lập trường title và trường snippet.
  2. Trong onMapLongClick(), hãy đặt trường title thành "Đã thả ghim". Đặ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ả 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.

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

  1. Tạo một mã giả lập phương thức trong MapsActivity có tên là setPoiClick(). Mã này sẽ lấy 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 OnPoiClickListener trên GoogleMap được 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í 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);
}
  1. Gọi showInfoWindow() trên poiMarker để hiển thị cửa sổ thông tin ngay lập tức.
poiMarker.showInfoWindow();
  1. Gọi setPoiClick() vào cuối onMapReady(). Truyền mMap vào.
  2. 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.

  1. Hãy truy cập vào https://mapstyle.withgoogle.com/ trong trình duyệt của bạn.
  2. Chọn Tạo kiểu.
  3. Chọn giao diện Ban đêm.
  4. Nhấp vào Lựa 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 > Màu nền. Thay đổi màu của 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 hiện ra.
  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. Để thiết lập kiểu JSON thành 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 định kiểu thành công. Nếu không thể tải tệp, phương thức này sẽ gửi Resources.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);
     }
  1. Chạy ứng dụng. Kiểu mới sẽ hiển thị khi bản đồ ở chế độ normal.

Google Maps ở kiểu 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 đồ 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.

  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 màu 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.

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áchì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.

  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 lệnh 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 biến có tên là homeOverlay:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions();
  1. Sử dụng phương thức BitmapDescriptorFactory.fromResource() để tạo đố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 vào đố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 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:
mMap.addGroundOverlay(homeOverlay);
  1. 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.

Một 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 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í.

  1. Trong tệp AndroidManifest.xml, hãy xác minh rằng quyền FINE_LOCATION đã có. 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 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);
   }
}
  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. 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:

  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ể 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.

  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. (Mã bên dưới 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, 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

  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:
<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 trong XML nữa. Thay vào đó, hãy tạo một thực thể 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 mảnh vào FrameLayout bằng cách sử dụng giao dịch mảnh với FragmentManager:
getSupportFragmentManager().beginTransaction()
       .add(R.id.fragment_container, mapFragment).commit();
  1. 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

  1. Tạo một mã giả lập phương thức trong MapsActivity có tên là setInfoWindowClickToPanorama(). Mã này sẽ lấy 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 Support StreetViewẢnh toàn cảnh

  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 của 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 đã chuyển sang:
StreetViewPanoramaOptions options =
       new StreetViewPanoramaOptions().position(
               marker.getPosition());
  1. Tạo một thực thể 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 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ại SupportMapFragment và không thoát khỏi ứng dụng:
getSupportFragmentManager().beginTransaction()
       .replace(R.id.fragment_container,
               streetViewFragment)
       .addToBackStack(null).commit();
  1. Gọi cho setInfoWindowClickToPanorama(mMap) trong onMapReady() sau cuộc gọi đến setPoiClick().
  2. 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 đồ.

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

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.

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ộ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 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ức GoogleMap.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ức mMap.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ức newInstance().

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:

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 Hoạt động trên Google Maps để tải Google Maps khi ứng dụng khởi chạy.
  2. 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.
  3. 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.
  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 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?

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?

  • MapViewMapFragment
  • MapFragmentMapActivity
  • MapViewMapActivity
  • 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.