Ihre eigene Place Place-Auswahl für Android erstellen (Java)

1. Hinweis

Hier erfahren Sie, wie Sie Ihren Nutzern mit der Google Maps Platform und dem Places SDK for Android eine Liste mit Orten präsentieren, über die ihre aktuellen Standorte ermittelt werden.

bd07a9ad2cb27a06

Vorbereitung

  • Grundlegende Java-Kenntnisse

Aufgaben

  • Karte in eine Android-App einbinden
  • Verwende die Berechtigungen zur Standortermittlung, um den Standort des Nutzers zu bestimmen.
  • Orte in der Nähe des Nutzerstandorts abrufen
  • Präsentieren Sie dem Nutzer wahrscheinlich Orte, um seinen aktuellen Standort zu ermitteln.

Aufgaben

Sie erstellen Ihre Android-App ganz neu, Sie können den Beispielcode aber auch beim Vergleich herunterladen. 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

Sollten während des Codelabs Probleme wie Codefehler, Grammatikfehler oder unklare Formulierungen auftreten, melden Sie es bitte über den Link Fehler melden links unten im Codelab.

2. Los gehts

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 du bereits Android Studio hast, überprüfe, ob du die aktuelle Version hast, indem du auf Android Studio klickst und Nach Updates suchst.

1f36bae83b64e33

Dieses Lab wurde mit Android Studio 3.4 geschrieben.

Android SDK

In Android Studio kannst du deine SDKs mit dem SDK-Manager konfigurieren. In diesem Lab wird das Android Q SDK verwendet.

  1. Klicke auf dem Android Studio-Begrüßungsbildschirm auf Konfigurieren & SDK.

d3fa03c269ec231c.png

  1. Klicken Sie das gewünschte SDK an und wählen Sie Übernehmen aus.

Falls Sie das SDK noch nicht haben, wird der Download des SDK auf Ihren Computer gestartet.

884e0aa1314f70d.png

Google Play-Dienste

Im SDK-Manager müssen auch Google Play-Dienste installiert werden.

  1. Klicken Sie auf den Tab SDK Tools und klicken Sie das Kästchen Google Play-Dienste an.

Aktualisieren Sie, wenn der Status Update verfügbar lautet.

ad6211fd78f3b629

3. Emulatoren vorbereiten

Sie können dazu Ihr eigenes Gerät verbinden oder den Android-Emulator verwenden.

Wenn Sie Ihr eigenes Gerät verwenden, gehen Sie zu Anleitung für echte Geräte: Google Play-Dienste aktualisieren am Ende dieser Seite.

Emulator hinzufügen

  1. Klicken Sie im Android-Willkommensbildschirm auf Konfigurieren und dann auf AVD-Manager.

5tt2d14c9c56d3f9.png

um das Dialogfeld Virtueller Android-Gerätemanager zu öffnen.

  1. Klicken Sie auf Virtuelles Gerät erstellen..., um eine Liste der Geräte aufzurufen, aus denen Sie auswählen können.

2D44Eada384F8b35.png

  1. Wählen Sie in der Spalte Play Store ein Gerät mit dem Symbol „Spielen“ d5722488d80cd6be.png aus und klicken Sie auf Weiter.

e0248f1c6e85ab7c.pngs

Es werden System-Images angezeigt, die Sie installieren können. Wenn neben Q für Android 9.+ (Google Play) das Wort Herunterladen angezeigt wird, klicken Sie auf Herunterladen.

316d0d1efabd9f24.png

  1. Klicken Sie auf Weiter, um dem virtuellen Gerät einen Namen zu geben, und dann auf Fertig.

Sie kehren zur Liste Meine virtuellen Geräte zurück.

  1. Klicke neben deinem neuen Gerät auf „Starten“ ba8adffe56d3b678:

7605864ed27f77ea

Nach wenigen Augenblicken wird der Emulator geöffnet.

Anleitung für Emulatoren – Google Play-Dienste aktualisieren

  1. Klicken Sie nach dem Starten des Emulators in der angezeigten Navigationsleiste auf ....**

2e1156e02643d018.png

Das Dialogfeld Erweiterte Steuerelemente wird geöffnet.

  1. Klicken Sie im Menü auf Google Play.

Wenn ein Update verfügbar ist, klicken Sie auf Aktualisieren.

5afd2686c5cad0e5.PNG

  1. Melden Sie sich mit einem Google-Konto im Emulator an.

Sie können Ihr eigenes Konto erstellen oder ein neues Konto erstellen, um Ihre Tests von Ihren personenbezogenen Daten zu trennen.

