Zaawansowany Android 09.1: Mapy Google

1. Witamy

Ćwiczenie z programowania jest częścią kursu „Advanced Android Development” (Zaawansowanego programowania na urządzeniach z Androidem) opracowanego przez zespół szkoleń Google Developers. Najwięcej korzyści z tego kursu przyniesie Ci wykonanie po kolei kolejnych ćwiczeń z programowania.

Szczegółowe informacje o kursie znajdziesz w omówieniu zaawansowanego programowania na Androida.

Wprowadzenie

Podczas tworzenia aplikacji za pomocą Map Google możesz dodawać do nich takie funkcje, jak zdjęcia satelitarne, zaawansowane elementy interfejsu, śledzenie lokalizacji i znaczniki lokalizacji. Możesz zwiększyć wartość standardowych Map Google, wyświetlając informacje z własnego zbioru danych, takie jak lokalizacje znanych miejsc do wędkowania czy wspinaczki. Możesz też tworzyć gry powiązane ze światem rzeczywistym – np. Pokemon Go.

W praktyce tworzysz aplikację Mapy Google o nazwie Wander.

Co warto wiedzieć

Musisz znać:

  • Podstawowe funkcje Map Google.
  • Uprawnienia czasu działania.
  • Tworzenie, tworzenie i uruchamianie aplikacji w Android Studio.
  • Uwzględniam biblioteki zewnętrzne w pliku build.gradle.

Czego się nauczysz

  • Zintegruj Mapę Google ze swoją aplikacją.
  • Wyświetl różne typy map.
  • Nadaj styl Mapom Google.
  • Dodaj znaczniki do mapy.
  • Zezwalaj użytkownikowi na umieszczanie znacznika w ciekawym miejscu.
  • Włącz śledzenie lokalizacji.
  • Włącz Google Street View.

Jakie zadania wykonasz

  • Pobierz klucz interfejsu API z Konsoli interfejsów API Google i zarejestruj go w swojej aplikacji.
  • Utwórz aplikację Wander z umieszczoną Mapą Google.
  • Dodaj do swojej aplikacji niestandardowe funkcje, takie jak znaczniki, styl i śledzenie lokalizacji.
  • Włącz w aplikacji śledzenie lokalizacji i Street View.

2. Aplikacje ogółem

W tym praktycznym zadaniu tworzysz aplikację Wander, która jest stylizowaną na Mapę Google. Aplikacja Wander pozwala umieszczać znaczniki w wybranych lokalizacjach, sprawdzać swoją lokalizację w czasie rzeczywistym i podziwiać panoramy Street View.

Stylowa Mapa Google

Google Street View w aplikacji na Androida

3. Zadanie 1. Konfigurowanie projektu i uzyskiwanie klucza interfejsu API

Interfejs API Map Google, taki jak Places API, wymaga klucza API. Aby uzyskać klucz interfejsu API, zarejestruj swój projekt w Konsoli interfejsów API Google. Klucz interfejsu API jest powiązany z certyfikatem cyfrowym, który łączy aplikację z jej autorem. Więcej informacji o używaniu certyfikatów cyfrowych i podpisywaniu aplikacji znajdziesz w artykule Podpisywanie aplikacji.

W praktyce należy użyć klucza interfejsu API dla certyfikatu debugowania. Certyfikat debugowania jest z założenia niezabezpieczony, zgodnie z opisem w artykule Podpisywanie kompilacji do debugowania. Opublikowane aplikacje na Androida, które używają interfejsu API Map Google, wymagają drugiego klucza interfejsu API – klucza certyfikatu wersji. Więcej informacji o uzyskiwaniu certyfikatu wersji znajdziesz w artykule Uzyskiwanie klucza interfejsu API.

Android Studio zawiera szablon aktywności w Mapach Google, który generuje przydatny kod szablonu. Kod szablonu zawiera plik google_maps_api.xml zawierający link ułatwiający uzyskanie klucza interfejsu API.

1.1 Tworzenie projektu Wander za pomocą szablonu Map

  1. Utwórz nowy projekt w Android Studio.
  2. Nadaj aplikacji nazwę „Wander”. Zaakceptuj wartości domyślne, aż dojdziesz do strony Dodaj aktywność.
  3. Wybierz szablon Aktywność w Mapach Google.
  4. Pozostaw domyślne pola Activity Name (Nazwa aktywności) i Layout Name (Nazwa układu).
  5. Zmień Tytuł na „Wędrówka”. i kliknij Zakończ.

Android Studio tworzy kilka dodatkowych plików związanych z mapami:

google_maps_api**.xml**

