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

  1. No Gerenciador de Soluções, clique duas vezes em package.appxmanifest e selecione a guia Recursos .
  2. 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).

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