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

Android:无需权限访问MediaStore获取Cursor数据及图片选择器Uri问题

无需权限访问相册数据及图片选择器返回Uri的解决方案

一、无需权限获取相册媒体基本数据

直接查询MediaStore.Images.Media.EXTERNAL_CONTENT_URI通常需要READ_EXTERNAL_STORAGE权限,无权限时Cursor会为空。但从Android 10(API 29)开始,系统允许无需存储权限读取媒体的非隐私元数据(如ID、文件名、媒体类型等),只需在查询时指定必要的非隐私列,避免请求文件路径这类敏感字段:

// 仅请求非隐私的元数据列
String[] projection = {
    MediaStore.MediaColumns._ID,
    MediaStore.MediaColumns.DISPLAY_NAME,
    MediaStore.MediaColumns.MIME_TYPE
};

Cursor cursor = context.getContentResolver().query(
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
    projection,
    null,
    null,
    null
);

这种情况下,即使没有存储权限,Cursor也会返回有效数据,但无法获取MediaStore.Images.Media.DATA(文件路径)这类隐私字段。如果你的需求只是获取媒体基本信息,这个方法完全适用。

二、无需权限访问图片选择器返回的Uri

你使用Intent.ACTION_PICK打开的图片选择器,返回的Uri本身带有系统授予的临时访问权限,不需要额外申请存储权限就能直接访问。问题出在你后续重新构造picUri的逻辑——通过ID拼接的Uri会丢失原有临时权限,导致需要权限才能访问。

正确的做法是直接使用选择器返回的selectedImage Uri,无需重新构造:

ContentResolver contentResolver = activity.getContentResolver();
try {
    InputStream inStream = contentResolver.openInputStream(selectedImage);
    final byte[] file = PicUtils.readFileBytes(inStream);
    // 后续处理逻辑
} catch (IOException e) {
    e.printStackTrace();
}

如果需要获取该图片的元数据,同样可以直接查询返回的Uri,无需权限:

String[] projection = {
    MediaStore.MediaColumns.DISPLAY_NAME,
    MediaStore.MediaColumns.MIME_TYPE
};
Cursor cursor = activity.getContentResolver().query(
    selectedImage,
    projection,
    null,
    null,
    null
);
if (cursor != null && cursor.moveToFirst()) {
    String fileName = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME));
    String mimeType = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE));
    cursor.close();
}

临时权限的有效期至你的Activity销毁为止,足够完成图片读取和处理操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:13:21