You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:20:33