Zaawansowany Android 09.1: Mapy Google

1. Witamy

Te ćwiczenia z programowania są częścią szkolenia zaawansowanego z zakresu programowania na Androida, które zostało opracowane przez zespół Google Developers Training. Najwięcej korzyści przyniesie Ci ukończenie wszystkich ćwiczeń w kolejności.

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

Wprowadzenie

Tworzenie aplikacji z Mapami Google umożliwia dodawanie do nich funkcji takich jak zdjęcia satelitarne, zaawansowane elementy sterujące interfejsu, śledzenie lokalizacji i znaczniki lokalizacji. Możesz zwiększyć wartość standardowych Map Google, wyświetlając informacje z własnego zbioru danych, np. lokalizacje znanych miejsc do wędkowania lub wspinaczki. Możesz też tworzyć gry powiązane ze światem rzeczywistym, takie jak Pokémon Go.

W tym ćwiczeniu utworzysz aplikację Map Google o nazwie Wander.

Co musisz już wiedzieć

Musisz znać:

  • podstawowe funkcje Map Google;
  • Uprawnienia czasu działania.
  • Tworzenie, kompilowanie i uruchamianie aplikacji w Android Studio.
  • uwzględnianie bibliotek zewnętrznych w pliku build.gradle;

Czego się nauczysz

  • Zintegruj Mapę Google z aplikacją.
  • wyświetlać różne typy map,
  • Nadaj styl mapie Google.
  • Dodaj znaczniki do mapy.
  • Umożliwia użytkownikowi umieszczenie znacznika w interesującym miejscu.
  • Włącz śledzenie lokalizacji.
  • Włącz Google Street View.

Jakie zadania wykonasz

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

2. Aplikacje ogółem

W tym ćwiczeniu utworzysz aplikację Wander, która będzie zawierać mapę Google ze stylem. Aplikacja Wander umożliwia umieszczanie znaczników w lokalizacjach, wyświetlanie swojej lokalizacji w czasie rzeczywistym i oglądanie panoram Street View.

mapę Google ze stylem,

Google Street View w aplikacji na Androida

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

Interfejs API Map Google, podobnie jak interfejs Places API, wymaga klucza interfejsu API. Aby uzyskać klucz interfejsu API, zarejestruj 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 tym ćwiczeniu użyjesz klucza interfejsu API dla certyfikatu debugowania. Certyfikat debugowania jest z założenia niezabezpieczony, co opisano w artykule Podpisywanie kompilacji do debugowania. Opublikowane aplikacje na Androida, które korzystają z 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 z linkiem, który ułatwia uzyskanie klucza interfejsu API.

1.1 Tworzenie projektu Wander za pomocą szablonu Mapy

  1. Utwórz nowy projekt w Android Studio.
  2. Nadaj nowej aplikacji nazwę „Wander”. Zaakceptuj ustawienia domyślne, aż dojdziesz do strony Dodaj aktywność.
  3. Wybierz szablon Aktywność w Mapach Google.
  4. Pozostaw domyślne wartości pól Nazwa aktywności i Nazwa układu.
  5. Zmień tytuł na „Wander” i kliknij Zakończ.

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

google_maps_api**.xml**

Ten plik konfiguracyjny służy do przechowywania klucza interfejsu API. Szablon generuje 2 pliki google_maps_api.xml: jeden do debugowania, a drugi do publikowania. Plik klucza interfejsu API dla certyfikatu debugowania znajduje się w src/debug/res/values. Plik klucza interfejsu API do certyfikatu wersji znajduje się w src/release/res/values. W tym ćwiczeniu 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 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() tej klasy do przygotowania Mapy Google. Aktywność zawierająca SupportMapFragment musi implementować interfejs OnMapReadyCallback i jego metodę onMapReady(). Metoda getMapAsync() zwraca obiekt GoogleMap, co oznacza, że mapa została wczytana.

1.2. Uzyskiwanie klucza interfejsu API

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

