Delen via


Geolocatie

Blader door het voorbeeld. Blader door het voorbeeld

In dit artikel wordt beschreven hoe u de .NET Multi-Platform App UI (.NET MAUI) IGeolocation interface kunt gebruiken. Deze interface biedt API's voor het ophalen van de huidige geolocatiecoördinaten van het apparaat.

De standaard implementatie van de IGeolocation-interface is beschikbaar via de eigenschap Geolocation.Default. Zowel de IGeolocation-interface als Geolocation klasse bevinden zich in de Microsoft.Maui.Devices.Sensors naamruimte.

Aan de slag

Voor toegang tot de geolocatie-functionaliteit is de volgende platformspecifieke installatie vereist:

Toestemmingen voor grove of fijne locatie, of beide, moeten worden opgegeven en geconfigureerd in het Android-project.

Als uw app is gericht op Android 5.0 (API-niveau 21) of hoger, moet u declareren dat uw app gebruikmaakt van de hardwarefuncties in het manifestbestand. Dit kan op de volgende manieren worden toegevoegd:

  • Voeg de assembly-gebaseerde machtiging toe.

    Open het bestand Platforms/Android/MainApplication.cs en voeg de volgende assemblykenmerken toe na using instructies:

    [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)]
    

    Als uw toepassing gericht is op Android 10 - Q (API-niveau 29 of hoger) en aanvraagt LocationAlways, moet u ook deze machtigingsaanvraag toevoegen:

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

    -of-

  • Werk het Android-manifest bij:

    Open het bestand Platforms/Android/AndroidManifest.xml en voeg het volgende toe in het manifest knooppunt:

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

    Als uw toepassing gericht is op Android 10 - Q (API-niveau 29 of hoger) en aanvraagt LocationAlways, moet u ook deze machtigingsaanvraag toevoegen:

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

    -of-

  • Werk het Android-manifest bij in de manifesteditor:

    Dubbelklik in Visual Studio op het bestand Platforms/Android/AndroidManifest.xml om de Android-manifesteditor te openen. Controleer vervolgens onder Vereiste machtigingen de bovenstaande machtigingen. Hiermee wordt het AndroidManifest.xml-bestand automatisch bijgewerkt.

Aanbeveling

Lees de Android-documentatie over updates van locatie op de achtergrond, omdat er met veel beperkingen rekening moet worden gehouden.

De laatst bekende locatie ophalen

Het apparaat heeft mogelijk de meest recente locatie van het apparaat in de cache opgeslagen. Gebruik de GetLastKnownLocationAsync() methode voor toegang tot de locatie in de cache, indien beschikbaar. Dit is vaak sneller dan het uitvoeren van een volledige locatiequery, maar kan minder nauwkeurig zijn. Als er geen locatie in de cache bestaat, retourneert deze methode null.

Opmerking

Indien nodig vraagt de Geolocatie-API de gebruiker om machtigingen.

In het volgende codevoorbeeld ziet u hoe u controleert op een locatie in de cache:

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";
}

Afhankelijk van het apparaat zijn mogelijk niet alle locatiewaarden beschikbaar. De Altitude eigenschap kan nullbijvoorbeeld zijn, een waarde van 0 hebben of een positieve waarde hebben die de meters boven zeeniveau aangeeft. Andere waarden die mogelijk niet aanwezig zijn, bevatten de Speed en Course eigenschappen.

De huidige locatie ophalen

Hoewel het controleren van de laatst bekende locatie van het apparaat sneller kan zijn, kan het ook onnauwkeurig zijn. Gebruik de GetLocationAsync methode om een query uit te voeren op het apparaat voor de huidige locatie. U kunt de nauwkeurigheid en time-out van de query configureren. Het is het beste om de methode-overbelasting te gebruiken die de parameters GeolocationRequest en CancellationToken vereist, omdat het enige tijd kan duren om de locatie van het apparaat op te halen.

Opmerking

Indien nodig vraagt de Geolocatie-API de gebruiker om machtigingen.

In het volgende codevoorbeeld ziet u hoe u de locatie van het apparaat aanvraagt, terwijl de annulering wordt ondersteund:

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();
}

Mogelijk zijn niet alle locatiewaarden beschikbaar, afhankelijk van het apparaat. De Altitude eigenschap kan nullbijvoorbeeld zijn, een waarde van 0 hebben of een positieve waarde hebben die de meters boven zeeniveau aangeeft. Andere waarden die mogelijk niet aanwezig zijn, omvatten Speed en Course.

Waarschuwing

In sommige scenario's kan GetLocationAsyncnull retourneren. Dit geeft aan dat het onderliggende platform de huidige locatie niet kan verkrijgen.

Luisteren naar locatiewijzigingen

