Android SDK: Erstellen Sie eine Mall Finder App - Mapview & Location
German (Deutsch) translation by Tatsiana Bochkareva (you can also view the original English article)
In diesem Lernprogramm erfahren Sie, wie Sie mithilfe der Google Maps-API Sonderziele (POI) überlagern und mithilfe der verfügbaren standortbasierten Dienste auf Ihrem Mobilteil Ihre Position in Bezug auf die verfügbaren POI-Standorte anzeigen. In diesem Fall verwenden wir Einkaufszentren als POI.
Ich habe diese Lektion in zwei Teile geteilt. Teil 1 (die in diesem Tutorial vorgestellte Lektion) behandelt:
- Verwenden des MapView-Objekts
- Verwenden Sie Ihren MD5-Fingerabdruck, um einen API-Schlüssel für die Verwendung von Google Maps zu erhalten
- Implementieren eines Standort-Listeners, um Ihren aktuellen Standort abzurufen
Teil 2 behandelt:
- Verwendung von den externen Bibliotheken in Ihrer App
- Erstellung von den Überlagerungen zur Darstellung Ihres aktuellen Standorts und verschiedener Sonderziele
Jetzt fangen wir an!
Schritt 1: Erstellen Sie ein neues Android-Projekt
Starten Sie die Eclipse-IDE und erstellen Sie ein neues Android-Projekt. Dazu in der Eclipse-IDE Navigieren Sie zu:
Datei > Erstellen > Neues Android-Projekt
Erstellen Sie das neue Projekt mit den folgenden Einstellungen:
Projektname: MallFinder
Build-Ziel: Google APIs Platform - 2.1 API Level 7
Anwendungsname: Mall Finder
Paketname: com.shawnbe.mallfinder
Aktivität erstellen: MallFinderActivity
MinimumSDK: 7


Klicken Sie nach dem Konfigurieren der Einstellungen auf Fertig stellen.
Schritt 2: Registrieren Sie sich bei Google für den API-Schlüssel
Da MapView-Objekte Google Maps verwenden, müssen Sie sich bei Google für einen API-Schlüssel registrieren und den Nutzungsbedingungen zustimmen, bevor Sie sie verwenden können. Dieser Prozess ist ziemlich einfach und schmerzlos und wir werden diesen Prozess Schritt für Schritt durchlaufen. Weitere Informationen finden Sie unter diesem Link zum Erhalt eines Maps-API-Schlüssels.
Um einen API-Schlüssel zu generieren, ist Ihr MD5-Fingerabdruck des Zertifikats erforderlich, mit dem Sie Ihre Anwendung signieren. Klingt verwirrend, ich weiß, aber es ist nicht so schwer, wie es sich anhört, wie Sie feststellen werden, während wir durch die verschiedenen Schritte gehen. Anstatt die Eingabeaufforderungsmethode zu verwenden, um Ihren MD5-Fingerabdruck wie im obigen Link beschrieben abzurufen, verwenden wir ein Keytool-Plugin für Eclipse. Weitere Informationen zum Keytool-Plugin finden Sie auf dieser Website.
Schritt 3: Installieren des Keytool Plugins
Navigieren Sie in der Eclipse-IDE zu Hilfe > Neue Software installieren.


Wenn das neue Fenster angezeigt wird, klicken Sie oben im Fenster auf die Schaltfläche "Hinzufügen".
Geben Sie "keytool" (ohne Anführungszeichen) in das Namensfeld und ein
http://www.keytool.sourceforge.net/update im Feld Standort.


OK klicken.
Nach einer kurzen Ladezeit wird im Popup-Fenster ein Kontrollkästchen mit der Bezeichnung "Keytool" angezeigt. Aktivieren Sie das Kontrollkästchen und klicken Sie auf Weiter. Überprüfen Sie die Bedingungen der Lizenzvereinbarung und klicken Sie zum Abschluss auf Weiter.
Hinweis: Während der Installation werden Sie möglicherweise aufgefordert, festzustellen, ob Sie den Sicherheitszertifikaten vertrauen. Wenn Sie dies tun, aktivieren Sie das Kontrollkästchen und klicken Sie auf OK, um die Installation fortzusetzen.


