Solicitar permissões de localização

Para proteger a privacidade do usuário, os apps que usam serviços de localização precisam solicitar permissões de localização.

Ao solicitar permissões de localização, siga as mesmas práticas recomendadas de qualquer outra permissão de execução. Uma diferença importante quando se trata de permissões de localização é que o sistema inclui várias permissões relacionadas à localização. As permissões solicitadas e a forma como você as solicita dependem dos requisitos de localização do caso de uso do seu app.

Esta página descreve os diferentes tipos de requisitos de localização e oferece orientações sobre como solicitar permissões de localização em cada caso.

Tipos de acesso à localização

Cada permissão tem uma combinação das seguintes características:

Localização em primeiro plano

Se o app tiver um recurso que compartilhe ou receba informações de localização apenas uma vez ou por um período definido, esse recurso exigirá acesso à localização em primeiro plano. Veja alguns exemplos:

  • Em um app de navegação, um recurso permite que os usuários recebam rotas passo a passo.
  • Em um app de mensagens, um recurso permite que os usuários compartilhem a localização atual com outro usuário.

O sistema considera que seu app está usando a localização em primeiro plano se um recurso do app acessar a localização atual do dispositivo em uma das seguintes situações:

  • Uma atividade pertencente ao seu app está visível.
  • Seu app está executando um serviço em primeiro plano. Quando um serviço em primeiro plano está em execução, o sistema aumenta o reconhecimento do usuário mostrando uma notificação contínua. Seu app mantém o acesso quando está em segundo plano, como quando o usuário pressiona o botão Início no dispositivo ou bloqueia a tela.

    Além disso, é recomendável declarar um tipo de serviço em primeiro plano de location, conforme mostrado no snippet de código a seguir. No Android 10 (API de nível 29) e versões mais recentes, é necessário declarar esse tipo de serviço em primeiro plano.

    <!-- Recommended for Android 9 (API level 28) and lower. -->
    <!-- Required for Android 10 (API level 29) and higher. -->
    <service
        android:name="MyNavigationService"
        android:foregroundServiceType="location" ... >
        <!-- Any inner elements would go here. -->
    </service>
    

Declare a necessidade de localização em primeiro plano quando seu app solicitar a permissão ACCESS_COARSE_LOCATION ou ACCESS_FINE_LOCATION, conforme mostrado no snippet a seguir:

<manifest ... >
  <!-- Always include this permission -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Include only if your app benefits from precise location access. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

Localização em segundo plano

Um app exige acesso à localização em segundo plano se um recurso do app compartilha constantemente a localização com outros usuários ou usa a API Geofence. Entre os exemplos estão os seguintes:

  • Em um app para compartilhamento de local com a família, um recurso permite que os usuários compartilhem a localização com os membros da família de forma contínua.
  • Em um app de IoT, um recurso permite que os usuários configurem os dispositivos da casa para que sejam desligados quando eles saem de casa e ligados novamente quando voltam.

O sistema considera que seu app está usando a localização em segundo plano se ele acessa a localização atual do dispositivo em qualquer situação diferente das descritas na seção primeiro plano. A precisão da localização em segundo plano é igual à precisão da localização em primeiro plano, que depende das permissões de localização declaradas pelo app.

No Android 10 (nível 29 da API) e versões mais recentes, é necessário declarar a permissão ACCESS_BACKGROUND_LOCATION no manifesto do app para solicitar acesso à localização em segundo plano durante a execução. Nas versões anteriores do Android, quando o app recebe acesso à localização em primeiro plano, também recebe acesso à localização em segundo plano automaticamente.

<manifest ... >
  <!-- Required only when requesting background location access on
       Android 10 (API level 29) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

Precisão

O Android é compatível com os seguintes níveis de precisão de local:

Aproximada
Fornece uma estimativa da localização do dispositivo, a cerca de 1,6 km. O app usa esse nível de precisão de localização quando você declara a permissão ACCESS_COARSE_LOCATION, mas não a permissão ACCESS_FINE_LOCATION.
Exata
Fornece uma estimativa da localização do dispositivo o mais precisa possível, geralmente a cerca de 50 metros, e às vezes até 3 metros ou mais aproximado. O app usa esse nível de precisão de localização quando você declara a permissão ACCESS_FINE_LOCATION.

