Freigeben über


Geolocation

Browse sample. Durchsuchen Sie das Beispiel

In diesem Artikel wird beschrieben, wie Sie die .NET Multi-Platform App UI (.NET MAUI) IGeolocation-Schnittstelle verwenden können. Diese Schnittstelle stellt APIs zum Abrufen der Koordinaten des aktuellen geografischen Standorts des Geräts bereit.

Die Standardimplementierung der IGeolocation-Schnittstelle ist über die Geolocation.Default-Eigenschaft verfügbar. Sowohl die IGeolocation-Schnittstelle als auch die Geolocation-Klasse sind im Microsoft.Maui.Devices.Sensors-Namespace enthalten.

Erste Schritte

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

Grobe oder feine Speicherplatzberechtigungen, oder beides, müssen angegeben werden und sollten 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:

  • Fügen Sie die assemblybasierte Berechtigung hinzu:

    Öffnen Sie die Datei Platforms/Android/MainApplication.cs und fügen Sie die folgenden Assembly-Attribute nach den using-Anweisungen 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)]
    

    Wenn Ihre App auf Android 10 – Q (API-Level 29 oder höher) ausgerichtet ist und LocationAlways anfordert, müssen Sie diese Berechtigungsanforderung ebenfalls hinzufügen:

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

    – oder –

  • Aktualisieren des Android-Manifests

    Öffnen Sie die Datei Platforms/Android/AndroidManifest.xml 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" />
    

    Wenn Ihre Anwendung auf Android 10 - Q (API-Level 29 oder höher) ausgerichtet ist und LocationAlways anfordert, müssen Sie diese Berechtigungsanforderung ebenfalls hinzufügen:

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

    - oder -

  • Aktualisieren Sie das Android-Manifest im Manifest-Editor:

    Doppelklicken Sie in Visual Studio auf die Datei Platforms/Android/AndroidManifest.xml, um den Android-Manifest-Editor zu öffnen. Überprüfen Sie dann unter Erforderliche Berechtigungen die oben aufgeführten Berechtigungen. Dadurch wird die Datei AndroidManifest.xml automatisch aktualisiert.

Tipp

Lesen Sie unbedingt die Android-Dokumentation über Standortaktualisierungen im Hintergrund, da es viele Einschränkungen gibt, die berücksichtigt werden müssen.

Abrufen des zuletzt bekannten Standorts

Das Gerät hat möglicherweise den neuesten Speicherort des Geräts zwischengespeichert. Verwenden Sie die GetLastKnownLocationAsync()-Methode, um auf den zwischengespeicherten Speicherort zuzugreifen, falls verfügbar. Dies ist häufig schneller als eine vollständige Abfrage, kann aber auch ungenauer sein. Wenn kein Ort im Cache vorhanden ist, gibt diese Methode null zurück.

Hinweis

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

Im folgenden Codebeispiel wird die Überprüfung auf einen zwischengespeicherten Speicherort veranschaulicht:

public async Task<string> GetCachedLocation()
{
    try
    {
        Location location = await Geolocation.Default.GetLastKnownLocationAsync();

        if (location != null)
            return $"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
    }

    return "None";
}

Je nach Gerät sind möglicherweise nicht alle Standortwerte verfügbar. Die Eigenschaft Altitude kann beispielsweise null sein, einen Wert von 0 haben oder einen positiven Wert, der die Meter über dem Meeresspiegel angibt. Andere Werte, die möglicherweise nicht vorhanden sind, sind die Eigenschaften Speed und Course.

Abrufen der aktuellen Position

Während die Überprüfung auf die letzte bekannte Position des Geräts schneller sein kann, kann es ungenau sein. Verwenden Sie die Methode GetLocationAsync, um das Gerät nach dem aktuellen Standort zu fragen. Sie können die Genauigkeit und das Timeout der Abfrage konfigurieren. Es ist am besten, die Methode zu überladen, die die Parameter GeolocationRequest und CancellationToken verwendet, da es einige Zeit dauern kann, den Standort des Geräts zu ermitteln.

Hinweis

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

Im folgenden Codebeispiel wird veranschaulicht, wie der Standort des Geräts angefordert wird, während der Abbruch unterstützt wird:

private CancellationTokenSource _cancelTokenSource;
private bool _isCheckingLocation;

public async Task GetCurrentLocation()
{
    try
    {
        _isCheckingLocation = true;

        GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));

        _cancelTokenSource = new CancellationTokenSource();

        Location location = await Geolocation.Default.GetLocationAsync(request, _cancelTokenSource.Token);

        if (location != null)
            Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
    }
    // Catch one of the following exceptions:
    //   FeatureNotSupportedException
    //   FeatureNotEnabledException
    //   PermissionException
    catch (Exception ex)
    {
        // Unable to get location
    }
    finally
    {
        _isCheckingLocation = false;
    }
}

public void CancelRequest()
{
    if (_isCheckingLocation && _cancelTokenSource != null && _cancelTokenSource.IsCancellationRequested == false)
        _cancelTokenSource.Cancel();
}

