Práticas recomendadas de permissões do app

Solicitações de permissão protegem informações confidenciais disponíveis em um dispositivo e só devem ser usadas quando o acesso às informações é necessário para o funcionamento do app. Este documento traz dicas de como conseguir os mesmos recursos (ou melhores) sem exigir o acesso a essas informações. Não se trata de uma discussão completa sobre o funcionamento das permissões no sistema operacional Android.

Para uma perspectiva mais geral das permissões do Android, consulte a Visão geral das permissões do app. Para ver detalhes sobre como trabalhar com permissões no seu código, consulte Solicitar permissões do app.

Princípios de como trabalhar com as permissões do Android

Recomendamos seguir estes princípios ao trabalhar com permissões do Android:

Nº 1: use apenas as permissões necessárias para o funcionamento do app.\ Dependendo de como as permissões são usadas, pode haver outra maneira de fazer o que é necessário (intents do sistema, identificadores, chamadas telefônicas em segundo plano) sem precisar de acesso a informações confidenciais.+

Nº 2: preste atenção às permissões exigidas pelas bibliotecas. Ao incluir uma biblioteca, você também herda os requisitos de permissões dela. Esteja ciente do que está sendo incluído, das permissões necessárias e do uso dessas permissões.

Nº 3: seja transparente. Ao solicitar uma permissão, é preciso informar com clareza o que está sendo acessado e por que, para que os usuários possam tomar decisões informadas. Disponibilize essas informações juntamente com a solicitação de permissão, incluindo caixas de diálogo de permissões de instalação, tempo de execução ou atualização.

Nº 4: deixe os acessos do sistema explícitos. Oferecendo indicações contínuas ao acessar recursos confidenciais (como a câmera ou o microfone), você deixa claro para os usuários quando está coletando dados e evita a percepção de que essa coleta está sendo feita clandestinamente.

As demais seções deste guia detalham essas regras no contexto do desenvolvimento de aplicativos para Android.

Permissões no Android 6.0 e em versões posteriores

O Android 6.0 Marshmallow introduziu um novo modelo de permissões que permite aos apps solicitar permissões ao usuário durante a execução, em vez de antes da instalação. Os apps compatíveis com o novo modelo solicitam permissões quando realmente precisam dos serviços ou dos dados protegidos pelos serviços. Embora isso não (necessariamente) mude o comportamento geral do app, algumas mudanças relevantes foram feitas na forma de processamento dos dados confidenciais do usuário:

Aumento no contexto situacional: os usuários recebem uma solicitação durante a execução no contexto do app, para concederem permissão de acesso ao recurso incluído nesses grupos de permissões. Os usuários estão mais atentos ao contexto em que a permissão é solicitada e, em caso de incompatibilidade entre sua solicitação e a finalidade do app, é ainda mais importante oferecer explicações detalhadas sobre o motivo da solicitação. Sempre que possível, ofereça uma explicação sobre a solicitação no momento em que ela ocorre e também em uma caixa de diálogo de acompanhamento, caso o usuário a negue.

Maior flexibilidade na concessão de permissões: os usuários podem negar o acesso a permissões individuais no momento da solicitação e nas configurações. No entanto, eles ainda podem se surpreender caso um recurso seja inutilizado como resultado dessa recusa. É recomendável monitorar quantos usuários estão negando permissões (por exemplo, usando o Google Analytics) para que você possa adaptar seu app para não depender dessa permissão ou oferecer uma explicação melhor sobre a necessidade da permissão para o funcionamento correto do app. Além disso, verifique se seu app processa as exceções criadas quando os usuários negam solicitações de permissão ou desativam as permissões nas configurações.

Aumento da carga de transações: é solicitado que os usuários concedam acesso para grupos de permissões individualmente, não como um conjunto. Dessa forma, é extremamente importante minimizar o número de permissões solicitadas, já que isso aumenta o trabalho do usuário em conceder permissões e a probabilidade de pelo menos uma delas ser negada.

Permissões que precisam se tornar um gerenciador padrão

Alguns apps dependem do acesso a informações confidenciais do usuário relacionadas a registros de chamadas e mensagens SMS. Se você quer solicitar as permissões específicas para registros de chamadas e mensagens SMS e publicar seu app na Play Store, é necessário solicitar que o usuário configure o app como gerenciador padrão para uma função básica do sistema antes de solicitar essas permissões durante a execução.

Para ver mais informações sobre gerenciadores padrão, incluindo orientações sobre como exibir uma solicitação de gerenciador padrão aos usuários, consulte o guia sobre permissões utilizadas somente para gerenciadores padrão.

Evite solicitar permissões desnecessárias