Se o usuário conceder a permissão de localização aproximada, o app só terá acesso à localização aproximada, independentemente das permissões que o app declarar.

O app ainda funcionará quando o usuário conceder apenas o acesso aproximado ao local. Se um recurso do seu app realmente precisar de acesso à localização precisa usando a permissão ACCESS_FINE_LOCATION, peça ao usuário para permitir que seu app acesse a localização precisa.

Solicitar acesso à localização no momento da execução

Quando um recurso do seu app precisar de acesso à localização, aguarde até que o usuário interaja com o recurso antes de solicitar a permissão. Esse fluxo de trabalho segue a prática recomendada de solicitar permissões de tempo de execução dentro do contexto, conforme descrito no guia sobre como solicitar permissões do app.

A Figura 1 mostra um exemplo de como executar esse processo. O app contém um recurso "compartilhar localização" que requer acesso à localização em primeiro plano. No entanto, a permissão de localização só é solicitada quando o usuário seleciona o botão Compartilhar localização.

Depois que o usuário seleciona o botão &quot;Compartilhar localização&quot;, a caixa de diálogo do sistema que pede permissão de localização é exibida
Figura 1. Recurso de compartilhamento de localização que precisa de acesso à localização em primeiro plano. O recurso será ativado se o usuário selecionar Permitir durante o uso do app.

O usuário pode conceder acesso apenas ao local aproximado

No Android 12 (API de nível 31) ou versões mais recentes, os usuários vão poder solicitar que o app recupere apenas informações de local aproximado, mesmo quando o app solicitar a permissão de execução ACCESS_FINE_LOCATION.

Para processar esse possível comportamento do usuário, não solicite apenas a permissão ACCESS_FINE_LOCATION sozinha. Em vez disso, inclua a ACCESS_FINE_LOCATION e a ACCESS_COARSE_LOCATION em uma única solicitação de execução. Se você tentar solicitar apenas a ACCESS_FINE_LOCATION, o sistema vai ignorar a solicitação em algumas versões do Android 12. Caso o app seja destinado ao Android 12 ou versões mais recentes, o sistema registra a seguinte mensagem de erro no Logcat:

ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION.

Quando o app solicitar ACCESS_FINE_LOCATION e ACCESS_COARSE_LOCATION, a caixa de diálogo de permissões do sistema incluirá as novas opções a seguir para o usuário:

  • Precisa: permite que o app receba informações de localização precisas.
  • Aproximada: permite que o app receba apenas informações de localização aproximadas.

A Figura 3 mostra que a caixa de diálogo contém uma dica visual para as duas opções, o que ajuda o usuário a escolher. Após o usuário decidir sobre o tipo da localização, ele tocará em um dos três botões para selecionar a duração da concessão de permissão.

No Android 12, os usuários podem acessar as configurações do sistema para definir a precisão de localização preferencial de qualquer app, independentemente da versão do SDK de destino. Isso ocorre mesmo quando o app é instalado em um dispositivo com o Android 11 ou versões anteriores e, em seguida, o usuário faz upgrade do dispositivo para o Android 12 ou versões mais recentes.

A caixa de diálogo se refere apenas à localização aproximada e
         contém três botões, um acima do outro
Figura 2. Caixa de diálogo de permissões do sistema exibida quando o app solicita apenas ACCESS_COARSE_LOCATION.
A caixa de diálogo tem dois conjuntos de opções, uma acima da outra
Figura 3. Caixa de diálogo de permissões do sistema que aparece quando o app solicita ACCESS_FINE_LOCATION e ACCESS_COARSE_LOCATION em uma única solicitação de ambiente de execução.

A escolha do usuário afeta as concessões de permissão

A tabela a seguir mostra as permissões que o sistema concede ao app, com base nas opções que o usuário escolhe na caixa de diálogo das permissões de execução:

Exata Aproximada
Durante o uso do app ACCESS_FINE_LOCATION e
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
Apenas esta vez ACCESS_FINE_LOCATION e
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
Negar Sem permissão de localização Sem permissão de localização

Para determinar quais permissões o sistema concedeu ao app, confira o valor de retorno da solicitação de permissões. Você pode usar as bibliotecas do Jetpack em códigos parecidos com o do exemplo a seguir, ou usar bibliotecas da plataforma, em que você gerencia o código de solicitação de permissão por conta própria.

