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:
- Abra a tela Informações do app de um app.
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()
.