Sempre que você pede uma permissão, o usuário é forçado a tomar uma decisão. Diminua o número de solicitações realizadas. Se o usuário estiver utilizando o Android 6.0 (API nível 23) ou posterior, sempre que ele tentar usar algum recurso novo do app que exija uma permissão, o app precisará interromper o trabalho do usuário com uma solicitação de permissão. Se o usuário estiver usando uma versão anterior do Android, ele precisará conceder todas as permissões do app no momento de instalação e, se a lista for longa demais ou parecer inapropriada, o usuário poderá decidir não instalar o app. Por esses motivos, é importante minimizar o número de permissões necessárias para o app.

Esta seção traz alternativas para casos de uso comuns que ajudarão a limitar o número de solicitações de permissão realizadas. Como o número e o tipo de permissões exibidas para o usuário afetam os downloads em comparação a outros apps semelhantes que solicitam menos permissões, é recomendável evitar a solicitação de permissões para recursos desnecessários.

Use um intent

Em vários casos, é possível escolher entre duas maneiras para que o app realize uma tarefa. Ele pode pedir permissão para realizar a tarefa em si ou usar um intent para fazer com que outro app a realize.

Por exemplo, imagine que seu app precise da função de tirar fotos com a câmera do dispositivo. Ele pode solicitar a permissão CAMERA, que concede acesso direto à câmera. Assim, o app usará as APIs relacionadas para controlar a câmera e tirar fotos. Essa abordagem concede ao app controle total sobre o processo de fotos e permite que você incorpore a IU da câmera.

No entanto, se a necessidade de acesso aos dados do usuário for pouco frequente, em outras palavras, se não for muito incômodo para o usuário receber uma caixa de diálogo durante a execução toda vez que o acesso aos dados for necessário, você poderá usar uma solicitação baseada em intent. O Android disponibiliza alguns intents de sistema que os apps podem usar sem precisar de permissões, uma vez que o usuário escolhe o que quer compartilhar com o app, se for o caso, no momento em que a solicitação baseada em intent é realizada.

Por exemplo, um tipo de ação de intent de MediaStore.ACTION_IMAGE_CAPTURE ou MediaStore.ACTION_VIDEO_CAPTURE pode ser usado para capturar imagens ou vídeos sem usar o objeto Camera diretamente (ou solicitar uma permissão). Nesse caso, o intent do sistema solicitará a permissão do usuário por você sempre que uma imagem for capturada.

Da mesma maneira, se você precisar fazer uma chamada telefônica, acessar os contatos do usuário etc., será possível realizar essas ações criando um intent adequado ou solicitando a permissão e acessando os objetos relevantes diretamente. Há vantagens e desvantagens em cada abordagem.

Uso de permissões:

  • O app tem controle total sobre a experiência do usuário quando você realiza a operação. No entanto, esse controle amplo aumenta a complexidade do seu código, já que é necessário projetar uma IU adequada.
  • É solicitado que o usuário conceda permissão uma vez, durante a execução ou no momento da instalação, dependendo da versão do Android utilizada. Depois disso, o app pode realizar a operação sem precisar de mais interações do usuário. No entanto, se o usuário não conceder a permissão (ou revogá-la posteriormente), o app não conseguirá realizar a operação.

Uso de intent:

  • Você não precisa projetar a IU para a operação. O app que processa o intent disponibiliza a IU.
  • O usuário pode usar o app que preferir para a tarefa. Por exemplo, ele pode escolher o app de fotos que quiser para tirar uma foto.
  • Se o usuário não tiver um app padrão para a operação, o sistema solicitará que ele escolha um. Se o usuário não designar um gerenciador padrão, ele poderá ter que passar por uma caixa de diálogo extra todas as vezes que realizar a operação.

Não sobrecarregue o usuário

Se o usuário estiver usando o Android 6.0 (API nível 23) ou posterior, ele precisará conceder as permissões do app durante a execução. Se várias solicitações de permissão forem exibidas de uma só vez, o usuário poderá se sentir sobrecarregado e sair do app. Em vez disso, solicite as permissões somente quando necessário.

Em alguns casos, uma ou mais permissões podem ser absolutamente essenciais para o app. Pode ser tentador solicitar todas essas permissões assim que o app é iniciado. Por exemplo, se você criar um app de fotografia, ele precisará de acesso à câmera do dispositivo. Quando o usuário abrir o app pela primeira vez, não se surpreenderá quando receber uma solicitação de permissão para usar a câmera. Mas se o mesmo app também tiver um recurso para compartilhar fotos com os contatos do usuário, o ideal seria não pedir a permissão READ_CONTACTS na primeira inicialização. Em vez disso, espere o usuário tentar usar o recurso de compartilhamento para solicitar a permissão.

Se o app oferece um tutorial, é interessante solicitar as permissões básicas no final da sequência do tutorial.

