Sdílet prostřednictvím


Geografická poloha

Browse sample. Procházení ukázky

Tento článek popisuje, jak můžete použít rozhraní .NET Multi-Platform App UI (.NET MAUI). IGeolocation Toto rozhraní poskytuje rozhraní API pro načtení aktuálních souřadnic geografické polohy zařízení.

Výchozí implementace IGeolocation rozhraní je k dispozici prostřednictvím Geolocation.Default vlastnosti. Rozhraní IGeolocation i Geolocation třída jsou obsaženy v Microsoft.Maui.Devices.Sensors oboru názvů.

Začínáme

Pro přístup k funkcím geografické polohy se vyžaduje následující nastavení specifické pro platformu:

Musí být zadána hrubá nebo podrobná oprávnění k umístění nebo obojí a měla by být nakonfigurována v projektu Android.

Pokud vaše aplikace cílí na Android 5.0 (úroveň rozhraní API 21) nebo vyšší, musíte deklarovat, že vaše aplikace používá hardwarové funkce v souboru manifestu. Můžete ho přidat následujícími způsoby:

  • Přidejte oprávnění založené na sestavení:

    Otevřete soubor Platforms/Android/MainApplication.cs a za direktivy using přidejte následující atributy sestavení:

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

    Pokud vaše aplikace cílí na Android 10 – Q (rozhraní API úrovně 29 nebo vyšší) a požaduje LocationAlwaysse, musíte také přidat tuto žádost o oprávnění:

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

    - nebo -

  • Aktualizace manifestu Androidu:

    Otevřete soubor Platforms/Android/AndroidManifest.xml a do uzlu přidejte následujícímanifest:

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

    Pokud vaše aplikace cílí na Android 10 – Q (rozhraní API úrovně 29 nebo vyšší) a požaduje LocationAlwaysse, musíte také přidat tuto žádost o oprávnění:

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

    - nebo -

  • Aktualizace manifestu Androidu v editoru manifestu:

    V sadě Visual Studio poklikejte na soubor Platforms/Android/AndroidManifest.xml a otevřete editor manifestu Androidu. Potom v části Požadovaná oprávnění zkontrolujte výše uvedená oprávnění. Tím se automaticky aktualizuje soubor AndroidManifest.xml .

Tip

Nezapomeňte si přečíst dokumentaci k Androidu o aktualizacích umístění na pozadí, protože je potřeba zvážit mnoho omezení.

Získání posledního známého umístění

Zařízení mohlo mít v mezipaměti nejnovější umístění zařízení. Použijte metodu GetLastKnownLocationAsync() pro přístup k umístění v mezipaměti, pokud je k dispozici. To je často rychlejší než provádění dotazu na úplné umístění, ale může být méně přesné. Pokud neexistuje žádné umístění v mezipaměti, vrátí tato metoda null.

Poznámka:

V případě potřeby rozhraní API geografické polohy vyzve uživatele k zadání oprávnění.

Následující příklad kódu ukazuje kontrolu umístění v mezipaměti:

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

V závislosti na zařízení nemusí být dostupné všechny hodnoty polohy. Vlastnost může být nullnapříklad Altitude , má hodnotu 0 nebo má kladnou hodnotu označující měřiče nad mořem. Mezi další hodnoty, které nemusí být přítomné, patří Speed vlastnosti a Course vlastnosti.

Získání aktuálního umístění

Při kontrole posledního známého umístění zařízení může být rychlejší, může to být nepřesné. Použijte metodu GetLocationAsync k dotazování zařízení na aktuální umístění. Můžete nakonfigurovat přesnost a časový limit dotazu. Nejlepší je přetížit metodu, která používá parametry GeolocationRequest , CancellationToken protože získání polohy zařízení může nějakou dobu trvat.

Poznámka:

V případě potřeby rozhraní API geografické polohy vyzve uživatele k zadání oprávnění.

Následující příklad kódu ukazuje, jak požádat o umístění zařízení a zároveň podporovat zrušení:

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

V závislosti na zařízení nemusí být dostupné všechny hodnoty polohy. Vlastnost může být nullnapříklad Altitude , má hodnotu 0 nebo má kladnou hodnotu označující měřiče nad mořem. Jiné hodnoty, které nemusí být zahrnuty Speed a Course.