Plik zawiera komentarz z długim adresem URL. Parametry adresu URL zawierają szczegółowe informacje o Twojej aplikacji.

  1. Skopiuj adres URL i wklej go w przeglądarce.
  2. Postępuj zgodnie z instrukcjami, aby utworzyć projekt w Konsoli interfejsów API Google. Ze względu na parametry w podanym adresie URL Konsola interfejsów API automatycznie włącza interfejs Google Maps Android API.
  3. Utwórz klucz interfejsu API i kliknij Ogranicz klucz, aby ograniczyć jego użycie 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ę tekst YOUR_KEY_HERE.
  5. Uruchom aplikację. W aktywności masz osadzoną mapę ze znacznikiem ustawionym w Sydney w Australii. (Marker Sydney jest częścią szablonu i możesz go później zmienić).

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

Mapy Google obejmują kilka typów map: normalną, hybrydową, satelitarną, terenu i „brak”. W tym zadaniu dodasz pasek aplikacji z menu opcji, które umożliwia użytkownikowi zmianę typu mapy. Przesuń początkową lokalizację mapy do lokalizacji swojego domu. Następnie dodaj obsługę znaczników, które wskazują pojedyncze lokalizacje na mapie i mogą zawierać etykietę.

2.1 Dodawanie typów map

Rodzaj mapy, której potrzebuje użytkownik, zależy od rodzaju informacji, których szuka. Podczas korzystania z map do nawigacji w samochodzie przydatne jest wyraźne wyświetlanie nazw ulic. Podczas wędrówki prawdopodobnie bardziej interesuje Cię, ile musisz się wspiąć, aby dotrzeć na szczyt góry. 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 > Android Resource File (Nowy > Plik zasobu Androida).
  2. W oknie nadaj plikowi nazwę map_options. Jako typ zasobu wybierz Menu. Kliknij OK.
  3. Aby utworzyć opcje mapy, zastąp kod w nowym pliku tym kodem: Typ mapy „none” został pominięty, ponieważ „none” oznacza 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ę, aby rozszerzyć klasę AppCompatActivity zamiast klasy FragmentActivity. Użycie AppCompatActivity spowoduje wyświetlenie paska aplikacji, a tym samym menu.
  3. MapsActivity zastąp metodę onCreateOptionsMenu() i rozszerz plik 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ę na to, 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 powstały Mapy Google. Domyślne wywołanie zwrotne animuje też mapę, aby przesunąć ją do Sydney. W tym kroku mapa zostanie przesunięta do lokalizacji domu bez umieszczania znacznika, a następnie powiększona 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 stronę 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 o szerokości i długości geograficznej.

  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 w niej wybrany początkowy poziom powiększenia. Poniższa lista pokazuje przybliżony poziom szczegółowości na poszczególnych poziomach 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 obiekt LatLng i zmienną zoom. Przesuń i powiększ kamerę, wywołując moveCamera() na obiekcie GoogleMap i przekazując nowy obiekt CameraUpdate:
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
  1. Uruchom aplikację. Mapa powinna przesunąć się do Twojego domu i powiększyć do wybranego poziomu.

2.3 Dodawanie znaczników mapy

Mapy Google mogą wyróżnić lokalizację za pomocą znacznika, który tworzysz za pomocą klasy Marker. Domyślny znacznik korzysta ze standardowej ikony Map Google: Znacznik w Mapach Google

Możesz rozszerzyć markery, aby wyświetlać informacje kontekstowe w oknach informacyjnych.

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

Okienko informacyjne przypiętego pinezką miejsca

  1. Utwórz w pliku MapsActivity wycinek metody o nazwie setMapLongClick(), która przyjmuje argument final GoogleMap i zwraca wartość 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 dotyka ekranu i przytrzymuje palec. Przekaż nowe wystąpienie OnMapLongClickListener, które zastępuje metodę onMapLongClick(). Argumentem wejściowym jest obiekt LatLng zawierający współrzędne lokalizacji, w której użytkownik kliknął:
private void setMapLongClick(final GoogleMap map) {
   map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
       @Override
       public void onMapLongClick(LatLng latLng) {
       }
   });
}
  1. W 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(). Przekaż w mMap.
  2. Uruchom aplikację. Naciśnij i przytrzymaj mapę, aby umieścić znacznik w wybranej lokalizacji.
  3. Kliknij znacznik, aby wyśrodkować go na ekranie.

