Dangerous Permission é uma categoria de permissões no Android que exigem consentimento explícito do usuário por meio de um diálogo em tempo de execução enquanto o aplicativo está em execução. De acordo com o Guia do Desenvolvedor Android, 2024, permissões perigosas têm ProtectionLevel dangerous e fornecem acesso a dados confidenciais: câmera, microfone, localização e contatos. Sem o consentimento explícito do usuário, o aplicativo não pode usar esses recursos.
Principais pontos
Dangerous Permission é uma categoria de permissões do sistema Android que fornecem acesso a dados confidenciais do usuário. Ao contrário das permissões normais, as permissões perigosas não são concedidas automaticamente durante a instalação — o aplicativo deve solicitá-las explicitamente em tempo de execução através do mecanismo introduzido no Android 6.0 Marshmallow (API 23).
A necessidade de solicitação explícita se deve à natureza dos dados que essas permissões protegem: localização do usuário, contatos pessoais, conteúdo da câmera e microfone, histórico de chamadas e SMS. O Android considera esses dados como sensíveis e exige que o usuário conceda acesso de forma consciente. De acordo com o Android Privacy Sandbox (2024), os usuários recusam cerca de 30 por cento das solicitações em tempo de execução em média.
Uma característica importante do Dangerous Permission é a possibilidade de revogá-lo a qualquer momento. O usuário pode ir em Configurações — Aplicativos — Permissões e desativar qualquer permissão perigosa. O aplicativo deve estar preparado para que uma permissão que foi concedida possa ser revogada a qualquer momento sem reinicialização.
O nível de proteção dangerous é definido nas definições de permissão do sistema no nível do SO. Quando um aplicativo declara uses-permission com este protectionLevel, o sistema marca a permissão como exigindo uma solicitação em tempo de execução. Ao contrário de normal, as permissões dangerous são sempre exibidas na interface de gerenciamento de permissões do sistema e podem ser revogadas.
Todas as permissões perigosas são agrupadas em Permission Groups por categoria funcional. Por exemplo, CAMERA e CAMERA2 estão no grupo CAMERA, ACCESS_FINE_LOCATION e ACCESS_COARSE_LOCATION estão no grupo LOCATION. Se um usuário concedeu uma permissão de um grupo, as permissões restantes do mesmo grupo são concedidas automaticamente sem um diálogo adicional.
A solicitação em tempo de execução é um mecanismo onde o aplicativo chama uma API do sistema para exibir um diálogo de solicitação de permissão. O usuário vê uma janela modal com o nome da permissão e botões Permitir e Negar. Após a resposta, o sistema chama o callback onRequestPermissionsResult com o resultado.
O ciclo completo inclui três etapas: verificar o status via checkSelfPermission, chamar requestPermissions se a permissão não estiver concedida e tratar o resultado em onRequestPermissionsResult. A verificação de status é obrigatória porque o usuário pode ter revogado a permissão a qualquer momento através das configurações, e chamar uma função sem verificação resultará em uma SecurityException.
fun checkAndRequestCameraPermission() {
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
openCamera()
}
else -> {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.CAMERA),
REQUEST_CAMERA_CODE
)
}
}
}
O tratamento do resultado ocorre em ActivityResultLauncher ou onRequestPermissionsResult. A abordagem moderna recomendada é usar ActivityResultContracts.RequestPermission, que fornece uma API mais limpa sem códigos de solicitação explícitos. Este contrato retorna um Boolean — se a permissão foi concedida ou não.
Solicite permissões perigosas estritamente no contexto do uso da funcionalidade, não na inicialização do aplicativo. Se o usuário pressionou o botão da câmera — solicite CAMERA. Se abriu um mapa — solicite LOCATION. Solicitações contextuais geram o dobro de concessões do que solicitar todas as permissões no primeiro lançamento. Também é recomendado não solicitar mais de uma permissão por vez para que o usuário entenda qual funcionalidade requer acesso.
O Android define vários grupos de permissões perigosas, cada um contendo uma ou mais constantes. A lista mais completa está disponível na classe Manifest.permission. Abaixo estão os principais grupos e permissões usados no desenvolvimento.
| Grupo Permission Group | Permissões | API de acesso |
|---|---|---|
| CAMERA | CAMERA | Camera API, CameraX |
| LOCATION | ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION | FusedLocationProvider, Geofence |
| MICROPHONE | RECORD_AUDIO | MediaRecorder, AudioRecord |
| PHONE | READ_PHONE_STATE, CALL_PHONE, READ_CALL_LOG | TelephonyManager |
| CONTACTS | READ_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTS | ContactsContract |
| SMS | READ_SMS, SEND_SMS, RECEIVE_SMS | SmsManager |
| STORAGE | READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE | MediaStore, File API |
| CALENDAR | READ_CALENDAR, WRITE_CALENDAR | CalendarContract |
A partir do Android 12, o Google endureceu os requisitos para algumas permissões. Por exemplo, BLUETOOTH_CONNECT e BLUETOOTH_SCAN se tornaram perigosas e exigem solicitação em tempo de execução. A permissão BODY_SENSORS_BACKGROUND também foi adicionada para acesso em segundo plano a sensores. Os desenvolvedores precisam atualizar o targetSdkVersion e testar as solicitações nas versões atuais do SO.
O Android 13 (API 33) introduziu novas permissões para notificações (POST_NOTIFICATIONS) e arquivos de mídia (READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO), substituindo o READ_EXTERNAL_STORAGE geral. Agora o acesso a fotos, vídeos e áudio é solicitado separadamente através de permissões especializadas sem um único diálogo.
As permissões Dangerous e Normal diferem fundamentalmente na forma de concessão, possibilidade de revogação e UX. Normal é concedida automaticamente durante a instalação, Dangerous exige um diálogo explícito em tempo de execução. Normal não pode ser revogada através das configurações, Dangerous pode ser desativada a qualquer momento. Essa assimetria cria diferentes padrões de desenvolvimento.
Do ponto de vista do código, as permissões perigosas exigem mais trabalho: checkSelfPermission, requestPermissions, tratamento de negação. Para as normais, basta uma linha no AndroidManifest.xml. No entanto, Dangerous Permission dá controle ao usuário, o que aumenta a confiança, especialmente para funcionalidades sensíveis como câmera ou localização.
A escolha entre categorias não cabe ao desenvolvedor — é determinada pelo sistema. O desenvolvedor apenas declara uses-permission, e o sistema determina a categoria com base no protectionLevel. No entanto, a estratégia de solicitação de permissões perigosas afeta a experiência do usuário: diálogos frequentes ou inadequados diminuem a classificação do aplicativo.
A forma moderna de solicitar permissões em Kotlin é usar ActivityResultContracts.RequestMultiplePermissions ou RequestPermission. Esses contratos fazem parte da biblioteca androidx.activity e fornecem uma API limpa baseada em lambdas, sem necessidade de sobrescrever onRequestPermissionsResult.
class CameraActivity : AppCompatActivity() {
private val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
openCamera()
} else {
showPermissionDeniedMessage()
}
}
fun requestCamera() {
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED ->
openCamera()
ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.CAMERA
) ->
showRationaleDialog()
else ->
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
}
}
Quando um aplicativo precisa de várias permissões perigosas ao mesmo tempo, use RequestMultiplePermissions. O contrato retorna Map<String, Boolean> onde a chave é o nome da permissão e o valor é o resultado. Isso é útil no primeiro lançamento quando você precisa solicitar CAMERA e RECORD_AUDIO para gravação de vídeo.
Se o usuário negar a solicitação, o método shouldShowRequestPermissionRationale retorna true. Isso sinaliza que é necessário mostrar uma explicação de por que a permissão é necessária. A melhor prática é mostrar um diálogo personalizado com uma explicação e um botão Tentar Novamente. Se o usuário negar a solicitação novamente com a caixa Never Ask Again marcada, shouldShowRequestPermissionRationale retornará false, e você precisa redirecionar para Configurações.
Never Ask Again é uma flag que o usuário pode definir ao recusar o diálogo em tempo de execução pela segunda vez. Depois disso, o diálogo padrão não é mais mostrado para essa permissão. A única forma de conceder acesso é redirecionar o usuário para as configurações do sistema de aplicativos.
O desenvolvedor precisa distinguir entre dois cenários de negação: primeiro, quando shouldShowRequestPermissionRationale retorna true (o usuário recusou mas o diálogo ainda pode ser mostrado), e segundo, quando o método retorna false (Never Ask Again está ativo ou a permissão está bloqueada por política). No segundo caso, você deve mostrar um botão Abrir Configurações.
fun handlePermissionDenied(permission: String) {
if (ActivityCompat.shouldShowRequestPermissionRationale(
this, permission
)) {
showRationaleDialog(permission)
} else {
showSettingsRedirectDialog(permission)
}
}
private fun showSettingsRedirectDialog(permission: String) {
AlertDialog.Builder(this)
.setTitle("Acesso negado")
.setMessage(
"Permissão bloqueada. Abra Configurações."
)
.setPositiveButton("Configurações") { _, _ ->
val intent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts(
"package", packageName, null
)
)
startActivity(intent)
}
.show()
}
É importante não solicitar a permissão novamente se shouldShowRequestPermissionRationale retornou false. Uma chamada repetida a requestPermissions neste caso não mostrará um diálogo — o resultado virá imediatamente com DENIED sem explicação. O usuário encontrará um comportamento confuso, o que afeta negativamente a experiência de uso do aplicativo.
Perguntas frequentes
As permissões perigosas incluem permissões com ProtectionLevel dangerous: CAMERA, RECORD_AUDIO, ACCESS_FINE_LOCATION, READ_CONTACTS, READ_SMS, READ_CALENDAR e outras. A lista completa está disponível na classe Manifest.permission.
Use ContextCompat.checkSelfPermission, passando o contexto e o nome da permissão. O método retorna PERMISSION_GRANTED ou PERMISSION_DENIED. A verificação deve ser realizada antes de cada chamada de API que exija uma permissão perigosa.
Um Permission Group agrupa permissões perigosas relacionadas. Se um usuário concede uma permissão de um grupo, as demais são concedidas automaticamente. Por exemplo, LOCATION inclui ACCESS_FINE_LOCATION e ACCESS_COARSE_LOCATION.
Verifique shouldShowRequestPermissionRationale após a negação. Se o método retornar false e a permissão ainda não foi concedida — Never Ask Again está ativo. Redirecione o usuário para Configurações via Intent com ACTION_APPLICATION_DETAILS_SETTINGS.
Sim, elas permanecem obrigatórias. No Android 13+, algumas permissões mudaram: POST_NOTIFICATIONS se tornou uma permissão de tempo de execução separada, e READ_EXTERNAL_STORAGE foi substituído por READ_MEDIA_IMAGES para acesso granular a arquivos de mídia.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também