Android 13의 변경사항으로, 새로운 미디어 파일 접근 권한이 추가되었습니다.
Android developer에서 소개된 자료는 세분화된 미디어 권한입니다.
1. 세분화된 미디어 파일 권한
이 변경사항은 Android 13 이상(API 33 or higher)을 타겟팅하는 앱을 대상으로 적용됩니다.
주요 내용은 미디어 파일 전체에 접근할 수 있는 READ_EXTERNAL_STORAGE
권한이 더 이상 사용되지 않고, 3개 권한으로 분리되었습니다.
- READ_MEDIA_IMAGES : 이미지, 사진 파일 접근 권한
- READ_MEDIA_VIDEO : 비디오 파일 접근 권한
- READ_MEDIA_AUDIO : 오디오 파일 접근 권한
따라서, 타겟 API가 33 이상인 앱은 READ_EXTERNAL_STORAGE
를 사용하지 말고, 필요에 따라서 3개의 권한을 사용자에게 요청하셔야 합니다.
2. Android 13에서 API 32 이하 앱의 동작 방식
새로운 미디어 파일 권한에 대한 변경사항은 타겟 API 33 이상 앱에 적용된다고 하였습니다. 하지만 API 32 이하 앱도 3개의 권한을 갖게되고, 실제로 이 권한으로 파일에 접근하게 됩니다.
다시 설명하면, 시스템은 API 32 이하 앱이 READ_EXTERNAL_STORAGE
권한을 갖고 있을 때, 3개 권한을 모두 부여해줍니다.
만약 앱이 READ_EXTERNAL_STORAGE
권한을 사용자에게 요청하여 권한을 받게 되면, 시스템은 3개의 권한을 앱에게 모두 부여해줍니다.
신규 파일 권한은 API 33에서 공개되었기 때문에, API 32 이하 앱은 이 권한의 존재를 알지 못하기 떄문에 직접 추가할 수 없습니다. 따라서 시스템이 자동으로 추가해주고 있습니다.
실제로 API 32 이하 앱에서 아래와 같은 코드로 READ_EXTERNAL_STORAGE
권한을 요청하면,
requestPermissions(
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
REQUEST_CODE)
다음과 같이 3개 권한에 대해서 모두 요청합니다. 팝업에서 Allow
버튼을 누르면 3개 권한이 모두 부여됩니다.
App 정보의 퍼미션 설정 화면에서는 아래와 같이 두개 항목 보여집니다. (비디오와 이미지 권한이 하나의 항목으로 합쳐짐)
권한이 부여되었을 때 adb 명령어로 권한 정보를 확인해보면, 아래와 같이 4개 퍼미션이 부여된 것을 볼 수 있습니다. (READ_EXTERNAL_STORAGE는 더 이상 파일 접근 권한이 없지만, 단순히 하위 호환성을 유지하기 위해 추가됨)
$ adb shell dumpsys package com.example.myapplication
Packages:
Package [com.example.myapplication] (68288f6):
versionCode=1 minSdk=23 targetSdk=31
...
runtime permissions:
android.permission.POST_NOTIFICATIONS: granted=false
android.permission.READ_EXTERNAL_STORAGE: granted=true
android.permission.READ_MEDIA_IMAGES: granted=true
android.permission.READ_MEDIA_AUDIO: granted=true
android.permission.READ_MEDIA_VIDEO: granted=true
한가지 더 알고 있어야할 것은, API 32 이하 앱의 경우, 사용자가 App 정보의 퍼미션 화면에서 Music and audio
권한을 회수해도 Photo and video
및 READ_EXTERNAL_STORAGE
권한이 모두 회수됩니다.
이 앱들은 READ_EXTERNAL_STORAGE
권한만 갖고 있기 때문에, 세분화된 퍼미션 중에 하나만 부여가 안되었을 때 대처를 할 수 없기 때문입니다. 그렇기 때문에 시스템은 모든 퍼미션을 회수합니다.
반면에 API 33 이상 앱은 3개 퍼미션에 대해서 따로 권한을 요청하고 있고, 각각의 퍼미션에 대해서 예외처리가 되어있기 때문에 별개로 권한을 부여, 회수할 수 있습니다.
3. Android 13에서 API 33 이상 앱의 동작 방식
API 33 이상 앱이 READ_EXTERNAL_STORAGE
권한을 앱에 선언하고 아래와 같은 코드로 사용자에게 권한을 요청해도 팝업이 발생하지 않습니다.
READ_EXTERNAL_STORAGE
권한은 이제 deprecated되어 사용되지 않기 때문입니다.
requestPermissions(
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
REQUEST_CODE)
또한, API 33 이상 앱은 새로운 미디어 권한을 모두 알고 있기 때문에, READ_EXTERNAL_STORAGE
권한을 앱에 선언해도 시스템이 자동으로 3개 권한을 추가해주지 않습니다.
필요하다면 앱이 아래와 같이 직접 권한을 선언해야 합니다.
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
그리고 권한을 요청할 때는, 아래와 같이 3개 퍼미션을 한번에 요청하거나, 필요할 때 따로 요청할 수 있습니다.
요청 팝업은 Music and audio
와 Photo and video
항목에 대해서 두번 발생합니다.
requestPermissions(
arrayOf(Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_MEDIA_VIDEO,
Manifest.permission.READ_MEDIA_IMAGES),
REQUEST_CODE)
마지막으로, App 정보의 Permissions 설정 화면에서 사용자가 일부 퍼미션을 회수해도, 다른 미디어 파일 권한은 회수되지 않습니다. 앱은 회수된 퍼미션에 대해서 확인이 가능하며, 필요 시 사용자에게 퍼미션이 필요하다고 설명하여 설정에서 변경하도록 요청할 수 있습니다.
4. Android 13으로 업그레이드 시, 기존 앱의 동작 방식
디바이스가 Android 13으로 업그레이드 할 때, API 32 이하 앱들은 어떻게 될까요?
READ_EXTERNAL_STORAGE
권한을 갖고 있는 API 32 이하 앱은 새로운 미디어 퍼미션 3개가 모두 부여됩니다.
따라서, Android 13으로 업그레이드 후 다시 요청할 필요가 없습니다.
Related Posts
- Android 14 - 사진/동영상 파일, 일부 접근 권한 소개
- Android - adb push, pull로 파일 복사, 다운로드
- Android 14 - 암시적 인텐트 변경사항 및 문제 해결
- Jetpack Compose - Row와 Column
- Android 13, AOSP 오픈소스 다운로드 및 빌드
- Android 13 - 세분화된 미디어 파일 권한
- Android 13에서 Notification 권한 요청, 알림 띄우기
- Android 13에서 'Access blocked: ComponentInfo' 에러 해결
- 에러 해결: android gradle plugin requires java 11 to run. you are currently using java 1.8.
- 안드로이드 - 코루틴과 Retrofit으로 비동기 통신 예제
- 안드로이드 - 코루틴으로 URL 이미지 불러오기
- Android - 진동, Vibrator, VibrationEffect 예제
- Some problems were found with the configuration of task 에러 수정
- Query method parameters should either be a type that can be converted into a database column or a List
- 우분투에서 Android 12 오픈소스 다운로드 및 빌드
- Android - ViewModel을 생성하는 방법
- Android - Transformations.map(), switchMap() 차이점
- Android - Transformations.distinctUntilChanged() 소개
- Android - TabLayout 구현 방법 (+ ViewPager2)
- Android - 휴대폰 전화번호 가져오는 방법
- Android 12 - Splash Screens 알아보기
- Android 12 - Incremental Install (Play as you Download) 소개
- Android - adb 명령어로 bugreport 로그 파일 추출
- Android - adb 명령어로 App 데이터 삭제
- Android - adb 명령어로 앱 비활성화, 활성화
- Android - adb 명령어로 특정 패키지의 PID 찾기
- Android - adb 명령어로 퍼미션 Grant 또는 Revoke
- Android - adb 명령어로 apk 설치, 삭제
- Android - adb 명령어로 특정 패키지의 프로세스 종료
- Android - adb 명령어로 screen capture 저장
- Android - adb 명령어로 System 앱 삭제, 설치
- Android - adb 명령어로 settings value 확인, 변경
- Android 12 - IntentFilter의 exported 명시적 선언
- Android - adb 명령어로 공장초기화(Factory reset)
- Android - adb logcat 명령어로 로그 출력