W lewym dolnym rogu ekranu pojawiają się przyciski nawigacyjne, które umożliwiają użytkownikowi korzystanie z Map Google w celu nawigowania do zaznaczonego miejsca.

Aby dodać okno informacyjne do znacznika:

  1. W obiekcie MarkerOptions ustaw pole title i pole snippet.
  2. onMapLongClick() ustaw pole title na „Przypięty punkt”. W polu snippet ustaw współrzędne lokalizacji w metodzie 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ę. Kliknij i przytrzymaj mapę, aby umieścić na niej znacznik lokalizacji. Kliknij znacznik, aby wyświetlić okno informacji.

2.4 Dodawanie odbiornika POI

Domyślnie na mapie wyświetlają się ciekawe miejsca wraz z odpowiadającymi im ikonami. Obejmują one parki, szkoły, budynki rządowe i inne. Gdy typ mapy jest ustawiony na normal, na mapie pojawiają się też punkty POI firm. Punkty POI firm to firmy takie jak sklepy, restauracje i hotele.

W tym kroku dodasz do mapy GoogleMap.OnPoiClickListener. Ten odbiornik kliknięć natychmiast umieszcza znacznik na mapie, zamiast czekać na naciśnięcie i przytrzymanie. Po kliknięciu wyświetla się też okno informacyjne z nazwą punktu.

Znacznik ciekawego miejsca

  1. Utwórz w MapsActivity metodę zastępczą o nazwie setPoiClick(), która przyjmuje argument final GoogleMap i zwraca void:
private void setPoiClick(final GoogleMap map) {}
  1. W metodzie setPoiClick() ustaw OnPoiClickListener na przekazanym GoogleMap:
map.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
   @Override
   public void onPoiClick(PointOfInterest poi) {
   }
});
  1. onPoiClick() umieść znacznik w lokalizacji POI. Ustaw tytuł na nazwę punktu. 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() na urządzeniu poiMarker, aby natychmiast wyświetlić okno informacji.
poiMarker.showInfoWindow();
  1. Wywołaj funkcję setPoiClick() na końcu funkcji onMapReady(). Przekaż w mMap.
  2. Uruchom aplikację i znajdź punkt orientacyjny, np. park. Kliknij punkt POI, aby umieścić na nim znacznik i wyświetlić jego nazwę w okienku 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ć za pomocą dostępnych atrybutów XML, tak jak każdy inny fragment. W tym kroku dostosujesz jednak wygląd i styl treści elementu MapFragment za pomocą metod obiektu GoogleMap. Aby dodać styl do mapy i dostosować znaczniki, użyj internetowego kreatora stylów. Możesz też dodać do lokalizacji domu GroundOverlay, który będzie się skalować i obracać wraz z mapą.

3.1 Dodawanie stylu do mapy

Aby utworzyć niestandardowy styl mapy, wygeneruj plik JSON, który określa sposób wyświetlania elementów na mapie.Nie musisz tworzyć tego pliku ręcznie: Google udostępnia Kreator stylów, który generuje plik JSON po wizualnym dostosowaniu stylu mapy. W tym ćwiczeniu dostosujesz styl mapy do „trybu nocnego”, co oznacza, że mapa będzie używać przyciemnionych kolorów i niskiego kontrastu, aby można było z niej korzystać w nocy.

  1. W przeglądarce otwórz stronę https://mapstyle.withgoogle.com/.
  2. Kliknij Utwórz styl.
  3. Wybierz motyw Noc.
  4. U dołu menu kliknij Więcej opcji.
  5. U dołu listy Rodzaj obiektu wybierz Woda > Wypełnienie. 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 katalogu res/raw plik o nazwie map_style.json.
  8. Wklej kod JSON do nowego pliku zasobu.
  9. Aby ustawić styl JSON na mapie, wywołaj setMapStyle() na obiekcie GoogleMap. Przekaż obiekt MapStyleOptions, który wczytuje plik JSON. Metoda setMapStyle() zwraca wartość logiczną wskazującą, czy stylizacja się powiodła. Jeśli nie można wczytać pliku, metoda zgłasza wyjątek Resources.NotFoundException.

