Dela via


Geolokalisering

Bläddra bland exempel. Bläddra i exemplet

Den här artikeln beskriver hur du kan använda .NET Multi-platform App UI (.NET MAUI) IGeolocation-gränssnittet. Det här gränssnittet innehåller API:er för att hämta enhetens aktuella geoplatskoordinater.

Standardimplementeringen av IGeolocation-gränssnittet är tillgänglig via egenskapen Geolocation.Default. Både IGeolocation-gränssnittet och Geolocation-klassen finns i namnområdet Microsoft.Maui.Devices.Sensors.

Kom igång

För att få åtkomst till geoplatsfunktionen krävs följande plattformsspecifika installation:

Grova eller fina platsbehörigheter, eller båda, måste anges och ska konfigureras i Android-projektet.

Om appen dessutom riktar in sig på Android 5.0 (API-nivå 21) eller senare måste du deklarera att appen använder maskinvarufunktionerna i manifestfilen. Detta kan läggas till på följande sätt:

  • Lägg till monteringsbaserade behörigheter:

    Öppna filen Plattformar/Android/MainApplication.cs och lägg till följande sammansättningsattribut efter using direktiv:

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

    Om ditt program riktar in sig på Android 10 – Q (API-nivå 29 eller senare) och begär LocationAlways, måste du också lägga till den här behörighetsbegäran:

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

    -eller-

  • Uppdatera Android-manifestet:

    Öppna filen Plattformar/Android/AndroidManifest.xml och lägg till följande i manifest noden:

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

    Om ditt program riktar in sig på Android 10 – Q (API-nivå 29 eller senare) och begär LocationAlways, måste du också lägga till den här behörighetsbegäran:

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

    -eller-

  • Uppdatera Android-manifestet i manifestredigeraren:

    I Visual Studio dubbelklickar du på filen Plattformar/Android/AndroidManifest.xml för att öppna Android-manifestredigeraren. Under Nödvändiga behörigheter kontrollerar du sedan de behörigheter som anges ovan. Detta uppdaterar automatiskt AndroidManifest.xml-filen .

Tips/Råd

Läs Android-dokumentationen om uppdateringar av bakgrundsplatser eftersom det finns många begränsningar som måste beaktas.

Hämta den senast kända platsen

Enheten kan ha cachelagrat enhetens senaste plats. GetLastKnownLocationAsync() Använd metoden för att komma åt den cachelagrade platsen, om den är tillgänglig. Detta går ofta snabbare än att göra en fullständig platsfråga, men kan vara mindre exakt. Om det inte finns någon cachelagrad plats returnerar nullden här metoden .

Anmärkning

Vid behov uppmanar geoplats-API:et användaren att ange behörigheter.

Följande kodexempel visar sökning efter en cachelagrad plats:

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

Beroende på enheten kan inte alla platsvärden vara tillgängliga. Egenskapen kan till exempel Altitude vara null, ha värdet 0 eller ha ett positivt värde som anger meter över havsnivån. Andra värden som kanske inte finns inkluderar Speed egenskaperna och Course .

Hämta den aktuella platsen

Det kan gå snabbare att söka efter enhetens senast kända plats , men det kan vara felaktigt. GetLocationAsync Använd metoden för att fråga enheten om den aktuella platsen. Du kan konfigurera frågans noggrannhet och tidsgräns. Det är bäst att använda metodöverbelastningen som använder parametrarna GeolocationRequest och CancellationToken, eftersom det kan ta lite tid att hämta positionen för enheten.

Anmärkning

Vid behov uppmanar geoplats-API:et användaren att ange behörigheter.

I följande kodexempel visas hur du begär enhetens plats, samtidigt som du stöder annullering:

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

Alla platsvärden kan inte vara tillgängliga, beroende på enheten. Egenskapen kan till exempel Altitude vara null, ha värdet 0 eller ha ett positivt värde som anger meter över havsnivån. Andra värden som kanske inte finns inkluderar Speed och Course.

Varning

GetLocationAsync kan returneras null i vissa scenarier. Detta indikerar att den underliggande plattformen inte kan hämta den aktuella platsen.