Daraufhin wird Google Play geöffnet und die Google Play-Dienste werden geöffnet.

  1. Klicken Sie auf Aktualisieren, um die aktuelle Version der Google Play-Dienste herunterzuladen.

f4bc067e80630b9c

Wenn Sie aufgefordert werden, die Kontoeinrichtung abzuschließen und eine Zahlungsoption hinzuzufügen, klicken Sie auf Überspringen.

Speicherort im Emulator festlegen

  1. Geben Sie nach dem Start des Emulators auf dem Startbildschirm „Karten“ ein, um das Google Maps App-Symbol zu öffnen.

2d996aadd53685a6

  1. Klicken Sie auf das Symbol, um es zu starten.

Eine Standardkarte wird angezeigt.

  1. Klicken Sie rechts unten auf der Karte auf Mein Standort c5b4e2fda57a7e71.png.

Du wirst aufgefordert, dem Telefon die Berechtigung zur Verwendung des Standorts zu erteilen.

f2b68044eabca151.png

  1. Klicken Sie auf ..., um das Menü Erweiterte Steuerelemente zu öffnen.
  2. Klicken Sie auf den Tab Standort.
  3. Geben Sie den Längen- und den Breitengrad ein.

Gib hier alles ein, was dir gefällt, achte aber darauf, dass es sich in einem Gebiet mit vielen Orten befindet.

(Verwenden Sie Breiten-20.7818 und Längengrad -156.4624 für die Stadt Kihei auf Maui in Hawaii, um die Ergebnisse aus diesem Codelab zu replizieren.)

  1. Klicken Sie auf Senden. Die Karte wird nun mit diesem Standort aktualisiert.

f9576b35218f4187

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:

  1. Suchen Sie über die Suchleiste auf dem Startbildschirm nach Google Play-Dienste und öffnen Sie sie.
  2. Klicken Sie auf Weitere Details.

Klicken Sie, sofern verfügbar, auf Aktualisieren.

ad16cdb975b5c3f7 baf0379ef8a9c88c

4. App-Shell mit einer Google Maps-Aktivität erstellen

  1. Wählen Sie auf dem Begrüßungsbildschirm von Android Studio die Option Neues Android Studio-Projekt starten aus.
  2. Wählen Sie auf dem Tab Smartphone und Tablet die Option Google Maps-Aktivitäten aus.

c9c80aa8211a8761

Das Dialogfeld Projekt konfigurieren wird geöffnet. Hier geben Sie einen Namen für Ihre App ein 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.

37f5b93b94ee118c

  1. Wählen Sie Java als Sprache und dann Androidx. Artefakte verwenden* aus.

Übernehmen Sie für die übrigen Einstellungen jeweils die Standardeinstellung.

  1. Klicken Sie auf Fertig.

5. Abhängigkeiten von Google-Diensten in die Gradle-Build-Datei einfügen

Wenn du die Berechtigung zur Standortermittlung in Android nutzen möchtest, benötigst du die Google Location and Activity Recognition API aus den Google Play-Diensten. Weitere Informationen zum Hinzufügen dieser und anderer APIs von Google Play-Diensten finden Sie unter Google Play-Dienste einrichten.

Android Studio-Projekte haben in der Regel zwei build.gradle-Dateien. Eine ist für das Gesamtprojekt und eine für die App. Wenn Sie den Android Studio-Projekt-Explorer in der Android-Ansicht haben, sehen Sie beide im Ordner Gradle Scripts. Sie müssen die Datei build.gradle (Module: app) bearbeiten, um Google-Dienste hinzuzufügen.

f3043429cf719c47.png

  1. Fügen Sie dem Abschnitt dependencies zwei Zeilen hinzu, um Google-Dienste für den Standort und die Places API hinzuzufügen (Beispielcode im Kontext).