Je nach Gerät sind möglicherweise nicht alle Standortwerte verfügbar. Die Eigenschaft Altitude kann beispielsweise null sein, einen Wert von 0 haben oder einen positiven Wert, der die Meter über dem Meeresspiegel angibt. Andere Werte, die möglicherweise nicht vorhanden sind, sind Speed und Course.

Warnung

GetLocationAsync kann in einigen Fällen null ergeben. Dies gibt an, dass die zugrunde liegende Plattform den aktuellen Speicherort nicht abrufen kann.

Auf Standortänderungen achten

Neben der Abfrage des Geräts für den aktuellen Speicherort können Sie auf Positionsänderungen achten, während sich eine App im Vordergrund befindet.

Um zu überprüfen, ob die App gerade auf Standortänderungen wartet, können Sie eine IsListeningForeground-Eigenschaft abfragen. Sobald Sie bereit sind, mit der Überwachung von Standortänderungen zu beginnen, sollten Sie die StartListeningForegroundAsync-Methode aufrufen. Diese Methode beginnt, auf Standortaktualisierungen zu warten und löst das Ereignis LocationChanged aus, wenn sich der Standort ändert, vorausgesetzt, die App befindet sich im Vordergrund. Das GeolocationLocationChangedEventArgs-Objekt, das dieses Ereignis begleitet, hat eine Location-Eigenschaft vom Typ Location, die den neu entdeckten Ort darstellt.

Hinweis

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

Das folgende Codebeispiel veranschaulicht, wie auf eine Standortänderung reagiert wird und wie der geänderte Standort verarbeitet wird:

async void OnStartListening()
{
    try
    {
        Geolocation.LocationChanged += Geolocation_LocationChanged;
        var request = new GeolocationListeningRequest((GeolocationAccuracy)Accuracy);
        var success = await Geolocation.StartListeningForegroundAsync(request);

        string status = success
            ? "Started listening for foreground location updates"
            : "Couldn't start listening";
    }
    catch (Exception ex)
    {
        // Unable to start listening for location changes
    }
}

void Geolocation_LocationChanged(object sender, GeolocationLocationChangedEventArgs e)
{
    // Process e.Location to get the new location
}

Die Fehlerbehandlung kann durch die Registrierung eines Ereignisbehandlers für das Ereignis ListeningFailed erfolgen. Das GeolocationListeningFailedEventArgs-Objekt, das dieses Ereignis begleitet, hat eine Error-Eigenschaft vom Typ GeolocationError, die angibt, warum das Abhören fehlgeschlagen ist. Wenn das ListeningFailed-Ereignis ausgelöst wird, wird das Warten auf weitere Ortswechsel beendet und es werden keine weiteren LocationChanged-Ereignisse ausgelöst.

Wenn Sie nicht mehr auf Standortänderungen warten wollen, rufen Sie die Methode StopListeningForeground auf:

void OnStopListening()
{
    try
    {
        Geolocation.LocationChanged -= Geolocation_LocationChanged;
        Geolocation.StopListeningForeground();
        string status = "Stopped listening for foreground location updates";
    }
    catch (Exception ex)
    {
        // Unable to stop listening for location changes
    }
}

Hinweis

Die StopListeningForeground-Methode hat keine Wirkung, wenn die App nicht auf Standortänderungen wartet.

Genauigkeit

In den folgenden Abschnitten wird der Abstand zur Positionsgenauigkeit pro Plattform beschrieben:

Wichtig

iOS hat einige Einschränkungen hinsichtlich der Genauigkeit. Weitere Informationen finden Sie im Abschnitt Plattformunterschiede.

Niedrigste

Plattform Abstand (in Metern)
Android 500
iOS 3000
Windows 1000–5000

Niedrig

Plattform Abstand (in Metern)
Android 500
iOS 1000
Windows 300–3000

Mittel (Standard)

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

Hoch

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

Sehr hoch

Plattform Abstand (in Metern)
Android 0–100
iOS ~0
Windows <= 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. Sie können dies feststellen, indem Sie die IsFromMockProvider auf einem beliebigen Location verwenden:

public async Task CheckMock()
{
    GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium);
    Location location = await Geolocation.Default.GetLocationAsync(request);

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

Abstand zwischen zwei Standorten

Mit der CalculateDistance-Methode wird die Entfernung zwischen zwei geografischen Orten berechnet. 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. Diese Berechnung ist als Großkreisentfernung bekannt.

Der folgende Code berechnet den Abstand zwischen den US-amerikanischen Städten Boston und San Francisco:

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(Double, Double, Double)-Konstruktor akzeptiert die Argumente Breitengrad und Längengrad. 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

In diesem Abschnitt werden die plattformspezifischen Unterschiede zur Geolocation-API beschrieben.

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 dieser Ort keine Höhe hat, wird 0.0 zurückgegeben.

Die Eigenschaft Location.ReducedAccuracy wird nur von iOS verwendet und liefert false auf allen anderen Plattformen.