W tym pliku konfiguracji przechowujesz klucz interfejsu API. Szablon wygeneruje 2 pliki google_maps_api.xml: 1 do debugowania i 1 dla wersji. Plik klucza interfejsu API certyfikatu debugowania znajduje się w lokalizacji src/debug/res/values. Plik klucza interfejsu API certyfikatu wersji znajduje się w lokalizacji src/release/res/values. W praktyce używamy tylko certyfikatu debugowania.

activity_maps.xml

Ten plik układu zawiera pojedynczy fragment, który wypełnia cały ekran. Klasa SupportMapFragment jest podklasą klasy Fragment. Możesz umieścić SupportMapFragment w pliku układu za pomocą tagu <fragment> w dowolnym elemencie ViewGroup, z dodatkowym atrybutem:

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

MapsActivity.java

Plik MapsActivity.java tworzy instancję klasy SupportMapFragment i używa metody getMapAsync() klasy do przygotowywania Map Google. Działanie zawierające SupportMapFragment musi implementować interfejs OnMapReadyCallback i metodę onMapReady() tego interfejsu. Metoda getMapAsync() zwraca obiekt GoogleMap, co oznacza, że mapa została wczytana.

1.2 Uzyskiwanie klucza interfejsu API

  1. Otwórz wersję do debugowania pliku google_maps_api.xml.

Plik zawiera komentarz z długim adresem URL. Parametry adresu URL zawierają konkretne informacje o aplikacji.

  1. Skopiuj URL i wklej go w przeglądarce.
  2. Aby utworzyć projekt w Konsoli interfejsów API Google, postępuj zgodnie z wyświetlanymi instrukcjami. Ze względu na parametry w podanym adresie URL konsola interfejsów API wie, że musi automatycznie włączyć interfejs API Map Google na Androida
  3. Utwórz klucz interfejsu API i kliknij Ogranicz klucz, aby ograniczyć możliwość używania klucza do aplikacji na Androida. Wygenerowany klucz interfejsu API powinien zaczynać się od AIza.
  4. W pliku google_maps_api.xml wklej klucz do ciągu znaków google_maps_key w miejscu, w którym znajduje się ciąg YOUR_KEY_HERE.
  5. Uruchom aplikację. W swojej aktywności masz umieszczoną mapę ze znacznikiem ustawionym w Sydney w Australii. (Znacznik Sydney jest częścią szablonu i możesz go później zmienić).

4. Zadanie 2. Dodawanie typów i znaczników map

W Mapach Google dostępnych jest kilka typów map: zwykłe, hybrydowe, satelitarne, terenowe i „brak”. W tym zadaniu dodasz pasek aplikacji z menu opcji, które umożliwia użytkownikowi zmianę typu mapy. Przenosisz lokalizację początkową mapy do swojej lokalizacji domowej. Następnie możesz dodać obsługę znaczników, które wskazują pojedyncze lokalizacje na mapie i mogą obejmować etykiety.

2.1 Dodawanie typów map

Typ mapy, której potrzebuje użytkownik, zależy od tego, jakich informacji potrzebuje. Podczas używania map do nawigacji w samochodzie nazwy ulic powinny być dobrze widoczne. Podczas wędrówki bardziej zależy Ci na tym, ile musisz się pokonać, aby dostać się na szczyt. W tym kroku dodasz pasek aplikacji z menu opcji, które umożliwia użytkownikowi zmianę typu mapy.

  1. Aby utworzyć nowy plik XML menu, kliknij prawym przyciskiem myszy katalog res i wybierz New > (Nowy >) Plik zasobów Androida.
  2. W oknie nadaj plikowi nazwę map_options. Jako typ zasobu wybierz Menu. Kliknij OK.
  3. Zastąp kod w nowym pliku poniższym kodem, aby utworzyć opcje mapy. Wartość „brak” typ mapy jest pomijany, ponieważ „none” (brak) spowoduje w ogóle brak mapy.
<?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. Utwórz zasoby w postaci ciągów znaków dla atrybutów title.
  2. W pliku MapsActivity zmień klasę, tak aby rozszerzała klasę AppCompatActivity zamiast rozszerzać klasę FragmentActivity. Jeśli użyjesz AppCompatActivity, wyświetli się pasek aplikacji, a tym samym menu.
  3. W pliku MapsActivity zastąp metodę onCreateOptionsMenu() i zwiększ rozmiar pliku map_options:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.map_options, menu);
   return true;
}
  1. Aby zmienić typ mapy, użyj metody setMapType() na obiekcie GoogleMap, przekazując jedną ze stałych typu mapy.

Zastąp metodę onOptionsItemSelected(). Wklej ten kod, aby zmienić typ mapy, gdy użytkownik wybierze jedną z opcji menu:

    @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. Uruchom aplikację. Aby zmienić typ mapy, użyj menu na pasku aplikacji. Zwróć uwagę, jak zmienia się wygląd mapy.