Nach der Installation werden Sie aufgefordert, Eclipse neu zu starten. Tun Sie dies und fahren Sie fort.
Schritt 4: Abrufen des MD5-Fingerabdrucks
Nach dem Neustart von Eclipse sollte ein neuer Menüpunkt "Keytool" mit einem kleinen Schlüsselsymbol daneben angezeigt werden.


Wir werden jetzt den Debug-Keystore öffnen. Hinweis: Der Speicherort kann je nach Betriebssystem variieren. Die Standardspeicherorte für verschiedene Betriebssysteme sind
- Windows Vista: C:\Benutzer\<Benutzer>\.android\debug.keystore
- Windows XP: C:\Dokumente und Einstellungen\<Benutzer>\.android\debug.keystore
- OS X und Linux: ~/.android/debug.keystore
Klicken Sie auf das Keytool-Menüelement > Keystore öffnen.
Klicken Sie auf die Schaltfläche Durchsuchen rechts neben dem Textfeld Dateiname, gehen Sie zum Speicherort des Debug-Keystores (Standardspeicherort oben) und wählen Sie die Datei debug.keystore aus.
Klicken Sie auf Öffnen und geben Sie "android" (ohne Anführungszeichen) ein. Dies ist das Standard-Debug-Passwort. Klicken Sie dann auf Laden.


Eine neue Keytool-Registerkarte sollte jetzt im unteren Bereich des Bildschirms angezeigt werden (Wenn Sie sie nicht sehen, navigieren Sie zu Fenster > Perspektive öffnen > Java-Browsing).


