В этой статье описывается, как использовать интерфейс многоплатформенного приложения .NET (.NET MAUI). IGeolocation Этот интерфейс предоставляет API для получения текущих координат географического расположения устройства.
Реализация интерфейса по умолчанию IGeolocation доступна через Geolocation.Default свойство. Интерфейс IGeolocation и Geolocation класс содержатся в Microsoft.Maui.Devices.Sensors пространстве имен.
Начать
Чтобы проверить функциональность класса Geolocation, нужно создать описанную ниже конфигурацию для конкретной платформы:
Необходимо указать необходимые или тонкие разрешения на расположение, а также настроить их в проекте Android.
Кроме того, если приложение предназначено для платформы Android 5.0 (уровень API 21) или более поздней версии, в файле манифеста необходимо объявить, что приложение использует аппаратные возможности. Для этого можно применить любой из следующих методов:
Добавьте разрешение на основе сборки:
Откройте файл Platform/Android/MainApplication.cs и добавьте следующие атрибуты сборки после using директив:
Если приложение предназначено для Android 10 — Q (уровень API 29 или более поздней версии) и запрашивает LocationAlwaysего, необходимо также добавить этот запрос на разрешение:
Если приложение предназначено для Android 10 — Q (уровень API 29 или более поздней версии) и запрашивает LocationAlwaysего, необходимо также добавить этот запрос на разрешение:
В Visual Studio дважды щелкните файл Platform/Android/AndroidManifest.xml , чтобы открыть редактор манифеста Android. Затем в разделе "Необходимые разрешения" проверка указанные выше разрешения. Это действие автоматически обновляет файл AndroidManifest.xml.
В файлах Platform/iOS/Info.plist и Platform/MacCatalyst/Info.plist добавьте следующие ключи и значения:
XML
<key>NSLocationWhenInUseUsageDescription</key><string>Fill in a reason why your app needs access to location.</string>
Элемент <string> является причиной того, что приложение запрашивает доступ к сведениям о расположении. Этот текст отображается пользователю.
Альтернатива редактированию файлов Platform/iOS/Info.plist и Platform/MacCatalyst/Info.plist напрямую открывает редактор plist. В редакторе можно добавить свойство "Конфиденциальность — расположение при использовании описания использования" и ввести значение для отображения пользователю.
Разрешение на полное расположение точности
Если вы собираетесь запросить полную точность с GeolocationRequest.RequestFullAccuracy помощью свойства, добавьте следующий словарь в файлы Platform/iOS/Info.plist и Platform/MacCatalyst/Info.plist :
XML
<key>NSLocationTemporaryUsageDescriptionDictionary</key><dict><key>TemporaryFullAccuracyUsageDescription</key><string>Fill in a reason why your app needs full accuracy</string></dict>
Элемент <string> является причиной того, что приложение запрашивает доступ к сведениям о расположении с полной точностью. Этот текст отображается пользователю.
Никакой настройки для этого не требуется.
Получение последнего известного расположения
Возможно, устройство кэшировало последнее расположение устройства. При GetLastKnownLocationAsync() наличии используйте метод для доступа к кэшированному расположению. Это часто быстрее, чем выполнение полного запроса расположения, но может быть менее точным. Если кэшированное расположение не существует, этот метод возвращается null.
Примечание
При необходимости API географического расположения запрашивает у пользователя разрешения.
В следующем примере кода демонстрируется проверка для кэшированного расположения:
C#
publicasync 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";
}
В зависимости от устройства могут быть доступны не все значения расположения. Например, Altitude свойство может иметь nullзначение 0 или положительное значение, указывающее метры над уровнем моря. Другие значения, которые могут не присутствовать, включают Speed и Course свойства.
Получение текущего расположения
Хотя проверка для последнего известного расположения устройства может быть более быстрым, он может быть неточным. GetLocationAsync Используйте метод для запроса устройства к текущему расположению. Вы можете настроить точность и время ожидания запроса. Лучше всего перегружать метод, использующий GeolocationRequest параметры и CancellationToken параметры, так как может потребоваться некоторое время, чтобы получить расположение устройства.
Примечание
При необходимости API географического расположения запрашивает у пользователя разрешения.
В следующем примере кода показано, как запросить расположение устройства, поддерживая отмену:
C#
private CancellationTokenSource _cancelTokenSource;
privatebool _isCheckingLocation;
publicasync 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;
}
}
publicvoidCancelRequest()
{
if (_isCheckingLocation && _cancelTokenSource != null && _cancelTokenSource.IsCancellationRequested == false)
_cancelTokenSource.Cancel();
}
Не все значения расположения могут быть доступны в зависимости от устройства. Например, Altitude свойство может иметь nullзначение 0 или положительное значение, указывающее метры над уровнем моря. В число других значений, которые могут отсутствовать, входят Speed и Course.
Предупреждение
GetLocationAsync может возвращаться null в некоторых сценариях. Это означает, что базовая платформа не может получить текущее расположение.
Прослушивание изменений расположения
Помимо запроса устройства к текущему расположению, вы можете прослушивать изменения расположения, пока приложение находится на переднем плане.
Чтобы проверка узнать, прослушивает ли приложение изменения расположения, есть IsListeningForeground свойство, которое можно запросить. После того как вы будете готовы начать прослушивание изменений расположения, следует вызвать StartListeningForegroundAsync метод. Этот метод начинает прослушивать обновления расположения и вызывает LocationChanged событие при изменении расположения, если приложение находится на переднем плане. Объект GeolocationLocationChangedEventArgs , сопровождающий это событие, имеет Location свойство типа Location, представляющее новое расположение, которое было обнаружено.
Примечание
При необходимости API географического расположения запрашивает у пользователя разрешения.
В следующем примере кода показано, как прослушивать изменение расположения и как обработать измененное расположение:
C#
asyncvoidOnStartListening()
{
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
}
}
voidGeolocation_LocationChanged(object sender, GeolocationLocationChangedEventArgs e)
{
// Process e.Location to get the new location
}
Обработка ошибок может быть реализована путем регистрации обработчика событий для ListeningFailed события. Объект GeolocationListeningFailedEventArgs , сопровождающий это событие, имеет Error свойство типа GeolocationError, указывающее, почему прослушивание завершилось сбоем. ListeningFailed Когда событие возникает, прослушивание дальнейших изменений расположения останавливается и дальнейшие LocationChanged события не возникают.
Чтобы прекратить прослушивание изменений расположения, вызовите StopListeningForeground метод:
C#
voidOnStopListening()
{
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
}
}
Примечание
Метод StopListeningForeground не влияет, если приложение не прослушивает изменения расположения.
Правильность
В следующих разделах описано расстояние точности расположения для каждой платформы:
Важно!
IOS имеет некоторые ограничения в отношении точности. Дополнительные сведения см. в разделе "Различия платформы".
Наиболее низкий
Платформа
Расстояние (в метрах)
Android
500
iOS
3000
Windows
1000–5000
Низкая
Платформа
Расстояние (в метрах)
Android
500
iOS
1000
Windows
300–3000
Medium (по умолчанию)
Платформа
Расстояние (в метрах)
Android
100–500
iOS
100
Windows
30–500
Высокая
Платформа
Расстояние (в метрах)
Android
0–100
iOS
10
Windows
<= 10
Лучшее
Платформа
Расстояние (в метрах)
Android
0–100
iOS
~0
Windows
<= 10
Обнаружение макетных расположений
Некоторые устройства могут возвращать расположение макетов от поставщика или приложения, которое предоставляет расположения макетов. Это можно обнаружить с помощью IsFromMockProvider любого Location:
C#
publicasync 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
}
}
Расстояние между двумя расположениями
Метод CalculateDistance вычисляет расстояние между двумя географическими расположениями. Это вычисляемое расстояние не принимает дороги или другие пути в учет, и является лишь самым коротким расстоянием между двумя точками вдоль поверхности Земли. Это вычисление называется вычислением расстояния большого круга .
Следующий код вычисляет расстояние между США городов Америки Бостона и Сан-Франциско:
C#
Location boston = new Location(42.358056, -71.063611);
Location sanFrancisco = new Location(37.783333, -122.416667);
double miles = Location.CalculateDistance(boston, sanFrancisco, DistanceUnits.Miles);
Конструктор Location(Double, Double, Double) принимает аргументы широты и долготы соответственно. Положительные значения широты находятся к северу от экватора, а положительные значения долготы — к востоку от нулевого меридиана. Используйте последний аргумент CalculateDistance, чтобы указать единицы измерения: мили или километры. Класс UnitConverters также определяет методы KilometersToMiles и MilesToKilometers для преобразования между двумя единицами измерения.
Различия между платформами
В этом разделе описываются различия платформы с API геолокации.
Высота на каждой платформе вычисляется по-разному.
В Android высота, если она доступна, возвращается в виде высоты над нормальным эллипсоидом всемирной геодезической системы координат в метрах. Если это расположение не имеет высоты, 0.0 возвращается.
Свойство Location.ReducedAccuracy используется только iOS и возвращается false на всех других платформах.
В iOS высота измеряется в метрах. Положительные значения указывают высоту выше уровня моря, а отрицательные значения указывают на высоту ниже уровня моря.
Начиная с iOS 14, пользователь может ограничить приложение от обнаружения расположения с полной точностью. Свойство Location.ReducedAccuracy указывает, используется ли расположение с меньшей точностью. Чтобы запросить полную точность, задайте GeolocationRequest.RequestFullAccuracy для свойства trueзначение :
Свойство Location.ReducedAccuracy используется только iOS и возвращается false на всех других платформах.
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Отзыв о .NET MAUI
.NET MAUI — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
Присоединитесь к серии встреч для создания масштабируемых решений искусственного интеллекта на основе реальных вариантов использования с другими разработчиками и экспертами.
Узнайте, как использовать интерфейс IGeocoding .NET MAUI в Microsoft.Maui.Devices.Sensors пространстве имен. Этот интерфейс предоставляет API для геокода метки в позиционной координате и обратного геокода в метку.
Узнайте, как использовать элемент управления Map, который является кроссплатформенным представлением для отображения и аннотирования карт. Элемент управления "Map" доступен в пакете NuGet Microsoft.Maui.Controls.Maps.
Узнайте, как использовать интерфейс IMap для .NET MAUI в Microsoft.Maui.ApplicationModel пространстве имен. Этот интерфейс позволяет приложению открывать установленное приложение карты с определенным расположением или меткой места.
Узнайте, как использовать класс разрешений .NET MAUI для проверки и запроса разрешений. Этот класс находится в Microsoft.Maui.ApplicationModel пространстве имен.
Узнайте, как использовать интерфейс IDeviceInfo для .NET MAUI в Microsoft.Maui.Devices пространстве имен, который предоставляет сведения об устройстве, на котором работает приложение.
Узнайте, как использовать интерфейс IVibration для .NET MAUI, который позволяет запускать и останавливать функциональные возможности вибрирования в течение требуемого периода времени.
Узнайте, как использовать интерфейс IConnectivity для .NET MAUI в Microsoft.Maui.Networking пространстве имен. С помощью этого интерфейса можно определить, можно ли взаимодействовать с Интернетом и какие сетевые устройства подключены.