2.2 Przesuwanie domyślnej lokalizacji na mapie

Domyślnie wywołanie zwrotne onMapReady() zawiera kod, który umieszcza znacznik w Sydney w Australii, gdzie utworzono Mapy Google. Domyślne wywołanie zwrotne również animuje mapę, aby przesunąć ją do Sydney. W tym kroku mapa zostanie powiększona do lokalizacji domu bez umieszczania znacznika, a następnie powiększa się do określonego poziomu.

  1. W metodzie onMapReady() usuń kod, który umieszcza znacznik w Sydney i przesuwa kamerę.
  2. Otwórz w przeglądarce www.google.com/maps i znajdź swój dom.
  3. Kliknij lokalizację prawym przyciskiem myszy i wybierz Co tu jest?

U dołu ekranu pojawi się małe okno z informacjami o lokalizacji, w tym szerokością i długością geograficzną.

  1. Utwórz nowy obiekt LatLng o nazwie home. W obiekcie LatLng użyj współrzędnych znalezionych w Mapach Google w przeglądarce.
  2. Utwórz zmienną float o nazwie zoom i ustaw jej odpowiedni początkowy poziom powiększenia. Oto lista pokazująca poziom szczegółowości poszczególnych poziomów powiększenia:
  • 1: świat
  • 5: ląd/kontynent
  • 10: miasto
  • 15: ulice
  • 20: budynki
  1. Utwórz obiekt CameraUpdate za pomocą metody CameraUpdateFactory.newLatLngZoom(), przekazując do niej obiekt LatLng i zmienną zoom. Przesuń i powiększ kamerę, wywołując funkcję moveCamera() w obiekcie GoogleMap i przekazując nowy obiekt CameraUpdate:
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
  1. Uruchom aplikację. Mapa powinna przesunąć się do domu i powiększyć do wybranego poziomu.

2.3 Dodawanie znaczników mapy

Mapy Google mogą wskazać lokalizację za pomocą znacznika, które tworzysz za pomocą klasy Marker. Domyślny znacznik ma standardową ikonę Map Google: Znacznik Map Google

Możesz rozszerzyć znaczniki, aby pokazać informacje kontekstowe w oknach informacyjnych.

W tym kroku dodajesz znacznik, gdy użytkownik dotknie i przytrzyma lokalizację na mapie. Następnie dodaj element InfoWindow, który wyświetla współrzędne znacznika po jego kliknięciu.

Okno informacyjne dotyczące umieszczonej pinezki

  1. Utwórz w elemencie MapsActivity pośrednik metody o nazwie setMapLongClick(), który przyjmuje final GoogleMap jako argument i zwraca void:
private void setMapLongClick(final GoogleMap map) {}
  1. Użyj metody setOnMapLongClickListener() obiektu GoogleMap, aby umieścić znacznik w miejscu, w którym użytkownik go dotyka i przytrzymuje. Przekaż nowe wystąpienie OnMapLongClickListener, które zastąpi metodę onMapLongClick(). Argument przychodzący to obiekt LatLng zawierający współrzędne lokalizacji, którą kliknął użytkownik:
private void setMapLongClick(final GoogleMap map) {
   map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
       @Override
       public void onMapLongClick(LatLng latLng) {
       }
   });
}
  1. Wewnątrz funkcji onMapLongClick() wywołaj metodę addMarker(). Przekaż nowy obiekt MarkerOptions z pozycją ustawioną na przekazaną wartość LatLng:
map.addMarker(new MarkerOptions().position(latLng));
  1. Wywołaj funkcję setMapLongClick() na końcu metody onMapReady(). Podaj: mMap.
  2. Uruchom aplikację. Naciśnij i przytrzymaj mapę, by umieścić znacznik w wybranej lokalizacji.
  3. Kliknij znacznik, który będzie wyśrodkowany na ekranie.

Przyciski nawigacyjne wyświetlają się w lewym dolnym rogu ekranu, dzięki czemu użytkownik może w aplikacji Mapy Google przejść do oznaczonego miejsca.

Aby dodać okno informacyjne dla znacznika:

  1. W obiekcie MarkerOptions ustaw pola title i snippet.
  2. W programie onMapLongClick() ustaw w polu title wartość „Pinezka”. W polu snippet podaj współrzędne lokalizacji wewnątrz metody 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. Uruchom aplikację. Naciśnij i przytrzymaj mapę, by upuścić znacznik lokalizacji. Dotknij znacznika, aby wyświetlić okno informacyjne.

2.4 Dodawanie detektora ciekawych miejsc

