Android 跳转系统相册选取图片/视频/音频/文档(适配全版本权限)

Android 跳转系统相册选取图片/视频/音频/文档(适配全版本权限)

一、权限适配说明

Android 11(API 30)及以上、Android 11 以下权限规则不同,Android 13+ 进一步细分媒体权限,需区分图片、视频、音频单独申请。

1. 权限清单(AndroidManifest.xml)

(1)Android 11+(含 Android 13/14)媒体权限
xml 复制代码
<!-- 读取图片 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!-- 读取视频(选视频时添加) -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- 读取音频(选音频时添加) -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<!-- 全局文件访问(可选,需手动跳转系统设置授权) -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
(2)Android 11 以下 存储权限
xml 复制代码
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

说明:代码中权限工具类基于 AndroidUtilCode 框架。

二、动态权限申请代码

1. Android 11+ 选取图片(动态申请)

kotlin 复制代码
PermissionUtils.permission(
    Manifest.permission.READ_MEDIA_IMAGES
).callback { isAllGranted, granted, deniedForever, denied ->
    if (isAllGranted) {
        // 权限通过,跳转相册
        goAlbum()
    } else {
        showError("请授予存储权限")
    }
}.request()

2. Android 11 以下 动态申请

kotlin 复制代码
PermissionUtils.permission(
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.WRITE_EXTERNAL_STORAGE
).callback { isAllGranted, granted, deniedForever, denied ->
    if (isAllGranted) {
        // 权限通过,跳转相册
        goAlbum()
    } else {
        showError("请授予存储权限")
    }
}.request()

补充:选取视频/音频 时,将权限替换为 READ_MEDIA_VIDEO / READ_MEDIA_AUDIO 即可。

三、跳转系统相册/文件选择器

核心方法 goAlbum()

优先使用 ACTION_OPEN_DOCUMENT(限定系统文件,规避异常文件选中问题),不推荐 ACTION_GET_CONTENT

kotlin 复制代码
private fun goAlbum() {
    val albumIntent = Intent(Intent.ACTION_OPEN_DOCUMENT)
    
    // ========== 按需设置文件类型(二选一/组合) ==========
    // 1. 只选图片
    albumIntent.type = "image/*"
    // 2. 只选视频
    // albumIntent.type = "video/*"
    // 3. 只选音频
    // albumIntent.type = "audio/*"
    // 4. 所有文件不限制
    // albumIntent.type = "*/*"

    // 5. 选取多种办公文档(自定义 MimeType)
    /*
    albumIntent.putExtra(
        Intent.EXTRA_MIME_TYPES,
        arrayOf(
            MimeType.DOC,
            MimeType.DOCX,
            MimeType.PDF,
            MimeType.PPT,
            MimeType.PPTX,
            MimeType.XLS,
            MimeType.XLSX,
            MimeType.TXT
        )
    )
    */

    // 开启多选
    albumIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
    // 启动选择器
    startActivityForResult(albumIntent, 100)
}

四、自定义文件 MimeType 常量类

kotlin 复制代码
object MimeType {
    const val DOC: String = "application/msword"
    const val DOCX: String = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
    const val XLS: String = "application/vnd.ms-excel application/x-excel"
    const val XLSX: String = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    const val PPT: String = "application/vnd.ms-powerpoint"
    const val PPTX: String = "application/vnd.openxmlformats-officedocument.presentationml.presentation"
    const val PDF: String = "application/pdf"
    const val TXT: String = "text/plain"
}

五、选择结果回调(onActivityResult)

接收返回的 Uri,通过 UriUtils(AndroidUtilCode)转换为本地文件路径:

kotlin 复制代码
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    // 校验请求码与返回结果
    if (resultCode != RESULT_OK || requestCode != 100) return

    data?.let {
        // Uri 转 File 对象
        val uriFile = UriUtils.uri2File(data.data)
        // 打印文件真实路径
        LogUtils.e("文件路径", uriFile.path)
    }
}

六、补充注意事项

  1. Intent 区别
    • ACTION_OPEN_DOCUMENT:仅选择系统目录文件,安全性高,推荐使用;
    • ACTION_GET_CONTENT:可跳转第三方文件管理器,易选中非法类型文件,不建议使用。
  2. 版本权限对应
    • Android 13+:图片/视频/音频必须分开申请 READ_MEDIA_* 系列权限;
    • Android 11~12:使用媒体权限,也可申请 MANAGE_EXTERNAL_STORAGE 全局文件权限(需引导用户手动开启);
    • Android 10 及以下:传统读写存储权限。
  3. 工具依赖:文中 PermissionUtilsUriUtilsLogUtils 均来自 AndroidUtilCode 开源工具库。
相关推荐
summerkissyou19873 小时前
Android - 摄像头 - hal - 开发教程,例子,常见问题,分析方法,解决方案
android
summerkissyou19874 小时前
Android 16 架构图
android
神龙天舞20014 小时前
MySQL 备库为什么会延迟好几个小时
android·数据库·mysql
weixin_495248406 小时前
短剧视频翻译配音指南:古装、甜宠与悬疑如何本地化?
音视频
禹亮科技7 小时前
制造业100㎡跨国技术评审会议室音视频整体解决方案(亿联+思必驰+讯飞AI落地实践)
人工智能·音视频·视频会议系统集成
有同事要进步8 小时前
gitee上面克隆项目出现错误
gitee
码农coding8 小时前
android12 systemUI 之锁屏
android
潜创微科技8 小时前
HDMI 分配器芯片方案商 IT66630 有源分配芯片方案
音视频
圆山猫8 小时前
[Virtualization](三):RISC-V H-extension 与 Guest 执行模式
android·java·risc-v
爱笑鱼8 小时前
Binder(七):getCallingUid() 读到的是谁?clearCallingIdentity() 又清掉了什么?
android