Aby nadać mapie styl, skopiuj ten kod do metody onMapReady(). W przypadku instrukcji logowania może być konieczne utworzenie ciągu znaków TAG:

     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 stylu trybu nocnego

3.2 Stylizowanie znacznika

Możesz jeszcze bardziej spersonalizować mapę, dostosowują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(), aby użyć domyślnego znacznika, ale zmienić jego kolor na niebieski:
.icon(BitmapDescriptorFactory.defaultMarker
       (BitmapDescriptorFactory.HUE_BLUE))
  1. Uruchom aplikację. Umieszczone przez Ciebie znaczniki będą teraz niebieskie, co lepiej pasuje do motywu nocnego aplikacji.

Zwróć uwagę, że markery POI są nadal czerwone, ponieważ nie dodano stylu do metody onPoiClick().

3.3 Dodawanie nakładki

Jednym ze sposobów dostosowania Mapy Google jest rysowanie na niej. Ta technika jest przydatna, jeśli chcesz wyróżnić określony typ lokalizacji, np. popularne miejsca do wędkowania. Obsługiwane są 3 typy nakładek:

  • Kształty: do mapy możesz dodawać linie łamane, wielokątyokręgi.
  • TileOverlay obiekty: nakładka z kafelkami definiuje zestaw obrazów, które są dodawane na wierzchu kafelków mapy podstawowej. Nakładki kafelkowe są przydatne, gdy chcesz dodać do mapy rozbudowane obrazy. Typowa nakładka z kafelkami obejmuje duży obszar geograficzny.
  • GroundOverlay obiekty: nakładka na teren to obraz przymocowany do mapy. W przeciwieństwie do znaczników nakładki na ziemię są zorientowane na powierzchnię Ziemi, a nie na ekran. Obracanie, pochylanie lub powiększanie mapy zmienia orientację obrazu. Nakładki na ziemię są przydatne, gdy chcesz umieścić jeden obraz w określonym obszarze na mapie.

W tym kroku dodasz nakładkę na ziemię w kształcie robota Androida w lokalizacji swojego domu.

  1. Pobierz ten obraz Androida i zapisz go w folderze res/drawable.
  2. onMapReady() po wywołaniu funkcji przenoszącej kamerę 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 z 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 obiektu GroundOverlayOptions, wywołując metodę position(). Przekaż obiekt home LatLng i wartość float określającą szerokość w metrach żądanej nakładki. W tym przykładzie szerokość 100 m jest odpowiednia:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
     .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
       .position(home, 100);
  1. Wywołaj funkcję addGroundOverlay() na obiekcie GoogleMap. Przekaż obiekt GroundOverlayOptions:
mMap.addGroundOverlay(homeOverlay);
  1. Uruchom aplikację. Powiększ widok swojej lokalizacji, a obraz Androida pojawi się jako nakładka.

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

Użytkownicy często korzystają z Map Google, aby sprawdzić swoją aktualną lokalizację. Lokalizację urządzenia możesz uzyskać za pomocą interfejsu API usług lokalizacyjnych. Aby wyświetlić lokalizację urządzenia na mapie bez dalszego wykorzystywania 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 ten przycisk, mapa wyśrodkuje się na lokalizacji urządzenia. Lokalizacja jest oznaczona niebieskim punktem, jeśli urządzenie jest nieruchome, lub niebieskim szewronem, jeśli urządzenie się porusza.

Stylizowana mapa Google ze śledzeniem lokalizacji

Możesz podać dodatkowe informacje o lokalizacji za pomocą Google Street View, czyli interaktywnego zdjęcia panoramicznego danego miejsca.

W tym zadaniu włączysz warstwę danych o lokalizacji i Street View, aby po kliknięciu przez użytkownika okna informacyjnego znacznika punktu orientacyjnego mapa przechodziła w tryb Street View.

4.1 Włączanie śledzenia lokalizacji

Włączenie śledzenia lokalizacji w Mapach Google wymaga tylko jednej linijki kodu. Musisz jednak upewnić się, że użytkownik przyznał uprawnienia do lokalizacji (za pomocą modelu uprawnień w czasie działania).

