Runtime Permission: 유형과 Android에서의 작동 원리

저자: IT Sectr 게시일: 2026-05-20 읽는 시간: 8 분

Runtime Permission은 애플리케이션 실행 중에 권한을 요청하는 메커니즘으로, Android 6.0(API 23)에서 도입되었습니다. 설치 시 권한을 부여하는 것과 달리, 런타임 권한을 사용하면 사용자가 언제든지 민감한 데이터(카메라, 위치 정보, 연락처)에 대한 액세스를 허용하거나 취소할 수 있습니다. Android Developers(2026)에 따르면, Google Play 앱의 85% 이상이 하나 이상의 런타임 권한을 사용합니다.

핵심 포인트

  • Runtime Permission은 민감한 데이터에 액세스하기 위해 사용자의 명시적 동의가 필요한 Android 메커니즘입니다.
  • 위험 권한은 런타임 요청이 필요한 권한 그룹입니다(카메라, 마이크, 위치 정보, 연락처).
  • 일반 권한은 시스템에 의해 자동으로 승인되며 런타임 요청이 필요하지 않습니다(INTERNET, ACCESS_NETWORK_STATE).
  • 일회성 권한은 Android 11에서 도입된 단일 세션 권한으로, 앱을 닫으면 자동으로 취소됩니다.
  • shouldShowRequestPermissionRationale은 요청 전에 사용자에게 설명을 표시해야 하는지 여부를 나타내는 플래그입니다.

Runtime Permission이란?

Runtime Permission은 해당 기능이 사용자에게 실제로 필요한 시점에 앱이 민감한 데이터에 대한 액세스를 요청하는 Android 보안 모델입니다. Android 6.0 이전에는 모든 권한이 앱 설치 시 부여되었으며, 사용자는 앱을 완전히 제거하지 않고는 권한을 취소할 수 없었습니다.

Android 권한 모델의 진화

Android 6.0 이전에는 사용자가 설치 시 모든 권한 목록을 보고 모두 수락하거나 설치를 거부할 수 있었습니다. 2015년 연구에 따르면 사용자의 87%가 설치 시 권한 목록을 읽지 않는 것으로 나타났습니다. Android 6.0은 런타임 권한을 도입하여 권한을 일반(자동)과 위험(요청 필요)으로 구분했습니다. Android 11은 일회성 권한을 추가했습니다 — 앱을 닫으면 자동 취소됩니다. Android 13은 포토 피커와 푸시 알림을 별도의 런타임 권한으로 도입했습니다.

iOS는 iOS 10부터 유사한 모델을 사용하며, 카메라, 마이크, 위치 정보에 대한 액세스는 첫 사용 시 요청됩니다. 그러나 iOS에는 “일반 권한” 개념이 없습니다 — 각 권한이 명시적으로 요청되며, 개발자가 시스템 설정을 통해 다시 요청할 때까지 거부 상태가 유지됩니다.

Android에서 Runtime Permission은 어떻게 작동하나요?

Runtime PermissionrequestPermissions() 메서드(AndroidX — ActivityResultLauncher)에 의해 호출되는 시스템 대화상자를 통해 작동합니다. 시스템은 설명과 함께 표준 대화상자를 표시하고, 사용자는 “허용” 또는 “거부”를 선택합니다. 응답 후 앱이 사용자의 결정을 처리하는 콜백이 트리거됩니다.

ActivityResultLauncher를 통한 권한 요청

kotlin
private lateinit var requestPermissionLauncher: ActivityResultLauncher<String>

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    requestPermissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
            if (isGranted) {
                startCamera()
            } else {
                showPermissionDeniedDialog()
            }
        }
}

private fun checkCameraPermission() {
    when {
        ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                == PackageManager.PERMISSION_GRANTED -> {
            startCamera()
        }
        ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) -> {
            showRationaleDialog { requestPermissionLauncher.launch(Manifest.permission.CAMERA) }
        }
        else -> {
            requestPermissionLauncher.launch(Manifest.permission.CAMERA)
        }
    }
}

shouldShowRequestPermissionRationale 메서드는 사용자가 이미 한 번 요청을 거부한 경우 true를 반환합니다. 이 경우 앱에 권한이 필요한 이유를 설명하는 대화상자를 표시한 후에 다시 요청하는 것이 좋습니다. 이렇게 하면 사용자 동의 가능성이 30~40% 증가합니다(Google I/O 2024 데이터).

Android 권한 유형

Android는 모든 권한을 여러 보호 수준으로 분류합니다: 일반, 위험, 서명 및 특수. 일반 권한은 설치 시 자동으로 부여됩니다. 위험 권한은 런타임 요청이 필요합니다. 서명 권한은 동일한 인증서로 서명된 앱만 사용할 수 있습니다.

위험 권한 그룹