Domyślnie ciekawe miejsca (POI) są wyświetlane na mapie wraz z odpowiednimi ikonami. Ciekawe miejsca to między innymi parki, szkoły i budynki urzędowe. Jeśli typ mapy jest ustawiony na normal, na mapie pojawiają się też ciekawe miejsca firm. Ważne miejsca związane z biznesem to firmy, takie jak sklepy, restauracje i hotele.

W tym kroku dodasz do mapy obiekt GoogleMap.OnPoiClickListener. Taki detektor od razu umieszcza znacznik na mapie, zamiast czekać na przytrzymaj. Detektor kliknięć wyświetla też okno informacyjne zawierające nazwę ciekawego miejsca.

Znacznik ciekawego miejsca

  1. Utwórz w elemencie MapsActivity pośrednik metody o nazwie setPoiClick(), który przyjmuje final GoogleMap jako argument i zwraca void:
private void setPoiClick(final GoogleMap map) {}
  1. W metodzie setPoiClick() ustaw wartość OnPoiClickListener w przekazywanych danych GoogleMap:
map.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
   @Override
   public void onPoiClick(PointOfInterest poi) {
   }
});
  1. W przypadku metody onPoiClick() umieść znacznik w lokalizacji ciekawego miejsca. Jako tytuł wpisz nazwę ciekawego miejsca. Zapisz wynik w zmiennej o nazwie poiMarker.
