Xamarin.Essentials: Geolocation

Die Klasse Geolocation stellt APIs zum Abrufen der Koordinaten des aktuellen geografischen Standorts des Geräts bereit.

Erste Schritte

Lesen Sie zum Einstieg in die Verwendung dieser API den Leitfaden mit ersten Schritte für Xamarin.Essentials, um sicherzustellen, dass die Bibliothek ordnungsgemäß installiert und in Ihren Projekten eingerichtet ist.

Der Zugriff auf die Geolocation-Funktionalität setzt die folgende plattformspezifische Einrichtung voraus:

Die Berechtigungen „Access Coarse Location“ (Standortzugriff (grob)) und „Access Fine Location“ (Standortzugriff (fein)) sind erforderlich und müssen im Android-Projekt konfiguriert werden. Außerdem müssen Sie, wenn Ihre App auf Android 5.0 (API-Ebene 21) oder höher ausgerichtet ist, deklarieren, dass Ihre App die Hardware-Features in der Manifestdatei verwendet. Das Hinzufügen erfolgt folgendermaßen:

Öffnen Sie die Datei AssemblyInfo.cs im Ordner Eigenschaften und fügen Sie Folgendes hinzu:

[assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
[assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
[assembly: UsesFeature("android.hardware.location", Required = false)]
[assembly: UsesFeature("android.hardware.location.gps", Required = false)]
[assembly: UsesFeature("android.hardware.location.network", Required = false)]

Alternativ können Sie das Android-Manifest aktualisieren:

Öffnen Sie die Datei AndroidManifest.xml im Ordner Eigenschaften, und fügen Sie Folgendes im Knoten Manifest hinzu:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />

Alternativ können Sie mit der rechten Maustaste auf das Android-Projekt klicken und die Eigenschaften des Projekts öffnen. Suchen Sie im Android-Manifest nach dem Bereich Erforderliche Berechtigungen: , und aktivieren Sie die Berechtigung ACCESS_COARSE_LOCATION (Standortzugriff (grob)) und ACCESS_FINE_LOCATION (Standortzugriff (fein)). Dadurch wird die Datei AndroidManifest.xml automatisch aktualisiert.

Wenn Ihre Anwendung für Android 10 (Q) (API-Ebene 29 oder höher) gedacht ist und LocationAlways anfordert, müssen Sie auch die folgende Berechtigung in AssemblyInfo.cs hinzufügen:

[assembly: UsesPermission(Manifest.Permission.AccessBackgroundLocation)]

Oder Sie fügen sie direkt in der Datei AndroidManifest.xml hinzu:

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

Es wird empfohlen, die Android-Dokumentation zu Standortupdates im Hintergrund zu lesen, da viele Einschränkungen berücksichtigt werden müssen.

Diese API verwendet Laufzeitberechtigungen unter Android. Stellen Sie sicher, dass Xamarin.Essentials vollständig initialisiert und die Verarbeitung von Berechtigungen in Ihrer App eingerichtet ist.

Im MainLauncher-Element des Android-Projekts bzw. in einem beliebigen Activity-Element, das gestartet wird, muss Xamarin.Essentials in der OnCreate-Methode initialisiert werden:

protected override void OnCreate(Bundle savedInstanceState) 
{
    //...
    base.OnCreate(savedInstanceState);
    Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
    //...
}    

Um Laufzeitberechtigungen unter Android zu verwalten, muss Xamarin.Essentials ein beliebiges OnRequestPermissionsResult-Element erhalten. Fügen Sie allen Activity-Klassen den folgenden Code hinzu:

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
    Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

    base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

Verwenden der Geolocation

Fügen Sie in Ihrer Klasse einen Verweis auf Xamarin.Essentials hinzu:

using Xamarin.Essentials;

Wenn erforderlich, verlangt die Geolocation-API vom Benutzer außerdem Berechtigungen.

Durch Aufrufen der GetLastKnownLocationAsync-Methode können Sie den letzten bekannten Standort des Geräts abrufen. Dies ist häufig schneller als eine vollständige Abfrage, kann aber auch ungenauer sein und zur Rückgabe von null führen, wenn kein zwischengespeicherter Standort vorhanden ist.

try
{
    var location = await Geolocation.GetLastKnownLocationAsync();

    if (location != null)
    {
        Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
    }
}
catch (FeatureNotSupportedException fnsEx)
{
    // Handle not supported on device exception
}
catch (FeatureNotEnabledException fneEx)
{
    // Handle not enabled on device exception
}
catch (PermissionException pEx)
{
    // Handle permission exception
}
catch (Exception ex)
{
    // Unable to get location
}

Mit GetLocationAsync können Sie die Koordinaten des aktuellen Standorts des Geräts abrufen. Es wird empfohlen, GeolocationRequest und CancellationToken vollständig zu übergeben, da es möglicherweise einige Zeit dauert, den Standort des Geräts abzurufen.

CancellationTokenSource cts;

async Task GetCurrentLocation()
{
    try
    {
        var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
        cts = new CancellationTokenSource();
        var location = await Geolocation.GetLocationAsync(request, cts.Token);

        if (location != null)
        {
            Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
        }
    }
    catch (FeatureNotSupportedException fnsEx)
    {
        // Handle not supported on device exception
    }
    catch (FeatureNotEnabledException fneEx)
    {
        // Handle not enabled on device exception
    }
    catch (PermissionException pEx)
    {
        // Handle permission exception
    }
    catch (Exception ex)
    {
        // Unable to get location
    }
}

protected override void OnDisappearing()
{
    if (cts != null && !cts.IsCancellationRequested)
        cts.Cancel();
    base.OnDisappearing();
}

Beachten Sie, dass alle Werte verfügbar sein können, da jedes Gerät die Geolocation über verschiedene Anbieter abfragt. Die Altitude-Eigenschaft kann z. B. null sein, den Wert 0 (null) haben oder einen positiven Wert aufweisen, also Meter über dem Meeresspiegel. Andere Werte, die möglicherweise nicht vorhanden sind, sind Speed und Course.

Genauigkeit der Geolocation

In der folgenden Tabelle ist die Genauigkeit bei den einzelnen Plattformen aufgeführt:

Niedrigste

Plattform Abstand (in Metern)
Android 500
iOS 3000
UWP 1000-5000

Niedrig

Plattform Abstand (in Metern)
Android 500
iOS 1000
UWP 300-3000

Mittel (Standard)

Plattform Abstand (in Metern)
Android 100–500
iOS 100
UWP 30-500

Hoch

Plattform Abstand (in Metern)
Android 0–100
iOS 10
UWP <= 10

Sehr hoch

Plattform Abstand (in Metern)
Android 0–100
iOS ~0
UWP <= 10

Ermitteln verfälschter Standorte

Einige Geräte geben möglicherweise einen verfälschten Standort über den Anbieter oder mithilfe einer Anwendung zurück, die das Verfälschen des Standorts ermöglicht. Mithilfe von IsFromMockProvider können Sie dies für jede Location-Klasse ermitteln.

var request = new GeolocationRequest(GeolocationAccuracy.Medium);
var location = await Geolocation.GetLocationAsync(request);

if (location != null)
{
    if(location.IsFromMockProvider)
    {
        // location is from a mock provider
    }
}

Abstand zwischen zwei Standorten

Die Klassen Location und LocationExtensions definieren CalculateDistance-Methoden, mit denen Sie den Abstand zwischen zwei geografischen Standorten berechnen können. Bei der Berechnung dieses Abstands werden weder Straßen noch andere Wege berücksichtigt. Es handelt sich lediglich um die kürzeste Entfernung zwischen den beiden Punkten auf der Erdoberfläche, auch als orthodromer Abstand oder Luftlinie bezeichnet.

Im Folgenden ein Beispiel:

Location boston = new Location(42.358056, -71.063611);
Location sanFrancisco = new Location(37.783333, -122.416667);
double miles = Location.CalculateDistance(boston, sanFrancisco, DistanceUnits.Miles);

Der Location-Konstruktor verfügt über Argumente für Breiten- und Längengrad in dieser Reihenfolge. Positive Breitengradwerte befinden sich nördlich vom Äquator und positive Längengradwerte östlich vom Nullmeridian. Verwenden Sie das letzte Argument für CalculateDistance, um Meilen oder Kilometer anzugeben. Die Klasse UnitConverters definiert außerdem die Methoden KilometersToMiles und MilesToKilometers zum Konvertieren der beiden Einheiten.

Plattformunterschiede

Die Höhe wird auf jeder Plattform anders berechnet.

Unter Android wird die Höhe, sofern verfügbar, in Metern über dem Referenzellipsoid WGS 84 angegeben. Wenn für diesen Standort keine Höhe angegeben ist, wird der Wert „0,0“ zurückgegeben.

API

Auf Channel 9 und auf YouTube finden Sie weitere Videos zu Xamarin.