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

Android:如何从媒体提供者URI获取文件路径与文件名?

解决content URI获取文件名时的column '_data' does not exist错误

你遇到的这个错误很常见,原因主要有两点:

  1. 从Android 10(API 29)开始,MediaStore.Audio.Media.DATA对应的_data列已经被官方废弃,系统不再保证这个列存在于媒体查询结果中;
  2. 你使用的content://com.android.providers.media.documents/document/audio%3A180是媒体文档提供者返回的URI,这类URI指向的是媒体库中的条目,而非直接的本地文件路径,所以直接查询_data必然会失败。

正确获取文件名的方法

下面给你两种可靠的实现方式:

方法1:查询通用的DISPLAY_NAME列

MediaStore.MediaColumns.DISPLAY_NAME是所有媒体类型(音频、图片、视频)都支持的列,直接返回文件的显示名称(也就是我们要的文件名):

Uri targetUri = Uri.parse("content://com.android.providers.media.documents/document/audio%3A180");
String fileName = null;

// 只查询需要的列,提升性能
String[] projection = {MediaStore.MediaColumns.DISPLAY_NAME};
Cursor cursor = context.getContentResolver().query(targetUri, projection, null, null, null);

if (cursor != null) {
    try {
        if (cursor.moveToFirst()) {
            int nameColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME);
            fileName = cursor.getString(nameColumnIndex);
        }
    } finally {
        cursor.close(); // 务必关闭Cursor,避免内存泄漏
    }
}
// 此时fileName就是音频文件的名称

方法2:通过文档ID关联查询(适用于更复杂的场景)

如果需要同时获取更多媒体信息,可以通过文档ID拆分出媒体条目ID,再关联查询媒体库:

Uri targetUri = Uri.parse("content://com.android.providers.media.documents/document/audio%3A180");
String fileName = null;

// 拆分文档ID,格式为"audio:180",分割后得到ID部分"180"
String documentId = DocumentsContract.getDocumentId(targetUri);
String[] splitId = documentId.split(":");
if (splitId.length == 2 && "audio".equals(splitId[0])) {
    String mediaId = splitId[1];
    String[] projection = {MediaStore.Audio.Media.DISPLAY_NAME};
    
    Cursor cursor = context.getContentResolver().query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        projection,
        MediaStore.Audio.Media._ID + "=?",
        new String[]{mediaId},
        null
    );
    
    if (cursor != null) {
        try {
            if (cursor.moveToFirst()) {
                fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
            }
        } finally {
            cursor.close();
        }
    }
}

重要注意事项

  • Scoped Storage限制:从Android 10开始,不要试图获取媒体文件的真实本地路径,系统通过Scoped Storage限制了直接文件系统访问,所有操作都应该通过ContentResolver完成;
  • 权限申请:确保你的应用已经申请了对应的权限,Android 12及以下需要READ_EXTERNAL_STORAGE,Android 13及以上可以申请更精细的READ_MEDIA_AUDIO权限;
  • Cursor关闭:所有查询得到的Cursor必须在使用完毕后关闭,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:56:25