Pause a mídia quando o áudio de outro app for selecionado para o primeiro plano

Nesse caso, o app precisa passar para o segundo plano quando o usuário recebe uma chamada telefônica e voltar ao foco somente quando a chamada for finalizada.

A abordagem comum nesses casos (por exemplo, quando um player de mídia é pausado ou silenciado durante uma chamada telefônica) é ouvir as mudanças no estado da chamada usando PhoneStateListener ou ouvir a transmissão de android.intent.action..PHONE_STATE. O problema dessa solução é que ela exige a permissão READ_PHONE_STATE, que força o usuário a conceder acesso a uma grande seção de dados confidenciais, como os códigos do hardware do dispositivo e do chip e o número de telefone da chamada recebida. Além disso, os eventos LISTEN_CELL_LOCATION e LISTEN_CELL_INFO exigem uma permissão de localização quando o app é executado no Android 10 (API nível 29) ou posterior (especialmente ACCESS_FINE_LOCATION, se o app for direcionado ao Android 10 ou posterior).

Você pode detectar se o usuário está em uma chamada telefônica sem as permissões READ_PHONE_STATE ou MODIFY_PHONE_STATE solicitando AudioFocus para seu app. Isso não requer permissões explícitas, já que não há acesso a informações confidenciais. Basta inserir o código necessário para colocar o áudio em segundo plano no manipulador de eventos onAudioFocusChange() e ele será executado automaticamente quando o SO alterar a seleção de áudio. Veja uma documentação mais detalhada sobre como fazer isso neste link.

Determine o dispositivo em que sua instância está sendo executada

Nesse caso, você precisa de um identificador exclusivo para determinar em qual dispositivo a instância do seu app está sendo executada.

Os aplicativos podem ter preferências ou mensagens específicas do dispositivo, por exemplo, salvar uma playlist específica do dispositivo na nuvem para que o usuário possa ter uma playlist diferente no carro e em casa. Uma solução comum é usar identificadores de dispositivos, como Device IMEI, mas isso exige o grupo de permissões Device ID and call information (PHONE no M+). Também é possível usar um identificador que não possa ser redefinido e que seja compartilhado em todos os apps.

Existem duas alternativas para o uso desses tipos de identificadores:

  1. Use a API InstanceID com.google.android.gms.iid. getInstance(Context context).getID() retornará um identificador exclusivo de dispositivo para a instância do seu aplicativo. O resultado é um identificador com escopo da instância do app que pode ser usado como chave ao armazenar informações sobre o app e que será redefinido se o usuário reinstalar o app.
  2. Crie o próprio identificador com escopo no armazenamento do seu app usando funções básicas, como randomUUID().

Crie um identificador exclusivo para análise de publicidade ou de usuários

Nesse caso, você precisa de um identificador exclusivo para criar um perfil para usuários que não se conectaram ao seu app (por exemplo, para direcionar anúncios ou medir as conversões).

Às vezes, a criação de um perfil para análise de publicidade e de usuários exige um identificador que seja compartilhado por outros aplicativos. Algumas soluções comuns envolvem o uso de identificadores de dispositivo, como Device IMEI, que exige o grupo de permissões Device ID and call information (PHONE na API nível 23 e posterior) e que não pode ser redefinido pelo usuário. Em qualquer um desses casos, além de usar um identificador que não pode ser redefinido e solicitar uma permissão que pode parecer estranha para os usuários, você também violará as Políticas do programa para desenvolvedores do Google Play.

Infelizmente, nesses casos, o uso das funções do sistema ou da API InstanceID com.google.android.gms.iid para criar um código com escopo do app não é uma solução apropriada, porque o código pode precisar ser compartilhado entre apps. Uma solução alternativa é usar o Advertising Identifier disponível da classe AdvertisingIdClient..Info por meio do método getId(). Você pode criar um objeto AdvertisingIdClient.Info usando o método getAdvertisingIdInfo(Context) e chamar o método getId() para usar o identificador. Esse método é bloqueador, portanto, não chame ele a partir da linha de execução principal. Uma explicação detalhada sobre esse método pode ser lida aqui.

Conheça as bibliotecas com que está trabalhando

Às vezes, as bibliotecas que você usa no seu aplicativo exigem permissões. Por exemplo, bibliotecas de anúncio ou de análise podem exigir acesso ao grupo de permissões LOCATION para implementar o recurso necessário. Contudo, do ponto de vista do usuário, a solicitação de permissão é enviada do seu app, não da biblioteca.

Assim como os usuários selecionam apps que usam menos permissões para proporcionar os mesmos recursos, os desenvolvedores precisam analisar as bibliotecas e selecionar SDKs de terceiros que não usem permissões desnecessárias. Por exemplo, se você está usando uma biblioteca que oferece o recurso de localização, não solicite a permissão FINE_LOCATION, a não ser que você esteja usando recursos de segmentação baseados na localização.