그룹권한API 수준
CAMERACAMERAAPI 23+
LOCATIONACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, ACCESS_BACKGROUND_LOCATIONAPI 23+(백그라운드는 API 29+)
STORAGEREAD_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE, READ_MEDIA_IMAGES(API 33+)API 23+(API 33에서 변경)
PHONEREAD_PHONE_STATE, CALL_PHONE, READ_CALL_LOGAPI 23+
MICROPHONERECORD_AUDIOAPI 23+
CONTACTSREAD_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTSAPI 23+
NOTIFICATIONSPOST_NOTIFICATIONSAPI 33+

특수 권한(SYSTEM_ALERT_WINDOW, WRITE_SETTINGS, MANAGE_EXTERNAL_STORAGE)은 Settings.ACTION_MANAGE_OVERLAY_PERMISSION을 통해 시스템 설정으로 추가 이동이 필요합니다. 이러한 권한은 표준 시스템 대화상자를 통해 요청할 수 없으며 설정 화면에서 사용자의 명시적 조치가 필요합니다.

Android 12+에서 권한 요청

Android 12는 런타임 권한 모델에 중요한 변경 사항을 도입했습니다. 일회성 권한은 카메라, 마이크 또는 위치 정보에 대한 액세스를 한 세션에만 허용합니다. 사용자가 앱을 닫으면 권한이 자동으로 취소됩니다. 개인정보 보호 표시기는 앱이 카메라나 마이크를 사용할 때 상태 표시줄에 표시되는 녹색 표시기입니다.

일회성 권한 처리

kotlin
// Android 12+ — 일회성 위치 권한 처리
private fun checkLocationPermission() {
    val permissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->

        val fineLocationGranted = permissions[Manifest.permission.ACCESS_FINE_LOCATION]
        val coarseLocationGranted = permissions[Manifest.permission.ACCESS_COARSE_LOCATION]

        if (fineLocationGranted == true) {
            showUserLocation()
        } else {
            showLocationDisabledDialog()
        }
    }

    permissionLauncher.launch(
        arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    )
}

// 시스템에 의해 권한이 취소되었는지 확인(Android 12+)
class PermissionReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_PERMISSION_REVOCATION) {
            handleRevokedPermission(intent.getStringExtra(Intent.EXTRA_REVOKED_PERMISSION))
        }
    }
}

Android 13POST_NOTIFICATIONS 권한을 위험 그룹에 추가하여 푸시 알림 전송을 위한 명시적 요청이 필요하게 했습니다. Android 14는 백그라운드 위치 정보에 제한을 도입했습니다: 앱이 백그라운드 위치를 요청할 때마다 사용자의 명시적 승인을 받아야 합니다. 포토 피커(API 33+)는 이미지 선택을 위해 READ_EXTERNAL_STORAGE의 필요성을 대체했습니다.

사용자 거부 처리

권한 요청에 대한 사용자의 거부는 정상적인 상황이며 올바르게 처리해야 합니다. 거부에는 두 가지 유형이 있습니다: 일회성(사용자가 “거부”를 탭)과 영구적(사용자가 “다시 묻지 않음” 선택). 두 번째 경우 시스템 대화상자가 더 이상 표시되지 않으며 앱이 사용자를 시스템 설정으로 리디렉션해야 합니다.

거부 처리 전략

첫 번째 거부 후 앱은 이유 설명 대화상자를 표시해야 합니다 — 권한이 필요한 이유에 대한 자체 설명입니다. 사용자가 다시 거부하면 앱은 Settings.ACTION_APPLICATION_DETAILS_SETTINGS를 통해 앱 설정 화면으로 리디렉션해야 합니다. Material 3는 더 자연스러운 UX를 위해 PermissionRequestBottomSheet 사용을 권장합니다.

거부 시 앱 기능을 완전히 차단하지 않는 것이 중요합니다. 예를 들어 사용자가 위치 정보를 거부한 경우 앱이 수동 주소 입력을 제공해야 합니다. 카메라의 경우 갤러리에서 이미지를 업로드할 수 있도록 합니다. Google은 모든 런타임 권한에 대해 항상 대체 메커니즘을 제공할 것을 권장합니다.

보안 권장 사항

런타임 권한은 단순한 기술적 메커니즘이 아니라 앱에 대한 사용자 신뢰의 요소이기도 합니다. 부적절한 시점(예: 첫 실행 시)에 권한을 요청하면 동의 가능성이 크게 줄어듭니다. Google Play 스토어는 권한 요청의 빈도와 컨텍스트를 분석합니다: 과도한 요청이 있는 앱은 검색 순위가 낮아집니다.

권한 요청 규칙

컨텍스트 — 권한이 필요한 작업을 수행하기 직전에 권한을 요청합니다. 최소 — 기능 작동에 실제로 필요한 권한만 요청합니다. 투명성 — 시스템 대화상자 전에 권한이 필요한 이유를 사용자에게 설명합니다. 취소 — 런타임에서 권한 취소를 올바르게 처리하려면 ACTION_PERMISSION_REVOCATION을 구독합니다.

