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

Android 11不使用MANAGE_EXTERNAL_STORAGE如何获取外部存储全部图片视频

适配Android 11+媒体资源读取的正确实现方案

如果你的应用仅需要读取公共目录下的图片、视频类媒体资源,完全不需要申请MANAGE_EXTERNAL_STORAGE权限,基于分区存储规则使用MediaStore加对应媒体权限即可实现需求,具体适配方案如下:

权限适配规则

  • Android 13(API 33+):无需申请旧版存储权限,仅需要申请对应细分媒体权限READ_MEDIA_IMAGES、READ_MEDIA_VIDEO
  • Android 11~12L(API 30~32):仅需要申请READ_EXTERNAL_STORAGE权限,无需申请存储管理权限和写入权限(写入自有媒体文件无需权限,修改其他应用创建的媒体文件走单独授权流程)
  • Android 10及以下:保留原有读写存储权限逻辑即可

清单文件权限声明

<!-- Android 13+ 媒体权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- Android 12及以下 读取存储权限 -->
<uses-permission
    android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />
<!-- Android 10及以下 写入存储权限 -->
<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="29" />
<!-- 无需声明MANAGE_EXTERNAL_STORAGE权限 -->

修正后的权限校验代码

private boolean checkMediaPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // Android 13及以上
        int readImgPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES);
        int readVideoPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_VIDEO);
        return readImgPermission == PackageManager.PERMISSION_GRANTED && readVideoPermission == PackageManager.PERMISSION_GRANTED;
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // Android 11~12L
        int readStoragePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
        return readStoragePermission == PackageManager.PERMISSION_GRANTED;
    } else { // Android 10及以下
        int readPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
        int writePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        return readPermission == PackageManager.PERMISSION_GRANTED && writePermission == PackageManager.PERMISSION_GRANTED;
    }
}

MediaStore全量查询图片/视频代码示例

// 定义需要查询的媒体字段
String[] projection = new String[]{
    MediaStore.Files.FileColumns._ID,
    MediaStore.Files.FileColumns.DISPLAY_NAME,
    MediaStore.Files.FileColumns.MIME_TYPE,
    MediaStore.Files.FileColumns.DATE_ADDED,
    MediaStore.Files.FileColumns.SIZE
};

// 过滤条件:仅查询图片、视频类型文件
String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + " IN (?,?)";
String[] selectionArgs = new String[]{
    String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE),
    String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO)
};

// 排序规则:按文件添加时间倒序
String sortOrder = MediaStore.Files.FileColumns.DATE_ADDED + " DESC";

// 执行查询
try (Cursor cursor = getContentResolver().query(
    MediaStore.Files.getContentUri("external"),
    projection,
    selection,
    selectionArgs,
    sortOrder
)) {
    if (cursor != null) {
        while (cursor.moveToNext()) {
            long mediaId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID));
            String fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME));
            // 拼接可直接访问的媒体Uri,可直接加载到ImageView、播放器中
            Uri mediaUri = ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), mediaId);
            // 此处添加你的业务处理逻辑
        }
    }
} catch (Exception e) {
    e.printStackTrace();
}

注意事项

  • 如果业务仅需要用户选择部分媒体文件,无需全量扫描,更推荐调用系统原生相册选择器,无需申请任何权限,适配成本更低
  • Android 11+如果需要修改/删除其他应用创建的媒体文件,走系统弹窗授权即可,无需申请存储管理权限
  • 仅文件管理器、备份类工具等需要访问全量任意文件的应用才允许申请MANAGE_EXTERNAL_STORAGE,普通媒体类应用申请该权限会被谷歌应用商店拒绝上架

内容的提问来源于stack exchange,提问作者Syed Fahad Hussain

相关产品推荐
方舟 Agent Plan

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

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