Upozorňující

GetLocationAsync v některých scénářích se může vrátit null . To znamená, že základní platforma nemůže získat aktuální umístění.

Naslouchání změnám umístění

Kromě dotazování zařízení na aktuální umístění můžete naslouchat změnám polohy, když je aplikace v popředí.

Pokud chcete zkontrolovat, jestli aplikace aktuálně naslouchá změnám polohy, existuje IsListeningForeground vlastnost, kterou můžete dotazovat. Jakmile budete připraveni začít naslouchat změnám umístění, měli byste metodu StartListeningForegroundAsync volat. Tato metoda začne naslouchat aktualizacím umístění a vyvolá LocationChanged událost při změně umístění za předpokladu, že je aplikace v popředí. Objekt GeolocationLocationChangedEventArgs , který doprovází tuto událost, má Location vlastnost typu Location, která představuje nové umístění, které bylo zjištěno.

Poznámka:

V případě potřeby rozhraní API geografické polohy vyzve uživatele k zadání oprávnění.

Následující příklad kódu ukazuje, jak naslouchat změně umístění a jak zpracovat změněné umístění:

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
}

Zpracování chyb lze implementovat registrací obslužné rutiny ListeningFailed události pro událost. Objekt GeolocationListeningFailedEventArgs , který doprovází tuto událost, má Error vlastnost typu GeolocationError, který označuje, proč naslouchání selhalo. Při vyvolání ListeningFailed události se zastaví naslouchání dalším změnám polohy a nebudou vyvolány žádné další LocationChanged události.

Pokud chcete zastavit naslouchání změnám polohy, zavolejte metodu StopListeningForeground :

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

Poznámka:

Metoda StopListeningForeground nemá žádný vliv, když aplikace nenaslouchá změnám polohy.

Přesnost

Následující části popisují vzdálenost přesnosti polohy na platformu:

Důležité

iOS má určitá omezení týkající se přesnosti. Další informace najdete v části Rozdíly platformy.

Nejnižší

Platforma Vzdálenost (v metrech)
Android 500
iOS 3000
Windows 1000 - 5000

Nejnižší

Platforma Vzdálenost (v metrech)
Android 500
iOS 1000
Windows 300 - 3000

Střední (výchozí)

Platforma Vzdálenost (v metrech)
Android 100 - 500
iOS 100
Windows 30-500

Nejvyšší

Platforma Vzdálenost (v metrech)
Android 0 - 100
iOS 10
Windows <= 10

Nejlepší

Platforma Vzdálenost (v metrech)
Android 0 - 100
iOS ~0
Windows <= 10

Zjišťování napodobených umístění

Některá zařízení můžou vrátit napodobené umístění od poskytovatele nebo aplikace, která poskytuje napodobená umístění. Můžete to zjistit pomocí libovolného IsFromMockProviderLocation:

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

Vzdálenost mezi dvěma umístěními

Metoda CalculateDistance vypočítá vzdálenost mezi dvěma geografickými umístěními. Tato počítaná vzdálenost nezohlední cesty ani jiné cesty a je jen nejkratší vzdálenost mezi dvěma body podél povrchu Země. Tento výpočet se označuje jako výpočet vzdálenosti velkého kruhu.

Následující kód vypočítá vzdálenost mezi USA městy Ameriky v Bostonu a San Franciscu:

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

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

Konstruktor Location(Double, Double, Double) přijímá argumenty zeměpisné šířky a délky v uvedeném pořadí. Kladné hodnoty zeměpisné šířky jsou sever od rovníku a kladné hodnoty délky jsou východně od prime meridianu. Pomocí posledního argumentu CalculateDistance můžete zadat míle nebo kilometry. Třída UnitConverters také definuje KilometersToMiles a MilesToKilometers metody pro převod mezi těmito dvěma jednotkami.

Rozdíly mezi platformami

Tato část popisuje rozdíly specifické pro platformu s rozhraním API geografické polohy.

Na každé platformě se výška počítá odlišně.

V Androidu je výška v případě, že je k dispozici, vrácena v metrech nad referenční elipsou WGS 84. Pokud toto umístění nemá výšku, 0.0 vrátí se.

Vlastnost Location.ReducedAccuracy používá pouze iOS a vrací se false na všech ostatních platformách.