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

Android 11+如何通过作用域存储访问/sdcard/Android/media文件夹

Android 11+ 无需MANAGE_EXTERNAL_STORAGE访问其他应用Android/media目录媒体文件方案

核心原理

Android 11(API 30)引入的作用域存储规则中,应用申请媒体读取权限后,可通过系统媒体库(MediaStore)读取所有其他应用存储在公共存储区域的媒体类文件(图片/视频/音频)。而第三方应用存放在/storage/emulated/0/Android/media/对应包名下的媒体文件会自动被系统收录到MediaStore,因此无需申请全文件管理权限即可访问。

前置权限配置

在AndroidManifest.xml中根据目标SDK版本声明对应权限:

  • targetSdk ≤ 32:仅需声明读取外部存储权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  • targetSdk ≥ 33:需声明对应细粒度媒体权限
<!-- 读取图片权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!-- 读取视频权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

应用运行时主动申请上述权限,用户授权后即可执行后续查询操作。

通过MediaStore查询目标目录媒体文件(以WhatsApp状态目录为例)

不要直接使用File API访问目标路径(Android 11+会直接触发权限错误),而是通过ContentResolver查询MediaStore,过滤相对路径即可拿到.Statuses目录下的所有图片、视频文件:

查询代码示例(Kotlin)

// 要查询的目标相对路径
val targetRelativePath = "Android/media/com.whatsapp/WhatsApp/Media/.Statuses/"

// 查询的列信息
val projection = arrayOf(
    MediaStore.MediaColumns._ID,
    MediaStore.MediaColumns.DISPLAY_NAME,
    MediaStore.MediaColumns.MIME_TYPE,
    MediaStore.MediaColumns.SIZE,
    MediaStore.MediaColumns.DATE_MODIFIED
)

// 查询条件:匹配相对路径
val selection = "${MediaStore.MediaColumns.RELATIVE_PATH} = ?"
val selectionArgs = arrayOf(targetRelativePath)

// 先查图片
val imageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
contentResolver.query(imageUri, projection, selection, selectionArgs, null)?.use { cursor ->
    while (cursor.moveToNext()) {
        val fileId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
        val fileUri = ContentUris.withAppendedId(imageUri, fileId)
        // 拿到fileUri即可读取文件内容、显示图片等
    }
}

// 再查视频,逻辑和图片一致
val videoUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
contentResolver.query(videoUri, projection, selection, selectionArgs, null)?.use { cursor ->
    while (cursor.moveToNext()) {
        val fileId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
        val fileUri = ContentUris.withAppendedId(videoUri, fileId)
        // 处理视频文件
    }
}

备用方案:存储访问框架(SAF)授权

如果部分设备或特殊目录下MediaStore查询不到内容,可以引导用户手动授权目标文件夹访问权限,授权后可持久化访问该目录下的所有文件,同样不需要全文件管理权限:

  1. 调用系统文件选择器,定位到/storage/emulated/0/Android/media/com.whatsapp/WhatsApp/Media/.Statuses/目录
  2. 用户确认授权后,拿到对应目录的Uri,通过DocumentFile即可访问目录下的所有文件
  3. 调用takePersistableUriPermission方法持久化权限,下次启动应用无需重复授权

注意事项

  • 该方案仅支持读取媒体类文件,非媒体格式的文件无法通过MediaStore获取
  • 仅做读取操作无需额外权限,如果需要修改、删除其他应用的媒体文件,需要额外申请WRITE_EXTERNAL_STORAGE(targetSdk≤32)或者触发用户交互确认
  • 不要尝试直接通过File路径读写Android目录下的文件,所有操作必须基于MediaStore返回的Uri或者SAF授权拿到的Uri执行

内容的提问来源于stack exchange,提问作者Shrinidhi K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:54:02