build.gradle (Modul: 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 Platform-Konto und kein Projekt mit aktivierter Abrechnung haben, lesen Sie den Leitfaden Erste Schritte mit der Google Maps Platform, um ein Rechnungskonto und ein Projekt zu erstellen.

  1. Klicken Sie in der Cloud Console auf das Drop-down-Menü für Projekte und wählen Sie das Projekt aus, das Sie für dieses Codelab verwenden möchten.

  1. Aktivieren Sie im Google Cloud Marketplace die für dieses Codelab erforderlichen Google Maps Platform APIs und SDKs. Folgen Sie dazu der Anleitung in diesem Video oder dieser Dokumentation.
  2. Generieren Sie in der Cloud Console auf der Seite Anmeldedaten einen API-Schlüssel. Folgen Sie der Anleitung in diesem Video oder dieser Dokumentation. Für alle Anfragen an die Google Maps Platform ist ein API-Schlüssel erforderlich.

Kopieren Sie den soeben erstellten API-Schlüssel. Wechseln Sie zurück zu Android Studio. Suchen Sie nach der Datei google_maps_api.xml unter Android > App > res > Wert.

Ersetzen Sie dabei YOUR_KEY_HERE durch den kopierten API-Schlüssel.

aa576e551a7a1009

Ihre App ist jetzt konfiguriert.

7. Layoutdatei bearbeiten

  1. Öffne im Projekt-Explorer die Datei activity_maps.xml unter Android > app > res > layout.

4e0d986480c57efa.png

  1. Rechts unten auf dem Bildschirm wird die einfache Benutzeroberfläche geöffnet. Unten können Sie die Tabs „Design“ und „Text“ für Ihr Layout auswählen. Wählen Sie Text aus und ersetzen Sie damit den gesamten Inhalt der Layoutdatei:

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>

Die Benutzeroberfläche sieht dann so aus:

1bf786808a4697ce

8. App-Leiste einrichten

Wenn Nutzer eine Schaltfläche auswählen möchten, um ihren aktuellen Ort auszuwählen, fügen Sie eine App-Leiste mit einem Symbol hinzu, das den aktuellen Ort des Nutzers und mögliche Orte in der Nähe anzeigt. Diese sieht wie folgt aus:

3a17c92b613a26c5

Auf einem Smartphone wird nur das Symbol angezeigt. Bei Tablets mit mehr Platz ist auch der Text enthalten.

Symbol erstellen

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

Das Asset-Studio wird geöffnet.

  1. Klicken Sie im Menü Symboltyp auf Aktionsleiste und Tabsymbole.
  2. Benenne dein Asset ic_geolocate.
  3. Wähle Clipart als Asset-Typ** aus.**
  4. Klicken Sie auf die Grafik neben Clip Art.

Das Fenster Symbol auswählen wird geöffnet.

  1. Wählen Sie ein Symbol aus.

Über die Suchleiste können Sie nach Symbolen mit Bezug zu Ihrer Absicht suchen.

  1. Suchen Sie nach dem Symbol „location“ und wählen Sie ein Symbol für den Standort aus.

Das Symbol für Mein Standort ist dasselbe wie das Symbol, das in der Google Maps App verwendet wird, wenn ein Nutzer die Kamera an ihrem aktuellen Standort befestigen möchte.

  1. Klicken Sie auf OK > Weiter > Fertigstellen und prüfen Sie,ob der neue Ordner drawable die neuen Symboldateien enthält.

b9e0196137ed18ae.png

String-Ressourcen hinzufügen

  1. Klicken Sie im Projekt-Explorer auf Android > App > res > values. Öffnen Sie dann die strings.xml-Datei.
  2. Fügen Sie nach <string name="title_activity_maps">Map</string> die folgenden Zeilen hinzu:

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. Mit den anderen Markierungen werden der Karte Markierungen hinzugefügt.

Der Code in der Datei sieht nun 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

  1. Klicken Sie im Projekt-Explorer auf Android > App. Klicken Sie anschließend mit der rechten Maustaste auf den Ordner res und wählen Sie Neu > Verzeichnis aus, um unter app/src/main/res ein neues Unterverzeichnis zu erstellen.
  2. Benennen Sie das Verzeichnis menu.
  3. Klicke mit der rechten Maustaste auf den Ordner menu und wähle Neu & ; Datei aus.
  4. Benennen Sie die Datei menu.xml.
  5. Füge diesen Code ein:
<?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>

Stil der App-Leiste aktualisieren

  1. Maximieren Sie im Projekt-Explorer die Datei Android > app > res > mit der values-Datei. Öffnen Sie dann die Datei styles.xml.
  2. Ändern Sie im <style>-Tag die übergeordnete Property in "Theme.AppCompat.NoActionBar".
  3. Notieren Sie sich die Property name, die Sie im nächsten Schritt verwenden.

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">

App-Design in der Datei „AndroidManifest.xml“ aktualisieren

  1. Klicke auf Android > app > manifests und öffne die Datei AndroidManifest.xml.
  2. 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">

Du kannst jetzt mit dem Programmieren beginnen.

9. Anwendung initialisieren

  1. Suchen Sie im Projekt-Explorer die Datei MapsActivity.java.

Sie finden sie in dem Ordner, der dem Paket entspricht, das Sie in Schritt 1 für Ihre App erstellt haben.

8b0fa27d417f5f55.png

  1. Öffnen Sie die Datei und Sie befinden sich im Java-Code-Editor.

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 fügen viele weitere Codeelemente in diesem Codelab hinzu.

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;

Unterschrift des Kurses aktualisieren

Die Places API verwendet AndroidX-Komponenten für die abwärtskompatible Unterstützung. Du musst sie also definieren, um die AppCompatActivity zu erweitern. Sie ersetzt die Erweiterung FragmentActivity, die für eine Google Maps-Aktivität standardmäßig definiert ist.

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {

Variablen der Klasse hinzufügen

Als Nächstes deklarieren Sie die verschiedenen Klassenvariablen, die in verschiedenen Klassenmethoden verwendet werden. Dazu gehören die UI-Elemente und Statuscodes. Diese sollten sich direkt unter der Variablendeklaration für GoogleMap mMap befinden.

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

Aktualisieren Sie die onCreate-Methode, um Berechtigungen für Standortnutzer für Standortdienste zu verarbeiten, UI-Elemente einzurichten und den Places API-Client zu erstellen.

Fügen Sie die folgenden Codezeilen zur Aktionsleiste, zur Einrichtung der Ansichten und zum Places-Client am Ende der vorhandenen onCreate()-Methode hinzu.

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 Menü der App-Leiste hinzufügen

Bei diesen beiden Methoden wird das App-Leisten-Menü hinzugefügt (mit einem einzigen Element, dem Symbol "Ort auswählen") und dem Klick des Nutzers auf das Symbol.

Kopieren Sie diese beiden Methoden in die Datei nach der Methode onCreate.

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

  1. Klicken Sie in Android Studio auf Run (Ausführen) oder RunMenü >Run'app'.

28bea91c68c36fb2.png

  1. Sie werden aufgefordert, das Bereitstellungsziel auszuwählen. Der ausgeführte Emulator sollte in dieser Liste angezeigt werden. Wenn Sie sie auswählen, wird die App für Android Studio im Emulator bereitgestellt.

f44658ca91f6f41a.png

Nach kurzer Zeit wird die App gestartet. Die Karte ist auf Sydney (Australien) mit der Schaltfläche „Ein Schaltfläche“ und der Liste mit nicht gefüllten Orten zu sehen.

68eb8c70f4748350.png

Der Fokus der Karte wird nur dann zum Standort des Nutzers verschoben, wenn du den Zugriff auf den Gerätestandort anfordern möchtest.

10. Berechtigungen zur Standortermittlung anfordern und verarbeiten

Standortberechtigungen anfordern, wenn die Karte bereit ist

  1. Definieren Sie eine Methode namens getLocationPermission, mit der Nutzerberechtigungen angefordert werden.

Fügen Sie diesen Code unter der soeben 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);
        }
    }
  1. Fügen Sie zwei Zeilen am Ende der bestehenden onMapReady-Methode hinzu, um Zoomsteuerelemente zu aktivieren und Standortberechtigungen für den 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 von angeforderten Berechtigungen verarbeiten

