Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule opisano sposób używania interfejsu użytkownika aplikacji wieloplatformowej platformy .NET (.NET MAUI). IGeolocation Ten interfejs udostępnia interfejsy API umożliwiające pobieranie bieżących współrzędnych geolokalizacji urządzenia.
Domyślna implementacja interfejsu IGeolocation
jest dostępna za pośrednictwem właściwości Geolocation.Default. Zarówno interfejs IGeolocation
, jak i klasa Geolocation
znajdują się w przestrzeni nazw Microsoft.Maui.Devices.Sensors
.
Rozpocznij
Aby uzyskać dostęp do funkcji geolokalizacji , wymagana jest następująca konfiguracja specyficzna dla platformy:
Należy określić uprawnienia do ogólnej lub dokładnej lokalizacji, lub oba, i skonfigurować je 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:
Dodaj uprawnienie oparte na zestawie:
Otwórz plik Platforms/Android/MainApplication.cs i dodaj następujące atrybuty asemblacji po
using
dyrektyw:[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)]
Jeśli aplikacja jest przeznaczona dla systemu Android 10 — Q (poziom interfejsu API 29 lub nowszy) i żąda
LocationAlways
, musisz również dodać to żądanie uprawnień:[assembly: UsesPermission(Android.Manifest.Permission.AccessBackgroundLocation)]
- lub -
Zaktualizuj manifest systemu Android:
Otwórz plik Platforms/Android/AndroidManifest.xml i dodaj następujący kod w węźle
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" />
Jeśli aplikacja jest przeznaczona dla systemu Android 10 — Q (poziom interfejsu API 29 lub nowszy) i żąda
LocationAlways
, musisz również dodać to żądanie uprawnień:<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
- lub -
Zaktualizuj manifest systemu Android w edytorze manifestu:
W programie Visual Studio kliknij dwukrotnie plik Platforms/Android/AndroidManifest.xml, aby otworzyć edytor manifestu systemu Android. Następnie w obszarze Wymagane uprawnienia sprawdź uprawnienia wymienione powyżej. Spowoduje to automatyczne zaktualizowanie pliku AndroidManifest.xml.
Wskazówka
Zapoznaj się z dokumentacją systemu Android dotyczącą aktualizacji lokalizacji w tle, ponieważ należy wziąć pod uwagę wiele ograniczeń.
Uzyskaj ostatnią znaną lokalizację
Urządzenie mogło zbuforować najnowszą lokalizację urządzenia.
GetLastKnownLocationAsync() Użyj metody , aby uzyskać dostęp do buforowanej lokalizacji, jeśli jest dostępna. Jest to często szybsze niż wykonywanie pełnego zapytania o lokalizację, ale może być mniej dokładne. Jeśli nie istnieje lokalizacja buforowana, ta metoda zwraca wartość null
.
Uwaga / Notatka
W razie potrzeby interfejs API geolokalizacji prosi użytkownika o przyznanie uprawnień.
W poniższym przykładzie kodu pokazano sprawdzanie lokalizacji buforowanej:
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";
}
W zależności od urządzenia nie wszystkie wartości lokalizacji mogą być dostępne. Na przykład właściwość Altitude może być null
, mieć wartość 0 lub wartość dodatnią wskazującą metry nad poziomem morza. Inne wartości, które mogą nie być obecne, obejmują właściwość Speed oraz właściwość Course.
Pobieranie bieżącej lokalizacji
Sprawdzanie ostatniej znanej lokalizacji urządzenia może być szybsze, ale może być niedokładne. Użyj metody , GetLocationAsync aby wysłać zapytanie do urządzenia dla bieżącej lokalizacji. Można skonfigurować dokładność i limit czasu zapytania. Najlepszym rozwiązaniem jest przeciążenie metody korzystającej z GeolocationRequest parametrów i CancellationToken , ponieważ uzyskanie lokalizacji urządzenia może zająć trochę czasu.
Uwaga / Notatka
W razie potrzeby interfejs API geolokalizacji prosi użytkownika o zgodę.
W poniższym przykładzie kodu pokazano, jak zażądać lokalizacji urządzenia, zapewniając możliwość anulowania:
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();
}
Nie wszystkie wartości lokalizacji mogą być dostępne w zależności od urządzenia. Na przykład, właściwość Altitude może mieć wartość null
, wartość 0 lub wartość dodatnią wskazującą metry nad poziomem morza. Inne wartości, które mogą nie być obecne, obejmują Speed i Course.
Ostrzeżenie
GetLocationAsync może zwrócić null
w niektórych scenariuszach. Oznacza to, że platforma bazowa nie może uzyskać bieżącej lokalizacji.
Nasłuchiwanie zmian lokalizacji
Oprócz zapytania urządzenia o bieżącą lokalizację, można nasłuchiwać zmian lokalizacji, gdy aplikacja jest na pierwszym planie.
Aby sprawdzić, czy aplikacja obecnie nasłuchuje zmian lokalizacji, można zapytać o właściwość IsListeningForeground. Gdy wszystko będzie gotowe do rozpoczęcia nasłuchiwania zmian lokalizacji, należy wywołać metodę StartListeningForegroundAsync . Ta metoda rozpoczyna nasłuchiwanie aktualizacji lokalizacji i zgłasza LocationChanged zdarzenie, gdy lokalizacja ulegnie zmianie, pod warunkiem, że aplikacja jest na pierwszym planie. Obiekt GeolocationLocationChangedEventArgs , który towarzyszy temu zdarzeniu, ma Location właściwość typu Location, która reprezentuje wykrytą nową lokalizację.
Uwaga / Notatka
W razie potrzeby interfejs API geolokalizacji prosi użytkownika o zezwolenia.
W poniższym przykładzie kodu pokazano, jak nasłuchiwać zmiany lokalizacji i jak przetwarzać zmienioną lokalizację:
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
}
Obsługę błędów można zaimplementować, rejestrując program obsługi zdarzeń dla ListeningFailed zdarzenia. Obiekt GeolocationListeningFailedEventArgs , który towarzyszy temu zdarzeniu, ma Error właściwość typu GeolocationError, która wskazuje, dlaczego nasłuchiwanie nie powiodło się. Po podniesieniu zdarzenia ListeningFailed zatrzymuje się nasłuchiwanie dalszych zmian lokalizacji i nie są wywoływane żadne dalsze zdarzenia LocationChanged.
Aby zatrzymać nasłuchiwanie zmian lokalizacji, wywołaj metodę 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
}
}
Uwaga / Notatka
Metoda StopListeningForeground nie ma wpływu, gdy aplikacja nie nasłuchuje zmian lokalizacji.
Sprawdzanie, czy usługi lokalizacji są włączone
Klasa Geolocation ma właściwość tylko IsEnabled
do odczytu, która może służyć do określenia, czy usługi lokalizacji zostały włączone na urządzeniu.
Dokładność
W poniższych sekcjach przedstawiono dokładność lokalizacji w zależności od platformy.
Ważne
System iOS ma pewne ograniczenia dotyczące dokładności. Aby uzyskać więcej informacji, zobacz sekcję Różnice między platformami .
Najniższy
Platforma | Odległość (w metrach) |
---|---|
Android | 500 |
Ios | 3000 |
Windows | 1000 - 5000 |
Niski
Platforma | Odległość (w metrach) |
---|---|
Android | 500 |
Ios | 1000 |
Windows | 300 - 3000 |
Średni (wartość domyślna)
Platforma | Odległość (w metrach) |
---|---|
Android | 100 - 500 |
Ios | 100 |
Windows | 30-500 |
Wysoki
Platforma | Odległość (w metrach) |
---|---|
Android | 0 - 100 |
Ios | 10 |
Windows | <= 10 |
Najlepsze
Platforma | Odległość (w metrach) |
---|---|
Android | 0 - 100 |
Ios | ~0 |
Windows | <= 10 |
Wykrywanie pozornych lokalizacji
Niektóre urządzenia mogą zwracać fikcyjną lokalizację od dostawcy lub przez aplikację udostępniającą fikcyjne lokalizacje. Możesz to wykryć, używając elementu IsFromMockProvider w dowolnym 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
}
}
Odległość między dwiema lokalizacjami
Metoda CalculateDistance oblicza odległość 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 na powierzchni Ziemi. To obliczenie jest określane jako obliczanie odległości z dużym okręgiem .
Poniższy kod oblicza odległość między miastami Stanów Zjednoczonych Ameryki Boston i San Francisco:
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) akceptuje odpowiednio argumenty szerokości geograficznej i długości geograficznej. 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 w CalculateDistance
określić mile lub kilometry. Klasa UnitConverters definiuje również metody KilometersToMiles oraz MilesToKilometers do konwertowania między dwiema jednostkami.
Różnice między platformami
W tej części opisano różnice specyficzne dla platformy związane z interfejsem API geolokalizacji.
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, 0.0
zostanie zwrócona.
Właściwość Location.ReducedAccuracy jest używana tylko przez system iOS i zwraca wartość false
na wszystkich innych platformach.