Android Location API
Links und Quellen
http://www.vogella.com/articles/AndroidLocationAPI/article.html
http://developer.android.com/reference/android/location/package-summary.html
Position bestimmen
Android kann die Position mit dem GPS Empfänger, über umgebende WLAN Netzwerke (die dann Online mit einer Google Datenbank abgeglichen werden) oder über die aktuelle Handyzelle bestimmen.
Für die Positionsbestimmung stellt Android das Package:
android.location
zur Verfügung.
Wichtige Komponenten
Location Manager
Class LocationManager für Zugriff auf Android location service
LocationProvider
Superclass für die LocationProvider die die Position liefern. Es gibt 3:
network //Mobile oder WiFi gps passive // für externe Geräte
LocationListener
Über den Location Manager kann man einen LocationListener registrieren um regelmäßige Positionsupdates zu bekommen.
Hinweis in Stackoverflow wird über Probleme mit dem onStatusChanged Listener auf diversen Versionen von Android s.u.
Criteria Objekt zur Provider Auswahl
Mit einem Criteria Objekt bleibt man flexibel bei der Auswahl des Providers (GPS, Netzwerk...)
Im Criteria Objekt werden Anforderungen zum Beispiel für die Genauigkeit des Ortes gesetzt und diese anschließend bei der Providerauswahl übergeben:
Criteria criteria = new Criteria(); // Default Settings können über set Methoden verändert werden
provider = locationManager.getBestProvider(criteria, false); // Provider mit Kriterien auswählen false bedeutet auch nicht aktivierte Provider werden berücksichtigt.
Location location = locationManager.getLastKnownLocation(provider);
Geocoder
Über die Geocoder Klasse kann man Positionsdaten zu Adressdaten und umgekehrt ermitteln (Google Service)
Notwendige Rechte / Permissions
ACCESS_FINE_LOCATION permission für GPS, ansonsten ACCESS_COARSE_LOCATION permission
Beispiel 1 - locationapi.simple
Android Location API - Simple Location
Location Snippets
User zum aktivieren von GPS auffordern
Hinweis: Es ist nicht möglich GPS nur über den Code zu starten.
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = service
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// Check if enabled and if not send user to the GSP settings
// Better solution would be to display a dialog (AlarmDialog) and suggesting to
// go to the settings
if (!enabled) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
Simulation auf dem Simulator
Auf dem Emulierten Device GoogleMaps aktivieren falls das aktivieren des GPS Simulators nicht klappt (Bugs). Man kann die DDMS Perspective von Eclipse nehmen um Geopositionen zu senden.
Window > Open Perspective > Other > DDMS
Über das Terinal und Telnet kann man auch Positionen schicken
telnet localhost 5554 geo fix 13.12 49.23
Probleme bei der Positionsabfrage umgehen
Quelle: http://stackoverflow.com/questions/2021176/how-can-i-check-the-current-status-of-the-gps-receiver
onStatusChanged() doesn't get called on Eclair and Froyo. It does get called on 1.6 though. Simply counting all available satellites is, of course, useless. Checking if any of the satellites returns true for usedInFix() isn't very helpful also. The system apparently loses the fix but still continue to report that there are several sats that are used in it. So, the only working solution we have, and the one we actually use in our application, is the following. Let's say we have this simple class that implements the GpsStatus.Listener:
private class MyGPSListener implements GpsStatus.Listener {
public void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
if (mLastLocation != null)
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
if (isGPSFix) { // A fix has been acquired.
// Do something.
} else { // The fix has been lost.
// Do something.
}
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
// Do something.
isGPSFix = true;
break;
}
}
}
OK, now in onLocationChanged() you should add the following:
@Override
public void onLocationChanged(Location location) {
if (location == null) return;
mLastLocationMillis = SystemClock.elapsedRealtime();
// Do something.
mLastLocation = location;
}
And that's it. Basically, this is the line that does it all:
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
You can tweak the milliseconds value of course, but I would suggest to set it around 3-5 seconds.
This actually works and though I haven't seen the source code that implements the standard GPS icon, this comes close to replicating its behavior. It could even outdo it lol. Hope this helps someone.