Android 앱을 개발하다 보면 “이 기능을 쓸 때 사용자에게 권한 동의를 받아야 하나?”가 자주 헷갈립니다.

갤러리에서 사진을 가져오거나 카메라로 촬영하는 기능도 어떤 API를 쓰느냐에 따라 권한이 필요한 경우와 아닌 경우가 나뉩니다.

이 글에서는 자주 쓰이는 기능별로 런타임 권한이 필요한 방식과 필요 없는 방식을 나눠서 정리합니다.

먼저 알아야 할 것: Android 권한의 두 단계

Android 6.0(API 23)부터 권한은 두 단계로 작동합니다.

  1. 매니페스트 선언AndroidManifest.xml<uses-permission>으로 선언
  2. 런타임 요청 — 앱 실행 중 사용자에게 동의를 받음

매니페스트에 선언만 하고 런타임 요청을 안 하면, 해당 권한이 필요한 API를 호출할 때 SecurityException이 발생할 수 있습니다.

갤러리 (사진/동영상 선택)

권한 필요 없음: Photo Picker

val pickMedia = rememberLauncherForActivityResult(
    ActivityResultContracts.PickVisualMedia()
) { uri ->
    // 선택한 사진의 URI
}

pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
  • Android 13부터 기본 제공, 그 이전 버전은 Google Play Services로 자동 백포트
  • 사용자가 피커에서 선택한 미디어만 URI로 전달되므로 저장소 권한 불필요
  • READ_EXTERNAL_STORAGEREAD_MEDIA_IMAGES 선언 없이 사용 가능
  • Google이 공식적으로 권장하는 방식

권한 필요함: 직접 MediaStore 조회

// 이 방식은 권한이 필요함
val cursor = contentResolver.query(
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
    projection, selection, selectionArgs, sortOrder
)
  • 앱이 기기의 전체 미디어를 직접 조회하는 방식
  • Android 12 이하: READ_EXTERNAL_STORAGE 필요
  • Android 13 이상: READ_MEDIA_IMAGES 필요
  • Google Play 정책상 이 권한을 왜 필요로 하는지 정당화해야 함
  • 갤러리 앱이나 사진 편집 앱처럼 전체 미디어에 접근해야 하는 경우에만 사용

정리

방식 권한 권장 여부
Photo Picker (PickVisualMedia) 불필요 권장
MediaStore 직접 조회 READ_EXTERNAL_STORAGE 또는 READ_MEDIA_IMAGES 갤러리 앱 등 특수 목적만

카메라 (사진 촬영)

권한 필요 없음: 시스템 카메라 인텐트

val takePicture = rememberLauncherForActivityResult(
    ActivityResultContracts.TakePicture()
) { success ->
    // 촬영 성공 여부
}

// FileProvider로 만든 URI 전달
takePicture.launch(photoUri)
  • 시스템 카메라 앱을 띄우고, 촬영 결과만 URI로 받아오는 방식
  • 앱이 카메라 하드웨어에 직접 접근하지 않으므로 CAMERA 권한 불필요
  • 매니페스트에 CAMERA 권한을 선언하지 않아야 함 (아래 주의사항 참고)

권한 필요함: Camera2 / CameraX 직접 접근

// 이 방식은 권한이 필요함
val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
cameraManager.openCamera(cameraId, callback, handler)
  • 앱이 카메라 하드웨어를 직접 제어 (프리뷰, 촬영, 필터 등)
  • CAMERA 권한 필수 (매니페스트 선언 + 런타임 요청)
  • 인스타그램, 스냅챗처럼 앱 내에서 카메라 화면을 직접 보여줘야 할 때 사용

주의: 매니페스트에 CAMERA를 선언하면 생기는 문제

시스템 카메라 인텐트(TakePicture())를 사용할 때 중요한 주의사항이 있습니다.

AndroidManifest.xmlCAMERA 권한을 선언만 해놓고 런타임에 사용자 동의를 받지 않으면, TakePicture() 인텐트를 실행할 때 SecurityException이 발생합니다.