Wenn der Nutzer auf das Dialogfeld zum Beantragen der Berechtigung antwortet, wird dieser Callback von Android aufgerufen.

Fügen Sie diesen Code nach der getLocationPermission()-Methode ein:

MapsActivity.java onRequestPermissionResult()

   /**
     * 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 wahrscheinlich Orte abrufen

Wenn der Nutzer in der App-Leiste auf Ort auswählen klickt, ruft die App die Methode pickCurrentPlace() auf, die die zuvor definierte getDeviceLocation()-Methode aufruft. Die Methode getDeviceLocation ruft eine andere Methode auf (getCurrentPlaceLikelihoods,), nachdem der neueste Gerätestandort abgerufen wurde.

FindCurrentPlace API aufrufen und Antwort verarbeiten

getCurrentPlaceLikelihoods erstellt einen findCurrentPlaceRequest und ruft die Aufgabe „Places API“ findCurrentPlace auf. Wenn die Aufgabe erfolgreich ist, wird ein findCurrentPlaceResponse zurückgegeben, das eine Liste von placeLikelihood-Objekten enthält. Jedes davon hat eine Reihe von Eigenschaften, einschließlich Name und Adresse des Orts sowie die Wahrscheinlichkeit, mit der Sie sich an diesem Ort aufhalten (doppelter Wert von 0 bis 1). Diese Methode verarbeitet die Antwort, indem Listen von Ortsdetails aus der placeLikelihoods erstellt werden.

Dieser Code durchläuft die fünf wahrscheinlichsten Orte und fügt ein Element mit einer Wahrscheinlichkeit von weniger als 0 einer Liste hinzu, die dann gerendert wird. Wenn es mehr oder weniger als fünf sein soll, bearbeiten Sie die Konstante M_MAX_ENTRIES.

Fügen Sie diesen Code nach der onMapReady-Methode 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());
                            }
                        }
                    }
                });
    }

Platzieren Sie die Kartenkamera am aktuellen Standort des Geräts.

Wenn der Nutzer die Berechtigung erteilt, ruft die App den letzten Standort des Nutzers ab und verschiebt die Kamera in der Mitte um diesen Standort.

Wenn der Nutzer die Berechtigung verweigert, wird die Kamera einfach auf die Standardposition verschoben, die zwischen den Konstanten am Anfang dieser Seite festgelegt wurde. Im Beispielcode ist sie Sydney, Australien.

Fügen Sie diesen Code nach der getPlaceLikelihoods()-Methode 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());
        }
    }

Berechtigung zur Standortermittlung prüfen, wenn der Nutzer auf „Ort auswählen“ klickt

Wenn der Nutzer auf Ort auswählen tippt, werden bei der Methode die Berechtigungen zur Standortermittlung geprüft und der Nutzer muss um Erlaubnis gebeten werden.

Wenn der Nutzer die Berechtigung erteilt hat, wird über die Methode getDeviceLocation aufgerufen, um die aktuell ermittelten Orte abzurufen.

  1. Fügen Sie diese Methode nach dem getDeviceLocation() hinzu:

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();
        }
    }
  1. Nachdem Sie pickCurrentPlace definiert haben, suchen Sie die Zeile in onOptionsItemSelected(), die pickCurrentPlace aufruft, 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, werden Sie gefragt, ob Sie die Berechtigung zur Standortermittlung erteilen möchten.

  • Wenn du die Berechtigung erteilst, wird diese Einstellung gespeichert. Du wirst dann nicht mehr dazu aufgefordert. Wenn Sie die Berechtigung ablehnen, werden Sie beim nächsten Tippen auf die Schaltfläche aufgefordert.
  • Obwohl getPlaceLikelihoods die wahrscheinlich aktuellen Orte abgerufen hat, werden diese von ListView noch nicht angezeigt. Sie können in Android Studio auf ⌘6 klicken, um die Protokolle in Logcat auf Anweisungen mit dem Tag MapsActivity zu prüfen und zu prüfen, ob die neuen Methoden ordnungsgemäß funktionieren.
  • Wenn Sie die Berechtigung erteilt haben, enthalten die Protokolle eine Anweisung für Latitude: und eine Anweisung für Longitude:, die den erkannten Standort des Geräts zeigt. Wenn du Google Maps und das erweiterte Menü des Emulators verwendet hast, um einen Standort für den Emulator anzugeben, wird in den folgenden Anweisungen der entsprechende Standort angezeigt.
  • Wenn der Aufruf von findCurrentPlace erfolgreich war, enthalten die Protokolle fünf Anweisungen, die die Namen und Speicherorte der fünf wahrscheinlichsten Orte drucken.

d9896a245b81bf3

12. Aktuelle Auswahl für Orte füllen

Handler für ausgewählte Orte einrichten

Überlegen wir, was passieren soll, wenn der Nutzer auf ein Element in der ListView klickt. Um dem Nutzer zu zeigen, wo er sich gerade befindet, können Sie dort eine Markierung hinzufügen. Wenn der Nutzer auf die Markierung klickt, wird ein Infofenster mit dem Namen des Orts und der Adresse 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 ausfüllen

Sie haben jetzt eine Liste mit den wahrscheinlichsten Orten, die der Nutzer gerade besucht. Nun können Sie dem Nutzer diese Optionen in ListView präsentieren. Sie können auch für den Klick-Listener von ListView festlegen, dass er den soeben definierten Klick-Handler verwendet.

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 Sie fillPlacesList jetzt definiert haben, suchen Sie die Zeile am Ende von findPlaceLikelihoods, die fillPlacesList aufruft, 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

Einen Ort auswählen

  1. Führen Sie die App noch einmal aus.

Wenn Sie auf Ort auswählen tippen, werden in der Liste benannte Orte in der Nähe des Standorts angezeigt. Nicht weit entfernt befinden sich in Maui Orte wie der Ululani Shave Ice and Sugar Beach Bake Shop. Da sich mehrere Orte sehr nah an den Standortkoordinaten befinden, ist dies eine Liste von Orten, an denen Sie sich vermutlich befinden.

  1. Klicken Sie auf einen Ortsnamen im ListView.

Du solltest nun eine Markierung auf der Karte sehen.

  1. Tippen Sie auf die Markierung.

Du kannst Ortsdetails sehen.

e52303cc0de6a513 864c74342fb52a01.png

Anderen Standort testen

Wenn du deinen Standort ändern möchtest und den Emulator verwendest, wird der Gerätestandort nicht automatisch aktualisiert, wenn du die Standortkoordinaten im erweiterten Menü des Emulators aktualisierst.

So umgehen Sie das Problem: Verwenden Sie die native Google Maps App, um Updates für den Standort des Emulators zu erzwingen.

  1. Öffnen Sie Google Maps.
  2. Tippen Sie auf ... > Standort, um den Breiten- und Längengrad in neue Koordinaten zu ändern. Tippen Sie dann auf Senden.
  3. Verwenden Sie beispielsweise "Breitengrad: 49.2768" und "Längengrad" -123.1142, um den Standort in die Innenstadt von Vancouver, Kanada, zu setzen.
  4. Überprüfen Sie, ob die neuen Koordinaten in Google Maps aktualisiert wurden. Möglicherweise müssen Sie in der Google Maps App auf die Schaltfläche Mein Standort tippen, um die erneute Zentrierung anzufordern.
  5. Kehren Sie zur aktuellen Place App zurück und tippen Sie auf Ort auswählen, um die Karte auf den neuen Koordinaten zu sehen und eine neue Liste mit Orten zu erhalten, die wahrscheinlich aktualisiert werden.

9adb99d1ce25c184

Webseite. Sie haben eine einfache App entwickelt, die nach den Orten am aktuellen Standort sucht und Ihnen die Wahrscheinlichkeit angibt, an welchem Ort Sie sich befinden. Viel Spaß!

Du kannst jetzt die App mit den Änderungen ausführen, die du vorgenommen hast, um diesen Bonusschritt abzuschließen.

14. Weitere Informationen

Wenn Sie den Diebstahl Ihres API-Schlüssels verhindern möchten, müssen Sie ihn schützen, damit ausschließlich Ihre Android-App den Schlüssel verwenden kann. Wenn Sie die Einschränkung nicht aufheben, kann jeder mit Ihrem Schlüssel Google Maps Platform APIs aufrufen und Ihnen Kosten in Rechnung stellen.

SHA-1-Zertifikat abrufen

Sie benötigen ihn später, wenn Sie Ihre API-Schlüssel einschränken. Im Folgenden finden Sie eine Anleitung zum Abrufen des 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 und Windows 7 den folgenden Befehl aus:

keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android

Die Ausgabe sollte 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 zur Veröffentlichung einer App bereit sind, folgen Sie der Anleitung in dieser Dokumentation, um Ihr Freigabezertifikat abzurufen.

Einschränkungen für den API-Schlüssel festlegen

  1. Gehen Sie in der Cloud Console zu APIs &Dienste > Anmeldedaten.

Der für diese App verwendete Schlüssel sollte unter API-Schlüssel aufgeführt sein.

  1. Klicken Sie auf 6454a04865d551e6, um die Schlüsseleinstellungen zu bearbeiten.

316b052c621ee91c

  1. Legen Sie auf der Seite „API-Schlüssel“ nach Schlüsseleinschränkungen die Anwendungseinschränkungen fest:
  2. Wähle Android-Apps aus und folge der Anleitung.
  3. Klicken Sie auf Element hinzufügen.
  4. Geben Sie Ihren Paketnamen und den SHA-1-Zertifikatfingerabdruck 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
  1. Zum weiteren Schutz können Sie die API-Einschränkungen festlegen.
  2. Wählen Sie nach API-Einschränkungen Schlüssel einschränken aus.
  3. Wähle das Maps SDK for Android und die Places API aus.
  4. Klicken Sie auf Fertig und Speichern.

15. Glückwunsch

Sie haben eine einfache App erstellt, die nach den wahrscheinlichsten Orten am aktuellen Standort sucht und eine Markierung auf der Karte für den vom Nutzer ausgewählten Ort hinzufügt.

Weitere Informationen