Kotlin

val locationPermissionRequest = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        when {
            permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
                // Precise location access granted.
            }
            permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
                // Only approximate location access granted.
            } else -> {
                // No location access granted.
            }
        }
    }

// ...

// Before you perform the actual permission request, check whether your app
// already has the permissions, and whether your app needs to show a permission
// rationale dialog. For more details, see Request permissions.
locationPermissionRequest.launch(arrayOf(
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION))

Java

ActivityResultLauncher<String[]> locationPermissionRequest =
    registerForActivityResult(new ActivityResultContracts
        .RequestMultiplePermissions(), result -> {
            Boolean fineLocationGranted = result.getOrDefault(
                    Manifest.permission.ACCESS_FINE_LOCATION, false);
            Boolean coarseLocationGranted = result.getOrDefault(
                    Manifest.permission.ACCESS_COARSE_LOCATION,false);
            if (fineLocationGranted != null && fineLocationGranted) {
                // Precise location access granted.
            } else if (coarseLocationGranted != null && coarseLocationGranted) {
                // Only approximate location access granted.
            } else {
                // No location access granted.
            }
        }
    );

// ...

// Before you perform the actual permission request, check whether your app
// already has the permissions, and whether your app needs to show a permission
// rationale dialog. For more details, see Request permissions.
locationPermissionRequest.launch(new String[] {
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION
});

Solicitar um upgrade para um local exato

Você pode solicitar que o usuário faça upgrade do acesso do app do local aproximado para o local exato. Antes de pedir ao usuário para atualizar o acesso do app para o local exato, considere se o caso de uso do app realmente exige esse nível de precisão. Se o app precisar parear um dispositivo com outros próximos por Bluetooth ou Wi-Fi, use o pareamento de dispositivo complementar ou as novas permissões de Bluetooth, em vez de solicitar a permissão ACCESS_FINE_LOCATION.

Para solicitar que o usuário faça upgrade do acesso de localização do app de aproximada para exata, faça o seguinte:

  1. Se necessário, explique por que o app precisa da permissão.
  2. Solicite as permissões ACCESS_FINE_LOCATION e ACCESS_COARSE_LOCATION juntas novamente. Como o usuário já autorizou o sistema a conceder uma localização aproximada ao app, a caixa de diálogo do sistema será diferente desta vez, como mostrado na Figura 4 e na Figura 5:
A caixa de diálogo contém as opções &quot;Mudar para local
         exato&quot;, &quot;Apenas esta vez&quot; e &quot;Negar&quot;.
Figura 4. Anteriormente, o usuário selecionou Aproximada e Durante o uso do app (na caixa de diálogo da Figura 3).
A caixa de diálogo contém as opções &quot;Apenas esta vez&quot; e
         &quot;Negar&quot;.
Figura 5. Anteriormente, o usuário selecionou Aproximada e Apenas esta vez (na caixa de diálogo da Figura 3).

Solicitar apenas a localização em primeiro plano inicialmente

Mesmo que vários recursos do seu app precisem de acesso à localização, é provável que apenas alguns deles precisem de acesso à localização em segundo plano. Portanto, é recomendado que o app faça solicitações incrementais de permissão de localização, pedindo o acesso à localização em primeiro plano e, depois, em segundo plano. Com as solicitações incrementais, você oferece aos usuários mais controle e transparência, porque eles podem entender melhor quais recursos do app precisam de acesso à localização em segundo plano.

A Figura 6 mostra um exemplo de app desenvolvido para processar solicitações incrementais. Os recursos "mostrar localização atual" e "recomendar lugares por perto" exigem acesso à localização em primeiro plano. No entanto, somente o recurso "recomendar lugares por perto" requer acesso à localização em segundo plano.

O botão que ativa o acesso à localização em primeiro plano fica a meia tela de distância do botão que permite a localização em segundo plano
Figura 6. Os dois recursos exigem acesso à localização, mas apenas o "recomendar lugares por perto" requer acesso à localização em segundo plano.

