Android 13设备上READ_EXTERNAL_STORAGE权限始终被拒绝问题
解决方案
问题根源
Android 13(API 33)对存储权限做了拆分,即便你的应用目标API是32,直接请求READ_EXTERNAL_STORAGE时,系统权限回调会出现兼容性问题——虽然设置里媒体权限已授予,但RequestMultiplePermissions()仍会返回PERMISSION_DENIED。这是因为Android 13不再将媒体权限状态映射回旧的READ_EXTERNAL_STORAGE权限的回调结果中。
修复步骤
更新Manifest权限声明
同时声明旧版存储权限和Android 13的媒体权限,并限制旧权限仅在API 32及以下生效:<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <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" />分版本请求权限
不要统一请求READ_EXTERNAL_STORAGE,根据系统版本切换请求的权限集合:val permissionsToRequest = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { arrayOf( Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_AUDIO, Manifest.permission.READ_MEDIA_VIDEO ) } else { arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE) } // 发起权限请求 registerForActivityResult(RequestMultiplePermissions()) { results -> // 处理权限结果 val hasAccess = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { results[Manifest.permission.READ_MEDIA_IMAGES] == true || results[Manifest.permission.READ_MEDIA_AUDIO] == true || results[Manifest.permission.READ_MEDIA_VIDEO] == true } else { results[Manifest.permission.READ_EXTERNAL_STORAGE] == true } if (hasAccess) { // 打开图库逻辑 } }.launch(permissionsToRequest)兼容已授予的媒体权限
如果用户已经在设置里授予了媒体权限,直接跳过权限请求逻辑进入图库:fun hasMediaAccess(): Boolean { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_AUDIO) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED } else { ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED } }
关键提醒
- 不要在Android 13设备上单独请求
READ_EXTERNAL_STORAGE,系统不会正确返回授权状态。 - 权限结果判断必须和请求的权限对应,不要依赖旧权限的返回值判断媒体访问权限。
内容的提问来源于stack exchange,提问作者Omar Assidi
相关产品推荐
相关产品推荐