Naast het uitvoeren van query's op het apparaat voor de huidige locatie, kunt u luisteren naar locatiewijzigingen terwijl een app zich op de voorgrond bevindt.

Als u wilt controleren of de app momenteel luistert naar locatiewijzigingen, is er een IsListeningForeground eigenschap die u kunt opvragen. Zodra u klaar bent om te luisteren naar locatiewijzigingen, moet u de StartListeningForegroundAsync methode aanroepen. Met deze methode begint het luisteren naar locatie-updates, en wordt de LocationChanged gebeurtenis geactiveerd wanneer de locatie verandert, op voorwaarde dat de app op de voorgrond draait. Het GeolocationLocationChangedEventArgs object dat bij deze gebeurtenis hoort, heeft een Location eigenschap, van het type Location, die de nieuwe locatie vertegenwoordigt die is gedetecteerd.

Opmerking

Indien nodig vraagt de Geolocatie-API de gebruiker om machtigingen.

In het volgende codevoorbeeld ziet u hoe u kunt luisteren naar een locatiewijziging en hoe u de gewijzigde locatie verwerkt:

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
}

Foutafhandeling kan worden geïmplementeerd door een gebeurtenis-handler voor de ListeningFailed gebeurtenis te registreren. Het GeolocationListeningFailedEventArgs object dat bij deze gebeurtenis hoort, heeft een Error eigenschap, van het type GeolocationError, die aangeeft waarom luisteren is mislukt. Wanneer de ListeningFailed gebeurtenis wordt gegenereerd, stopt het luisteren naar verdere locatiewijzigingen en worden er geen verdere LocationChanged gebeurtenissen gegenereerd.

Als u wilt stoppen met luisteren naar locatiewijzigingen, roept u de StopListeningForeground methode aan:

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

Opmerking

De StopListeningForeground methode heeft geen effect wanneer de app niet luistert naar locatiewijzigingen.

Controleren of locatieservices zijn ingeschakeld

De Geolocation klasse heeft een alleen-lezen IsEnabled eigenschap die kan worden gebruikt om te bepalen of locatieservices zijn ingeschakeld op het apparaat.

Nauwkeurigheid

In de volgende secties wordt de locatienauwkeurigheidsafstand per platform beschreven.

Belangrijk

iOS heeft enkele beperkingen met betrekking tot nauwkeurigheid. Zie de sectie Platformverschillen voor meer informatie.

Laagste

Platvorm Afstand (in meters)
Android 500
Ios 3000
Ramen 1000 - 5000

Laag

Platvorm Afstand (in meters)
Android 500
Ios 1000
Ramen 300 - 3000

Gemiddeld (standaard)

Platvorm Afstand (in meters)
Android 100 - 500
Ios 100
Ramen 30-500

Hoog

Platvorm Afstand (in meters)
Android 0 - 100
Ios 10
Ramen <= 10

Beste

Platvorm Afstand (in meters)
Android 0 - 100
Ios ~0
Ramen <= 10

Mocklocaties detecteren

Sommige apparaten kunnen een gesimuleerde locatie retourneren van de provider of door een toepassing die gesimuleerde locaties biedt. U kunt dit detecteren met behulp van de IsFromMockProvider op elk Location.

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

Afstand tussen twee locaties

De CalculateDistance methode berekent de afstand tussen twee geografische locaties. Deze berekende afstand houdt geen rekening met wegen of andere paden en is slechts de kortste afstand tussen de twee punten langs het oppervlak van de aarde. Deze berekening wordt de grote cirkelafstandsberekening genoemd.

Met de volgende code wordt de afstand tussen de Amerikaanse steden Boston en San Francisco berekend:

Location boston = new Location(42.358056, -71.063611);
Location sanFrancisco = new Location(37.783333, -122.416667);

double miles = Location.CalculateDistance(boston, sanFrancisco, DistanceUnits.Miles);

De Location(Double, Double, Double) constructor accepteert respectievelijk de argumenten voor breedtegraad en lengtegraad. Positieve breedtegraadwaarden bevinden zich ten noorden van de evenaar en positieve lengtegraadwaarden liggen ten oosten van de PrimeDian. Gebruik het laatste argument om mijlen of kilometers aan te CalculateDistance geven. De UnitConverters klasse definieert KilometersToMiles en MilesToKilometers methoden voor het converteren tussen de twee eenheden.

Platformverschillen

In deze sectie worden de platformspecifieke verschillen met de geolocatie-API beschreven.

Hoogte wordt op elk platform anders berekend.

Op Android wordt, indien beschikbaar, hoogte geretourneerd in meters boven de WGS 84 referentie-ellipsoïde. Als deze locatie geen hoogte heeft, wordt 0.0 geretourneerd.

De Location.ReducedAccuracy eigenschap wordt alleen gebruikt door iOS en retourneert false op alle andere platforms.