O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Solicitar permissões do app

Cada app Android é executado em um sandbox com acesso limitado. Se o app precisa usar recursos ou informações fora do próprio sandbox, declare uma permissão e configure uma solicitação de permissão que forneça esse acesso. Essas etapas fazem parte do fluxo de trabalho para usar permissões.

Se você declarar qualquer permissão perigosa e se o app for instalado em um dispositivo que executa o Android 6.0 (API de nível 23) ou mais recente, será necessário solicitar as permissões perigosas no tempo de execução, seguindo as etapas deste guia.

Se você não declarar nenhuma permissão perigosa ou se o app estiver instalado em um dispositivo que executa o Android 5.1 (API de nível 22) ou nterior, as permissões serão concedidas automaticamente, e não será necessário concluir as etapas restantes desta página.

Princípios básicos

Os princípios básicos para solicitar permissões no tempo de execução são os seguintes:

  • Solicite permissões no contexto, quando o usuário começar a interagir com o recurso que requer a permissão.
  • Não bloqueie o usuário. Sempre ofereça a opção de cancelar um fluxo de IU educacional relacionado a permissões.
  • Se o usuário negar ou revogar uma permissão necessária para um recurso, faça uma degradação suave para que ele possa continuar usando o app, possivelmente desativando o recurso que requer a permissão.
  • Não presuma nenhum comportamento do sistema. Por exemplo, não presuma que as permissões aparecem no mesmo grupo de permissões. Um grupo de permissões apenas ajuda o sistema a minimizar o número de caixas de diálogo que são apresentadas ao usuário quando um app solicita permissões relacionadas.

Fluxo de trabalho para solicitar permissões

Antes de declarar e solicitar permissões de execução no seu app, avalie se ele precisa fazer isso. É possível atender a muitos casos de uso no app, como tirar fotos, pausar a reprodução de mídia e exibir anúncios relevantes, sem precisar declarar nenhuma permissão.

Se você concluir que seu app precisa declarar e solicitar permissões de execução, siga estas etapas:

  1. No arquivo de manifesto do app, declare as permissões que o app pode precisar solicitar.
  2. Projete a UX do seu app para que ações específicas sejam associadas a permissões de execução específicas. Os usuários precisam saber quais ações podem exigir que eles concedam permissão para o app acessar dados particulares.
  3. Espere o usuário invocar a tarefa ou ação no app que exige acesso a dados particulares específicos do usuário. Nesse momento, o app pode solicitar a permissão de execução necessária para acessar esses dados.
  4. Confira se o usuário já concedeu a permissão de execução que o app exige. Se tiver concedido, seu app poderá acessar os dados particulares do usuário. Caso contrário, continue para a próxima etapa.

    Você precisa conferir se tem essa permissão sempre que realizar uma operação que precise dela.

  5. Confira se o app precisa mostrar uma justificativa para o usuário, explicando por que é necessário conceder uma permissão de execução específica. Se o sistema determinar que seu app não mostrará uma justificativa, prossiga para a próxima etapa diretamente, sem exibir um elemento da IU.

    No entanto, se o sistema determinar que o app precisa exibir uma justificativa, apresente-a ao usuário em um elemento da IU. Essa justificativa precisa explicar claramente quais dados o app está tentando acessar e quais os benefícios ele pode oferecer ao usuário se conceder a permissão de execução. Depois que o usuário confirmar essa justificativa, siga para a próxima etapa.

  6. Solicite a permissão de execução que seu app exige para acessar os dados particulares do usuário. O sistema exibe uma solicitação de permissão de execução, como a mostrada na página de visão geral das permissões.

  7. Confira a resposta do usuário, seja para conceder ou negar a permissão de execução.

  8. Se a permissão foi concedida ao seu app, você pode acessar os dados particulares do usuário. Se a permissão tiver sido negada, faça uma degradação suave da experiência do app para que ele forneça funcionalidade ao usuário, mesmo sem as informações protegidas pela permissão.

A Figura 1 ilustra o fluxo de trabalho e o conjunto de decisões associadas a esse processo:

Figura 1. Diagrama que mostra o fluxo de trabalho para declarar e solicitar permissões de execução no Android.

Determinar se o app já recebeu a permissão

Para verificar se o usuário já concedeu uma permissão específica ao app, transmita essa permissão para o método ContextCompat.checkSelfPermission(). Esse método retorna PERMISSION_GRANTED ou PERMISSION_DENIED, dependendo se o app tem ou não a permissão.

Explicar por que seu app precisa da permissão