public void onPoiClick(PointOfInterest poi) {
   Marker poiMarker = mMap.addMarker(new MarkerOptions()
       .position(poi.latLng)
       .title(poi.name);
}
  1. Zadzwoń pod numer showInfoWindow() pod numerem poiMarker, aby natychmiast wyświetlić okno informacyjne.
poiMarker.showInfoWindow();
  1. Zadzwoń na nr setPoiClick() pod koniec onMapReady(). Podaj: mMap.
  2. Uruchom aplikację i znajdź ciekawe miejsce, np. park. Dotknij ciekawego miejsca, aby umieścić na nim znacznik i wyświetlić jego nazwę w oknie informacyjnym.

5. Zadanie 3. Nadaj styl mapie

Mapy Google możesz dostosowywać na wiele sposobów, nadając im niepowtarzalny wygląd.

Obiekt MapFragment możesz dostosować, korzystając z dostępnych atrybutów XML, tak jak w przypadku innych fragmentów. W tym kroku możesz jednak dostosować wygląd i styl zawartości obiektu MapFragment, korzystając z metod dotyczących obiektu GoogleMap. Za pomocą kreatora stylu online możesz dodać styl do mapy i dostosować znaczniki. Możesz też dodać do lokalizacji domu obiekt GroundOverlay, który skaluje i obraca się wraz z mapą.

3.1 Dodawanie stylu do mapy

Aby utworzyć niestandardowy styl mapy, wygenerujesz plik JSON, który określa sposób wyświetlania obiektów na mapie. Nie musisz tworzyć tego pliku JSON ręcznie. Google udostępnia kreator stylu, który generuje plik JSON po wybraniu wizualnego stylu mapy. W praktycznym kontekście można zmienić styl mapy na „tryb nocny”, co oznacza, że mapa jest używana w nocy i używa ciemnych kolorów i niskiego kontrastu.

  1. Otwórz w przeglądarce stronę https://mapstyle.withgoogle.com/.
  2. Wybierz Utwórz styl.
  3. Wybierz motyw Noc.
  4. U dołu menu kliknij Więcej opcji.
  5. U dołu listy Typ obiektu wybierz Woda > Wypełnij. Zmień kolor wody na ciemnoniebieski (np. #160064).
  6. Kliknij Zakończ. Skopiuj kod JSON z wyświetlonego wyskakującego okienka.
  7. W Android Studio utwórz w katalogu res katalog zasobów o nazwie raw. Utwórz w usłudze res/raw plik o nazwie map_style.json.
  8. Wklej kod JSON do nowego pliku zasobów.
  9. Aby ustawić styl JSON na mapę, wywołaj setMapStyle() w obiekcie GoogleMap. Przekazuj obiekt MapStyleOptions, który wczytuje plik JSON. Metoda setMapStyle() zwraca wartość logiczną wskazującą, czy styl został zastosowany. Jeśli nie można wczytać pliku, metoda zgłasza Resources.NotFoundException.

Skopiuj poniższy kod do metody onMapReady(), aby określić styl mapy. Konieczne może być utworzenie ciągu TAG na potrzeby instrukcji dziennika:

     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. Uruchom aplikację. Nowy styl powinien być widoczny, gdy mapa jest w trybie normal.

Mapa Google w trybie nocnym

3.2 Określanie stylu znacznika

Możesz jeszcze bardziej spersonalizować mapę, określając styl znaczników. W tym kroku zmienisz domyślne czerwone znaczniki, aby pasowały do schematu kolorów trybu nocnego.

  1. W metodzie onMapLongClick() dodaj ten wiersz kodu do konstruktora MarkerOptions(), by użyć znacznika domyślnego, ale zmienić jego kolor na niebieski:
.icon(BitmapDescriptorFactory.defaultMarker
       (BitmapDescriptorFactory.HUE_BLUE))
  1. Uruchom aplikację. Znaczniki, które umieścisz, będą miały odcień niebieski, co bardziej pasuje do motywu trybu nocnego w aplikacji.

Znaczniki ciekawych miejsc nadal są czerwone, ponieważ styl do metody onPoiClick() nie został dodany.

3.3 Dodawanie nakładki

Jednym ze sposobów dostosowywania Map Google jest rysowanie na niej. Ta technika jest przydatna, jeśli chcesz wyróżnić konkretny rodzaj lokalizacji, np. popularne łowiska. Obsługiwane są 3 typy nakładek:

  • Kształty: do mapy możesz dodawać linie łamane, wielokąty i okręgi.
  • Obiekty TileOverlay: nakładka z kafelkami definiuje zestaw obrazów dodawanych na podstawowych kafelkach mapy. Nakładki z kafelkami są przydatne, gdy chcesz dodać do mapy rozległe zdjęcia. Typowa nakładka z kafelkami pokrywa duży obszar geograficzny.
  • GroundOverlay obiekty: nakładka na ziemi to obraz umieszczony na stałe na mapie. W przeciwieństwie do znaczników nakładki na powierzchni są zorientowane na powierzchnię Ziemi, a nie na ekran. Obracanie, przechylanie lub powiększanie mapy powoduje zmianę orientacji obrazu. Nakładki na powierzchni są przydatne, gdy chcesz poprawić pojedynczy obraz w jednym obszarze mapy

W tym kroku dodajesz do lokalizacji domu nakładkę na ziemi w kształcie Androida.

  1. Pobierz ten obraz Androida i zapisz go w folderze res/drawable.
  2. W onMapReady() po wywołaniu przeniesienia kamery do pozycji wyjściowej utwórz obiekt GroundOverlayOptions. Przypisz obiekt do zmiennej o nazwie homeOverlay:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions();
  1. Użyj metody BitmapDescriptorFactory.fromResource(), aby utworzyć obiekt BitmapDescriptor na podstawie powyższego obrazu. Przekaż obiekt do metody image() obiektu GroundOverlayOptions:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
    .image(BitmapDescriptorFactory.fromResource(R.drawable.android));
  1. Ustaw właściwość position dla obiektu GroundOverlayOptions, wywołując metodę position(). Przekaż obiekt LatLng home i float dla szerokości w metrach żądanej nakładki. W tym przykładzie szerokość 100 m się sprawdza:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
     .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
       .position(home, 100);
  1. Wywołaj funkcję addGroundOverlay() w obiekcie GoogleMap. Przekaż obiekt GroundOverlayOptions:
mMap.addGroundOverlay(homeOverlay);
  1. Uruchom aplikację. Powiększ lokalizację domu, a obraz Androida pojawi się jako nakładka.

6. Zadanie 4. Włącz śledzenie lokalizacji i Street View

Użytkownicy często używają Map Google, by sprawdzić swoją aktualną lokalizację. Możesz też sprawdzić lokalizację urządzenia za pomocą interfejsu Location Services API. Aby wyświetlić na mapie lokalizację urządzenia bez dalszego korzystania z danych Location, możesz użyć warstwy danych o lokalizacji.

Warstwa danych o lokalizacji dodaje przycisk Moja lokalizacja w prawym górnym rogu mapy. Gdy użytkownik kliknie przycisk, mapa zostanie wyśrodkowana na lokalizacji urządzenia. Lokalizacja jest wyświetlana jako niebieska kropka, jeśli urządzenie jest nieruchome, oraz niebieska szewron, gdy urządzenie jest w ruchu.

Stylowa mapa Google ze śledzeniem lokalizacji

Możesz podać dodatkowe informacje o danej lokalizacji, korzystając z Google Street View – zdjęcia panoramicznego, którego można użyć do nawigacji.

W tym zadaniu włączysz warstwę danych o lokalizacji i funkcję Street View, dzięki czemu, gdy użytkownik kliknie okno informacyjne ze znacznikiem ciekawego miejsca, mapa przejdzie w tryb Street View.

4.1 Włączanie śledzenia lokalizacji

Aby włączyć śledzenie lokalizacji w Mapach Google, wystarczy wpisać jeden wiersz kodu. Musisz jednak upewnić się, że użytkownik przyznał dostęp do lokalizacji (korzystając z modelu uprawnień czasu działania).

W tym kroku prosisz o dostęp do lokalizacji i włączysz śledzenie lokalizacji.

  1. Sprawdź, czy w pliku AndroidManifest.xml znajduje się uprawnienie FINE_LOCATION. Android Studio wstawił to uprawnienie podczas wybierania szablonu Map Google.
  2. Aby włączyć śledzenie lokalizacji w swojej aplikacji, utwórz w MapsActivity metodę o nazwie enableMyLocation(), która nie przyjmuje żadnych argumentów i nie zwraca niczego.
  3. Zdefiniuj metodę enableMyLocation(). Sprawdź, czy masz uprawnienie ACCESS_FINE_LOCATION. Po przyznaniu uprawnień włącz warstwę lokalizacji. W przeciwnym razie poproś o uprawnienie:
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. Wywołaj funkcję enableMyLocation() z wywołania zwrotnego onMapReady(), aby włączyć warstwę lokalizacji.
  2. Zastąp metodę onRequestPermissionsResult(). Jeśli uprawnienia zostały przyznane, wywołaj funkcję 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. Uruchom aplikację. W prawym górnym rogu znajduje się teraz przycisk Moja lokalizacja, który pozwala określić bieżącą lokalizację urządzenia.

4.2 Włączanie Street View

W Mapach Google dostępna jest usługa Street View, czyli panoramiczny widok lokalizacji z elementami sterującymi umożliwiającymi nawigację po wyznaczonej ścieżce. Street View nie jest dostępne na całym świecie.

W tym kroku możesz włączyć panoramę Street View, która będzie aktywowana, gdy użytkownik kliknie okno informacyjne ciekawego miejsca. Musisz zrobić 2 czynności:

  1. Odróżnij znaczniki ciekawych miejsc od innych znaczników, ponieważ chcesz, aby funkcje aplikacji działały tylko w przypadku tych miejsc. W ten sposób można uruchamiać funkcję Street View po kliknięciu przez użytkownika okna informacyjnego ciekawego miejsca, ale nie po kliknięciu przez użytkownika innego rodzaju znacznika.

Klasa Marker zawiera metodę setTag(), która umożliwia dołączanie danych. (dane mogą być dowolne z okresu od Object). Umieszczasz tag na znacznikach tworzonych, gdy użytkownicy klikają ciekawe miejsca.

  1. Gdy użytkownik kliknie otagowane okno informacyjne w elemencie OnInfoWindowClickListener, zastąp MapFragment elementem StreetViewPanoramaFragment. (Poniższy kod korzysta z interfejsów SupportMapFragment i SupportStreetViewPanoramaFragment do obsługi Androida w wersji starszej niż 12).

Jeśli którykolwiek z fragmentów zmieni się w czasie działania, musisz dodać go w klasie Activity, a nie statycznie w kodzie XML.

Dodawanie tagów do znacznika ciekawego miejsca

  1. W wywołaniu zwrotnym onPoiClick() zadzwoń pod numer setTag() (poiMarker). Przekaż dowolny dowolny ciąg:
poiMarker.setTag("poi");

Zastąp statyczny fragment SupportMapFragment instancją środowiska wykonawczego

  1. Otwórz activity_maps.xml i zmień element w układ ramki, który posłuży za kontener na fragmenty:
<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. W sekcji onCreate() w MapsActivity usuń kod, który znajduje tag SupportMapFragment według identyfikatora, ponieważ w kodzie XML nie ma już statycznego elementu SupportMapFragment. Zamiast tego utwórz nową instancję środowiska wykonawczego instancji SupportMapFragment, wywołując metodę SupportMapFragment.newInstance():
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
  1. Dodaj fragment do FrameLayout, używając transakcji fragmentu z parametrem FragmentManager:
getSupportFragmentManager().beginTransaction()
       .add(R.id.fragment_container, mapFragment).commit();
  1. Zachowaj wiersz kodu, który aktywuje asynchroniczne ładowanie mapy:
mapFragment.getMapAsync(this);

Ustawianie elementu OnInfoWindowClickListener i sprawdzanie tagu znacznika

  1. Utwórz w regionie MapsActivity pośrednik metody o nazwie setInfoWindowClickToPanorama(), który przyjmuje GoogleMap jako argument i zwraca void:
private void setInfoWindowClickToPanorama(GoogleMap map) {}
  1. Ustaw OnInfoWindowClickListener na GoogleMap:
map.setOnInfoWindowClickListener(
       new GoogleMap.OnInfoWindowClickListener() {
           @Override
           public void onInfoWindowClick(Marker marker) {
           }
       });
  1. W metodzie onInfoWindowClick() sprawdź, czy znacznik zawiera tag ciągu ustawiony w metodzie onPoiClick():
if (marker.getTag() == "poi") {}

Zastąp fragment SupportMapFragment elementem SupportStreetViewPanoramaFragment

  1. Gdy znacznik zawiera tag, określ lokalizację panoramy Street View, używając obiektu StreetViewPanoramaOptions. Ustaw właściwość position obiektu na pozycję przekazanego znacznika:
StreetViewPanoramaOptions options =
       new StreetViewPanoramaOptions().position(
               marker.getPosition());
  1. Utwórz nową instancję SupportStreetViewPanoramaFragment, przekazując utworzony przez siebie obiekt options:
SupportStreetViewPanoramaFragment streetViewFragment
       = SupportStreetViewPanoramaFragment
       .newInstance(options);
  1. Rozpocznij transakcję dotyczącą fragmentu. Zastąp zawartość kontenera fragmentów nowym fragmentem: streetViewFragment. Dodaj transakcję do stosu tylnego, tak aby naciśnięcie Wstecz wskazało interfejs SupportMapFragment i nie wyjdzieło z aplikacji:
getSupportFragmentManager().beginTransaction()
       .replace(R.id.fragment_container,
               streetViewFragment)
       .addToBackStack(null).commit();
  1. Zadzwoń pod numer setInfoWindowClickToPanorama(mMap) za onMapReady() po zakończeniu połączenia z numerem setPoiClick().
  2. Uruchom aplikację. Powiększ miasto z widokiem Street View, np. Mountain View (siedziba siedziby Google) i znajdź ciekawe miejsce, np. park. Dotknij ciekawego miejsca, aby umieścić znacznik i wyświetlić okno informacyjne. Kliknij okno informacyjne, aby przejść do trybu Street View w miejscu, w którym znajduje się znacznik. Naciśnij przycisk Wstecz, aby powrócić do fragmentu mapy.

Google Street View w aplikacji na Androida

7. Kod rozwiązania

kod rozwiązania Wander.

8. Wyzwanie dotyczące kodowania

Wyzwanie: po dotknięciu okna informacyjnego ważnego miejsca w lokalizacji, w której Street View nie jest dostępne, zobaczysz czarny ekran.

9. Podsumowanie

  • Aby korzystać z interfejsu API Map Google, potrzebujesz klucza interfejsu API z Konsoli interfejsów API Google.
  • Użycie w Androidzie Studio szablonu aktywności w Mapach Google powoduje wygenerowanie Activity z pojedynczym SupportMapFragment w układzie aplikacji. Szablon dodaje też ACCESS_FINE_PERMISSION do pliku manifestu aplikacji, implementuje OnMapReadyCallback w Twojej aktywności i zastępuje wymaganą metodę onMapReady().

Aby zmienić typ mapy obiektu GoogleMap w czasie działania, użyj metody GoogleMap.setMapType(). Istnieją następujące typy map Google:

  • Normalna: typowa mapa drogowa. Pokazywać drogi, niektóre obiekty wybudowane przez ludzi oraz ważne obiekty naturalne, takie jak rzeki. Widoczne są również etykiety dróg i obiektów.
  • Hybrydowa: dane zdjęć satelitarnych z dodanymi mapami dróg. Widoczne są również etykiety dróg i obiektów.
  • Satelita: dane zdjęcia. Etykiety dróg i obiektów nie są widoczne.
  • Teren: dane topograficzne. Mapa obejmuje kolory, linie konturowe i etykiety, a także cieniowanie perspektywy. Widoczne są też niektóre drogi i etykiety.
  • Brak**:** brak mapy.

Mapy Google – informacje:

  • Znacznik to wskaźnik konkretnej lokalizacji geograficznej.
  • Po kliknięciu znacznika domyślnie wyświetli się okno informacyjne z informacjami o lokalizacji.
  • Domyślnie ciekawe miejsca (POI) są wyświetlane na mapie podstawowej wraz z odpowiednimi ikonami. Ciekawe miejsca to między innymi parki, szkoły i budynki urzędowe.
  • Oprócz tego ciekawe miejsca firm (sklepy, restauracje, hotele i inne) domyślnie wyświetlają się na mapie, jeśli typ mapy to normal.
  • Kliknięcia ważnych miejsc możesz rejestrować za pomocą OnPoiClickListener.
  • Za pomocą kreatora stylów możesz zmienić wygląd niemal wszystkich elementów mapy Google. Kreator stylów generuje plik JSON, który należy przekazać do Map Google przy użyciu metody setMapStyle().
  • Możesz dostosować znaczniki, zmieniając kolor domyślny lub zastępując domyślną ikonę znacznika obrazem niestandardowym.

Inne ważne informacje:

  • Użyj nakładki na powierzchnię, aby dostosować zdjęcie do lokalizacji geograficznej.
  • Za pomocą obiektu GroundOverlayOptions możesz określić obraz, jego rozmiar w metrach i jego położenie. Przekaż ten obiekt do metody GoogleMap.addGroundOverlay(), aby ustawić nakładkę na mapę.
  • Jeśli Twoja aplikacja ma uprawnienie ACCESS_FINE_LOCATION, możesz włączyć śledzenie lokalizacji za pomocą metody mMap.setMyLocationEnabled(true).
  • Google Street View zapewnia panoramiczne widoki 360° z wyznaczonych dróg na danym obszarze.
  • Użyj metody StreetViewPanoramaFragment.newInstance(), aby utworzyć nowy fragment Street View.
  • Aby określić opcje dla widoku, użyj obiektu StreetViewPanoramaOptions. Przekaż obiekt do metody newInstance().

10. Więcej informacji

Pokrewną dokumentację dotyczącą koncepcji można znaleźć w artykule 9.1: Interfejs API Map Google.

Dokumentacja dla deweloperów aplikacji na Androida:

Dokumentacja źródłowa:

11. Homework

W tej sekcji znajdziesz możliwe zadania domowe dla uczniów wykonujących te ćwiczenia w ramach zajęć prowadzonych przez nauczyciela. Zadaniem nauczyciela jest:

  • W razie potrzeby przypisz zadanie domowe.
  • Wyjaśnij uczniom, jak mogą przesyłać zadania domowe.
  • Oceniaj zadania domowe.

Nauczyciele mogą korzystać z tych sugestii tyle razy, ile zechcą. Możesz też przypisać dowolne inne zadanie domowe, które według nich jest odpowiednie.

Jeśli radzisz sobie z programowaniem samodzielnie, możesz sprawdzić swoją wiedzę, korzystając z tych zadań domowych.

Tworzenie i uruchamianie aplikacji

  1. Utwórz nową aplikację korzystającą z szablonu aktywności w Mapach Google, który wczytuje Mapy Google po uruchomieniu aplikacji.
  2. Po załadowaniu Map Google przenieś aparat do lokalizacji szkoły, domu lub innej lokalizacji.
  3. Dodaj do mapy dwa znaczniki: jeden w lokalizacji szkoły, a drugi w domu lub innej lokalizacji.
  4. Spersonalizuj ikony znaczników, zmieniając kolor domyślny lub zastępując domyślną ikonę znacznika obrazem niestandardowym.

Wskazówka: zapoznaj się z dokumentacją onMapReady (GoogleMap googleMap).

Odpowiedz na te pytania

Pytanie 1

Która metoda jest wywoływana, gdy mapa jest wczytywana i gotowa do użycia w aplikacji?

Pytanie 2

Za pomocą których komponentów Androida możesz dodać Mapy Google do swojej aplikacji?

  • MapViewMapFragment
  • MapFragmentMapActivity
  • MapViewMapActivity
  • Tylko MapFragment

Pytanie 3

Jakie typy map oferuje interfejs API Map Google na Androida?

  • Normalny, hybrydowy, teren, satelita i plan działania
  • Normalne, hybrydowe, terenowe, satelitarne i brak
  • Hybrydowa, terenowa, satelitarna, plan rozwoju i „brak”
  • Normalny, teren, satelita, mapa obrazu i „brak”

Pytanie 4

Jaki interfejs został wdrożony, aby dodać funkcję kliknięcia do ciekawego miejsca?

  • GoogleMap.OnPoiListener
  • GoogleMap.OnPoiClickListener
  • GoogleMap.OnPoiClick
  • GoogleMap.OnPoiClicked

Przesyłanie aplikacji do oceny

Wskazówki dla oceniających

Sprawdź, czy aplikacja ma te funkcje:

  • Po uruchomieniu aplikacji Mapy Google wyświetlają się prawidłowo, co oznacza, że klucz interfejsu API został poprawnie wygenerowany.
  • Po wczytaniu mapy Google kamera przesuwa się do lokalizacji domu lub szkoły ucznia. Ten krok powinien zostać wykonany w kodzie w metodzie wywołania zwrotnego onMapReady (GoogleMap googleMap).
  • Znaczniki są wyświetlane w lokalizacji szkoły ucznia i innej lokalizacji, na przykład w domu ucznia.
  • Te dwa znaczniki są dostosowane. Na przykład znaczniki używają koloru innego niż domyślny czerwony lub mają niestandardową ikonę.

12. Następne ćwiczenia

Aby zobaczyć wszystkie ćwiczenia z programowania w ramach szkolenia dla zaawansowanych z programowania na Androida, odwiedź stronę docelową szkoleń z programowania dla zaawansowanych aplikacji na Androida.