Restringir interações com outros apps

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

Este guia explica como ver o conjunto de permissões declarado por outro app. Ele 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. Por fim, esta página fornece orientações sobre várias outras maneiras de aplicar padrões de interação entre apps.

Ver 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.

Restringir interações com as atividades do seu app

As permissões aplicadas usando o atributo android:permission na tag <activity> no manifesto restringem quem pode iniciar essa 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

As permissões aplicadas usando o atributo android:permission na tag <service> no manifesto restringem quem pode iniciar ou se vincular ao Service associado. A permissão é verificada durante Context.startService(), Context.stopService() e Context.bindService(). Se o autor da chamada não tiver a permissão necessária, ocorrerá uma SecurityException.

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

As permissões aplicadas usando o atributo android:permission na tag <provider> restringem quem pode 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 a seguir. Diferente de outros componentes, há dois atributos separados de permissão que se podem definir: android:readPermission restringe quem pode ler dados no provedor e android:writePermission restringe quem pode gravar nele. Observe que, se um provedor é protegido com as permissões de leitura e gravação, a permissão de gravação sozinha não significa que seja possível ler os dados de um provedor.

As permissões são verificadas quando você recupera um provedor pela primeira vez e à medida que você realiza operações no provedor. Se você não tiver nenhuma das permissões, uma SecurityException ocorrerá. O uso de ContentResolver.query() exige que se tenha 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. Em particular, seu 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 a compatibilidade do seu app com 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 dá a outro app permissões de leitura, gravação e leitura/gravação, respectivamente, para o URI de dados incluído na intent. O outro app recebe essas permissões para o URI específico, independentemente de ele ter ou não a permissão para acessar os dados no provedor de conteúdo de maneira mais geral.

Por exemplo, suponha que um usuário esteja visualizando um e-mail no seu app e nele há uma imagem como anexo. 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 que um app de visualização de imagens a acesse.

Outra consideração é a visibilidade do app. Se o app for direcionado ao Android 11 (API de nível 30) ou versões mais recentes, o sistema deixará alguns apps visíveis automaticamente para o seu, mas 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 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

As permissões aplicadas usando o atributo android:permission na tag <receiver> restringem quem pode 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. Como resultado, uma falha de permissão não resulta em uma exceção retornada ao autor da chamada. Ela apenas não exibe o Intent.

Da mesma forma, é possível fornecer uma permissão a Context.registerReceiver() para controlar quem pode transmitir para um receptor registrado programaticamente. Por outro lado, uma permissão pode ser concedida 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 Como restringir transmissões com permissões.

Outras verificações de permissões

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().