Se o método ContextCompat.checkSelfPermission() retornar PERMISSION_DENIED, chame shouldShowRequestPermissionRationale(). Se esse método retornar true, mostre uma IU educacional para o usuário. Nessa IU, descreva o motivo pelo qual o recurso que o usuário quer ativar precisa de uma permissão específica.

Solicitar permissões

Depois que o usuário visualizar uma IU educacional ou o valor de retorno shouldShowRequestPermissionRationale() indicar que você não precisa mostrar uma IU educacional dessa vez, solicite a permissão. Os usuários veem uma caixa de diálogo de permissão do sistema, na qual podem escolher se querem conceder uma permissão específica ao app.

Normalmente, você gerencia um código de solicitação como parte da solicitação de permissão e inclui esse código na lógica de callback de permissão. Outra opção é usar o contrato RequestPermission, incluído em uma biblioteca AndroidX, em que você permite que o sistema gerencie o código de solicitação de permissão para você. Como o uso do contrato RequestPermission simplifica sua lógica, é recomendável usá-lo quando possível.

Permitir que o sistema gerencie o código de solicitação de permissão

Para permitir que o sistema gerencie o código associado a uma solicitação de permissões, adicione uma dependência na biblioteca androidx.activity no arquivo build.gradle do módulo. Use a versão 1.2.0 ou mais recente da biblioteca.

Em seguida, você pode usar uma das seguintes classes:

As etapas a seguir mostram como usar o contrato RequestPermission. O processo é quase o mesmo para o contrato RequestMultiplePermissions.

  1. Na lógica de inicialização da atividade ou do fragmento, transmita uma implementação de ActivityResultCallback para uma chamada para registerForActivityResult(). O ActivityResultCallback define como o app processa a resposta do usuário à solicitação de permissão.

    Mantenha uma referência ao valor de retorno de registerForActivityResult(), que é do tipo ActivityResultLauncher.

  2. Para exibir a caixa de diálogo de permissões do sistema quando necessário, chame o método launch() na instância de ActivityResultLauncher que você salvou na etapa anterior.

    Depois que launch() for chamado, a caixa de diálogo de permissões do sistema será exibida. Quando o usuário faz uma escolha, o sistema invoca de maneira assíncrona a implementação de ActivityResultCallback, que você definiu na etapa anterior.

    Observação: seu app não pode personalizar a caixa de diálogo exibida quando você chama launch(). Para oferecer mais informações ou contexto ao usuário, mude a IU do seu app para que seja mais fácil entender o motivo pelo qual um recurso do app precisa de uma permissão específica. Por exemplo, você pode mudar o texto no botão que ativa o recurso.

    Além disso, o texto na caixa de diálogo de permissão do sistema faz referência ao grupo de permissões associado à permissão solicitada. Esse grupo de permissões foi projetado para facilitar o uso do sistema, e seu app não pode depender de permissões estarem dentro ou fora de um grupo de permissões específico.

O snippet de código a seguir mostra como lidar com a resposta de permissões:

Kotlin

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher. You can use either a val, as shown in this snippet,
// or a lateinit var in your onAttach() or onCreate() method.
val requestPermissionLauncher =
    registerForActivityResult(RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // features requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    }

Java

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher, as an instance variable.
private ActivityResultLauncher<String> requestPermissionLauncher =
    registerForActivityResult(new RequestPermission(), isGranted -> {
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // features requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    });

E este snippet de código demonstra o processo recomendado para verificar se há uma permissão e solicitar uma permissão do usuário quando necessário:

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
    }
    shouldShowRequestPermissionRationale(...) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected. In this UI,
        // include a "cancel" or "no thanks" button that allows the user to
        // continue using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        // The registered ActivityResultCallback gets the result of this request.
        requestPermissionLauncher.launch(
                Manifest.permission.REQUESTED_PERMISSION)
    }
}

Java

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (shouldShowRequestPermissionRationale(...)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected. In this UI,
    // include a "cancel" or "no thanks" button that allows the user to
    // continue using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    // The registered ActivityResultCallback gets the result of this request.
    requestPermissionLauncher.launch(
            Manifest.permission.REQUESTED_PERMISSION);
}

Gerenciar o código de solicitação de permissão

Em vez de permitir que o sistema gerencie o código de solicitação de permissão, você mesmo pode gerenciá-lo. Para isso, inclua o código da solicitação em uma chamada para requestPermissions().

O snippet de código a seguir demonstra como solicitar uma permissão usando um código de solicitação:

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
        performAction(...)
    }
    shouldShowRequestPermissionRationale(...) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected. In this UI,
        // include a "cancel" or "no thanks" button that allows the user to
        // continue using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        requestPermissions(CONTEXT,
                arrayOf(Manifest.permission.REQUESTED_PERMISSION),
                REQUEST_CODE)
    }
}

