Xamarin.Essentials: Geografická poloha

Třída Geolocation poskytuje rozhraní API pro načtení aktuálních souřadnic geografické polohy zařízení.

Začínáme

Pokud chcete začít používat toto rozhraní API, přečtěte si příručku Začínáme pro a ujistěte se, že je knihovna správně nainstalovaná a nastavená ve vašich projektech.

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

Vyžaduje se oprávnění Coarse a Fine Location a musí být nakonfigurovaná v projektu pro Android. Kromě toho platí, že 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:

Otevřete soubor AssemblyInfo.cs ve složce Properties a přidejte:

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

Nebo aktualizujte manifest Androidu:

Otevřete soubor AndroidManifest.xml ve složce Vlastnosti a do uzlu manifestu přidejte následující kód:

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

Nebo klikněte pravým tlačítkem na projekt pro Android a otevřete jeho vlastnosti. V části Manifest pro Android vyhledejte oblast Požadovaná oprávnění: a zaškrtněte ACCESS_COARSE_LOCATION a ACCESS_FINE_LOCATION oprávnění. Tím se automaticky aktualizuje AndroidManifest.xml souboru.

Pokud vaše aplikace cílí na Android 10 – Q (úroveň rozhraní API 29 nebo vyšší) a žádá o umístění, musíte do souboru AssemblyInfo.cstaké přidat následující oprávnění:

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

Nebo přímo do AndroidManifest.xml:

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

Pokud se doporučuje přečíst si dokumentaci k androidu o aktualizacích umístění na pozadí, protože existuje mnoho omezení, která je potřeba zvážit.

Toto rozhraní API používá oprávnění modulu runtime v Androidu. Ujistěte Xamarin.Essentials se, že je plně inicializované a že je ve vaší aplikaci nastaveno zpracování oprávnění.

V projektu androidu nebo v MainLauncher projektu, Activity který se Xamarin.Essentials spustí, musí být inicializována v OnCreate metodě :

protected override void OnCreate(Bundle savedInstanceState) 
{
    //...
    base.OnCreate(savedInstanceState);
    Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
    //...
}    

Pokud chcete v Androidu zpracovávat oprávnění modulu runtime, Xamarin.Essentials musí přijmout všechny OnRequestPermissionsResult . Do všech tříd přidejte následující Activity kód:

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
    Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

    base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

Použití geografické polohy

Do třídy Xamarin.Essentials přidejte odkaz na :

using Xamarin.Essentials;

Rozhraní API pro geografickou polohu také v případě potřeby vyzve uživatele k zadání oprávnění.

Poslední známou polohu zařízení můžete získat voláním metody . To je často rychlejší než úplné dotazování, ale může být méně přesné a může se vrátit, pokud žádné umístění null v mezipaměti neexistuje.

try
{
    var location = await Geolocation.GetLastKnownLocationAsync();

    if (location != null)
    {
        Console.WriteLine($"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
}

K dotazování souřadnic polohy aktuálního zařízení je možné použít . Nejlepší je předat ho naplno, a protože získání polohy zařízení může nějakou dobu GeolocationRequestCancellationToken trvat.

CancellationTokenSource cts;

async Task GetCurrentLocation()
{
    try
    {
        var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
        cts = new CancellationTokenSource();
        var location = await Geolocation.GetLocationAsync(request, cts.Token);

        if (location != null)
        {
            Console.WriteLine($"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
    }
}

protected override void OnDisappearing()
{
    if (cts != null && !cts.IsCancellationRequested)
        cts.Cancel();
    base.OnDisappearing();
}

Všimněte si, že všechny hodnoty mohou být dostupné kvůli tomu, jak se každé zařízení dotazuje na geografickou polohu prostřednictvím různých poskytovatelů. Vlastnost může být například , má hodnotu 0 nebo má kladnou hodnotu, která je v metrech Altitudenull nad úrovní vody. Mezi další hodnoty, které nemusí být k dispozici, patří Speed a Course .

Přesnost geografické polohy

Následující tabulka uvádí přesnost pro každou platformu:

Nejnižší

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

Nízká

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

Střední (výchozí)

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

Vysoká

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

Nejlepší

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

Detekce napodob v umístěních

Některá zařízení mohou od poskytovatele nebo aplikace, která poskytuje napodobované umístění, vrátit napodobované umístění. To můžete zjistit pomocí příkazu IsFromMockProvider na libovolném . Location

var request = new GeolocationRequest(GeolocationAccuracy.Medium);
var location = await Geolocation.GetLocationAsync(request);

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

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

Třídy LocationLocationExtensions a definují CalculateDistance metody, které umožňují vypočítat vzdálenost mezi dvěma geografickými umístěními. Tato počítaná vzdálenost nezohlední silnici ani jiné cesty a je pouze nejkratší vzdálenost mezi dvěma body na povrchu Země, která se také označuje jako vzdálenost s velkým kruhem nebo kolokálně, vzdálenost "jako smyšlený bod".

Tady je příklad:

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 má argumenty zeměpisné šířky a délky v tomto pořadí. Kladné hodnoty zeměpisné šířky jsou severně od rovníku a kladné hodnoty zeměpisné délky jsou východně od éra Prime. Pomocí posledního argumentu můžete CalculateDistance určit mil nebo kilometrů. Třída UnitConverters také definuje metody a pro převod mezi těmito dvěma KilometersToMilesMilesToKilometers jednotkami.

Rozdíly mezi platformami

Nadmořská výška se na každé platformě počítá odlišně.

V Androidu se nadměrnávýška (pokud je k dispozici) vrátí v metrech nad referenčním elipsoidem WGS 84. Pokud toto umístění nemá nadmořskou výšku, vrátí se hodnota 0,0.

rozhraní API

Další videa o Xamarinu najdete na Channel 9 a YouTube.