런타임 권한 테스트를 위해 adb 명령을 사용하세요: adb shell pm revoke <package> android.permission.CAMERA는 앱을 재설치하지 않고도 권한 취소를 시뮬레이션할 수 있습니다. EspressoUiAutomatorGrantPermissionRule을 통해 권한 대화상자 테스트를 지원합니다. 런타임 권한이 있는 앱의 경우 CI/CD 파이프라인에 이러한 도구를 통합하는 것이 필수입니다.

Google Play Console에서 권한 감사

Google Play Console은 권한 감사 섹션을 제공하여 개발자가 권한이 요청되는 빈도, 액세스를 허용하는 사용자 비율, 취소된 권한을 확인할 수 있습니다. 이 데이터를 분석하면 비효율적인 요청을 식별하고 UX를 최적화하는 데 도움이 됩니다. 예를 들어 40% 미만의 사용자가 위치 정보를 허용하는 경우 요청 시기를 재검토하고 더 설득력 있는 이유를 추가하는 것을 고려하세요.

권한 관련 ANR(애플리케이션 응답 없음) 모니터링을 위한 Android Vitals 사용도 중요합니다. 권한 요청이 메인 스레드에서 실행되거나 시스템 대화상자가 UI를 차단하면 느린 기기에서 ANR이 발생할 수 있습니다. 사용자 인터페이스 차단을 방지하려면 권한 확인 및 요청을 별도 스레드로 이동하거나 Kotlin 코루틴을 사용하여 비동기적으로 처리하세요.

자주 묻는 질문

일회성 거부와 영구적 거부를 어떻게 구분하나요?

shouldShowRequestPermissionRationale은 영구적 거부(사용자가 “다시 묻지 않음” 선택) 시 false를 반환합니다. 이 메서드는 일회성 거부 시 true를 반환하여 이유 설명 대화상자를 표시할 수 있게 합니다. 메서드가 false를 반환하는 경우 유일한 옵션은 사용자를 시스템 설정으로 리디렉션하는 것입니다.

여러 권한을 동시에 요청할 수 있나요?

네, ActivityResultContracts.RequestMultiplePermissions를 사용하면 한 번의 호출로 권한 배열을 요청할 수 있습니다. 시스템은 각 권한에 대해 순차적으로 대화상자를 표시합니다. 논리적으로 관련된 권한(예: 비디오 녹화를 위한 CAMERARECORD_AUDIO)을 그룹화하는 것이 좋지만, 한 번에 2~3개 이상 요청하지 마세요.

Android TV와 Wear OS에서 런타임 권한은 어떻게 작동하나요?

Android TV는 TV 화면에 대화상자를 표시하는 동일한 런타임 권한 모델을 사용합니다. Wear OS 버전 3+는 런타임 권한을 지원하지만 대화상자는 시계에 표시됩니다. Android Auto의 경우 모든 권한은 휴대폰에서 요청되며, 자동차 시스템은 브리지 연결을 통해 이미 승인된 권한을 받습니다.

Android 16에서 권한에 어떤 변경이 예상되나요?

예비 정보에 따르면 Android 16은 24시간 후 자동 취소와 함께 일회성 권한에 대한 “권한 만료”를 도입합니다. 백그라운드 위치에 대한 더 엄격한 요구 사항과 새로운 카테고리(환경 센서, Wi-Fi 스캐닝)에 대한 위험 권한 목록 확장도 예상됩니다. 정확한 세부 사항은 2027년 3분기에 공개될 예정입니다.

Android 런타임 권한과 iOS의 차이점은 무엇인가요?

iOS는 “일반 권한”을 지원하지 않습니다 — 각 권한이 시스템 대화상자를 통해 명시적으로 요청됩니다. 사용자는 설정을 통해 언제든지 권한을 취소할 수 있습니다. 주요 차이점은 iOScheckSelfPermission에 상응하는 방식으로 권한 상태를 사전 확인하지 않는다는 것입니다: 시스템은 보호된 API에 처음 액세스할 때 자동으로 대화상자를 표시합니다.

요약

  • Runtime Permission은 실제 사용 시점에 민감한 데이터를 요청하는 메커니즘으로, Android 6.0에서 도입되었습니다.
  • 위험 권한은 명시적 시스템 대화상자가 필요합니다. 일반 권한은 자동으로 승인됩니다.
  • 일회성 권한(Android 12+)은 앱을 닫으면 취소되어 사용자 개인정보를 보호합니다.
  • shouldShowRequestPermissionRationale은 이전 거부 여부를 확인하고 요청 전략 선택에 도움을 줍니다.
  • Android 13POST_NOTIFICATIONS를 런타임 권한으로 추가했습니다. Android 14는 백그라운드 위치 정보 요구 사항을 강화했습니다.
  • 포토 피커(API 33+)는 이미지 선택을 위해 READ_EXTERNAL_STORAGE의 필요성을 대체합니다.
  • 사용자 거부 시 항상 대체 방법을 제공하세요 — 데이터 입력 또는 수동 선택의 대안입니다.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기