Geografická poloha
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
LocationAlways
se, musíte také přidat tuto žádost o oprávnění:[assembly: UsesPermission(Android.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
LocationAlways
se, 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 null
napří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 null
napří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 IsFromMockProvider 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
}
}
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.