O processo para fazer solicitações incrementais é o seguinte:

  1. Primeiro, seu app precisa indicar aos usuários os recursos que exigem acesso à localização em primeiro plano, como o recurso "compartilhar localização" da Figura 1 ou "mostrar localização atual" da Figura 2.

    É recomendável desativar o acesso do usuário a recursos que exijam acesso à localização em segundo plano até que o app receba acesso à localização em primeiro plano.

  2. Posteriormente, quando o usuário explorar uma funcionalidade que exija acesso à localização em segundo plano, você poderá solicitar acesso a esse tipo de localização.

Solicitar localização em segundo plano, se necessário

Figura 7. A página "Configurações" inclui uma opção chamada Permitir o tempo todo, que concede acesso à localização em segundo plano.

O conteúdo da caixa de diálogo de permissão depende da versão do SDK de destino

Quando um recurso no app solicita uma localização em segundo plano em um dispositivo com Android 10 (nível 29 da API), a caixa de diálogo de permissões do sistema inclui uma opção chamada Permitir o tempo todo. Se o usuário selecionar essa opção, o recurso no seu app terá acesso à localização em segundo plano.

No Android 11 (API de nível 30) e versões mais recentes, a caixa de diálogo do sistema não inclui a opção Permitir o tempo todo. Em vez disso, os usuários precisam ativar a localização em segundo plano em uma página de configurações, conforme mostrado na Figura 7.

É possível ajudar os usuários a acessar essa página de configurações seguindo as práticas recomendadas ao solicitar a permissão de localização em segundo plano. O processo para conceder a permissão depende da versão do SDK de destino do seu app.

O app é direcionado ao Android 11 ou a versões mais recentes

Se o app não tiver a permissão ACCESS_BACKGROUND_LOCATION e shouldShowRequestPermissionRationale() retornar true, mostre uma IU informativa aos usuários que inclua o seguinte:

  • Uma explicação clara sobre por que o recurso do app precisa de acesso à localização em segundo plano.
  • O rótulo visível para o usuário da opção de configurações que concede a localização em segundo plano, por exemplo, Permitir o tempo todo na figura 7. Você pode chamar getBackgroundPermissionOptionLabel() para receber esse rótulo. O valor de retorno desse método é localizado de acordo com a preferência de idioma do dispositivo do usuário.
  • Uma opção para os usuários recusarem a permissão. Se os usuários recusarem o acesso à localização em segundo plano, poderão continuar usando o app.
Os usuários podem tocar na notificação do sistema para mudar as configurações
  de localização de um app
Figura 8. Notificação que lembra ao usuário que ele concedeu acesso à localização em segundo plano a um app.

O app é direcionado ao Android 10 ou anterior

Quando um recurso no seu app solicitar acesso à localização em segundo plano, os usuários verão uma caixa de diálogo do sistema. Essa caixa de diálogo inclui uma opção para navegar até as opções de permissão de localização do app em uma página de configurações.

Se o app já segue as práticas recomendadas para solicitar permissões de localização, não é preciso modificá-lo para ter compatibilidade com esse comportamento.

O usuário pode afetar a precisão da localização em segundo plano

Se o usuário solicitar o aproximado, as escolhas dele na caixa de diálogo de permissões de localização também se aplicarão à localização em segundo plano. Em outras palavras, se o usuário conceder ao app a permissão ACCESS_BACKGROUND_LOCATION, mas apenas para acesso ao local aproximado em primeiro plano, o app também terá acesso ao local aproximado em segundo plano.

Lembrete da concessão de localização em segundo plano

No Android 10 e versões mais recentes, quando um recurso do app acessa a localização do dispositivo em segundo plano pela primeira vez depois que o usuário concede acesso a ela, o sistema programa uma notificação para enviar ao usuário. Essa notificação lembra o usuário de que ele permitiu que o app acessasse a localização do dispositivo o tempo todo. Um exemplo dessa notificação é mostrado na Figura 8.

Conferir se há requisitos de localização nas dependências do SDK do app

Verifique se o app usa SDKs que dependem das permissões de localização, principalmente a permissão ACCESS_FINE_LOCATION. Consulte este artigo no Medium sobre como se familiarizar com os comportamentos das dependências do SDK (em inglês).

Outros recursos

Para ter mais informações sobre permissões de localização no Android, consulte o seguinte material:

Vídeos