Xamarin.Essentials:Geolokalizacja

Klasa Geolocation udostępnia interfejsy API umożliwiające pobieranie bieżących współrzędnych geolokalizacji urządzenia.

Rozpocznij

Aby rozpocząć korzystanie z tego interfejsu API, przeczytaj przewodnik wprowadzający , Xamarin.Essentials aby upewnić się, że biblioteka jest prawidłowo zainstalowana i skonfigurowana w projektach.

Aby uzyskać dostęp do funkcji geolokalizacji , wymagana jest następująca konfiguracja specyficzna dla platformy:

Wymagane są uprawnienia Coarse i Fine Location i muszą być skonfigurowane w projekcie systemu Android. Ponadto jeśli aplikacja jest przeznaczona dla systemu Android 5.0 (poziom 21 interfejsu API) lub nowszy, musisz zadeklarować, że aplikacja korzysta z funkcji sprzętowych w pliku manifestu. Można to dodać w następujący sposób:

Otwórz plik AssemblyInfo.cs w folderze Właściwości i dodaj:

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

Lub zaktualizuj manifest systemu Android:

Otwórz plik AndroidManifest.xml w folderze Właściwości i dodaj następujące elementy w węźle manifestu:

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

Możesz też kliknąć prawym przyciskiem myszy projekt systemu Android i otworzyć właściwości projektu. W obszarze Manifest systemu Android znajdź wymagane uprawnienia: obszar i sprawdź uprawnienia ACCESS_COARSE_LOCATION i ACCESS_FINE_LOCATION . Spowoduje to automatyczne zaktualizowanie pliku AndroidManifest.xml .

Jeśli aplikacja jest przeznaczona dla systemu Android 10 — Q (poziom interfejsu API 29 lub nowszy) i żąda lokalizacjiAlways, musisz również dodać następujące uprawnienie do AssemblyInfo.cs:

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

Lub bezpośrednio do AndroidManifest.xml:

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

Zaleca się przeczytanie dokumentacji systemu Android dotyczącej aktualizacji lokalizacji w tle, ponieważ należy wziąć pod uwagę wiele ograniczeń.

Ten interfejs API używa uprawnień środowiska uruchomieniowego w systemie Android. Upewnij się, że Xamarin.Essentials obsługa uprawnień została w pełni zainicjowana, a obsługa uprawnień jest skonfigurowana w aplikacji.

W projekcie MainLauncher systemu Android lub dowolnym Activity uruchomionym Xamarin.Essentials projekcie musi zostać zainicjowana w metodzie OnCreate :

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

Aby obsłużyć uprawnienia środowiska uruchomieniowego w systemie Android, Xamarin.Essentials musi otrzymać dowolny OnRequestPermissionsResult. Dodaj następujący kod do wszystkich Activity klas:

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

Korzystanie z geolokalizacji

Dodaj odwołanie do Xamarin.Essentials klasy:

using Xamarin.Essentials;

Interfejs API geolokalizacji wyświetli również monit o uprawnienia użytkownika w razie potrzeby.

Ostatnią znaną lokalizację urządzenia można uzyskać, wywołując metodę GetLastKnownLocationAsync . Jest to często szybsze, a następnie wykonywanie pełnego zapytania, ale może być mniej dokładne i może zwracać null , jeśli nie istnieje buforowana lokalizacja.

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
}

Aby wykonywać zapytania dotyczące współrzędnych lokalizacji bieżącego urządzenia, GetLocationAsync można go użyć. Najlepiej jest przekazać pełny GeolocationRequest kod i CancellationToken ponieważ uzyskanie lokalizacji urządzenia może zająć trochę czasu.

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

Zwróć uwagę, że wszystkie wartości mogą być dostępne ze względu na to, jak każde urządzenie wykonuje zapytania dotyczące geolokalizacji za pośrednictwem różnych dostawców. Na przykład Altitude właściwość może mieć nullwartość , ma wartość 0 lub wartość dodatnią, która znajduje się w metrach nad poziomem morza. Inne wartości, które mogą nie być obecne, obejmują Speed i Course.

Dokładność geolokalizacji

W poniższej tabeli przedstawiono dokładność dla poszczególnych platform:

Najniższe

Platforma Odległość (w metrach)
Android 500
iOS 3000
Platforma UWP 1000 - 5000

Niski

Platforma Odległość (w metrach)
Android 500
iOS 1000
Platforma UWP 300 - 3000

Średni (wartość domyślna)

Platforma Odległość (w metrach)
Android 100–500
iOS 100
Platforma UWP 30-500

Wys.

Platforma Odległość (w metrach)
Android 0 - 100
iOS 10
Platforma UWP <= 10

Najlepsze

Platforma Odległość (w metrach)
Android 0 - 100
iOS ~0
Platforma UWP <= 10

Wykrywanie pozornych lokalizacji

Niektóre urządzenia mogą zwracać pozorną lokalizację od dostawcy lub przez aplikację udostępniającą pozorne lokalizacje. Możesz to wykryć, używając elementu IsFromMockProvider w dowolnym Locationobiekcie .

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

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

Odległość między dwiema lokalizacjami

Klasy Location i LocationExtensions definiują CalculateDistance metody, które umożliwiają obliczenie odległości między dwiema lokalizacjami geograficznymi. Ta obliczona odległość nie bierze pod uwagę dróg ani innych ścieżek i jest tylko najkrótszą odległością między dwoma punktami wzdłuż powierzchni Ziemi, znanym również jako odległość wielkiego koła lub potocznie, odległość "jak leci wrona".

Oto przykład:

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 ma argumenty szerokości i długości geograficznej w tej kolejności. Dodatnie wartości szerokości geograficznej są na północ od równika, a dodatnie wartości długości geograficznej są na wschód od Regionu Głównego. Użyj argumentu końcowego, aby CalculateDistance określić kilometry lub kilometry. Klasa UnitConverters definiuje KilometersToMilesMilesToKilometers również metody i do konwertowania między dwiema jednostkami.

Różnice między platformami

Wysokość jest obliczana inaczej na każdej platformie.

W systemie Android wysokość, jeśli jest dostępna, jest zwracana w metrach powyżej wielokropka WGS 84 odwołania. Jeśli ta lokalizacja nie ma wysokości, zwracana jest wartość 0,0.

interfejs API

Więcej filmów na platformie Xamarin można znaleźć w witrynach Channel 9 i YouTube.