Obter a localização do usuário
Importante
Desativação do serviço Bing Maps para empresas
O UWP MapControl e os serviços de mapa do namespace Windows.Services.Maps dependem do Bing Maps. O Bing Maps for Enterprise foi preterido e será desativado, momento em que o MapControl e os serviços não receberão mais dados.
Para obter mais informações, consulte a documentação da Central de Desenvolvedores do Bing Maps e do Bing Maps.
Observação
O MapControl e os serviços de mapa exigem uma chave de autenticação de mapas chamada MapServiceToken. Para saber mais sobre como obter e definir uma chave de autenticação de mapas, consulte Solicitar uma chave de autenticação de mapas.
Encontre a localização do usuário e responda às alterações na localização. O acesso à localização do usuário é gerenciado pelas configurações de privacidade no aplicativo Configurações do Windows. Este tópico também mostra como verificar se seu aplicativo tem permissão para acessar a localização do usuário.
Ativar a funcionalidade de localização
- No Gerenciador de Soluções, clique duas vezes em package.appxmanifest e selecione a guia Recursos .
- Na lista Recursos, marque a caixa Local. Isso adiciona a funcionalidade do
location
dispositivo ao arquivo de manifesto do pacote.
<Capabilities>
<!-- DeviceCapability elements must follow Capability elements (if present) -->
<DeviceCapability Name="location"/>
</Capabilities>
Obter o local atual
Esta seção descreve como detectar a localização geográfica do usuário usando APIs no namespace Windows.Devices.Geolocation.
Etapa 1: Solicitar acesso à localização do usuário
A menos que seu aplicativo tenha capacidade de localização aproximada (consulte a observação), você deve solicitar acesso à localização do usuário usando o método RequestAccessAsync antes de tentar acessar a localização. Você deve chamar o método RequestAccessAsync do thread da interface do usuário e seu aplicativo deve estar em primeiro plano. Seu aplicativo não poderá acessar as informações de localização do usuário até que ele conceda permissão ao seu aplicativo.*
using Windows.Devices.Geolocation;
...
var accessStatus = await Geolocator.RequestAccessAsync();
O método RequestAccessAsync solicita permissão ao usuário para acessar sua localização. O usuário é solicitado apenas uma vez (por aplicativo). Após a primeira vez que eles concedem ou negam permissão, esse método não solicita mais permissão ao usuário. Para ajudar o usuário a alterar as permissões de localização depois de solicitado, recomendamos que você forneça um link para as configurações de localização, conforme demonstrado posteriormente neste tópico.
Observação
O recurso de localização aproximada permite que seu aplicativo obtenha uma localização intencionalmente ofuscada (imprecisa) sem obter a permissão explícita do usuário (no entanto, a opção de localização em todo o sistema ainda deve estar ativada). Para saber como utilizar a localização baixa em seu aplicativo, consulte o método AllowFallbackToConsentlessPositions na classe Geolocator.
Etapa 2: Obter a localização do usuário e registrar-se para alterações nas permissões de localização
O método GetGeopositionAsync executa uma leitura única do local atual. Aqui, uma switch
instrução é usada com accessStatus (do exemplo anterior) para agir somente quando o acesso ao local do usuário é permitido. Se o acesso à localização do usuário for permitido, o código criará um objeto Geolocator , registrará alterações nas permissões de localização e solicitará a localização do usuário.
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;
}
Etapa 3: Lidar com alterações nas permissões de localização
O objeto Geolocator aciona o evento StatusChanged para indicar que as configurações de localização do usuário foram alteradas. Esse evento passa o status correspondente por meio da propriedade Status do argumento (do tipo PositionStatus). Observe que esse método não é chamado do thread da interface do usuário e o objeto Dispatcher invoca as alterações da interface do usuário.
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;
}
});
}
Responda a atualizações de localização
Esta seção descreve como usar o evento PositionChanged para receber atualizações da localização do usuário durante um período de tempo. Como o usuário pode revogar o acesso ao local a qualquer momento, é importante chamar RequestAccessAsync e usar o evento StatusChanged , conforme mostrado na seção anterior.
Esta seção pressupõe que você já habilitou a funcionalidade de localização e chamou RequestAccessAsync do thread da interface do usuário do aplicativo em primeiro plano.
Etapa 1: Definir o intervalo do relatório e registrar-se para atualizações de localização
Neste exemplo, uma switch
instrução é usada com accessStatus (do exemplo anterior) para agir somente quando o acesso ao local do usuário é permitido. Se o acesso à localização do usuário for permitido, o código criará um objeto Geolocator , especificará o tipo de rastreamento e se registrará para atualizações de localização.
O objeto Geolocator pode disparar o evento PositionChanged com base em uma alteração na posição (rastreamento baseado em distância) ou em uma alteração no tempo (rastreamento baseado em periódico).
- Para rastreamento baseado em distância, defina a propriedade MovementThreshold.
- Para acompanhamento baseado em periódico, defina a propriedade ReportInterval .
Se nenhuma propriedade for definida, uma posição será retornada a cada 1 segundo (equivalente a ReportInterval = 1000
). Aqui, um intervalo de relatório de 2 segundos (ReportInterval = 2000
) é usado.
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;
}
Etapa 2: lidar com atualizações de localização
O objeto Geolocator dispara o evento PositionChanged para indicar que a localização do usuário foi alterada ou que o tempo passou, dependendo de como você o configurou. Esse evento passa o local correspondente por meio da propriedade Position do argumento (do tipo Geoposition). Neste exemplo, o método não é chamado do thread da interface do usuário e o objeto Dispatcher invoca as alterações da interface do usuário.
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);
});
}
Alterar as configurações de privacidade de localização
Se as configurações de privacidade de localização não permitirem que seu aplicativo acesse a localização do usuário, recomendamos que você forneça um link conveniente para as configurações de privacidade de localização no aplicativo Configurações. Neste exemplo, um controle Hyperlink é usado para navegar até o 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>
Como alternativa, seu aplicativo pode chamar o método LaunchUriAsync para iniciar o aplicativo Configurações do código. Para saber mais, consulte Iniciar o aplicativo Configurações do Windows.
using Windows.System;
...
bool result = await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-location"));
Solucionar problemas em seu aplicativo
Antes que seu aplicativo possa acessar a localização do usuário, a localização deve estar habilitada no dispositivo. No aplicativo Configurações, verifique se as seguintes configurações de privacidade de localização estão ativadas:
- Localização para este dispositivo... está ativado (não aplicável no Windows 10 Mobile)
- A configuração dos serviços de localização, Localização, está ativada
- Em Escolher aplicativos que podem usar sua localização, seu aplicativo é definido como ativado