Na tym etapie wysyłasz prośbę o dostęp do lokalizacji i włączasz śledzenie lokalizacji.

  1. W pliku AndroidManifest.xml sprawdź, czy uprawnienie FINE_LOCATION jest już obecne. Android Studio wstawiło to uprawnienie, gdy wybrano szablon Map Google.
  2. Aby włączyć śledzenie lokalizacji w aplikacji, utwórz w pliku MapsActivity metodę o nazwie enableMyLocation(), która nie przyjmuje argumentów i niczego nie zwraca.
  3. Określ metodę enableMyLocation(). Sprawdź, czy masz uprawnienie ACCESS_FINE_LOCATION. Jeśli uprawnienia zostały przyznane, włącz warstwę lokalizacji. W przeciwnym razie poproś o uprawnienia:
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. Aby włączyć warstwę lokalizacji, wywołaj funkcję enableMyLocation() z wywołania zwrotnego onMapReady().
  2. Zastąp metodę onRequestPermissionsResult(). Jeśli uprawnienia zostaną 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 pojawi się przycisk Moja lokalizacja, który wyświetla bieżącą lokalizację urządzenia.

4.2 Włączanie Street View

Mapy Google udostępniają widok Street View, czyli panoramiczny widok miejsca z elementami sterującymi, które umożliwiają poruszanie się po wyznaczonej ścieżce. Street View nie ma zasięgu globalnego.

W tym kroku włączysz panoramę Street View, która będzie się aktywować, gdy użytkownik kliknie okno informacji o interesującym go miejscu. Musisz wykonać 2 czynności:

  1. Odróżnij markery POI od innych markerów, ponieważ chcesz, aby funkcje aplikacji działały tylko w przypadku markerów POI. Dzięki temu możesz uruchomić Street View, gdy użytkownik kliknie okno informacyjne punktu POI, ale nie wtedy, gdy kliknie inny rodzaj znacznika.

Klasa Marker zawiera metodę setTag(), która umożliwia dołączanie danych. (Dane mogą być dowolnymi informacjami rozszerzającymi zakres Object). Ustawisz tag na znacznikach, które są tworzone, gdy użytkownicy klikają punkty POI.

  1. Gdy użytkownik kliknie otagowane okno informacyjne w OnInfoWindowClickListener, zastąp MapFragment elementem StreetViewPanoramaFragment. (Poniższy kod używa symboli SupportMapFragmentSupportStreetViewPanoramaFragment, aby obsługiwać wersje Androida starsze niż API 12).

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

Oznaczanie znacznika ciekawego miejsca

  1. W wywołaniu zwrotnym onPoiClick() wywołaj funkcję setTag() w poiMarker. Przekaż dowolny ciąg znaków:
poiMarker.setTag("poi");

Zastąpienie statycznego elementu SupportMapFragment instancją czasu działania

  1. Otwórz activity_maps.xml i zmień element na układ ramki, który będzie służyć jako kontener fragmentów:
<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 pliku onCreate() w MapsActivity usuń kod, który wyszukuje element SupportMapFragment według identyfikatora, ponieważ w pliku XML nie ma już statycznego elementu SupportMapFragment. Zamiast tego utwórz nową instancję środowiska wykonawczego SupportMapFragment, wywołując SupportMapFragment.newInstance():
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
  1. Dodaj fragment do FrameLayout za pomocą transakcji fragmentu z użyciem FragmentManager:
getSupportFragmentManager().beginTransaction()
       .add(R.id.fragment_container, mapFragment).commit();
  1. Pozostaw wiersz kodu, który wywołuje asynchroniczne ładowanie mapy:
mapFragment.getMapAsync(this);

Ustawianie OnInfoWindowClickListener i sprawdzanie tagu markera

  1. Utwórz w pliku MapsActivity wycinek metody o nazwie setInfoWindowClickToPanorama(), która przyjmuje argument GoogleMap 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 ciąg tekstowy tagu ustawiony w metodzie onPoiClick():
if (marker.getTag() == "poi") {}

Zastąpienie elementu SupportMapFragment elementem SupportStreetViewPanoramaFragment

  1. Jeśli znacznik zawiera tag, określ lokalizację panoramy Street View za pomocą 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 obiekt options:
SupportStreetViewPanoramaFragment streetViewFragment
       = SupportStreetViewPanoramaFragment
       .newInstance(options);
  1. Rozpocznij transakcję fragmentu. Zastąp zawartość kontenera fragmentu nowym fragmentem streetViewFragment. Dodaj transakcję do stosu wstecznego, aby naciśnięcie przycisku Wstecz spowodowało powrót do SupportMapFragment, a nie zamknięcie aplikacji:
getSupportFragmentManager().beginTransaction()
       .replace(R.id.fragment_container,
               streetViewFragment)
       .addToBackStack(null).commit();
  1. Zadzwoń pod numer setInfoWindowClickToPanorama(mMap)onMapReady() po zakończeniu rozmowy z setPoiClick().
  2. Uruchom aplikację. Przybliż widok miasta, które jest objęte Street View, np. Mountain View (siedziba główna Google), i znajdź punkt orientacyjny, np. park. Kliknij punkt POI, aby umieścić znacznik i wyświetlić okno informacji. Kliknij okno informacyjne, aby przejść do trybu Street View w lokalizacji znacznika. Aby wrócić do fragmentu mapy, naciśnij przycisk Wstecz.

Google Street View w aplikacji na Androida

7. Kod rozwiązania

Wander kod rozwiązania.

8. Wyzwanie związane z kodowaniem

Problem: jeśli klikniesz okno informacyjne punktu POI w lokalizacji, w której nie ma zdjęć Street View, zobaczysz czarny ekran.

9. Podsumowanie

  • Aby korzystać z interfejsu API Map Google, musisz mieć klucz interfejsu API z Konsoli interfejsów API Google.
  • W Android Studio użycie szablonu aktywności Map Google generuje element Activity z jednym elementem SupportMapFragment w układzie aplikacji. Szablon dodaje też do manifestu aplikacji element ACCESS_FINE_PERMISSION, implementuje w aktywności element OnMapReadyCallback i zastępuje wymaganą metodę onMapReady().

Aby zmienić typ mapy GoogleMap w czasie działania programu, użyj metody GoogleMap.setMapType(). Mapa Google może być jednym z tych typów:

  • Normalna: typowa mapa drogowa. Wyświetla drogi, niektóre obiekty stworzone przez człowieka i ważne elementy naturalne, takie jak rzeki. Widoczne są też etykiety dróg i obiektów.
  • Hybrydowa: dane ze zdjęć satelitarnych z dodanymi mapami dróg. Widoczne są też etykiety dróg i obiektów.
  • Satelita: dane fotograficzne. Etykiety dróg i obiektów nie są widoczne.
  • Teren: dane topograficzne. Mapa zawiera kolory, poziomice i etykiety oraz cieniowanie perspektywiczne. Widoczne są też niektóre drogi i etykiety.
  • Brak**:** brak mapy.

Informacje o Mapach Google:

  • Znacznik to wskaźnik konkretnego położenia geograficznego.
  • Po kliknięciu znacznika domyślnie wyświetla się okno informacyjne z informacjami o lokalizacji.
  • Domyślnie ciekawe miejsca pojawiają się na mapie podstawowej wraz z odpowiednimi ikonami. Obejmują one parki, szkoły, budynki rządowe i inne.
  • Dodatkowo biznesowe ważne miejsca (sklepy, restauracje, hotele itp.) domyślnie pojawiają się na mapie, gdy typ mapy to normal.
  • Kliknięcia w przypadku POI możesz rejestrować za pomocą OnPoiClickListener.
  • Za pomocą kreatora stylów możesz zmieniać wygląd niemal wszystkich elementów Mapy Google. Kreator stylów generuje plik JSON, który przekazujesz do Mapy Google za pomocą metody setMapStyle().
  • Możesz dostosować znaczniki, zmieniając domyślny kolor lub zastępując domyślną ikonę znacznika niestandardowym obrazem.

