ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Android 13 - Granular media permissions
    프로그래밍/Android 2022. 5. 23. 16:42
    반응형

    Affected when?

    • Application targets Android 13

     

    Added new permissions

    Android 12 Android 13 

     

    New permissions

    Applications must request one or more new permissions instead of the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions.

    The set of permissions that you request depends on the type(s) of media that your app needs to access:

    Type of media Permission to request Remarks
    Images and photos https://developer.android.com/reference/android/Manifest.permission#READ_MEDIA_IMAGES  
    Videos https://developer.android.com/reference/android/Manifest.permission#READ_MEDIA_VIDEO  
    Audio files https://developer.android.com/reference/android/Manifest.permission#READ_MEDIA_AUDIO  
    Files and documents  https://developer.android.com/reference/android/Manifest.permission#READ_EXTERNAL_STORAGE Recommended set
    android:maxSdkVersion="32"

    Note: You don't need to declare the WRITE_EXTERNAL_STORAGE permission at all anymore. (Scoped storage from Android 10)

     

    Photos & videos

    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

    Music & other audio

    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

    Files and documents

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

     

    In Android 13, 

    If the user previously granted your app the READ_EXTERNAL_STORAGE permission, the system automatically grants each of the new permissions to your app. 

     

    From settings,

    TargetSdkVersion < 33 TargetSdkVersion = 33
    Only have a READ_EXTERNAL_STORAGE permission Adds new permissions,
    changed not to allowed



     
     
     

     

    From runtime permission, 

    TargetSdkVersion < 33 TargetSdkVersion = 33
    Only have a READ_EXTERNAL_STORAGE permission Adds new permissions,
    changed not to allowed
     



     

     

     
     

     

    Read images/videos/audio from File, MediaStore

    Android OS Tiramisu READ_EXTERNAL_STORAGE READ_MEDIA_IMAGES
    READ_MEDIA_VIDEO
      requestLegacyExternalStorage X requestLegacyExternalStorage = true requestLegacyExternalStorage X requestLegacyExternalStorage = true
    TargetSdkVersion < Tiramisu File O
    MediaStore O
    File O
    MediaStore O
    File X
    MediaStore X
    File X
    MediaStore X
    TargetSdkVersion = Tiramisu File X
    MediaStore X
    File X
    MediaStore X
    File O
    MediaStore O
    File O
    MediaStore O

     

    Read files File, MediaStore?

    • Android 10 can access a pdf file with File class (OK) (requestLegacyExternalStorage, READ_EXTERNAL_STORAGE Permission)
    • Android 11 can't access a pdf file with File class (NOT OK) (requestLegacyExternalStorage, READ_EXTERNAL_STORAGE Permission)
      • but a file picker is OK (without READ_EXTERNAL_STORAGE Permission)

     

    How to fix

    // app/build.gradle
    android {
        compileSdkPreview "Tiramisu"
        defaultConfig {
            applicationId "com.example.examplefgs"
            minSdk 21
            targetSdkPreview "Tiramisu"
    }
    // AndroidManifest.xml
    <manifest ...>
        <!-- Required only if your app targets Android 13. -->
        <!-- Declare one or more the following permissions only if your app needs
        to access data that's protected by them. -->
        <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
        <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
        <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
    
        <!-- Required to maintain app compatibility. -->
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
                         android:maxSdkVersion="32" />
        <application ...>
            ...
        </application>
    </manifest>

     

    ExampleMainActivity.kt

    class ExampleMainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_storage_permission)
    
            val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                READ_IMAGE_PERMISSIONS
            } else {
                DEPRECATED_READ_PERMISSIONS
            }
            if (isNeedRequestImagePermissions()) {
                requestPermissions(permissions)
                return
            }
        }
        
        private fun isNeedRequestImagePermissions(): Boolean =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                checkSelfPermission(
                    Manifest.permission.READ_MEDIA_IMAGES
                ) != PackageManager.PERMISSION_GRANTED
            } else {
                checkSelfPermission(
                    Manifest.permission.READ_EXTERNAL_STORAGE
                ) != PackageManager.PERMISSION_GRANTED
            }
    
        private fun isNeedRequestVideoPermissions(): Boolean =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                checkSelfPermission(
                    Manifest.permission.READ_MEDIA_VIDEO
                ) != PackageManager.PERMISSION_GRANTED
            } else {
                checkSelfPermission(
                    Manifest.permission.READ_EXTERNAL_STORAGE
                ) != PackageManager.PERMISSION_GRANTED
            }
    
        private fun isNeedRequestAudioPermissions(): Boolean =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                checkSelfPermission(
                    Manifest.permission.READ_MEDIA_AUDIO
                ) != PackageManager.PERMISSION_GRANTED
            } else {
                checkSelfPermission(
                    Manifest.permission.READ_EXTERNAL_STORAGE
                ) != PackageManager.PERMISSION_GRANTED
            }
            
        companion object {
            private val DEPRECATED_READ_PERMISSIONS = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
    
            private val READ_IMAGE_PERMISSIONS = arrayOf(Manifest.permission.READ_MEDIA_IMAGES)
            private val READ_VIDEO_PERMISSIONS = arrayOf(Manifest.permission.READ_MEDIA_VIDEO)
            private val READ_AUDIO_PERMISSIONS = arrayOf(Manifest.permission.READ_MEDIA_AUDIO)
        }
    }

     

     

    https://developer.android.com/about/versions/11/privacy/permissions

    https://developer.android.com/about/versions/13/behavior-changes-13#:~:text=Granular%20media%20permissions,-Figure%201.&text=If%20the%20user%20previously%20granted,shown%20in%20the%20preceding%20table.

    https://proandroiddev.com/notification-runtime-permission-android13-190c796254d5

    반응형
Designed by Tistory.