Restringir interações com outros apps

Permissões não servem apenas para solicitar recursos do sistema. Também é possível restringir o modo como outros apps podem interagir com os componentes do seu.

Este guia explica como verificar o conjunto de permissões declarado por outro app. Este guia também explica como configurar atividades, serviços, provedores de conteúdo e broadcast receivers para restringir o modo como outros apps podem interagir com o seu.

Verificar as permissões de outro app

Para ver o conjunto de permissões declarado por outro app, use um dispositivo ou emulador para concluir as seguintes etapas:

  1. Abra a tela Informações do app de um app.
  2. Selecione Permissões. A tela Permissões do app será carregada.

    Essa tela mostra um conjunto de grupos de permissões. O sistema organiza nesses grupos o conjunto de permissões declarado por um app.

Há várias outras formas úteis de verificar permissões:

  • Durante uma chamada para um serviço, transmita uma string de permissão para Context.checkCallingPermission(). Esse método retorna um número inteiro que indica se a permissão foi concedida ao processo de chamada atual. Essa opção só pode ser usada ao realizar uma chamada vinda de outro processo, geralmente por uma interface IDL publicada em um serviço ou de alguma outra forma oferecida ao processo.
  • Para conferir se outro processo concedeu uma permissão específica, transmita o processo (PID) para Context.checkPermission().
  • Para verificar se outro pacote recebeu uma permissão específica, transmita o nome do pacote para PackageManager.checkPermission().

Restringir interações com as atividades do seu app

Use o atributo android:permission na tag <activity> no manifesto para restringir quais outros apps podem iniciar esse Activity. A permissão é verificada durante Context.startActivity() e Activity.startActivityForResult(). Se o autor da chamada não tiver a permissão necessária, ocorrerá uma SecurityException.

Restringir interações com os serviços do seu app

Use o atributo android:permission na tag <service> no manifesto para restringir quais outros apps podem iniciar ou ser vinculados ao Service associado. A permissão é verificada durante Context.startService(), Context.stopService() e Context.bindService(). Se o autor da chamada não tem a permissão necessária, ocorre uma SecurityException.

Restringir interações com os provedores de conteúdo do seu app

Use o atributo android:permission na tag <provider> para restringir quais outros apps podem acessar os dados em um ContentProvider. Provedores de conteúdo têm uma unidade de segurança adicional importante chamada permissões de URI, descrita na seção a seguir. Diferentemente dos outros componentes, há dois atributos de permissão separados que você pode definir para provedores de conteúdo: android:readPermission restringe os outros apps que podem ler dados no provedor, e android:writePermission restringe quais outros apps podem gravar nele. Se um provedor está protegido com as permissões de leitura e gravação, apenas a permissão de gravação não permite que um app leia dados de um provedor.

As permissões são verificadas quando o provedor é recuperado pela primeira vez e quando um app executa operações no provedor. Se o app solicitante não tem nenhuma das permissões, ocorre uma SecurityException. O uso de ContentResolver.query() exige a permissão de leitura. O uso de ContentResolver.insert(), ContentResolver.update() ou ContentResolver.delete() exige a permissão de gravação. Em todos esses casos, não ter a permissão exigida resulta em uma SecurityException.

Permitir acesso por URI

O sistema oferece um controle mais detalhado sobre como outros apps podem acessar os provedores de conteúdo do seu app. Especificamente, o provedor de conteúdo pode se proteger com permissões de leitura e gravação e ainda permitir que os clientes diretos compartilhem URIs específicos com outros apps. Para declarar o suporte do seu app a esse modelo, use o atributo android:grantUriPermissions ou o elemento <grant-uri-permission>.

Também é possível conceder permissões por URI. Ao iniciar uma atividade ou retornar um resultado para uma atividade, defina a sinalização de intent Intent.FLAG_GRANT_READ_URI_PERMISSION, a sinalização de intent Intent.FLAG_GRANT_WRITE_URI_PERMISSION ou ambas. Isso concede a outros apps permissões de leitura, gravação ou leitura/gravação, respectivamente, para o URI de dados incluído na intent. Outros apps recebem essas permissões para o URI específico, independente de terem permissão para acessar os dados no provedor de conteúdo de modo geral.

Por exemplo, suponha que um usuário esteja usando seu app para visualizar um e-mail com um anexo de imagem. Outros apps não podem acessar todo o conteúdo do e-mail, mas podem ter interesse na imagem. Seu app pode usar uma intent e a sinalização de intent Intent.FLAG_GRANT_READ_URI_PERMISSION para permitir que um app de visualização de imagem a veja.

Outra consideração é a visibilidade do app. Se o app for direcionado ao Android 11 (nível 30 da API) ou versões mais recentes, o sistema vai deixar alguns apps automaticamente visíveis para o seu e ocultar outros por padrão. Se o app tiver um provedor de conteúdo e tiver concedido permissões de URI a outro app, ele vai ficar visível automaticamente para o outro.

Para saber mais, veja o material de referência para os métodos grantUriPermission(), revokeUriPermission() e checkUriPermission().

Restringir interações com os broadcast receivers do seu app

Use o atributo android:permission na tag <receiver> para restringir quais outros apps podem enviar transmissões para o BroadcastReceiver associado. A permissão é verificada depois que Context.sendBroadcast() retorna, enquanto o sistema tenta entregar a transmissão enviada a um determinado receptor. Isso significa que uma falha de permissão não resulta em uma exceção retornada ao autor da chamada,. Ela apenas não mostra a Intent.

Da mesma forma, você pode fornecer uma permissão a Context.registerReceiver() para controlar quais outros apps podem ser transmitidos para um receptor registrado programaticamente. Por outro lado, você pode fornecer uma permissão ao chamar Context.sendBroadcast() para restringir quais broadcast receivers podem receber a transmissão.

Observe que, tanto um receptor quanto um transmissor podem exigir uma permissão. Quando isso acontece, as duas verificações de permissão precisam passar pela intent para serem entregues ao destino associado. Para saber mais, consulte Restringir transmissões com permissões.