Inne ważne informacje:

  • Użyj nakładki na ziemię, aby przypisać obraz do położenia geograficznego.
  • Użyj obiektu GroundOverlayOptions, aby określić obraz, jego rozmiar w metrach i pozycję. Przekaż ten obiekt do metody GoogleMap.addGroundOverlay(), aby ustawić nakładkę na mapie.
  • Jeśli Twoja aplikacja ma uprawnienie ACCESS_FINE_LOCATION, możesz włączyć śledzenie lokalizacji za pomocą metody mMap.setMyLocationEnabled(true).
  • Google Street View udostępnia panoramiczne widoki 360° z wybranych dróg na obsługiwanym obszarze.
  • Aby utworzyć nowy fragment Street View, użyj metody StreetViewPanoramaFragment.newInstance().
  • Aby określić opcje widoku, użyj obiektu StreetViewPanoramaOptions. Przekaż obiekt do metody newInstance().

10. Więcej informacji

Dokumentacja powiązanego pojęcia znajduje się w sekcji 9.1. Interfejs API Map Google.

Dokumentacja dla deweloperów aplikacji na Androida:

Dokumentacja:

11. Zadanie domowe

W tej sekcji znajdziesz listę możliwych zadań domowych dla uczniów, którzy wykonują ten codelab w ramach kursu prowadzonego przez instruktora. Nauczyciel musi:

  • W razie potrzeby przypisz zadanie domowe.
  • Poinformuj uczniów, jak przesyłać zadania domowe.
  • oceniać zadania domowe,

Instruktorzy mogą korzystać z tych sugestii w dowolnym zakresie i mogą zadawać inne zadania domowe, które uznają za odpowiednie.

Jeśli samodzielnie wykonujesz to laboratorium, możesz użyć tych zadań domowych, aby sprawdzić swoją wiedzę.

Tworzenie i uruchamianie aplikacji

  1. Utwórz nową aplikację, która korzysta z szablonu aktywności Map Google. Po uruchomieniu aplikacji wczytuje on Mapy Google.
  2. Gdy mapa Google się załaduje, przesuń kamerę do lokalizacji szkoły, domu lub innego miejsca, które ma dla Ciebie znaczenie.
  3. Dodaj do mapy 2 znaczniki: jeden w lokalizacji szkoły, a drugi w domu lub innym ważnym miejscu.
  4. Dostosuj ikony znaczników, zmieniając domyślny kolor lub zastępując domyślną ikonę znacznika niestandardowym obrazem.

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

Odpowiedz na te pytania

Pytanie 1

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

Pytanie 2

Jakich komponentów Androida możesz użyć, aby dodać Mapy Google do aplikacji?

  • MapViewMapFragment
  • MapFragmentMapActivity
  • MapViewMapActivity
  • Tylko MapFragment

Pytanie 3

Jakie rodzaje map oferuje interfejs API Map Google na Androida?

  • Normalna, hybrydowa, terenowa, satelitarna i drogowa
  • normalny, hybrydowy, terenowy, satelitarny i „brak”
  • Hybrydowa, terenowa, satelitarna, drogowa i „brak”
  • Normalny, teren, satelitarny, mapa obrazkowa i „brak”

Pytanie 4

Jakiego interfejsu używasz, aby dodać funkcję kliknięcia do ciekawego miejsca?

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

Prześlij aplikację do oceniania

Wskazówki dla oceniających

Sprawdź, czy aplikacja ma te funkcje:

  • Po uruchomieniu aplikacji mapa Google wyświetla się prawidłowo, co oznacza, że klucz interfejsu API został wygenerowany prawidłowo.
  • Po wczytaniu Mapy Google kamera przesuwa się do domu lub szkoły ucznia. W kodzie ten krok powinien nastąpić w metodzie wywołania zwrotnego onMapReady (GoogleMap googleMap).
  • Markery są wyświetlane w lokalizacji szkoły ucznia i w innej lokalizacji, np. w domu ucznia.
  • Znaczniki są dostosowane. Na przykład znaczniki mogą mieć kolor inny niż domyślny czerwony lub używać niestandardowej ikony.

12. Następne ćwiczenie

Aby zobaczyć wszystkie ćwiczenia w ramach szkolenia Advanced Android Development, otwórz stronę docelową ćwiczeń Advanced Android Development.