Explique por que as permissões são necessárias

A caixa de diálogo de permissões exibida pelo sistema quando você chama requestPermissions() informa quais permissões o app solicita, mas não explica o motivo. Em alguns casos, o usuário pode achar isso confuso. É recomendável explicar ao usuário por que as permissões são necessárias para o app antes de chamar requestPermissions().

Pesquisas mostram que os usuários se sentem muito mais à vontade com solicitações de permissões quando sabem por que o app precisa delas. Um estudo com usuários revelou que:

(...) a disposição do usuário de conceder determinada permissão a um app para dispositivos móveis é significativamente influenciada pela finalidade associada a essa permissão. Por exemplo, a disposição do usuário de conceder acesso à própria localização varia de acordo com o motivo da solicitação: se ela é necessária para oferecer compatibilidade com um recurso básico do app ou se será usada para compartilhar essa informação com uma rede de publicidade ou empresa de análise.1

Com base na pesquisa realizada pelo grupo do Professor Jason Hong da Universidade Carnegie Mellon, concluiu-se que, de forma geral:

(...) quando as pessoas sabem por que um app está usando uma informação tão importante como a localização delas (por exemplo, para anúncios segmentados), se sentem mais confortáveis do que quando são informadas apenas que um app está usando essa informação.1

Sendo assim, se você está usando apenas uma parte das chamadas de API que se encaixam em um grupo de permissões, é importante listar de maneira explícita quais permissões estão sendo usadas e o porquê. Por exemplo:

  • Se você só está usando a localização aproximada, informe isso ao usuário na descrição do app ou em artigos de ajuda relacionados.
  • Se você precisa de acesso a mensagens SMS para receber códigos de autenticação que protegem o usuário contra fraudes, informe isso na descrição do app e/ou na primeira vez que acessar os dados.

    Observação: se o app for destinado ao Android 8.0 (API nível 26) ou posterior, não solicite a permissão READ_SMS como parte da verificação das credenciais do usuário. Em vez disso, gere um token específico do app usando createAppSpecificSmsToken() e passe esse token para outro app ou serviço que possa enviar uma mensagem SMS de verificação.

Em certas condições, também é pertinente informar os usuários sobre acessos a dados confidenciais em tempo real. Por exemplo, caso você esteja acessando a câmera ou o microfone, é recomendável informar o usuário com um ícone de notificação em algum lugar do app ou na bandeja de notificações (se o aplicativo estiver sendo executado em segundo plano). Assim, o usuário não terá a impressão de que os dados estão sendo coletados clandestinamente.

Por fim, se você precisar solicitar permissão para que um recurso do seu app funcione, mas o motivo não estiver claro para o usuário, encontre uma maneira de informar por que você precisa das permissões mais confidenciais.

Teste ambos os modelos de permissões

A partir do Android 6.0 (API nível 23), os usuários concedem e revogam permissões do app durante a execução, não no momento da instalação. Dessa forma, é preciso testar seu app em um conjunto mais amplo de condições. Antes do Android 6.0, você podia presumir que, se o app estivesse em execução, ele tinha todas as permissões declaradas no próprio manifesto. A partir do Android 6.0, o usuário pode ativar ou desativar permissões para qualquer app, inclusive apps segmentados para a API nível 22 ou anterior. Você precisa testar para garantir que seu app funcione corretamente, independentemente de ter ou não permissões.

As dicas a seguir ajudarão você a encontrar problemas de código relacionados a permissões em dispositivos com a API nível 23 ou posterior:

  • Identifique as permissões atuais do aplicativo e os caminhos de código relacionados.
  • Teste o fluxo de usuários entre serviços e dados protegidos por permissão.
  • Teste várias combinações de permissões concedidas ou revogadas. Por exemplo, um app de câmera pode listar CAMERA, READ_CONTACTS e ACCESS_FINE_LOCATION no manifesto. Você precisa testar o app com cada permissão ativada e desativada, para garantir que o app consiga processar todas as configurações de permissões corretamente.
  • Use a ferramenta adb para gerenciar permissões na linha de comando:
    • Liste as permissões e os status por grupo:
      $ adb shell pm list permissions -d -g
    • Conceda ou revogue uma ou mais permissões:
      $ adb shell pm [grant|revoke] <permission-name> ...
  • Analise o aplicativo para descobrir os serviços que usam permissões.

Recursos adicionais

Referências

[1] Modeling Users’ Mobile App Privacy Preferences: Restoring Usability in a Sea of Permission Settings, de J. Lin B. Liu, N. Sadeh e J. Hong. Nos procedimentos do SOUPS 2014.