Lyssna efter platsändringar

Förutom att fråga enheten om den aktuella platsen kan du lyssna efter platsändringar medan en app är i förgrunden.

Om du vill kontrollera om appen lyssnar efter platsändringar finns det en IsListeningForeground egenskap som du kan fråga efter. När du är redo att börja lyssna efter platsändringar bör du anropa StartListeningForegroundAsync metoden. Den här metoden börjar lyssna efter platsuppdateringar och genererar LocationChanged händelsen när platsen ändras, förutsatt att appen är i förgrunden. Objektet GeolocationLocationChangedEventArgs som medföljer den här händelsen har en Location egenskap av typen Location, som representerar den nya platsen som har identifierats.

Anmärkning

Vid behov uppmanar geoplats-API:et användaren att ange behörigheter.

I följande kodexempel visas hur du lyssnar efter en platsändring och hur du bearbetar den ändrade platsen:

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
}

Felhantering kan implementeras genom att registrera en händelsehanterare för ListeningFailed händelsen. Objektet GeolocationListeningFailedEventArgs som medföljer den här händelsen har en Error egenskap av typen GeolocationError, som anger varför det inte gick att lyssna. När händelsen ListeningFailed aktiveras upphör lyssnandet efter ytterligare platsändringar och inga fler LocationChanged händelser aktiveras.

Om du vill sluta lyssna efter platsändringar anropar du StopListeningForeground metoden:

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

Anmärkning

Metoden StopListeningForeground har ingen effekt när appen inte lyssnar efter platsändringar.

Kontrollera om platstjänster är aktiverade

Klassen Geolocation har en skrivskyddad IsEnabled egenskap som kan användas för att avgöra om platstjänster har aktiverats på enheten.

Noggrannhet

I följande avsnitt beskrivs avståndet för platsnoggrannhet per plattform:

Viktigt!

iOS har vissa begränsningar när det gäller noggrannhet. Mer information finns i avsnittet Plattformsskillnader .

Lägsta

Plattform Avstånd (i meter)
Android 500
Ios 3000
Windows 1000 - 5000

Låg

Plattform Avstånd (i meter)
Android 500
Ios 1 000
Windows 300 - 3000

Medel (Standard)

Plattform Avstånd (i meter)
Android 100 - 500
Ios 100
Windows 30-500

Högt

Plattform Avstånd (i meter)
Android 0 - 100
Ios 10
Windows <= 10

Bäst

Plattform Avstånd (i meter)
Android 0 - 100
Ios ~0
Windows <= 10

Identifiera falska platser

Vissa enheter kan returnera en falsk plats från providern eller av ett program som tillhandahåller falska platser. Du kan identifiera detta med hjälp av IsFromMockProvider för alla 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
    }
}

Avstånd mellan två platser

Metoden CalculateDistance beräknar avståndet mellan två geografiska platser. Detta beräknade avstånd tar inte hänsyn till vägar eller andra vägar, och är bara det kortaste avståndet mellan de två punkterna längs jordens yta. Den här beräkningen kallas för beräkningen av stora cirkelavstånd .

Följande kod beräknar avståndet mellan städerna Boston och San Francisco i USA:

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

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

Konstruktorn Location(Double, Double, Double) tar emot argumenten för latitud och longitud, i nämnd ordning. Positiva latitudvärden ligger norr om ekvatorn och positiva longitudvärden ligger öster om Prime Meridian. Använd det sista argumentet till CalculateDistance för att ange miles eller kilometer. Klassen UnitConverters definierar också KilometersToMiles och MilesToKilometers metoder för konvertering mellan de två enheterna.

Plattformsskillnader

I det här avsnittet beskrivs de plattformsspecifika skillnaderna med geoplats-API:et.

Höjden beräknas på olika sätt på varje plattform.

På Android returneras höjd, om tillgängligt, i meter ovanför WGS 84-referensellipsoiden. Om den här platsen inte har någon höjd, 0.0 returneras.

Egenskapen Location.ReducedAccuracy används endast av iOS och returneras false på alla andra plattformar.