Android 13中如何申请访问PDF等文件的权限?
Android 13 目标版本下非媒体文件的权限适配方案
当应用的targetSdkVersion设置为33(Android 13)时,原有的READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限已被废弃,必须使用新的权限体系。官方文档主要覆盖了媒体文件的细分权限,但对于非媒体文件(如文档、压缩包等)的处理说明较少,以下是具体适配方案:
一、媒体文件权限替换
如果仅需访问图片、视频或音频等媒体文件,直接使用对应的细分权限即可,无需申请写入权限(Android 13默认允许对媒体文件的写入操作):
- 访问图片:
READ_MEDIA_IMAGES - 访问视频:
READ_MEDIA_VIDEO - 访问音频:
READ_MEDIA_AUDIO
二、非媒体文件的权限处理
对于非媒体文件,有两种主流适配方案:
方案1:使用MANAGE_EXTERNAL_STORAGE权限(特殊权限)
该权限允许应用全面访问设备存储,但属于特殊权限,需要在Google Play审核时说明用途,仅适合文件管理器类等确实需要全局存储访问的应用。
- 权限声明:在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" /> - 申请方式:无法通过常规权限弹窗申请,需引导用户跳转到系统设置页面手动开启:
fun requestManageStoragePermission(activity: Activity) { val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).apply { data = Uri.parse("package:${activity.packageName}") } activity.startActivityForResult(intent, REQUEST_CODE_MANAGE_STORAGE) }
方案2:使用存储访问框架(SAF,推荐)
这是Android官方推荐的方式,无需申请任何存储权限,通过让用户手动选择文件或目录来获取访问权限,符合隐私规范,适合大多数仅需访问特定文件的应用。
修改原有的权限申请逻辑,改用SAF实现文件选择:
private lateinit var documentPickerLauncher: ActivityResultLauncher<Intent> private var permissionSuccessCallback: ((FileData?) -> Unit)? = null // 初始化文件选择器 fun initDocumentPicker(activity: Activity) { documentPickerLauncher = activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { val uri = result.data?.data permissionSuccessCallback?.invoke(uri?.let { FileData(it) }) } else { permissionSuccessCallback?.invoke(null) } } } // 发起文件选择请求 fun requestFileAccess(callback: (FileData?) -> Unit) { permissionSuccessCallback = callback val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) // 设置允许选择的文件类型,*/*表示所有文件,可根据需求修改为特定类型(如application/pdf) type = "*/*" } documentPickerLauncher.launch(intent) }
修改点击事件逻辑:
binding.tvUploadDoc.setOnClickListener { fileUtils.requestFileAccess { result -> if (result == null) { displayNeverAskAgainDialog(langData?.dialogsStrings?.storagePermissions.getSafe()) } else { file = result.uri.let { uri -> uri?.let { fileUtils.getMimeType(requireContext(), uri)?.let { mimeType -> fileUtils.copyUriToFile( requireContext(), it, fileUtils.getFileNameFromUri(requireContext(), uri), mimeType ) } } } saveFile() } } }
方案对比
- MANAGE_EXTERNAL_STORAGE:权限范围大,但审核门槛高,不适合普通应用
- 存储访问框架(SAF):无需权限、用户授权透明,符合Android隐私政策,是大多数应用的首选方案
内容的提问来源于stack exchange,提问作者Shafiq ur Rehman
相关产品推荐
相关产品推荐