공식 문서의 설명:

If your app declares that it uses the CAMERA permission which is not granted, then attempting to use this action will result in a SecurityException.

즉, 인텐트 방식만 사용하는 앱이라면 매니페스트에 CAMERA 권한을 아예 선언하지 않는 것이 올바른 방법입니다.

선택지는 두 가지입니다.

  • 매니페스트에서 CAMERA 권한 빼기 (권장) — 인텐트 위임만 쓰면 선언 자체가 불필요. Play Store에서 “카메라 권한 필요” 라벨도 안 붙음
  • 매니페스트에 선언했으면 런타임 요청도 함께 하기 — 인텐트 실행 전에 CAMERA 권한 요청 후, 승인되면 런처 실행

정리

방식 권한 매니페스트 선언 권장 여부
시스템 카메라 인텐트 (TakePicture) 불필요 하지 않음 단순 촬영에 권장
Camera2 / CameraX 직접 접근 CAMERA 필수 필수 앱 내 카메라 UI 필요 시

파일 선택 (문서, PDF 등)

권한 필요 없음: Storage Access Framework (SAF)

val openDocument = rememberLauncherForActivityResult(
    ActivityResultContracts.OpenDocument()
) { uri ->
    // 선택한 문서의 URI
}

openDocument.launch(arrayOf("application/pdf"))
  • 시스템 파일 피커를 통해 사용자가 직접 파일을 선택
  • 저장소 권한 없이 사용 가능
  • ACTION_OPEN_DOCUMENT (장기 접근), ACTION_GET_CONTENT (일회성 가져오기) 제공
  • 디렉터리 단위 접근은 ACTION_OPEN_DOCUMENT_TREE 사용

권한 필요함: 저장소 직접 접근

  • 앱이 파일 시스템을 직접 탐색하는 방식
  • Android 10 이하: READ_EXTERNAL_STORAGE / WRITE_EXTERNAL_STORAGE 필요
  • Android 11 이상: Scoped Storage 적용으로 직접 접근이 제한됨
  • 파일 매니저 앱 등 특수 목적에서만 MANAGE_EXTERNAL_STORAGE 사용

위치 정보

위치는 권한 없이 접근할 수 있는 대안이 없습니다.

권한 정밀도
ACCESS_COARSE_LOCATION 대략적 위치 (약 3km 반경)
ACCESS_FINE_LOCATION 정확한 위치 (GPS)
ACCESS_BACKGROUND_LOCATION 앱이 백그라운드일 때도 위치 접근
  • 매니페스트 선언 + 런타임 요청 필수
  • Android 12 이상에서는 대략적 위치만 허용하는 옵션이 추가됨

알림 (Notification)

Android 버전 권한
12 이하 권한 요청 없이 알림 전송 가능
13 이상 POST_NOTIFICATIONS 런타임 권한 필요

Android 13부터 알림을 보내려면 사용자 동의가 필요합니다.

전체 요약

기능 권한 불필요 (권장) 권한 필요
갤러리 사진 선택 Photo Picker (PickVisualMedia) MediaStore 직접 조회
카메라 촬영 시스템 카메라 인텐트 (TakePicture) Camera2 / CameraX 직접 접근
파일 선택 SAF (OpenDocument) 저장소 직접 접근
위치 정보 대안 없음 ACCESS_FINE_LOCATION
알림 Android 12 이하 Android 13 이상 POST_NOTIFICATIONS

Android 전체 흐름을 보면 권한 없이 사용할 수 있는 API로 대체하는 방향으로 발전하고 있습니다. Photo Picker, SAF, 시스템 카메라 인텐트처럼 사용자가 직접 선택한 항목만 앱에 전달하는 방식이 개인정보 보호와 사용자 경험 모두에서 유리합니다.

앱이 전체 미디어나 카메라 하드웨어에 직접 접근해야 하는 특수한 경우가 아니라면, 권한 없이 동작하는 API를 우선으로 선택하는 것을 권장합니다.

Updated: