1. Hinweis
Hier erfahren Sie, wie Sie die Google Maps Platform und das Places SDK for Android verwenden, um Ihren Nutzern eine Liste von Orten zu präsentieren, damit sie ihren aktuellen Standort ermitteln können.
Vorbereitung
- Grundkenntnisse in Java
Aufgaben
- Karte in eine Android-App einbinden
- Verwenden Sie Standortberechtigungen, um den Standort des Nutzers zu ermitteln.
- Orte in der Nähe des aktuellen Standorts des Nutzers abrufen.
- Dem Nutzer werden wahrscheinliche Orte angezeigt, damit er seinen aktuellen Standort identifizieren kann.
Aufgaben
Sie erstellen Ihre Android-App von Grund auf neu, können aber den Beispielcode zum Vergleichen herunterladen, wenn Sie Fehler beheben. Laden Sie den Beispielcode von GitHub herunter oder geben Sie Folgendes ein, wenn Sie Git für die Befehlszeile eingerichtet haben:
git clone https://github.com/googlecodelabs/current-place-picker-android.git
Wenn Sie bei der Bearbeitung dieses Codelabs auf Probleme stoßen (z. B. Codefehler, Grammatikfehler, unklare Formulierungen), melden Sie das Problem bitte über den Link Fehler melden unten links im Codelab.
2. Jetzt starten
Bevor Sie mit diesem Codelab beginnen, müssen Sie Folgendes einrichten:
Android Studio
Laden Sie Android Studio unter https://developer.android.com/studio herunter.
Wenn Sie Android Studio bereits haben, prüfen Sie, ob Sie die neueste Version verwenden. Klicken Sie dazu auf Android Studio > Check for Updates... (Nach Updates suchen).
Dieses Lab wurde mit Android Studio 3.4 erstellt.
Android SDK
In Android Studio können Sie die gewünschten SDKs mit dem SDK Manager konfigurieren. In diesem Lab wird das Android Q SDK verwendet.
- Klicken Sie auf dem Android Studio-Begrüßungsbildschirm auf Konfigurieren > SDK-Manager.
- Klicken Sie das Kästchen für das gewünschte SDK an und dann auf Übernehmen.
Wenn Sie das SDK noch nicht haben, wird es auf Ihren Computer heruntergeladen.
Google Play-Dienste
Außerdem müssen Sie die Google Play-Dienste über den SDK Manager installieren.
- Klicken Sie auf den Tab SDK Tools und wählen Sie das Kästchen Google Play Services aus.
Aktualisieren Sie die App, wenn der Status Update verfügbar lautet.
3. Emulator vorbereiten
Um die App auszuführen, können Sie Ihr eigenes Gerät anschließen oder den Android-Emulator verwenden.
Wenn Sie Ihr eigenes Gerät verwenden, fahren Sie mit Anleitung für echte Geräte: Google Play-Dienste aktualisieren am Ende dieser Seite fort.
Emulator hinzufügen
- Klicken Sie im Android Studio-Begrüßungsbildschirm auf Configure > AVD Manager.
Dadurch wird das Dialogfeld Android Virtual Device Manager geöffnet.
- Klicken Sie auf Virtuelles Gerät erstellen…, um eine Liste der Geräte zu öffnen, aus denen Sie auswählen können.
- Wählen Sie in der Spalte Play Store ein Gerät mit dem Play-Symbol
aus und klicken Sie auf Weiter.
Es wird eine Reihe von System-Images angezeigt, die Sie installieren können. Wenn neben Q-Targeting Android 9.+ (Google Play) das Wort Herunterladen steht, klicken Sie auf Herunterladen.
- Klicken Sie auf Weiter, um Ihrem virtuellen Gerät einen Namen zu geben, und klicken Sie dann auf Fertig stellen.
Sie kehren zur Liste Meine virtuellen Geräte zurück.
- Klicken Sie neben Ihrem neuen Gerät auf „Starten“
:
Nach einigen Augenblicken wird der Emulator geöffnet.
Emulatoranleitung – Google Play-Dienste aktualisieren
- Klicken Sie nach dem Start des Emulators in der angezeigten Navigationsleiste auf …**.**
Dadurch wird das Dialogfeld Erweiterte Einstellungen geöffnet.
- Klicken Sie im Menü auf Google Play.
Wenn ein Update verfügbar ist, klicken Sie auf Aktualisieren.
- Melden Sie sich mit einem Google-Konto im Emulator an.
Sie können Ihr eigenes Konto verwenden oder kostenlos ein neues Konto erstellen, um Ihre Tests von Ihren persönlichen Daten zu trennen.
Google Play wird dann mit den Google Play-Diensten geöffnet.
- Klicken Sie auf Aktualisieren, um die neueste Version der Google Play-Dienste zu erhalten.
Wenn Sie aufgefordert werden, die Kontoeinrichtung abzuschließen und eine Zahlungsmethode hinzuzufügen, klicken Sie auf Überspringen.
Standort im Emulator festlegen
- Wenn der Emulator gestartet wurde, geben Sie auf dem Startbildschirm „maps“ in die Suchleiste ein, um das Google Maps App-Symbol aufzurufen.
- Klicken Sie auf das Symbol, um die App zu starten.
Sie sehen eine Standardkarte.
- Klicken Sie rechts unten auf der Karte auf Mein Standort
.
Sie werden aufgefordert, dem Smartphone die Berechtigung zur Verwendung des Standorts zu erteilen.
- Klicken Sie auf …, um das Menü Erweiterte Steuerelemente zu öffnen.
- Klicken Sie auf den Tab Standort.
- Geben Sie einen Breiten- und einen Längengrad ein.
Geben Sie hier einen beliebigen Ort ein, aber achten Sie darauf, dass es sich um eine Gegend mit vielen Orten handelt.
Verwenden Sie den Breitengrad 20.7818 und den Längengrad -156.4624 für die Stadt Kihei auf Maui in Hawaii, um die Ergebnisse aus diesem Codelab zu reproduzieren.
- Klicken Sie auf Senden. Die Karte wird mit diesem Standort aktualisiert.
Sie können Ihre App jetzt ausführen und mit Standort testen.
Anleitung für echte Geräte – Google Play-Dienste aktualisieren
Wenn Sie ein echtes Android-Gerät verwenden, gehen Sie so vor:
- Suchen Sie über die Suchleiste auf dem Startbildschirm nach Google Play-Dienste und öffnen Sie die App.
- Klicken Sie auf Weitere Informationen.
Klicken Sie, sofern verfügbar, auf Aktualisieren.
4. App-Shell mit einer Google Maps-Aktivität erstellen
- Wählen Sie auf dem Android Studio-Begrüßungsbildschirm Start a new Android Studio project aus.
- Wählen Sie auf dem Tab Smartphone und Tablet die Option Google Maps-Aktivitäten aus.
Das Dialogfeld Projekt konfigurieren wird geöffnet. Hier geben Sie Ihrer App einen Namen und erstellen das Paket basierend auf Ihrer Domain.
Hier sind die Einstellungen für eine App namens „Current Place“, die dem Paket com.google.codelab.currentplace
entspricht.
- Wählen Sie Java als Sprache aus und aktivieren Sie androidx-Artefakte verwenden*.
Übernehmen Sie für die übrigen Einstellungen jeweils die Standardeinstellung.
- Klicken Sie auf Fertig.
5. Google-Dienste-Abhängigkeiten der Gradle-Build-Datei hinzufügen
Für den Zugriff auf Standortberechtigungen in Android benötigen Sie die Google Location and Activity Recognition API aus den Google Play-Diensten. Weitere Informationen zum Hinzufügen dieser und anderer Google Play-Dienste-APIs finden Sie unter Google Play-Dienste einrichten.
Android Studio-Projekte haben in der Regel zwei build.gradle
-Dateien. Eine für das gesamte Projekt und eine für die App. Wenn Sie den Android Studio-Projektexplorer in der Ansicht Android haben, sehen Sie beide im Ordner Gradle Scripts
. Sie müssen die Datei build.gradle (Module: app)
bearbeiten, um Google-Dienste hinzuzufügen.
- Fügen Sie dem Abschnitt
dependencies
zwei Zeilen hinzu, um Google-Dienste für Standort und die Places API hinzuzufügen ( Beispielcode im Kontext).
build.gradle (Module: app)
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. Google Maps Platform APIs aktivieren und API-Schlüssel abrufen
Für den folgenden Aktivierungsschritt müssen Sie das Maps SDK for Android und die Places API aktivieren.
Google Maps Platform einrichten
Wenn Sie noch kein Google Cloud-Konto und kein Projekt mit aktivierter Abrechnung haben, lesen Sie bitte den Leitfaden Erste Schritte mit Google Maps Platform, um ein Rechnungskonto und ein Projekt zu erstellen.
- Klicken Sie in der Cloud Console auf das Drop-down-Menü für das Projekt und wählen Sie das Projekt aus, das Sie für dieses Codelab verwenden möchten.
- Aktivieren Sie die für dieses Codelab erforderlichen APIs und SDKs der Google Maps Platform im Google Cloud Marketplace. Folgen Sie dazu der Anleitung in diesem Video oder dieser Dokumentation.
- Generieren Sie einen API-Schlüssel in der Cloud Console auf der Seite Anmeldedaten. Folgen Sie dazu dieser Anleitung oder dieser Dokumentation. Für alle Anfragen an die Google Maps Platform ist ein API-Schlüssel erforderlich.
Kopieren Sie den gerade erstellten API-Schlüssel. Wechseln Sie zurück zu Android Studio und suchen Sie die Datei google_maps_api.xml
unter Android > app > res > values.
Ersetzen Sie YOUR_KEY_HERE
durch den kopierten API-Schlüssel.
Ihre App ist jetzt konfiguriert.
7. Layoutdatei bearbeiten
- Öffnen Sie im Projekt-Explorer die Datei
activity_maps.xml
unter Android >app
>res
>layout
.
- Die grundlegende Benutzeroberfläche wird rechts auf dem Bildschirm geöffnet. Über die Tabs unten können Sie den Design- oder Texteditor für Ihr Layout auswählen. Wählen Sie Text aus und ersetzen Sie den gesamten Inhalt der Layoutdatei durch Folgendes:
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>
Dadurch erhalten Sie eine Benutzeroberfläche, die so aussieht:
8. App-Leiste einrichten
Wenn Sie dem Nutzer eine Schaltfläche zur Auswahl seines aktuellen Standorts zur Verfügung stellen möchten, fügen Sie eine App-Leiste mit einem Symbol hinzu, über das der aktuelle Standort des Nutzers ermittelt und wahrscheinliche Orte in der Nähe angezeigt werden. Diese sieht wie folgt aus:
Auf einem Smartphone wird nur das Symbol angezeigt. Auf einem Tablet mit mehr Platz wird der Text ebenfalls angezeigt.
Symbol erstellen
- Klicken Sie im Projekt-Explorer auf Android > app, klicken Sie dann mit der rechten Maustaste auf den Ordner res und wählen Sie Neu > Image Asset aus.
Asset Studio wird geöffnet.
- Klicken Sie im Menü Symboltyp auf Aktionsleisten- und Tabsymbole.
- Geben Sie dem Asset den Namen
ic_geolocate
. - Wählen Sie Clip Art als Asset-Typ aus.
- Klicken Sie auf die Grafik neben ClipArt.
Dadurch wird das Fenster Symbol auswählen geöffnet.
- Wähle ein Symbol aus.
Über die Suchleiste können Sie nach Symbolen suchen, die zu Ihrer Intention passen.
- Suchen Sie nach
location
und wählen Sie ein standortbezogenes Symbol aus.
Das Symbol Mein Standort ist dasselbe wie in der Google Maps App, wenn ein Nutzer die Kamera auf seinen aktuellen Standort ausrichten möchte.
- Klicken Sie auf OK > Weiter > Fertigstellen und prüfen Sie, ob ein neuer Ordner mit dem Namen
drawable
vorhanden ist, der Ihre neuen Symboldateien enthält.
String-Ressourcen hinzufügen
- Klicken Sie im Projekt-Explorer auf Android > app > res > values und öffnen Sie die Datei
strings.xml
. - Fügen Sie die folgenden Zeilen nach
<string name="title_activity_maps">Map</string>
ein:
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>
Die erste Zeile wird in der App-Leiste verwendet, wenn neben dem Symbol Platz für ein Textlabel ist. Die anderen werden für Markierungen verwendet, die Sie der Karte hinzufügen.
Der Code in der Datei sieht jetzt so aus:
<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>
App-Leiste hinzufügen
- Klicken Sie im Projekt-Explorer auf Android > app, klicken Sie dann mit der rechten Maustaste auf den Ordner
res
und wählen Sie Neu > Verzeichnis aus, um ein neues Unterverzeichnis unterapp/src/main/res
zu erstellen. - Geben Sie dem Verzeichnis den Namen
menu
. - Klicken Sie mit der rechten Maustaste auf den Ordner
menu
und wählen Sie Neu > Datei aus. - Benennen Sie die Datei
menu.xml
. - Fügen Sie diesen Code ein:
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>
App-Leistenstil aktualisieren
- Maximieren Sie im Projekt-Explorer Android >
app
>res
>values
und öffnen Sie die Dateistyles.xml
. - Ändern Sie im Tag
<style>
das Attribut „parent“ in"Theme.AppCompat.NoActionBar"
. - Notieren Sie sich die
name
-Eigenschaft, die Sie im nächsten Schritt verwenden.
styles.xml
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
App-Theme in AndroidManifest.xml aktualisieren
- Klicken Sie auf Android >
app
>manifests
und öffnen Sie die DateiAndroidManifest.xml
. - Suchen Sie die Zeile
android:theme
und bearbeiten oder bestätigen Sie den Wert@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">
Jetzt können Sie mit dem Programmieren beginnen.
9. App initialisieren
- Suchen Sie im Projekt-Explorer nach der Datei
MapsActivity.java
.
Sie befindet sich in dem Ordner, der dem Paket entspricht, das Sie in Schritt 1 für Ihre App erstellt haben.
- Öffnen Sie die Datei. Sie befinden sich jetzt im Java-Codeeditor.
Places SDK und andere Abhängigkeiten importieren
Fügen Sie diese Zeilen oben in MapsActivity.java
ein und ersetzen Sie die vorhandenen Importanweisungen.
Sie enthalten die vorhandenen Importe und viele weitere, die im Code in diesem Codelab verwendet werden.
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;
Klassensignatur aktualisieren
Die Places API verwendet AndroidX-Komponenten für die Abwärtskompatibilität. Daher müssen Sie sie definieren, um die AppCompatActivity
zu erweitern. Sie ersetzt die FragmentActivity
-Erweiterung, die standardmäßig für eine Maps-Aktivität definiert ist.
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
Klassenvariablen hinzufügen
Als Nächstes deklarieren Sie die verschiedenen Klassenvariablen, die in den verschiedenen Klassenmethoden verwendet werden. Dazu gehören die UI-Elemente und Statuscodes. Sie sollten direkt unter der Variablendeklaration für GoogleMap mMap
stehen.
// 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;
onCreate-Methode aktualisieren
Sie müssen die Methode onCreate
aktualisieren, um die Nutzerberechtigungen für Standortdienste zur Laufzeit zu verarbeiten, die UI-Elemente einzurichten und den Places API-Client zu erstellen.
Fügen Sie die folgenden Codezeilen für die Aktionssymbolleiste, die Einrichtung der Ansichten und den Places-Client am Ende der vorhandenen onCreate()
-Methode ein.
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);
}
Code für das App-Leistenmenü hinzufügen
Mit diesen beiden Methoden wird das App-Leistenmenü (mit einem einzelnen Element, dem Symbol „Ort auswählen“) hinzugefügt und der Klick des Nutzers auf das Symbol verarbeitet.
Kopieren Sie diese beiden Methoden nach der Methode onCreate
in Ihre Datei.
MapsActivity.java onCreateOptionsMenu() und 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);
}
}
Jetzt testen
- Klicken Sie in Android Studio auf Ausführen oder Menü „Ausführen“ > „App“ ausführen.
- Sie werden aufgefordert, das Bereitstellungsziel auszuwählen. Der ausgeführte Emulator sollte in dieser Liste angezeigt werden. Wählen Sie es aus. Android Studio stellt die App dann für Sie auf dem Emulator bereit.
Nach wenigen Augenblicken wird die App gestartet. Die Karte wird mit Sydney, Australien, im Mittelpunkt angezeigt. Außerdem ist nur eine Schaltfläche zu sehen und die Liste der Orte ist leer.
Der Fokus der Karte wird nicht auf den Standort des Nutzers verschoben, es sei denn, Sie fordern die Berechtigung für den Zugriff auf den Standort des Geräts an.
10. Berechtigungen zur Standortermittlung anfordern und verarbeiten
Berechtigungen zur Standortermittlung anfordern, nachdem die Karte bereit ist
- Definieren Sie eine Methode namens
getLocationPermission
, die Nutzerberechtigungen anfordert.
Fügen Sie diesen Code unter der gerade erstellten onOptionsSelected
-Methode ein.
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);
}
}
- Fügen Sie am Ende der vorhandenen
onMapReady
-Methode zwei Zeilen hinzu, um die Zoomsteuerung zu aktivieren und Standortberechtigungen vom Nutzer anzufordern.
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();
}
Ergebnis der angeforderten Berechtigungen verarbeiten
Wenn der Nutzer auf das Dialogfeld „Berechtigung anfordern“ reagiert, wird dieser Callback von Android aufgerufen.
Fügen Sie diesen Code nach der Methode getLocationPermission()
ein:
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. Aktuellen Standort abrufen und wahrscheinliche Orte ermitteln
Wenn der Nutzer in der App-Leiste auf Pick Place (Ort auswählen) klickt, ruft die App die Methode pickCurrentPlace()
auf, die die zuvor definierte Methode getDeviceLocation()
aufruft. Die Methode getDeviceLocation
ruft nach dem Abrufen des letzten Gerätestandorts eine andere Methode auf: getCurrentPlaceLikelihoods,
.
findCurrentPlace-API aufrufen und Antwort verarbeiten
getCurrentPlaceLikelihoods
erstellt ein findCurrentPlaceRequest
und ruft die Places API-Aufgabe findCurrentPlace
auf. Wenn die Aufgabe erfolgreich ist, wird ein findCurrentPlaceResponse
zurückgegeben, das eine Liste von placeLikelihood
-Objekten enthält. Jeder dieser Orte hat eine Reihe von Eigenschaften, darunter den Namen und die Adresse des Orts sowie die Wahrscheinlichkeit, dass Sie sich an diesem Ort befinden (ein Double-Wert zwischen 0 und 1). Diese Methode verarbeitet die Antwort, indem sie Listen mit Ortsdetails aus der placeLikelihoods
erstellt.
Dieser Code durchläuft die fünf wahrscheinlichsten Orte und fügt diejenigen mit einer Wahrscheinlichkeit von mehr als 0 einer Liste hinzu, die dann gerendert wird. Wenn Sie mehr oder weniger als fünf anzeigen möchten, bearbeiten Sie die Konstante M_MAX_ENTRIES
.
Fügen Sie diesen Code nach der Methode onMapReady
ein.
MapsActivity.java getCurrentPlaceLikelihoods()
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());
}
}
}
});
}
Kartenkamera zum aktuellen Standort des Geräts bewegen
Wenn der Nutzer die Berechtigung erteilt, ruft die App den letzten Standort des Nutzers ab und zentriert die Kamera auf diesen Standort.
Wenn der Nutzer die Berechtigung verweigert, wird die Kamera einfach an den Standardspeicherort verschoben, der in den Konstanten am Anfang dieser Seite definiert ist (im Beispielcode ist das Sydney, Australien).
Fügen Sie diesen Code nach der Methode getPlaceLikelihoods()
ein:
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());
}
}
Berechtigungen zur Standortermittlung prüfen, wenn der Nutzer auf „Ort auswählen“ klickt
Wenn der Nutzer auf Pick Place (Ort auswählen) tippt, wird mit dieser Methode geprüft, ob Standortberechtigungen vorhanden sind. Falls nicht, wird der Nutzer aufgefordert, die Berechtigung zu erteilen.
Wenn der Nutzer die Berechtigung erteilt hat, ruft die Methode getDeviceLocation
auf, um den Vorgang zum Abrufen der aktuellen wahrscheinlichen Orte zu starten.
- Fügen Sie diese Methode nach
getDeviceLocation()
ein:
MapsActivity.java pickCurrentPlace()
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();
}
}
- Nachdem
pickCurrentPlace
definiert wurde, suchen Sie inonOptionsItemSelected()
nach der Zeile, in derpickCurrentPlace
aufgerufen wird, und entfernen Sie die Kommentarzeichen.
MapsActivity.java onOptionItemSelected()
case R.id.action_geolocate:
// COMMENTED OUT UNTIL WE DEFINE THE METHOD
// Present the Current Place picker
pickCurrentPlace();
return true;
Jetzt testen
Wenn Sie die App jetzt ausführen und auf Ort auswählen tippen, sollten Sie aufgefordert werden, die Berechtigungen zur Standortermittlung zu erteilen.
- Wenn Sie die Berechtigung erteilen, wird diese Einstellung gespeichert und Sie werden nicht noch einmal dazu aufgefordert. Wenn Sie die Berechtigung verweigern, werden Sie beim nächsten Tippen auf die Schaltfläche wieder dazu aufgefordert.
getPlaceLikelihoods
hat zwar die wahrscheinlichen aktuellen Orte abgerufen,ListView
zeigt sie aber noch nicht an. In Android Studio können Sie auf ⌘6 klicken, um die Logs in Logcat nach Anweisungen mit dem Tag MapsActivity zu durchsuchen und so zu prüfen, ob Ihre neuen Methoden richtig funktionieren.- Wenn Sie die Berechtigung erteilt haben, enthalten die Protokolle eine Anweisung für
Latitude:
und eine Anweisung fürLongitude:
mit dem erkannten Standort des Geräts. Wenn Sie Google Maps und das erweiterte Menü des Emulators verwendet haben, um einen Standort für den Emulator anzugeben, wird dieser Standort in diesen Anweisungen angezeigt. - Wenn der Aufruf von
findCurrentPlace
erfolgreich war, enthalten die Logs fünf Anweisungen, in denen die Namen und Standorte der fünf wahrscheinlichsten Orte ausgegeben werden.
12. Auswahl für „Aktueller Ort“ füllen
Handler für ausgewählte Orte einrichten
Überlegen wir uns, was passieren soll, wenn der Nutzer auf ein Element in der ListView
klickt. Um die Auswahl des Nutzers zu bestätigen, können Sie an diesem Ort eine Markierung auf der Karte hinzufügen. Wenn der Nutzer auf diese Markierung klickt, wird ein Infofenster mit dem Namen und der Adresse des Orts eingeblendet.
Fügen Sie diesen Klick-Handler nach der pickCurrentPlace
-Methode ein.
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));
}
};
ListView füllen
Nachdem Sie die Liste der wahrscheinlichsten Orte, die der Nutzer gerade besucht, erstellt haben, können Sie diese Optionen dem Nutzer in der ListView
präsentieren. Sie können auch den ListView
-Klick-Listener so festlegen, dass der gerade definierte Klick-Handler verwendet wird.
Fügen Sie diese Methode nach dem Klick-Handler ein:
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);
}
Nachdem fillPlacesList
definiert wurde, suchen Sie die Zeile gegen Ende von findPlaceLikelihoods
, in der fillPlacesList
aufgerufen wird, und entfernen Sie die Kommentarzeichen.
MapsActivity.java fillPlaceLikelihoods()
// COMMENTED OUT UNTIL WE DEFINE THE METHOD
// Populate the ListView
fillPlacesList();
Das ist der gesamte Code, der für die Auswahl des aktuellen Orts erforderlich ist.
13. Anwendung ausführen
Ort auswählen
- Starten Sie die App noch einmal.
Wenn Sie diesmal auf Ort auswählen tippen, wird die Liste mit benannten Orten in der Nähe des Standorts gefüllt. In der Nähe dieses Ortes auf Maui befinden sich Ululani's Hawaiian Shave Ice und Sugar Beach Bake Shop. Da die verschiedenen Orte sehr nah an den Standortkoordinaten liegen, wird hier eine Liste wahrscheinlicher Orte angezeigt, an denen Sie sich befinden könnten.
- Klicken Sie in der
ListView
auf einen Ortsnamen.
Auf der Karte sollte eine Markierung zu sehen sein.
- Tippen Sie auf die Markierung.
Sie können Ortsdetails sehen.
Anderen Ort testen
Wenn Sie Ihren Standort ändern möchten und den Emulator verwenden, wird der Gerätestandort nicht automatisch aktualisiert, wenn Sie die Standortkoordinaten im erweiterten Menü des Emulators aktualisieren.
So umgehen Sie dieses Problem: Verwenden Sie die native Google Maps App, um Updates des Emulatorstandorts zu erzwingen:
- Öffnen Sie Google Maps.
- Tippen Sie auf das Dreipunkt-Menü > Standort, um den Breiten- und Längengrad in neue Koordinaten zu ändern. Tippen Sie dann auf Senden.
- Sie können beispielsweise den Breiten- und Längengrad 49.2768 und -123.1142 verwenden, um den Standort auf das Stadtzentrum von Vancouver, Kanada, festzulegen.
- Prüfen Sie, ob Google Maps auf Ihre neuen Koordinaten zentriert wurde. Möglicherweise müssen Sie in der Google Maps App auf die Schaltfläche Mein Standort tippen, um die Neuzentrierung anzufordern.
- Kehren Sie zur App „Aktueller Ort“ zurück und tippen Sie auf Ort auswählen, um die Karte mit den neuen Koordinaten aufzurufen und eine neue Liste wahrscheinlicher aktueller Orte zu sehen.
Webseite. Sie haben eine einfache App entwickelt, die die Orte am aktuellen Standort prüft und Ihnen die Wahrscheinlichkeit angibt, an welchem Ort Sie sich befinden. Viel Spaß!
Führe die App nun mit den vorgenommenen Änderungen aus, um diesen Bonusschritt abzuschließen.
14. Nächste Schritte
Um Diebstahl Ihres API-Schlüssels zu verhindern, müssen Sie ihn so schützen, dass nur Ihre Android-App den Schlüssel verwenden kann. Wenn Sie Ihren Schlüssel nicht einschränken, kann jeder, der ihn hat, Google Maps Platform APIs aufrufen und Ihnen dadurch Kosten verursachen.
SHA-1-Zertifikat abrufen
Sie benötigen diese später, wenn Sie Ihre API-Schlüssel einschränken. Im Folgenden finden Sie eine Anleitung zum Abrufen Ihres Debug-Zertifikats.
Öffne unter Linux oder macOS ein Terminalfenster und gib Folgendes ein:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
Führen Sie unter Windows Vista oder Windows 7 den folgenden Befehl aus:
keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
Die Ausgabe sollte in etwa so aussehen:
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
Die Zeile, die mit SHA1 beginnt, enthält den SHA-1-Fingerabdruck des Zertifikats. Der Fingerabdruck ist eine Abfolge aus 20 zweistelligen Hexadezimalzahlen, die durch Doppelpunkte getrennt sind.
Wenn Sie eine App veröffentlichen möchten, folgen Sie der Anleitung in dieser Dokumentation, um Ihr Release-Zertifikat abzurufen.
Einschränkungen für API-Schlüssel hinzufügen
- Rufen Sie in der Cloud Console APIs & Dienste > Anmeldedaten auf.
Der Schlüssel, den Sie für diese App verwendet haben, sollte unter „API-Schlüssel“ aufgeführt sein.
- Klicken Sie auf
, um die Schlüsseleinstellungen zu bearbeiten.
- Legen Sie auf der Seite „API-Schlüssel“ nach Schlüsseleinschränkungen die Anwendungseinschränkungen fest. Gehen Sie dazu so vor:
- Wähle Android-Apps aus und folge der Anleitung.
- Klicken Sie auf Element hinzufügen.
- Geben Sie den Paketnamen und den SHA-1-Zertifikat-Fingerabdruck ein, den Sie im vorherigen Abschnitt abgerufen haben.
Beispiel:
com.google.codelab.currentplace
BB:0D:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:75s
- Legen Sie zum zusätzlichen Schutz die API-Einschränkungen fest. Gehen Sie dazu so vor:
- Wählen Sie nach den API-Einschränkungen Schlüssel einschränken aus.
- Wählen Sie das Maps SDK for Android und die Places API aus.
- Klicken Sie auf Fertig und Speichern.
15. Glückwunsch
Sie haben eine einfache App entwickelt, die die wahrscheinlichsten Orte am aktuellen Standort ermittelt und der Karte eine Markierung für den vom Nutzer ausgewählten Ort hinzufügt.
Weitere Informationen
- Um die Entwicklung zu beschleunigen, können Sie die Maps SDK for Android-Dienstprogrammbibliothek nutzen. Diese Dienstprogramme übernehmen die Hauptarbeit für einige der beliebtesten Aufgaben für Apps, die die Google Maps Platform verwenden.
- Weitere Codebeispiele für die meisten Funktionen der Google Maps Platform-SDKs für Android finden Sie in den geklonten Repositories für Maps SDK for Android – Beispiele und Places SDK for Android – Demos.
- Informationen zum Umgang mit dreistufigen Standortberechtigungen in Android Q finden Sie im Codelab Standortaktualisierungen in Android mit Kotlin empfangen.