Java

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (shouldShowRequestPermissionRationale(...)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected. In this UI,
    // include a "cancel" or "no thanks" button that allows the user to
    // continue using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    requestPermissions(CONTEXT,
            new String[] { Manifest.permission.REQUESTED_PERMISSION },
            REQUEST_CODE);
}

Depois que o usuário responder à caixa de diálogo de permissões do sistema, o sistema invocará a implementação do app de onRequestPermissionsResult(). O sistema passa a resposta do usuário para a caixa de diálogo de permissão, bem como o código de solicitação definido, conforme mostrado no snippet de código seguir:

Kotlin

override fun onRequestPermissionsResult(requestCode: Int,
        permissions: Array<String>, grantResults: IntArray) {
    when (requestCode) {
        PERMISSION_REQUEST_CODE -> {
            // If request is cancelled, the result arrays are empty.
            if ((grantResults.isNotEmpty() &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                // Permission is granted. Continue the action or workflow
                // in your app.
            } else {
                // Explain to the user that the feature is unavailable because
                // the features requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return
        }

        // Add other 'when' lines to check for other
        // permissions this app might request.
        else -> {
            // Ignore all other requests.
        }
    }
}

Java

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission is granted. Continue the action or workflow
                // in your app.
            }  else {
                // Explain to the user that the feature is unavailable because
                // the features requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return;
        }
        // Other 'case' lines to check for other
        // permissions this app might request.
    }
}

Processar negação de permissão

Se o usuário negar uma solicitação de permissão, seu app precisará ajudar a entender as implicações de negar essa permissão. Mais especificamente, seu app precisa informar os usuários sobre os recursos que não funcionam devido à ausência da permissão. Ao fazer isso, lembre-se das seguintes práticas recomendadas:

  • Direcione a atenção do usuário. Destaque uma parte específica da IU do app em que a funcionalidade será limitada porque o app não tem a permissão necessária. Veja alguns exemplos do que você pode fazer:

    • Mostrar uma mensagem em que os resultados ou dados do recurso seriam exibidos.
    • Exibir um botão diferente que contenha um ícone e uma cor de erro.
  • Seja específico. Não exiba uma mensagem genérica. Em vez disso, mencione quais recursos não estão disponíveis porque o app não tem a permissão necessária.

  • Não bloqueie a interface do usuário. Em outras palavras, não exiba uma mensagem de aviso em tela cheia que impeça o usuário de continuar usando o app.

Ao mesmo tempo, o app precisa respeitar a decisão do usuário de negar uma permissão. A partir do Android 11 (API de nível 30), se o usuário tocar mais de uma vez em Negar para uma permissão específica durante a vida útil da instalação do app em um dispositivo, a caixa de diálogo de permissões do sistema não será exibida se o app solicitar a permissão novamente. A ação do usuário implica "não perguntar novamente". Em versões mais antigas, os usuários tinham acesso à caixa de diálogo de permissões do sistema toda vez que o app solicitava uma permissão, a menos que uma caixa de seleção "não perguntar novamente" tivesse sido selecionada.

Em determinadas situações, a permissão pode ser negada automaticamente, sem que o usuário realize nenhuma ação. Da mesma forma, uma permissão também pode ser concedida de forma automática. É importante não presumir nada sobre o comportamento automático. Sempre que seu app precisar acessar uma funcionalidade que exija uma permissão, verifique se ele ainda tem essa permissão.

Para oferecer a melhor experiência do usuário ao pedir permissões do app, consulte também as Práticas recomendadas de permissões do app.

Permissões únicas

A opção chamada &quot;Apenas esta vez&quot; é o segundo dos três botões na
    caixa de diálogo.
Figura 2. Caixa de diálogo do sistema que aparece quando um app solicita uma permissão única.

A partir do Android 11 (API de nível 30), sempre que seu app solicita uma permissão relacionada a localização, microfone ou câmera, a caixa de diálogo de permissões voltada ao usuário contém uma opção chamada Apenas esta vez, conforme mostrado na Figura 2. Se o usuário selecionar essa opção na caixa de diálogo, seu app receberá uma permissão única temporária.

O app poderá acessar os dados relacionados por um período que depende do comportamento do app e das ações do usuário:

  • Enquanto a atividade do seu app estiver visível, ele poderá acessar os dados.
  • Se o usuário colocar o app em segundo plano, o app poderá continuar acessando os dados por um curto período.
  • Se um serviço for iniciado em primeiro plano enquanto a atividade estiver visível, e o usuário mover o app para o segundo plano, o app continuará acessando os dados relacionados até que o serviço em primeiro plano seja interrompido.
  • Se o usuário revogar a permissão única (por exemplo, nas configurações do sistema), o app não poderá acessar os dados, independentemente de um serviço ter sido iniciado em primeiro plano. Como acontece com qualquer permissão, se o usuário revogar a permissão única do app, o processo do app será encerrado.

