Получение расположения пользователя
Внимание
Bing Maps для выхода на пенсию службы Enterprise
Службы MapControl UWP и карты из пространства имен Windows.Services.Maps используют карты Bing. Карты Bing для предприятия устарели и будут прекращены, в то время как mapControl и службы больше не будут получать данные.
Дополнительные сведения см. в документации по Центру разработчиков карт Bing и картам Bing.
Примечание.
Для служб MapControl и служб карт требуется ключ проверки подлинности карт с именем MapServiceToken. Дополнительные сведения о получении и настройке ключа проверки подлинности карт см. в разделе "Запрос ключа проверки подлинности карт".
Найдите расположение пользователя и ответьте на изменения в расположении. Доступ к расположению пользователя управляется параметрами конфиденциальности в приложении параметров Windows. В этом разделе также показано, как проверить, имеет ли приложение разрешение на доступ к расположению пользователя.
Включение возможности расположения
- В Обозреватель решений дважды щелкните package.appxmanifest и перейдите на вкладку "Возможности".
- В списке возможностей установите флажок " Расположение". Это добавляет
location
возможность устройства в файл манифеста пакета.
<Capabilities>
<!-- DeviceCapability elements must follow Capability elements (if present) -->
<DeviceCapability Name="location"/>
</Capabilities>
Получение текущего расположения
В этом разделе описывается, как определить географическое расположение пользователя с помощью API в пространстве имен Windows.Devices.Geolocation.
Шаг 1. Запрос доступа к расположению пользователя
Если приложение не имеет возможности грубого расположения (см. примечание), необходимо запросить доступ к расположению пользователя с помощью метода RequestAccessAsync , прежде чем пытаться получить доступ к расположению. Необходимо вызвать метод RequestAccessAsync из потока пользовательского интерфейса, и приложение должно находиться на переднем плане. Ваше приложение не сможет получить доступ к сведениям о расположении пользователя до тех пор, пока пользователь не предоставит пользователю разрешение на ваше приложение.*
using Windows.Devices.Geolocation;
...
var accessStatus = await Geolocator.RequestAccessAsync();
Метод RequestAccessAsync запрашивает пользователю разрешение на доступ к их расположению. Пользователю предлагается только один раз (для каждого приложения). После первого предоставления или запрета разрешения этот метод больше не запрашивает у пользователя разрешение. Чтобы помочь пользователю изменить разрешения расположения после запроса, рекомендуется предоставить ссылку на параметры расположения, как показано далее в этом разделе.
Примечание.
Функция грубого расположения позволяет приложению получать намеренно закрытое (непрозрачное) расположение без получения явного разрешения пользователя (переключатель расположения на уровне системы должен оставаться на месте). Сведения об использовании грубого расположения в приложении см. в методе AllowFallbackToConsentlessPositions в классе Геолокатора.
Шаг 2. Получение расположения пользователя и регистрация изменений в разрешениях расположения
Метод GetGeopositionAsync выполняет однократное чтение текущего расположения. Здесь оператор используется с accessStatus (из предыдущего примера), чтобы действовать только в том случае, switch
если доступ к расположению пользователя разрешен. Если доступ к расположению пользователя разрешен, код создает объект геолокатора , регистрирует изменения в разрешениях расположения и запрашивает расположение пользователя.
switch (accessStatus)
{
case GeolocationAccessStatus.Allowed:
_rootPage.NotifyUser("Waiting for update...", NotifyType.StatusMessage);
// If DesiredAccuracy or DesiredAccuracyInMeters are not set (or value is 0), DesiredAccuracy.Default is used.
Geolocator geolocator = new Geolocator { DesiredAccuracyInMeters = _desireAccuracyInMetersValue };
// Subscribe to the StatusChanged event to get updates of location status changes.
_geolocator.StatusChanged += OnStatusChanged;
// Carry out the operation.
Geoposition pos = await geolocator.GetGeopositionAsync();
UpdateLocationData(pos);
_rootPage.NotifyUser("Location updated.", NotifyType.StatusMessage);
break;
case GeolocationAccessStatus.Denied:
_rootPage.NotifyUser("Access to location is denied.", NotifyType.ErrorMessage);
LocationDisabledMessage.Visibility = Visibility.Visible;
UpdateLocationData(null);
break;
case GeolocationAccessStatus.Unspecified:
_rootPage.NotifyUser("Unspecified error.", NotifyType.ErrorMessage);
UpdateLocationData(null);
break;
}
Шаг 3. Обработка изменений в разрешениях расположения
Объект Geolocator активирует событие StatusChanged, чтобы указать, что параметры расположения пользователя изменились. Это событие передает соответствующее состояние через свойство status аргумента (типа PositionStatus). Обратите внимание, что этот метод не вызывается из потока пользовательского интерфейса, а объект диспетчера вызывает изменения пользовательского интерфейса.
using Windows.UI.Core;
...
async private void OnStatusChanged(Geolocator sender, StatusChangedEventArgs e)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// Show the location setting message only if status is disabled.
LocationDisabledMessage.Visibility = Visibility.Collapsed;
switch (e.Status)
{
case PositionStatus.Ready:
// Location platform is providing valid data.
ScenarioOutput_Status.Text = "Ready";
_rootPage.NotifyUser("Location platform is ready.", NotifyType.StatusMessage);
break;
case PositionStatus.Initializing:
// Location platform is attempting to acquire a fix.
ScenarioOutput_Status.Text = "Initializing";
_rootPage.NotifyUser("Location platform is attempting to obtain a position.", NotifyType.StatusMessage);
break;
case PositionStatus.NoData:
// Location platform could not obtain location data.
ScenarioOutput_Status.Text = "No data";
_rootPage.NotifyUser("Not able to determine the location.", NotifyType.ErrorMessage);
break;
case PositionStatus.Disabled:
// The permission to access location data is denied by the user or other policies.
ScenarioOutput_Status.Text = "Disabled";
_rootPage.NotifyUser("Access to location is denied.", NotifyType.ErrorMessage);
// Show message to the user to go to location settings.
LocationDisabledMessage.Visibility = Visibility.Visible;
// Clear any cached location data.
UpdateLocationData(null);
break;
case PositionStatus.NotInitialized:
// The location platform is not initialized. This indicates that the application
// has not made a request for location data.
ScenarioOutput_Status.Text = "Not initialized";
_rootPage.NotifyUser("No request for location is made yet.", NotifyType.StatusMessage);
break;
case PositionStatus.NotAvailable:
// The location platform is not available on this version of the OS.
ScenarioOutput_Status.Text = "Not available";
_rootPage.NotifyUser("Location is not available on this version of the OS.", NotifyType.ErrorMessage);
break;
default:
ScenarioOutput_Status.Text = "Unknown";
_rootPage.NotifyUser(string.Empty, NotifyType.StatusMessage);
break;
}
});
}
Реагирование на обновления расположения
В этом разделе описывается, как использовать событие PositionChanged для получения обновлений расположения пользователя в течение определенного периода времени. Так как пользователь может отозвать доступ к расположению в любое время, важно вызвать RequestAccessAsync и использовать событие StatusChanged, как показано в предыдущем разделе.
В этом разделе предполагается, что вы уже включили возможность расположения и назвали RequestAccessAsync из потока пользовательского интерфейса приложения переднего плана.
Шаг 1. Определение интервала отчета и регистрация для обновлений расположения
В этом примере оператор используется с accessStatus (из предыдущего примера), чтобы действовать только в том случае, switch
если доступ к расположению пользователя разрешен. Если доступ к расположению пользователя разрешен, код создает объект Геолокатора , указывает тип отслеживания и регистрируется для обновлений расположения.
Объект геолокатора может активировать событие PositionChanged на основе изменения позиции (отслеживания на основе расстояния) или изменения времени (периодическое отслеживание на основе расстояния).
- Для отслеживания на основе расстояния задайте свойство MovementThreshold.
- Для периодического отслеживания задайте свойство ReportInterval .
Если ни один из свойств не задан, позиция возвращается каждые 1 секунду (эквивалентно ReportInterval = 1000
). Здесь используется интервал отчета 2 секунды (ReportInterval = 2000
).
using Windows.Devices.Geolocation;
...
var accessStatus = await Geolocator.RequestAccessAsync();
switch (accessStatus)
{
case GeolocationAccessStatus.Allowed:
// Create Geolocator and define periodic-based tracking (2 second interval).
_geolocator = new Geolocator { ReportInterval = 2000 };
// Subscribe to the PositionChanged event to get location updates.
_geolocator.PositionChanged += OnPositionChanged;
// Subscribe to StatusChanged event to get updates of location status changes.
_geolocator.StatusChanged += OnStatusChanged;
_rootPage.NotifyUser("Waiting for update...", NotifyType.StatusMessage);
LocationDisabledMessage.Visibility = Visibility.Collapsed;
StartTrackingButton.IsEnabled = false;
StopTrackingButton.IsEnabled = true;
break;
case GeolocationAccessStatus.Denied:
_rootPage.NotifyUser("Access to location is denied.", NotifyType.ErrorMessage);
LocationDisabledMessage.Visibility = Visibility.Visible;
break;
case GeolocationAccessStatus.Unspecified:
_rootPage.NotifyUser("Unspecified error!", NotifyType.ErrorMessage);
LocationDisabledMessage.Visibility = Visibility.Collapsed;
break;
}
Шаг 2. Обработка обновлений расположения
Объект Geolocator активирует событие PositionChanged, чтобы указать, что расположение пользователя изменилось или прошло время, в зависимости от того, как вы настроили его. Это событие передает соответствующее расположение через свойство Position аргумента (типа Geoposition). В этом примере метод не вызывается из потока пользовательского интерфейса, а объект диспетчера вызывает изменения пользовательского интерфейса.
using Windows.UI.Core;
...
async private void OnPositionChanged(Geolocator sender, PositionChangedEventArgs e)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
_rootPage.NotifyUser("Location updated.", NotifyType.StatusMessage);
UpdateLocationData(e.Position);
});
}
Изменение параметров конфиденциальности расположения
Если параметры конфиденциальности расположения не позволяют приложению получать доступ к расположению пользователя, рекомендуется предоставить удобную ссылку на параметры конфиденциальности расположения в приложении "Параметры ". В этом примере элемент управления Гиперссылка используется в ms-settings:privacy-location
URI.
<!--Set Visibility to Visible when access to location is denied -->
<TextBlock x:Name="LocationDisabledMessage" FontStyle="Italic"
Visibility="Collapsed" Margin="0,15,0,0" TextWrapping="Wrap">
<Run Text="This app is not able to access Location. Go to "/>
<Hyperlink NavigateUri="ms-settings:privacy-location">
<Run Text="Settings"/>
</Hyperlink>
<Run Text=" to check the location privacy settings."/>
</TextBlock>
Кроме того, приложение может вызвать метод LaunchUriAsync, чтобы запустить приложение Settings из кода. Дополнительные сведения см. в разделе "Запуск приложения параметров Windows".
using Windows.System;
...
bool result = await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-location"));
Устранение неполадок приложений
Прежде чем приложение сможет получить доступ к расположению пользователя, необходимо включить расположение на устройстве. В приложении "Параметры" убедитесь, что включены следующие параметры конфиденциальности расположения:
- Расположение для этого устройства... включен (неприменимо в Windows 10 Mobile)
- Параметр служб расположений, расположение, включен
- В разделе "Выбор приложений, которые могут использовать ваше расположение", приложение установлено включено