Klicken Sie auf den kleinen Pfeil links neben dem Pfad debug.keystore, um den androiddebugkey anzuzeigen.
Doppelklicken Sie auf den androiddubugkey und kopieren Sie den MD5-Fingerabdruck.
Öffnen Sie Ihren Webbrowser und rufen Sie die folgende URL auf. http://code.google.com/android/maps-api-signup.html
Lesen Sie die Allgemeinen Geschäftsbedingungen. Wenn Sie damit einverstanden sind, geben Sie den MD5-Fingerabdruck in das Textfeld ein und klicken Sie auf "API-Schlüssel generieren". Notieren Sie sich Ihren API-Schlüssel, da dieser benötigt wird, damit MapView funktioniert.
Schritt 5: Fügen Sie die MapView zum Layout hinzu
In diesem Schritt fügen wir der Layoutdatei eine MapView hinzu.
Öffnen Sie die Datei main.xml unter MallFinder > res > layout > main.xml und aktualisieren Sie die Datei so, dass sie ein FrameLayout und MapView enthält, wie unten gezeigt:
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
3 |
android:layout_width="fill_parent" |
4 |
android:layout_height="fill_parent" |
5 |
android:orientation="vertical" > |
6 |
<FrameLayout
|
7 |
android:layout_width="fill_parent" |
8 |
android:layout_height="fill_parent"> |
9 |
<com.google.android.maps.MapView
|
10 |
android:id="@+id/mapView" |
11 |
android:layout_width="fill_parent" |
12 |
android:layout_height="fill_parent" |
13 |
android:clickable="true" |
14 |
android:apiKey="PUT YOUR API KEY HERE"/> |
15 |
</FrameLayout>
|
16 |
</LinearLayout>
|
Das obige Layout erstellt eine MapView über den gesamten verfügbaren Bildschirmbereich. Bevor wir die App ausführen können, um MapView anzuzeigen, müssen noch einige weitere Schritte ausgeführt werden. Wenn Sie die App im aktuellen Status ausführen, wird das Schließen erzwungen.
Schritt 6: Einrichten von Berechtigungen und Deklarieren erforderlicher Bibliotheken
Da unsere Anwendung Daten von Google Maps herunterlädt und auch auf Informationen vom GPS des Mobilteils oder anderen standortbasierten Diensten zugreifen muss, müssen wir die erforderlichen Berechtigungen anfordern, um diese Dienste und Funktionen in der Android Manifest-Datei verwenden zu können.
Öffnen Sie dazu die Android-Manifestdatei unter MallFinder > AndroidManifest.xml.
Fügen Sie die folgenden Zeilen nach dem schließenden Anwendungs-Tag (</application>), aber vor dem schließenden Manifest-Tag (</manifest>) hinzu.
1 |
<uses-feature android:name="android.hardware.location.gps"/> |
2 |
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> |
3 |
<uses-permission android:name="android.permission.INTERNET"/> |
In diesem Beispiel benötige ich FINE_LOCATION nicht, aber ich habe dies hier aufgenommen, da ich mir vorstelle, dass Sie möglicherweise Anpassungen an Ihrem Code vornehmen möchten, um die verschiedenen Anbieter zu testen. Wenn Sie den genauesten Speicherort erhalten möchten, benötigen Sie die Berechtigungen FINE_LOCATION . Im Allgemeinen sollten Sie für jede Produktionsanwendung keine Berechtigungen anfordern, die Sie nicht benötigen. Dies ist eine sehr schlechte Vorgehensweise und macht den Benutzer vorsichtig mit Ihrer App, wenn Sie weitere Berechtigungen anfordern. Wenn Sie nicht beabsichtigen, die genauesten Anbieter zu verwenden, können Sie die Berechtigung auf android.permission.ACCESS_COARSE_LOCATION anpassen.
Um Google Maps in unserer MapView verwenden zu können, müssen wir die Bibliothek in unserer Manifest-Datei deklarieren. Fügen Sie dazu auch den folgenden Code zwischen dem schließenden Aktivitäts-Tag und dem schließenden Anwendungs-Tag hinzu:
1 |
<uses-library android:required="true" android:name="com.google.android.maps" /> |
Da wir uns bereits in der Android Manifest-Datei befinden, sollten wir die Titelleiste entfernen, da ich dies für unnötig halte. Es verwendet zu viel von unserem begrenzten Bildschirmplatz. Um es zu entfernen, fügen Sie die folgende Zeile in das Anwendungs-Tag ein:
1 |
android:theme="@android:style/Theme.NoTitleBar" |
Damit können Sie unsere Manifest-Datei bearbeiten. Unsere vollständige Manifest-Datei sieht nun folgendermaßen aus:
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
3 |
package="com.shawnbe.mallfinder" |
4 |
android:versionCode="1" |
5 |
android:versionName="1.0" > |
6 |
<uses-sdk android:minSdkVersion="7" /> |
7 |
<application
|
8 |
android:icon="@drawable/ic_launcher" |
9 |
android:label="@string/app_name" |
10 |
android:theme="@android:style/Theme.NoTitleBar"> |
11 |
<activity
|
12 |
android:label="@string/app_name" |
13 |
android:name=".MallFinderActivity" > |
14 |
<intent-filter > |
15 |
<action android:name="android.intent.action.MAIN" /> |
16 |
|
17 |
<category android:name="android.intent.category.LAUNCHER" /> |
18 |
</intent-filter>
|
19 |
</activity>
|
20 |
<uses-library android:required="true" android:name="com.google.android.maps" /> |
21 |
</application>
|
22 |
<uses-feature android:name="android.hardware.location.gps"/> |
23 |
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> |
24 |
<uses-permission android:name="android.permission.INTERNET"/> |
25 |
</manifest>
|
Schritt 7: Einrichten der MapView
Bevor wir MapView in Aktion sehen können, müssen wir einige Anpassungen an der MallFinderActivity-Klasse vornehmen.
Öffnen Sie die Hauptaktivitätsklasse (MallFinderActivity.java) unter:
MallFinder > src > com.shawnbe.mallfinder > MallFinderActivity.class
In unserer App benötigen wir diese Klasse, um die MapActivity und nicht die Aktivität zu erweitern, damit MapView funktioniert.
Aktualisieren Sie die Zeile:
1 |
public class MallFinderActivity extends Activity { |
zu:
1 |
public class MallFinderActivity extends MapActivity { |
Wenn Sie die MapActivity-Klasse erweitern, müssen Sie die isRouteDisplayed() -Methode implementieren, sodass wir auch die folgende Skeleton-Methode hinzufügen müssen:
1 |
@Override
|
2 |
protected boolean isRouteDisplayed() { |
3 |
// TODO Auto-generated method stub
|
4 |
return false; |
5 |
}
|
An diesem Punkt können wir die App starten und die MapView anzeigen. Lassen Sie uns jedoch einige Optionen festlegen, z. B. die Zoomstufe und die sichtbaren Ebenen. Wir beginnen mit der Deklaration der folgenden Variablen vor der onCreate-Methode:
1 |
private MapController mapController; |
2 |
private MapView mapView; |
Fügen Sie der onCreate-Methode die folgenden Codezeilen hinzu.
1 |
mapView = (MapView)findViewById(R.id.mapView); |
2 |
mapView.setBuiltInZoomControls(true); |
3 |
mapView.setSatellite(false); |
4 |
mapView.setStreetView(true); |
5 |
mapController = mapView.getController(); |
6 |
mapController.setZoom(13); |
Der obige Code zeigt nur die Street-Ebene an und verbirgt die Satellitenebene. Ich habe dies als persönliche Präferenz gewählt, da ich es einfacher finde, in diesem Format zu lesen. Sie können dies nach Belieben anpassen, indem Sie die booleschen Werte false und true ändern. Zusätzlich ist die Zoomstufe auf 13 eingestellt, dies kann jedoch auch angepasst werden, wobei 1 ein ganzes Weltbild und 20 der maximale Zoom ist.
Schließlich können wir die Anwendung starten, um sicherzustellen, dass bis zu diesem Punkt alles wie erwartet ausgeführt wird.
Es gibt verschiedene Möglichkeiten, die Anwendung auszuführen, die erste:
Klicken Sie im Paket-Explorer mit der rechten Maustaste auf das Projekt > Ausführen als > Android-Anwendung
Oder
Klicken Sie im Menü auf Ausführen > Ausführen


Wählen Sie dann Ihr Mobilteil oder Ihren Emulator aus. Sie sollten eine Karte sehen, die Ihren gesamten Bildschirm mit Ausnahme der Benachrichtigungsleiste am oberen Bildschirmrand abdeckt, sowie in der Lage sein, zu scrollen und mit der Prise zu zoomen.


Schritt 8: Ermitteln Ihres aktuellen Standorts
Um Ihren aktuellen Standort abzurufen, verwenden wir die locationManager-Klasse, mit der die Anwendung den Standort des Geräts abrufen kann. Dieser Vorgang kann einige Zeit dauern, um eine Korrektur für den aktuellen Standort zu erhalten. Daher wird empfohlen, Ihren lastKnownLocation zu verwenden, bis Sie eine genauere Korrektur für Ihren aktuellen Standort erhalten.
Deklarieren Sie zwei weitere Variablen direkt unter den Variablen, die wir in Schritt 7 oben deklariert haben:
1 |
private LocationManager locationManager; |
2 |
private GeoPoint currentLocation; |
Fügen Sie der MallFinderActivity.java-Klasse außerdem die folgenden Methoden hinzu:
1 |
public void getLastLocation(){ |
2 |
String provider = getBestProvider(); |
3 |
currentLocation = locationManager.getLastKnownLocation(provider); |
4 |
if(currentLocation != null){ |
5 |
setCurrentLocation(currentLocation); |
6 |
}
|
7 |
else
|
8 |
{
|
9 |
Toast.makeText(this, "Location not yet acquired", Toast.LENGTH_LONG).show(); |
10 |
}
|
11 |
}
|
12 |
|
13 |
public void animateToCurrentLocation(){ |
14 |
if(currentPoint!=null){ |
15 |
mapController.animateTo(currentPoint); |
16 |
}
|
17 |
}
|
18 |
|
19 |
public String getBestProvider(){ |
20 |
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); |
21 |
Criteria criteria = new Criteria(); |
22 |
criteria.setPowerRequirement(Criteria.NO_REQUIREMENT); |
23 |
criteria.setAccuracy(Criteria.NO_REQUIREMENT); |
24 |
String bestProvider = locationManager.getBestProvider(criteria, true); |
25 |
return bestProvider; |
26 |
}
|
27 |
|
28 |
public void setCurrentLocation(Location location){ |
29 |
int currLatitude = (int) (location.getLatitude()*1E6); |
30 |
int currLongitude = (int) (location.getLongitude()*1E6); |
31 |
currentLocation = new GeoPoint(currLatitude,currLongitude); |
32 |
|
33 |
currentLocation = new Location(""); |
34 |
currentLocation.setLatitude(currentPoint.getLatitudeE6() / 1e6); |
35 |
currentLocation.setLongitude(currentPoint.getLongitudeE6() / 1e6); |
36 |
}
|
Fügen Sie am Ende der onCreate-Methode die folgenden zwei Zeilen hinzu:
1 |
getLastLocation(); |
2 |
animateToCurrentLocation(); |
Die onCreate-Methode sieht nun folgendermaßen aus:
1 |
public void onCreate(Bundle savedInstanceState) { |
2 |
super.onCreate(savedInstanceState); |
3 |
setContentView(R.layout.main); |
4 |
mapView = (MapView)findViewById(R.id.mapView); |
5 |
mapView.setBuiltInZoomControls(true); |
6 |
mapView.setSatellite(false); |
7 |
mapView.setStreetView(true); |
8 |
mapController = mapView.getController(); |
9 |
mapController.setZoom(13); |
10 |
getLastLocation(); |
11 |
animateToCurrentLocation(); |
12 |
}
|
Die Methode getLastLocation erstellt eine Instanz der locationManager-Klasse und bestimmt anhand der Anforderungen, welcher Anbieter für die Standortdienste am besten geeignet ist. Im obigen Code geben wir keine Kriterien für den Anbieter an. Sie können die Kriterien jedoch basierend auf Ihren Genauigkeits- und Leistungsanforderungen mithilfe der Methoden criteria.setAccuracy() und criteria.SetPowerRequirement() anpassen. In Schritt 6 oben habe ich erwähnt, dass Sie möglicherweise Ihre Kriterien anpassen möchten, um den genauesten Ort zu erhalten. Wenn Sie dies tun möchten, setzen Sie die Genauigkeitskriterien auf ACCURACY_FINE und die Codezeile sieht folgendermaßen aus:
1 |
criteria.setAccuracy(Criteria.ACCURACY_FINE); |
Der Grund, warum ich mich nicht für den genauesten Anbieter (GPS) entschieden habe, ist, dass ich diesen Code in Innenräumen testen würde und meine Position möglicherweise nie sperren würde. Sie können dies jedoch selbst testen, die Genauigkeit ändern und nach draußen gehen und sehen Sie, ob Sie eine GPS-Sperre für Ihre aktuelle Position erhalten können.
Abhängig von den angegebenen Kriterien verwendet Ihr Mobilteil möglicherweise verschiedene Anbieter. Dies ist normalerweise GPS oder Netzwerk (kann jedoch unterschiedlich sein). Der letzte bekannte Standort wird dann mindestens so lange als aktueller Standort festgelegt, bis wir einen genaueren und aktualisierten Standort erhalten. Der Breiten- und Längengrad des aktuellen Standorts wird dann gefunden und wir animieren oder scrollen die Karte, um sie um diese Koordinaten zu zentrieren.
Jetzt, da wir die letzte bekannte Position haben, verwenden wir den Standort-Listener, um Änderungen an unserem Standort zu erkennen und die App zu aktualisieren, sobald diese Änderungen auftreten. Dazu benötigen wir unsere Aktivitätsklasse (MallFinderActivity.java), um locationListener zu implementieren. Zuerst aktualisieren wir die Zeile:
1 |
public class MallFinderActivity extends MapActivity { |
zu:
1 |
public class MallFinderActivity extends MapActivity implements LocationListener{ |
Um den Location Listener zu implementieren, müssen wir einige Methoden überschreiben. Daher fügen wir die folgenden Barebone-Methoden hinzu (Wenn ich mich auf Skeleton- oder Barebone-Methoden beziehe, meine ich, dass die Shell für die Methoden erstellt wird, aber sie tun eigentlich nichts diesmal):
1 |
@Override
|
2 |
public void onLocationChanged(Location arg0) { |
3 |
// TODO Auto-generated method stub
|
4 |
}
|
5 |
|
6 |
@Override
|
7 |
public void onProviderDisabled(String arg0) { |
8 |
// TODO Auto-generated method stub
|
9 |
}
|
10 |
|
11 |
@Override
|
12 |
public void onProviderEnabled(String arg0) { |
13 |
// TODO Auto-generated method stub
|
14 |
}
|
15 |
|
16 |
@Override
|
17 |
public void onStatusChanged(String arg0, int arg1, Bundle arg2) { |
18 |
// TODO Auto-generated method stub
|
19 |
}
|
Wir werden die onLocationChanged-Methode verwenden, um Aktualisierungen an unserem Standort zu erkennen, und diese dann mithilfe der setcurrentLocation-Methode als unseren aktuellen Standort festlegen.
Aktualisieren Sie die onlocationChanged-Methode, um Folgendes widerzuspiegeln:
1 |
@Override
|
2 |
public void onLocationChanged(Location newLocation) { |
3 |
// TODO Auto-generated method stub
|
4 |
setCurrentLocation(newLocation); |
5 |
}
|
Fügen Sie die folgenden Codezeilen hinzu. Diese Methoden fordern jede Sekunde Aktualisierungen an, wenn die App gestartet oder fortgesetzt wird, und hören auch auf, nach Aktualisierungen zu suchen, wenn die App angehalten oder beendet wird.
1 |
@Override
|
2 |
protected void onResume() { |
3 |
super.onResume(); |
4 |
locationManager.requestLocationUpdates(getBestProvider(), 1000, 1, this); |
5 |
}
|
6 |
|
7 |
@Override
|
8 |
protected void onPause() { |
9 |
super.onPause(); |
10 |
locationManager.removeUpdates(this); |
11 |
}
|
Wenn Sie die Anwendung an diesem Punkt ausführen, sollte sich MapView um Ihren letzten bekannten Standort zentrieren. Wenn Ihr Mobilteil einen Fix erhalten kann, wird es so aktualisiert, dass es sich um Ihren aktuellen Standort zentriert. Abhängig von den in Schritt 7 festgelegten Genauigkeitskriterien variiert die Zeitspanne, um eine Lösung für Ihren Standort zu erhalten. In dieser Lektion haben wir gelernt, wie Sie MapView verwenden, den locationListener implementieren und Ihren aktuellen Standort ermitteln. In der nächsten Lektion werden wir dies erweitern und eine externe Bibliothek hinzufügen, um die Überlagerungen in MapView zu verarbeiten und einige Informationen in Ballon-Popups anzuzeigen, wenn die verschiedenen Punkte von Interesse abgegriffen werden.



