Informacje o tym ćwiczeniu (w Codelabs)
1. Zanim zaczniesz
Dowiedz się, jak używać Google Maps Platform oraz pakietu Places SDK dla Androida do przedstawiania użytkownikom listy miejsc w celu identyfikowania ich aktualnych lokalizacji.
Wymagania wstępne
- Podstawowe umiejętności dotyczące języka Java
Jakie zadania wykonasz:
- Dodawanie mapy do aplikacji na Androida.
- Użyj geolokalizacji, aby określić lokalizację użytkownika.
- Pobierz miejsca w pobliżu bieżącej lokalizacji użytkownika.
- Wyświetl użytkownikowi prawdopodobne miejsce, aby określić jego bieżącą lokalizację.
Co stworzysz
Aplikację na Androida tworzysz od zera, ale możesz pobrać przykładowy kod i porównać go przy debugowaniu. Pobierz przykładowy kod z GitHuba lub, jeśli masz skonfigurowane używanie Git w wierszu poleceń, wpisz to:
git clone https://github.com/googlecodelabs/current-place-picker-android.git
Jeśli podczas ćwiczeń z programowania napotkasz jakiekolwiek błędy (błędy w kodzie, błędy gramatyczne, niezrozumiałe słowa lub coś innego) zgłoś je, klikając link Zgłoś błąd w lewym dolnym rogu ćwiczeń z programowania.
2. Wypróbuj
Przed rozpoczęciem tych ćwiczeń musisz skonfigurować te elementy:
Android Studio,
Pobierz aplikację Android Studio ze strony https://developer.android.com/studio.
Jeśli masz już aplikację Android Studio, upewnij się, że masz jej najnowszą wersję, klikając Android Studio > Sprawdź dostępność aktualizacji...
Ten moduł został napisany w Android Studio 3.4.
Android SDK
W Android Studio możesz skonfigurować wybrane pakiety SDK za pomocą Menedżera pakietów. W tym module wykorzystano pakiet SDK Androida Q.
- Na ekranie powitalnym Android Studio kliknij Skonfiguruj > Menedżer pakietów SDK.
- Zaznacz pole wyboru pakietu SDK i kliknij Zastosuj.
Jeśli nie masz pakietu SDK, rozpocznie się pobieranie pakietu na komputer.
Usługi Google Play
Z poziomu menedżera SDK musisz też zainstalować Usługi Google Play.
- Kliknij kartę Narzędzia SDK i zaznacz pole wyboru Usługi Google Play.
Zmień stan, jeśli wyświetli się komunikat Dostępna aktualizacja.
3. Przygotowywanie emulatora
Aby ją uruchomić, podłącz swoje urządzenie lub użyj emulatora Androida.
Jeśli korzystasz z własnego urządzenia, przejdź do sekcji Rzeczywiste instrukcje dotyczące urządzenia: aktualizowanie Usług Google Play na końcu tej strony.
Dodaj emulator
- Na ekranie powitalnym Android Studio kliknij Skonfiguruj > AVD Manager (Menedżer AVD).
Otworzy się okno Menedżer urządzeń wirtualnych z Androidem.
- Kliknij Utwórz urządzenie wirtualne..., aby otworzyć listę urządzeń do wyboru.
- Wybierz urządzenie z ikoną Play
w kolumnie Sklep Play i kliknij Dalej.
Zobaczysz zestaw obrazów systemowych, które możesz zainstalować. Jeśli obok pozycji Q na pozycji Android 9.+ (Google Play) widać napis Pobierz, kliknij Pobierz.
- Kliknij Dalej, by nazwać urządzenie wirtualne, a potem kliknij Zakończ.
Wrócisz do listy Twoje urządzenia wirtualne.
- Kliknij Start
obok nowego urządzenia:
Po chwili uruchomi się emulator.
Instrukcje dotyczące emulatorów – aktualizowanie Usług Google Play
- Po uruchomieniu emulatora kliknij ... na wyświetlonym pasku nawigacyjnym****.
Otworzy się okno Rozszerzone elementy sterujące.
- Kliknij Google Play w menu.
Jeśli aktualizacja jest dostępna, kliknij Aktualizuj.
- Zaloguj się do emulatora za pomocą konta Google.
Możesz korzystać z własnego konta lub bezpłatnie utworzyć nowe konto, aby oddzielać testy od swoich danych osobowych.
Następnie Google Play otwiera się w Usługach Google Play.
- Kliknij Aktualizuj, aby pobrać najnowszą wersję Usług Google Play.
Jeśli pojawi się prośba o dokończenie konfiguracji konta i dodanie opcji płatności, kliknij Pomiń.
Ustawianie lokalizacji w emulatorze
- Po uruchomieniu emulatora wpisz w pasku wyszukiwania na ekranie głównym &&tt;maps", aby wyświetlić ikonę aplikacji Mapy Google.
- Kliknij ikonę, aby ją uruchomić.
Pojawi się mapa domyślna.
- W prawym dolnym rogu mapy kliknij Twoja lokalizacja
.
Pojawi się prośba o przyznanie telefonu uprawnień do korzystania z lokalizacji.
- Kliknij ..., by otworzyć menu Rozszerzone elementy sterujące.
- Kliknij kartę Lokalizacja.
- Wpisz szerokość i długość geograficzną.
Możesz wpisać tu wszystko, co lubisz, ale pamiętaj, aby umieścić go w miejscu pełnym wielu miejsc.
(Użyj opcji Współrzędne 20.7818 i Długość geograficzna -156.4624 dla miasta Kihei na Hawajach, aby powielić wyniki ćwiczenia z programowania).
- Kliknij Wyślij, a mapa zostanie zaktualizowana o tę lokalizację.
Wszystko jest gotowe do uruchomienia aplikacji i przetestowania jej z wykorzystaniem lokalizacji.
Rzeczywiste instrukcje dotyczące urządzeń – aktualizowanie Usług Google Play
Jeśli używasz rzeczywistego urządzenia z Androidem, wykonaj te czynności:
- Użyj paska wyszukiwania na ekranie głównym, aby wyszukać i otworzyć Usługi Google Play.
- Kliknij Więcej szczegółów.
Kliknij Aktualizuj, jeśli jest dostępna.
4. Tworzenie powłoki aplikacji za pomocą aktywności w Mapach Google
- Na ekranie powitalnym Android Studio wybierz Rozpocznij nowy projekt Android Studio.
- Na karcie Telefon i tablet wybierz Aktywność w Mapach Google.
Otworzy się okno Skonfiguruj projekt. Tutaj możesz nazwać aplikację i utworzyć pakiet na podstawie domeny.
Oto ustawienia aplikacji o nazwie Obecne miejsce, która odpowiada pakietowi com.google.codelab.currentplace
.
- Wybierz Java jako język i Użyj artefaktów androidx. *.
W pozostałych ustawieniach zachowaj wartości domyślne.
- Kliknij Zakończ.
5. Dodaj zależności Google Services do pliku kompilacji Gradle
Aby uzyskać dostęp do dostępu do lokalizacji na urządzeniu z Androidem, musisz mieć interfejs Google Location and Activity Recognition API firmy Usługi Google Play. Więcej informacji o dodawaniu tego i innych interfejsów API Usług Google Play znajdziesz w artykule Konfigurowanie Usług Google Play.
Projekty Android Studio mają zwykle dwa pliki build.gradle
. Jeden jest przeznaczony do całego projektu, a drugi dotyczy aplikacji. Jeśli w widoku Androida masz eksplorator projektów Android Studio, oba zobaczysz w folderze Gradle Scripts
. Musisz edytować plik build.gradle (Module: app)
, aby dodać usługi Google.
- Dodaj 2 wiersze do sekcji
dependencies
, by dodać usługi Google do lokalizacji i interfejsu Places API (przykładowy kod w kontekście).
build.gradle (moduł: aplikacja)
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.google.codelab.currentplace"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.google.android.gms:play-services-maps:16.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'com.google.android.gms:play-services-location:16.0.0'
implementation 'com.google.android.libraries.places:places:1.1.0'
}
6. Włączanie interfejsów API Google Maps Platform i uzyskiwanie klucza interfejsu API
W następnym kroku włącz Pakiet SDK Map na Androida i Places API.
Konfigurowanie Google Maps Platform
Jeśli nie masz jeszcze konta Google Cloud Platform ani projektu z włączonymi płatnościami, przeczytaj przewodnik Pierwsze kroki z Google Maps Platform, by utworzyć konto rozliczeniowe i projekt.
- W Cloud Console kliknij menu projektu i wybierz projekt, którego chcesz użyć w tym ćwiczeniu z programowania.
- Włącz interfejsy API i pakiety SDK Google Maps Platform wymagane w ramach tego ćwiczenia z ćwiczeń w Google Cloud Marketplace. W tym celu wykonaj czynności opisane w tym filmie lub w tej dokumentacji.
- Wygeneruj klucz interfejsu API na stronie Dane logowania w Cloud Console. Odpowiednie instrukcje znajdziesz w tym filmie lub w tej dokumentacji. Wszystkie żądania wysyłane do Google Maps Platform wymagają klucza interfejsu API.
Skopiuj utworzony przed chwilą klucz interfejsu API. Wróć do Androida Studio i znajdź plik google_maps_api.xml
w sekcji Android > app > res > value.
Zastąp YOUR_KEY_HERE
skopiowanym kluczem interfejsu API.
Twoja aplikacja jest teraz skonfigurowana.
7. Edytuj plik układu
- W eksploratorze projektu otwórz plik
activity_maps.xml
w Androidzie >app
>res
>layout
.
- Po prawej stronie ekranu zobaczysz podstawowy interfejs, a u dołu znajdują się karty umożliwiające wybór projektu lub edytora tekstu. Wybierz Tekst i zastąp całą zawartość pliku układu tym:
activity_maps.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:titleTextColor="@android:color/white"
android:background="@color/colorPrimary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="349dp"
tools:context=".MapsActivity" />
<ListView
android:id="@+id/listPlaces"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
Pozwala to uzyskać interfejs podobny do tego:
8. Konfigurowanie paska aplikacji
Aby umożliwić użytkownikowi kliknięcie wybranego miejsca, dodaj pasek aplikacji z ikoną znajdującą bieżącą lokalizację użytkownika i wyświetlającą prawdopodobnie miejsca w pobliżu. Będzie on wyglądał :
Na telefonie widać tylko ikonę. Na tablecie z większą ilością miejsca także tekst.
Tworzenie ikony
- W eksploratorze projektu kliknij Android > app, a potem kliknij prawym przyciskiem myszy folder res i wybierz Nowy > Zasób graficzny.
Otworzy się Studio zasobów.
- W menu Typ ikony kliknij Ikony na pasku działań i kartach.
- Nazwij zasób
ic_geolocate
. - Jako typ zasobu wybierz Klip.**
- Kliknij grafikę obok Clip art.
Otworzy się okno Wybierz ikonę.
- Wybierz ikonę.
Aby znaleźć powiązane z nimi ikony, użyj paska wyszukiwania.
- Wyszukaj hasło
location
i wybierz ikonę związaną z lokalizacją.
Ikona moja lokalizacja jest taka sama jak ta w aplikacji Mapy Google, gdy użytkownik chce zrobić zdjęcie aparatu w bieżącej lokalizacji.
- Kliknij OK > Dalej > Zakończ, a następnie potwierdź, że istnieje nowy folder o nazwie
drawable
, który zawiera nowe pliki ikon.
Dodawanie zasobów ciągu znaków
- W eksploratorze projektu kliknij Android > app > res > values, a następnie otwórz plik
strings.xml
. - Dodaj te wiersze po
<string name="title_activity_maps">Map</string>
:
strings.xml,
<string name="action_geolocate">Pick Place</string>
<string name="default_info_title">Default Location</string>
<string name="default_info_snippet">No places found, because location permission is disabled.</string>
Pierwszy wiersz jest używany na pasku aplikacji, gdy jest miejsce na umieszczenie etykiety tekstowej obok ikony. Pozostałe służą do dodawania znaczników do mapy.
Teraz kod w pliku wygląda tak:
<resources>
<string name="app_name">Current Place</string>
<string name="title_activity_maps">Map</string>
<string name="action_geolocate">Pick Place</string>
<string name="default_info_title">Default Location</string>
<string name="default_info_snippet">No places found, because location permission is disabled.</string>
</resources>
Dodawanie paska aplikacji
- W eksploratorze projektu kliknij Android > app, a potem kliknij prawym przyciskiem myszy folder
res
i wybierz Nowy > Katalog, aby utworzyć nowy podkatalog w sekcjiapp/src/main/res
. - Nazwij katalog
menu
. - Kliknij prawym przyciskiem myszy folder
menu
i wybierz Nowy > Plik. - Nazwij plik
menu.xml
. - Wklej ten kod:
menu.xml
<?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">
<!-- "Locate me", should appear as action button if possible -->
<item
android:id="@+id/action_geolocate"
android:icon="@drawable/ic_geolocate"
android:title="@string/action_geolocate"
app:showAsAction="always|withText" />
</menu>
Aktualizowanie stylu paska aplikacji
- W eksploratorze projektu rozwiń sekcję Android & gt;
app
>res
>values
, a następnie otwórz plikstyles.xml
. - W tagu
<style>
zmień właściwość nadrzędną na"Theme.AppCompat.NoActionBar"
. - Zwróć uwagę na właściwość
name
, której użyjesz w następnym kroku.
styles.xml
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
Zaktualizuj motyw aplikacji w pliku AndroidManifest.xml
- Kliknij Android >
app
>manifests
, i otwórz plikAndroidManifest.xml
. - Znajdź wiersz
android:theme
i zmień lub potwierdź wartość, która ma być@style/AppTheme
.
AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
Możesz teraz zacząć programować.
9. Inicjowanie aplikacji
- Znajdź plik
MapsActivity.java
w eksploratorze projektu.
Jest on w folderze odpowiadającym pakietowi utworzonemu w kroku 1 dla aplikacji.
- Otwórz plik w edytorze kodu Java.
Importowanie pakietu SDK Miejsc i innych zależności
Dodaj te wiersze u góry tabeli MapsActivity.java
, zastępując istniejące instrukcje importu.
Obejmują one istniejące importy i umożliwiają dodanie wielu innych elementów używanych w kodzie w tym ćwiczeniu z programowania.
MapsActivity.java
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.libraries.places.api.Places;
import com.google.android.libraries.places.api.model.Place;
import com.google.android.libraries.places.api.model.PlaceLikelihood;
import com.google.android.libraries.places.api.net.FindCurrentPlaceRequest;
import com.google.android.libraries.places.api.net.FindCurrentPlaceResponse;
import com.google.android.libraries.places.api.net.PlacesClient;
import java.util.Arrays;
import java.util.List;
Aktualizowanie podpisu zajęć
Interfejs Places API używa komponentów Android X, aby zapewnić zgodność wsteczną, więc musisz go zdefiniować, aby poszerzyć pole AppCompatActivity
. Zastępuje rozszerzenie FragmentActivity
, które jest domyślnie zdefiniowane w przypadku aktywności na mapie.
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
Dodawanie zmiennych klasy
Następnie zadeklaruj różne zmienne klas używane w różnych metodach klasy. Obejmują one elementy interfejsu i kody stanu. Powinny one znajdować się poniżej deklaracji zmiennej GoogleMap mMap
.
// New variables for Current Place picker
private static final String TAG = "MapsActivity";
ListView lstPlaces;
private PlacesClient mPlacesClient;
private FusedLocationProviderClient mFusedLocationProviderClient;
// The geographical location where the device is currently located. That is, the last-known
// location retrieved by the Fused Location Provider.
private Location mLastKnownLocation;
// A default location (Sydney, Australia) and default zoom to use when location permission is
// not granted.
private final LatLng mDefaultLocation = new LatLng(-33.8523341, 151.2106085);
private static final int DEFAULT_ZOOM = 15;
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private boolean mLocationPermissionGranted;
// Used for selecting the Current Place.
private static final int M_MAX_ENTRIES = 5;
private String[] mLikelyPlaceNames;
private String[] mLikelyPlaceAddresses;
private String[] mLikelyPlaceAttributions;
private LatLng[] mLikelyPlaceLatLngs;
Zaktualizuj metodę onCreate
Musisz zaktualizować metodę onCreate
, aby obsługiwać uprawnienia użytkowników w środowisku wykonawczym dotyczące usług lokalizacyjnych, skonfigurować elementy interfejsu i utworzyć klienta interfejsu Places API.
Dodaj następujące wiersze kodu dotyczące paska narzędzi działań, konfiguracji widoków danych i klienta Miejsc na końcu obecnej metody onCreate()
.
MapsActivity.java onCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
//
// PASTE THE LINES BELOW THIS COMMENT
//
// Set up the action toolbar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Set up the views
lstPlaces = (ListView) findViewById(R.id.listPlaces);
// Initialize the Places client
String apiKey = getString(R.string.google_maps_key);
Places.initialize(getApplicationContext(), apiKey);
mPlacesClient = Places.createClient(this);
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
}
Dodawanie kodu menu paska aplikacji
Te 2 metody dodają menu na pasku aplikacji (z 1 elementem, ikoną Wybierz miejsce) i kliknij ikonę użytkownika.
Skopiuj te 2 metody do pliku po metodzie onCreate
.
MapsActivity.java onCreateOptionsMenu() i onOptionsItemSelected()
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_geolocate:
// COMMENTED OUT UNTIL WE DEFINE THE METHOD
// Present the current place picker
// pickCurrentPlace();
return true;
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
Testowanie
- W Android Studio kliknij Uruchom lub Uruchom menu > Uruchom „app'”.
- Musisz wybrać cel wdrożenia. Na tej liście powinien być widoczny emulator uruchomiony. Wybierz ją, a Android Studio wdroży aplikację w emulatorze.
Po kilku chwilach aplikacja się uruchamia. Wyświetlasz mapę w Sydney w Australii z jednym przyciskiem i listą niezapełnionych miejsc.
Mapa nie zostanie przeniesiona do lokalizacji użytkownika, chyba że poprosisz o dostęp do lokalizacji urządzenia.
10. Prośba o dostęp do lokalizacji i jej obsługa
Poproś o dostęp do lokalizacji, gdy mapa będzie gotowa
- Zdefiniuj metodę o nazwie
getLocationPermission
, która prosi o uprawnienia użytkowników.
Wklej ten kod pod nowo utworzoną metodę onOptionsSelected
.
MapsActivity.java getLocationPermission()
private void getLocationPermission() {
/*
* Request location permission, so that we can get the location of the
* device. The result of the permission request is handled by a callback,
* onRequestPermissionsResult.
*/
mLocationPermissionGranted = false;
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
} else {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
}
- Dodaj 2 wiersze na końcu obecnej metody
onMapReady
, aby włączyć sterowanie powiększeniem i poprosić użytkownika o dostęp do lokalizacji.
MapsActivity.java onMapReady()
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
//
// PASTE THE LINES BELOW THIS COMMENT
//
// Enable the zoom controls for the map
mMap.getUiSettings().setZoomControlsEnabled(true);
// Prompt the user for permission.
getLocationPermission();
}
Obsługa wyniku z żądanych uprawnień
Gdy użytkownik odpowie na okno z prośbą o zgodę na wykorzystanie danych, wywołanie zwrotne jest wywoływane przez Androida.
Wklej ten kod po metodzie getLocationPermission()
:
MapsActivity.java onRequestPermissionsResult()
/**
* Handles the result of the request for location permissions
*/
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[],
@NonNull int[] grantResults) {
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
}
}
}
11. Pobierz bieżącą lokalizację i pobierz prawdopodobne miejsca
Gdy użytkownik kliknie Wybierz miejsce na pasku aplikacji, aplikacja wywołuje metodę pickCurrentPlace()
, która wywołuje wcześniej zdefiniowaną metodę getDeviceLocation()
. Po pobraniu najnowszej lokalizacji urządzenia metoda getDeviceLocation
wywołuje inną metodę, getCurrentPlaceLikelihoods,
.
Wywołanie interfejsu API FindCurrentPlace i obsługuj odpowiedź
getCurrentPlaceLikelihoods
tworzy findCurrentPlaceRequest
i wywołuje zadanie Places API findCurrentPlace
. Jeśli zadanie zostanie ukończone, zostanie zwrócony obiekt findCurrentPlaceResponse
zawierający listę obiektów placeLikelihood
. Każda z nich ma kilka właściwości, w tym nazwę i adres miejsca oraz prawdopodobieństwo, że znajdziesz się w tym miejscu (wartość podwójna od 0 do 1). Ta metoda obsługuje odpowiedzi, tworząc listy miejsc z placeLikelihoods
.
Kod ten analizuje 5 najpopularniejszych miejsc i dodaje do tej listy te, które mają prawdopodobieństwo wyższe niż 0. Jeśli chcesz wyświetlić wartość większą lub mniejszą niż 5, zmodyfikuj stałą M_MAX_ENTRIES
.
Wklej ten kod po metodzie onMapReady
.
MapsActivity.java getCurrentPlaceLikeliationals()
private void getCurrentPlaceLikelihoods() {
// Use fields to define the data types to return.
List<Place.Field> placeFields = Arrays.asList(Place.Field.NAME, Place.Field.ADDRESS,
Place.Field.LAT_LNG);
// Get the likely places - that is, the businesses and other points of interest that
// are the best match for the device's current location.
@SuppressWarnings("MissingPermission") final FindCurrentPlaceRequest request =
FindCurrentPlaceRequest.builder(placeFields).build();
Task<FindCurrentPlaceResponse> placeResponse = mPlacesClient.findCurrentPlace(request);
placeResponse.addOnCompleteListener(this,
new OnCompleteListener<FindCurrentPlaceResponse>() {
@Override
public void onComplete(@NonNull Task<FindCurrentPlaceResponse> task) {
if (task.isSuccessful()) {
FindCurrentPlaceResponse response = task.getResult();
// Set the count, handling cases where less than 5 entries are returned.
int count;
if (response.getPlaceLikelihoods().size() < M_MAX_ENTRIES) {
count = response.getPlaceLikelihoods().size();
} else {
count = M_MAX_ENTRIES;
}
int i = 0;
mLikelyPlaceNames = new String[count];
mLikelyPlaceAddresses = new String[count];
mLikelyPlaceAttributions = new String[count];
mLikelyPlaceLatLngs = new LatLng[count];
for (PlaceLikelihood placeLikelihood : response.getPlaceLikelihoods()) {
Place currPlace = placeLikelihood.getPlace();
mLikelyPlaceNames[i] = currPlace.getName();
mLikelyPlaceAddresses[i] = currPlace.getAddress();
mLikelyPlaceAttributions[i] = (currPlace.getAttributions() == null) ?
null : TextUtils.join(" ", currPlace.getAttributions());
mLikelyPlaceLatLngs[i] = currPlace.getLatLng();
String currLatLng = (mLikelyPlaceLatLngs[i] == null) ?
"" : mLikelyPlaceLatLngs[i].toString();
Log.i(TAG, String.format("Place " + currPlace.getName()
+ " has likelihood: " + placeLikelihood.getLikelihood()
+ " at " + currLatLng));
i++;
if (i > (count - 1)) {
break;
}
}
// COMMENTED OUT UNTIL WE DEFINE THE METHOD
// Populate the ListView
// fillPlacesList();
} else {
Exception exception = task.getException();
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
Log.e(TAG, "Place not found: " + apiException.getStatusCode());
}
}
}
});
}
Umieść kamerę na mapie w bieżącej lokalizacji urządzenia
Jeśli użytkownik pozwoli na korzystanie z tej funkcji, aplikacja pobierze jego najnowszą lokalizację, a następnie powiększy kamerę.
Jeśli użytkownik odmówi przyznania uprawnień, aplikacja przeniesie aparat do domyślnej lokalizacji zdefiniowanej wśród stałych na początku tej strony (w przykładowym kodzie jest to Sydney w Australii).
Wklej ten kod po metodzie getPlaceLikelihoods()
:
MapsActivity.java getDeviceLocation()
private void getDeviceLocation() {
/*
* Get the best and most recent location of the device, which may be null in rare
* cases when a location is not available.
*/
try {
if (mLocationPermissionGranted) {
Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation();
locationResult.addOnCompleteListener(this, new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
if (task.isSuccessful()) {
// Set the map's camera position to the current location of the device.
mLastKnownLocation = task.getResult();
Log.d(TAG, "Latitude: " + mLastKnownLocation.getLatitude());
Log.d(TAG, "Longitude: " + mLastKnownLocation.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(mLastKnownLocation.getLatitude(),
mLastKnownLocation.getLongitude()), DEFAULT_ZOOM));
} else {
Log.d(TAG, "Current location is null. Using defaults.");
Log.e(TAG, "Exception: %s", task.getException());
mMap.moveCamera(CameraUpdateFactory
.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
}
getCurrentPlaceLikelihoods();
}
});
}
} catch (SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
Sprawdzanie dostępu do lokalizacji, gdy użytkownik kliknie Wybierz miejsce
Gdy użytkownik kliknie Wybierz miejsce, ta metoda sprawdzi dostęp do lokalizacji i wyświetli użytkownikowi prośbę o przyznanie uprawnień, jeśli jej nie przyzna.
Jeśli użytkownik udzielił zgody, ta metoda wywołuje metodę getDeviceLocation
, by rozpocząć proces pobierania informacji o aktualnie dostępnych miejscach.
- Dodaj tę metodę po
getDeviceLocation()
:
MapsActivity.java selectCurrentPlace()
private void pickCurrentPlace() {
if (mMap == null) {
return;
}
if (mLocationPermissionGranted) {
getDeviceLocation();
} else {
// The user has not granted permission.
Log.i(TAG, "The user did not grant location permission.");
// Add a default marker, because the user hasn't selected a place.
mMap.addMarker(new MarkerOptions()
.title(getString(R.string.default_info_title))
.position(mDefaultLocation)
.snippet(getString(R.string.default_info_snippet)));
// Prompt the user for permission.
getLocationPermission();
}
}
- Po zdefiniowaniu elementu
pickCurrentPlace
znajdź wiersz wonOptionsItemSelected()
, który wywołuje poleceniepickCurrentPlace
, i usuń komentarz.
MapsActivity.java onOptionItemSelected()
case R.id.action_geolocate:
// COMMENTED OUT UNTIL WE DEFINE THE METHOD
// Present the Current Place picker
pickCurrentPlace();
return true;
Testowanie
Jeśli uruchomisz aplikację teraz i klikniesz Wybierz miejsce, aplikacja powinna poprosić o dostęp do lokalizacji.
- Jeśli zezwolisz na dostęp, preferencje zostaną zapisane i nie pojawi się pytanie. Gdy odmówisz zgody, po następnym kliknięciu przycisku pojawi się prośba.
getPlaceLikelihoods
pobrał(a) prawdopodobne bieżące miejsca, aleListView
ich nie wyświetla. W Android Studio możesz kliknąć ⌘6, aby sprawdzić dzienniki w Logcat pod kątem instrukcji oznaczonych tagiem MapsActivity, aby sprawdzić, czy nowe metody działają prawidłowo.- Jeśli przyznasz odpowiednie uprawnienia, dzienniki będą zawierać instrukcję
Latitude:
oraz instrukcjęLongitude:
wykrywającą lokalizację urządzenia. Jeśli do określenia lokalizacji dla emulatora wcześniej użyto Map Google i rozwiniętego menu emulatora, instrukcje te wskazują tę lokalizację. - Jeśli Udało się wywołać interfejs
findCurrentPlace
, dzienniki zawierają 5 informacji, które wydrukują imiona i nazwiska oraz lokalizacje pięciu miejsc.
12. Wypełnij selektor bieżącego miejsca
Konfigurowanie modułu obsługi wybranych miejsc
Zastanówmy się, co mamy zrobić, gdy użytkownik kliknie pozycję w ListView
. Aby potwierdzić wybór użytkownika, który jest w danym miejscu, możesz dodać znacznik do mapy w tym miejscu. Jeśli użytkownik kliknie ten znacznik, wyświetli się okno informacyjne z nazwą i adresem miejsca.
Wklej ten moduł do obsługi kliknięć po metodzie pickCurrentPlace
.
MapsActivity.java listClickedHandler
private AdapterView.OnItemClickListener listClickedHandler = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
// position will give us the index of which place was selected in the array
LatLng markerLatLng = mLikelyPlaceLatLngs[position];
String markerSnippet = mLikelyPlaceAddresses[position];
if (mLikelyPlaceAttributions[position] != null) {
markerSnippet = markerSnippet + "\n" + mLikelyPlaceAttributions[position];
}
// Add a marker for the selected place, with an info window
// showing information about that place.
mMap.addMarker(new MarkerOptions()
.title(mLikelyPlaceNames[position])
.position(markerLatLng)
.snippet(markerSnippet));
// Position the map's camera at the location of the marker.
mMap.moveCamera(CameraUpdateFactory.newLatLng(markerLatLng));
}
};
Wypełnianie listy
Mając już listę z największym prawdopodobieństwem odwiedzanej przez użytkownika miejsca, możesz wyświetlić te opcje w ListView
. Możesz też ustawić detektor kliknięć ListView
tak, aby używał właśnie zdefiniowanego modułu obsługi kliknięć.
Wklej tę metodę po module obsługi kliknięć:
MapsActivity.java FillPlacesList()
private void fillPlacesList() {
// Set up an ArrayAdapter to convert likely places into TextViews to populate the ListView
ArrayAdapter<String> placesAdapter =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mLikelyPlaceNames);
lstPlaces.setAdapter(placesAdapter);
lstPlaces.setOnItemClickListener(listClickedHandler);
}
Teraz, gdy fillPlacesList
jest zdefiniowany, znajdź wiersz na końcu findPlaceLikelihoods
, który wywołuje fillPlacesList
, i cofnij jego komentarz.
MapsActivity.java FillPlaceLikeliationals()
// COMMENTED OUT UNTIL WE DEFINE THE METHOD
// Populate the ListView
fillPlacesList();
To cały kod wymagany do selektora bieżącego miejsca.
13. Uruchom aplikację
Testowanie miejsca
- Ponownie uruchom aplikację.
Tym razem gdy klikniesz Wybierz miejsce, aplikacja zapełni listę na podstawie nazw miejsc w pobliżu tej lokalizacji. Niedaleko tej lokalizacji na Maui znajdują się takie miejsca jak Ululani&hl=pl's Hawaiian Shave Ice i Sugar Beach Bake Shop. Kilka miejsc znajduje się bardzo blisko współrzędnych lokalizacji, dlatego jest to lista prawdopodobnie odwiedzonych przez Ciebie miejsc.
- Kliknij nazwę miejsca w kolumnie
ListView
.
Powinien pojawić się znacznik na mapie.
- Kliknij znacznik.
Wyświetlą się szczegółowe informacje o miejscu.
Testowanie innej lokalizacji
Jeśli chcesz zmienić lokalizację i korzystasz z emulatora, lokalizacja urządzenia nie jest automatycznie aktualizowana podczas aktualizowania współrzędnych lokalizacji w emulatorze i rozszerzonym menu.
Aby obejść ten problem, wykonaj te czynności, aby wymusić aktualizację lokalizacji emulatora:
- Otwórz Mapy Google.
- Wybierz ... > Lokalizacja, aby zmienić szerokość i długość geograficzną na nowe współrzędne, a następnie kliknij Wyślij.
- Możesz na przykład podać lokalizację 49, 2768 i Długość geograficzna: -123, 1142 w celu ustawienia lokalizacji na centrum Vancouver w Kanadzie.
- Sprawdź, czy w Mapach Google zostały niedawno wprowadzone nowe współrzędne. Może być konieczne kliknięcie przycisku Moja lokalizacja w aplikacji Mapy Google.
- Wróć do aplikacji Aktualne miejsce i kliknij Wybierz miejsce, aby zobaczyć mapę na nowych współrzędnych i zobaczyć nową listę prawdopodobnie aktualnych miejsc.
Gotowe! Udało Ci się utworzyć prostą aplikację, która sprawdza miejsca w bieżącej lokalizacji i przewiduje, które z nich są aktualne. Miłego korzystania z punktów.
Teraz możesz uruchomić aplikację z wprowadzonymi przez Ciebie zmianami, aby zakończyć ten dodatkowy krok!
14. Dalsze kroki
Aby zapobiec kradzieży klucza interfejsu API, musisz go zabezpieczyć tak, by mógł z niego korzystać tylko Twoja aplikacja na Androida. Jeśli pozostawisz to pole nieograniczone, każda osoba, która będzie miała Twój klucz, będzie mogła go używać do wywoływania interfejsów API Google Maps Platform i do naliczania opłat.
Pobieranie certyfikatu SHA-1
Będzie Ci ona potrzebna później, gdy ograniczysz klucze interfejsu API. Poniżej znajdziesz instrukcje, jak uzyskać certyfikat debugowania.
W systemie Linux lub macOS otwórz okno terminala i wpisz te informacje:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
W systemach Windows Vista i Windows 7 uruchom następujące polecenie:
keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
Dane wyjściowe powinny wyglądać podobnie do tych:
Alias name: androiddebugkey Creation date: Jan 01, 2013 Entry type: PrivateKeyEntry Certificate chain length: 1 Certificate[1]: Owner: CN=Android Debug, O=Android, C=US Issuer: CN=Android Debug, O=Android, C=US Serial number: 4aa9b300 Valid from: Mon Jan 01 08:04:04 UTC 2013 until: Mon Jan 01 18:04:04 PST 2033 Certificate fingerprints: MD5: AE:9F:95:D0:A6:86:89:BC:A8:70:BA:34:FF:6A:AC:F9 SHA1: BB:0D:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:75 Signature algorithm name: SHA1withRSA Version: 3
Wiersz zaczynający się od SHA1 zawiera odcisk cyfrowy certyfikatu SHA-1 certyfikatu. Odcisk cyfrowy jest sekwencją 20 cyfr szesnastkowych rozdzielonych dwukropkami.
Gdy wszystko będzie gotowe do opublikowania aplikacji, wykonaj instrukcje opisane w tej dokumentacji, aby pobrać certyfikat wersji.
Dodawanie ograniczeń do klucza interfejsu API
- W Cloud Console otwórz APIs & Services > Credentials (Dane logowania).
Klucz używany w tej aplikacji powinien być widoczny w sekcji Klucze API.
- Kliknij
, aby edytować ustawienia kluczyka.
- Na stronie klucza interfejsu API w sekcji Ograniczenia klucza ustaw Ograniczenia aplikacji, wykonując te czynności:
- Wybierz Aplikacje na Androida i postępuj zgodnie z instrukcjami.
- Kliknij Dodaj produkt.
- Wpisz nazwę pakietu i odcisk cyfrowy certyfikatu SHA-1 (pobrane w poprzedniej sekcji).
Przykład:
com.google.codelab.currentplace
BB:0D:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:75s
- Aby zapewnić sobie dodatkową ochronę, ustaw Ograniczenia interfejsu API, wykonując opisane poniżej czynności.
- Po wprowadzeniu ograniczeń interfejsu API wybierz Ogranicz klucz.
- Wybierz pakiet SDK Maps na Androida i interfejs Places API.
- Kliknij Gotowe i Zapisz.
15. Gratulacje
Udało Ci się utworzyć prostą aplikację, która sprawdza, które miejsca w danej lokalizacji są najbardziej prawdopodobne, i dodać do mapy znacznik miejsca wybranego przez użytkownika.
Więcej informacji
- Aby przyspieszyć programowanie, użyj pakietu SDK Map Google na Androida. Te narzędzia to ciężka praca w przypadku najpopularniejszych zadań związanych z aplikacjami korzystającymi z Google Maps Platform.
- Aby zobaczyć więcej przykładów kodu pokazujących większość funkcji pakietów Google Maps Platform SDK na Androida, utwórz kopie repozytoriów dla przykładowych pakietów Maps SDK na Androida i Places SDK na Androida.
- Aby dowiedzieć się, jak korzystać z uprawnień dostępu do lokalizacji w trybie trójstanowym w Androidzie Q, wykonaj ćwiczenia z ćwiczenia z kursu Odbieranie aktualizacji lokalizacji w Androidzie przy użyciu aplikacji Kotlin.