위험(dangerous) 권한을 실행 중에 사용자에게 요청하는 절차.
- normal — 설치 시 자동 승인 (INTERNET · VIBRATE · ACCESS_NETWORK_STATE)
- dangerous — 실행 중 사용자 동의 필요 (CAMERA · 위치 · 연락처 · 알림)
- signature — 같은 키로 서명된 앱만
private val launcher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted -> if (granted) openCamera() else showRationale() }
when {
ContextCompat.checkSelfPermission(this, CAMERA) == PERMISSION_GRANTED -> openCamera()
shouldShowRequestPermissionRationale(CAMERA) -> showWhyDialog() // 한 번 거부했다
else -> launcher.launch(CAMERA)
}
세 갈래를 다 처리해야 한다
-
허용됨 — 바로 진행
-
거부했지만 재요청 가능 — 왜 필요한지 설명하고 다시 묻는다
-
영구 거부 — 시스템 다이얼로그가 안 뜬다 → 설정으로 안내한다
-
세 번째를 빠뜨리면 "버튼을 눌러도 아무 일도 안 일어나는" 앱이 된다
// 영구 거부 판별 — 요청했는데 다이얼로그가 안 뜨고 바로 false 가 온 경우
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null)).let(::startActivity)
언제든 취소될 수 있다
-
사용자가 설정에서 권한을 끄면
- Android 11+ 는 앱 프로세스를 종료한다
- "오래 안 쓴 앱" 은 권한이 자동 해제된다 (자동 초기화)
-
권한은 '한 번 받으면 끝' 이 아니다. 쓰기 직전에 늘 확인한다
버전별로 늘어난 것들
- Android 11 — 위치 '이번만 허용' · 백그라운드 위치는 별도 화면에서 재요청
- Android 12 — 대략적/정확한 위치 선택 · 근처 기기 권한 분리
- Android 13 — POST_NOTIFICATIONS 가 런타임 권한이 됐다
- READ_EXTERNAL_STORAGE 가 미디어 타입별로 쪼개졌다
- Android 14 — 부분 미디어 접근 (사진 몇 장만 선택)
권한을 아예 피하는 길
- 사진 선택 — Photo Picker (ACTION_PICK_IMAGES) → 저장소 권한 불필요
- 파일 선택 — Storage Access Framework → 권한 불필요
- 연락처 선택 ContactsContract 의 피커 인텐트 → 권한 불필요
"권한을 요청하지 않고 같은 목적을 이루는 API 가 있는가" 를 먼저 본다
면접 함정
- ❌ "매니페스트에 선언하면 쓸 수 있다" → dangerous 권한은 런타임 요청이 필수다.
- ❌ "한 번 허용하면 영구다" → 자동 초기화와 사용자 회수가 있다.
Compose에서의 권한 처리
val permissionState = rememberPermissionState(Manifest.permission.CAMERA)
when {
permissionState.status.isGranted -> CameraPreview()
permissionState.status.shouldShowRationale -> RationaleCard(
onRequest = { permissionState.launchPermissionRequest() }
)
else -> LaunchedEffect(Unit) { permissionState.launchPermissionRequest() }
}
// implementation("com.google.accompanist:accompanist-permissions:...")
요청 시점 설계
❌ 앱 첫 실행에 권한 5개를 연속으로 묻는다
- 맥락이 없어 대부분 거부하고, 영구 거부로 굳는다
✅ 그 기능을 쓰려는 순간에 묻는다 "사진을 첨부하려면 카메라 권한이 필요합니다" 를 먼저 보여 주고 사용자가 '계속' 을 누르면 시스템 다이얼로그를 띄운다
한 번 영구 거부되면 되돌리려면 사용자가 설정에 들어가야 한다 — 첫 요청이 사실상 유일한 기회다
권한 없이도 동작하는 경로
권한이 없다고 기능을 막지 않는다
카메라 거부 → 갤러리에서 선택하는 경로를 남긴다
위치 거부 → 주소를 직접 입력하게 한다
알림 거부 → 앱 안에서 배지로 알린다
"권한을 안 주면 못 쓴다" 는 앱은 삭제된다