Partilhar via


Obter a localização do utilizador

Importante

Desativação do serviço Bing Maps for Enterprise

A UWP MapControl e serviços de mapa da namespace Windows.Services.Maps dependem do Bing Maps. O Bing Maps for Enterprise foi preterido e será desativado, quando o MapControl e os serviços não receberão mais dados.

Para obter mais informações, consulte a Central de Desenvolvedores do Bing Maps e documentação do Bing Maps

Observação

MapControl e serviços de mapa exigem uma chave de autenticação de mapas chamada MapServiceToken. Para obter mais informações 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 utilizador e responda a alterações na localização. O acesso à localização do utilizador é gerido pelas definições de privacidade na aplicação Definiçõ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 capacidade de localização

  1. No Explorador de Soluções, clique duas vezes em package.appxmanifest e selecione o separador Capacidades.
  2. Na lista de Capacidades , marque a caixa de seleção Localização. Isso adiciona a capacidade de dispositivo location ao arquivo de manifesto do pacote.
  <Capabilities>
    <!-- DeviceCapability elements must follow Capability elements (if present) -->
    <DeviceCapability Name="location"/>
  </Capabilities>

Obter a localização atual

Esta seção descreve como detetar a localização geográfica do usuário usando APIs no namespaceWindows.Devices.Geolocation.

Etapa 1: Solicitar acesso à localização do usuário

A menos que a sua aplicação tenha capacidade de localização aproximada (consulte a nota), deve pedir acesso à localização do utilizador usando o método RequestAccessAsync antes de tentar aceder ao local. Você deve chamar o método RequestAccessAsync na thread da UI e o seu aplicativo deve estar em primeiro plano. Seu aplicativo não poderá acessar as informações de localização do usuário até que o usuário conceda permissão ao seu aplicativo.*

using Windows.Devices.Geolocation;
...
var accessStatus = await Geolocator.RequestAccessAsync();

O método RequestAccessAsync solicita ao usuário permissão para acessar seu local. O utilizador só é notificado uma vez (por aplicação). 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 que ele for solicitado, recomendamos que você forneça um link para as configurações de local, conforme demonstrado posteriormente neste tópico.

Observação

O recurso de localização aproximada permite que a sua aplicação obtenha uma localização deliberadamente imprecisa sem obter a permissão explícita do utilizador (a configuração de localização a nível de sistema ainda deve estar em, no entanto). Para saber como utilizar a localização grosseira na sua aplicação, 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 local

O GetGeopositionAsync método executa uma leitura única do local atual. Aqui, uma instrução switch é usada com accessStatus (do exemplo anterior) para agir somente quando o acesso à localização do usuário é permitido. Se o acesso à localização do usuário for permitido, o código criará um objetoGeolocalizador, 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: Gerir alterações nas permissões de localização

O objeto Geolocator dispara o eventoStatusChanged 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 a partir do thread da interface do usuário e o objetoDispatcher 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;
        }
    });
}

Responder 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 utilizador pode revogar o acesso à localização 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á tenha habilitado o recurso de localização e chamado RequestAccessAsync a partir do thread da interface do usuário do seu aplicativo em primeiro plano.

Etapa 1: Definir o intervalo de relatório e registrar-se para atualizações de local

Neste exemplo, uma instrução switch é usada com accessStatus (do exemplo anterior) para agir somente quando o acesso à localização do usuário é permitido. Se o acesso à localização do usuário for permitido, o código criará um objetoGeolocalizador, especificará o tipo de rastreamento e se registrará para atualizações de localização.

O objeto Geolocalizador pode acionar o evento PositionChanged com base numa mudança de posição (rastreamento baseado em distância) ou numa mudança de tempo (rastreamento periódico).

Se nenhuma das propriedades 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 objetoGeolocator aciona o eventoPositionChanged para indicar que o local do usuário foi alterado ou o tempo passou, dependendo de como você o configurou. Esse evento passa o local correspondente através da propriedade Position do argumento (que é do tipo Geoposition). Neste exemplo, o método não é chamado a partir do thread da UI e o objeto Dispatcher invoca as alterações da UI.

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 definições de privacidade da localização

Se as definições de privacidade de localização não permitirem que a sua aplicação aceda à localização do utilizador, recomendamos que forneça uma ligação conveniente para as definições de privacidade de localização na aplicação Configurações. Neste exemplo, um controle Hyperlink é usado para navegar até o URI ms-settings:privacy-location.

<!--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 as Configurações de aplicativo a partir do código. Para mais informações, consulte Abrir a aplicação Definições do Windows.

using Windows.System;
...
bool result = await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-location"));

Solucionar problemas do seu aplicativo

Para que a sua aplicação possa aceder à localização do utilizador, Localização deve estar ativada no dispositivo. Na aplicação Definições, verifique se as seguintes definições de privacidade de localização estão ativadas:

  • Localização deste dispositivo... está ativado (não aplicável no Windows 10 Mobile)
  • A configuração de serviços de localização, Localização, está ativada
  • Em Escolher aplicações que podem utilizar a sua localização, a sua aplicação está definida para no