Da próxima vez que o usuário abrir o app e um recurso dele solicitar acesso à localização, ao microfone ou à câmera, a solicitação vai aparecer novamente.

Redefinir automaticamente as permissões de apps não usados

Se o app foi para Android 11 (API de nível 30) ou mais recentes e não for usado por alguns meses, o sistema protegerá os dados do usuário redefinindo automaticamente as permissões confidenciais que o usuário concedeu. Essa ação tem o mesmo efeito que se o usuário visualizasse uma permissão nas configurações do sistema e mudasse o nível de acesso do app para Negar.

Se o app seguir as práticas recomendadas para solicitar permissões no tempo de execução, não será preciso fazer alterações nele.

Solicitar que o usuário desative a redefinição automática

Se necessário, você pode pedir ao usuário para impedir que o sistema redefina as permissões do seu app. Isso é útil em situações em que os usuários esperam que o app funcione em segundo plano mesmo sem interação, como nos seguintes casos de uso:

Figura 3. O usuário desativou a redefinição automática de permissões para determinado app.
  • Fornecer segurança familiar.
  • Sincronizar dados.
  • Comunicar-se com dispositivos inteligentes.
  • Parear com dispositivos complementares.

Para direcionar o usuário para a página do app nas configurações do sistema, chame uma intent que inclua a ação Intent.ACTION_AUTO_REVOKE_PERMISSIONS. Nessa tela, os usuários podem impedir que o sistema redefina as permissões do app fazendo o seguinte:

  1. Toque em Permissões, que carrega a tela de configurações Permissões do app.
  2. Desative a opção denominada Remover permissões se o app não for usado, como mostrado na Figura 3.

Determinar se a redefinição automática está desativada

Para verificar se a funcionalidade de redefinição automática está desativada para seu app, chame isAutoRevokeWhitelisted(). Se esse método retornar true, o sistema não redefinirá automaticamente as permissões do app.

Pedir para se tornar o gerenciador padrão, se necessário

Alguns apps dependem do acesso a informações confidenciais do usuário relacionadas a registros de chamadas e mensagens SMS. Se você quiser solicitar permissões especificamente para registros de chamadas e mensagens SMS e publicar seu app na Play Store, precisará solicitar que o usuário configure seu app como o gerenciador padrão de uma função principal do sistema antes de solicitar essas permissões de execução.

Para ver mais informações sobre gerenciadores padrão, incluindo orientações sobre como mostrar uma solicitação de gerenciador padrão para o usuário, consulte o guia sobre permissões usadas somente em gerenciadores padrão.

Testar permissões de execução

Esta seção descreve como testar vários aspectos das permissões de execução.

Conceder todas as permissões de execução

Para conceder todas as permissões de execução automaticamente ao instalar um app em um emulador ou dispositivo de teste, use a opção -g para o comando adb shell install, conforme demonstrado no snippet de código a seguir:

adb shell install -g PATH_TO_APK_FILE

Fazer a redefinição automática das permissões do seu app

Para verificar se o sistema redefine as permissões do app, faça o seguinte:

  1. Salve o tempo padrão que o sistema aguarda para redefinir as permissões de um app. Dessa forma, você pode restaurá-lo após o teste:

    threshold=$(adb shell device_config get permissions \
      auto_revoke_unused_threshold_millis2)
    
  2. Reduza o tempo que o sistema aguarda para redefinir as permissões. No exemplo a seguir, o sistema é modificado para redefinir as permissões de um app apenas um segundo depois que você parar de interagir com um app:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  3. Invoque o processo de redefinição automática manualmente, conforme mostrado no snippet a seguir. Certifique-se de que o dispositivo de teste esteja ligado por um curto período, cerca de 45 segundos, antes de executar este comando.

    adb shell cmd jobscheduler run -u 0 -f \
      com.google.android.permissioncontroller 2
    
  4. Verifique se o app pode processar o evento de redefinição automática.

  5. Restaure o tempo padrão que o sistema aguarda antes de redefinir automaticamente as permissões de um app:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold
    

Outros recursos

Para mais informações sobre permissões, leia estes artigos:

Para saber mais sobre solicitação de permissões, faça o download destes apps de amostra:

  • Amostra do Android RuntimePermissionsBasic Java | Kotlin (links em inglês)