Android:从SD卡中的文件Uri获取文件路径

3
我们试图获取保存在SD卡中的文件路径,并将其传递给一个实用程序。然而,当我们使用URI打开游标时,只有两列被提取,路径(_data列)缺失。请告诉我如何获取路径。该查询对于任何存储在内部存储中的文件都有效。
方案为“content”。
代码片段:
cursor = context.getContentResolver().query(uri, null, null, null, null);
if (null != cursor && cursor.moveToFirst())
{
    int testcolCount = cursor.getColumnCount();
    for (int i = 0; i < testcolCount; i++)
    {
        String colName = cursor.getColumnName(i);
        String colValue = cursor.getString(i);
        System.out.println("" + i + ": " + colName + ":" + colValue + "\n");
    }

    //This prints only two columns, _display_name and _size
}

1
你可以无需解释就投票,这是同样的原因。为什么不在android聊天室和一些android论坛上发布你的问题呢? - tgkprog
1
你的问题质量非常低,我曾经点赞过它,但现在已经删除了。没有上下文。你谈论某个文件,然后似乎跳到了一些光标/数据库API?注意:我没有对你的问题投反对票。以防你想要抱怨某人 :-) https://www.youtube.com/watch?v=LXrTUuTJRn0 - tgkprog
那不是数据库查询。他正在使用ContentResolver。请注意,我建议查看ContentProvider。您的解析器代码在我看来是正确的。您可能正在错误地调用它,或者它可能不像您想象的那样工作。 - John Lord
1
@KrishnanVS 你在尝试使用哪个API级别?因为从API级别29开始,您无法直接访问外部存储。您需要使用存储访问框架。请参阅此处以获取更多信息:https://developer.android.com/training/data-storage/shared/documents-files - Parag Pawar
@JohnLord,当我通过游标进行迭代时,我得到了2列数据,所以我猜调用是正确的?不确定为什么“_data”不在列中。 - Krishnan V S
显示剩余8条评论
3个回答

2
不要试图获取路径,因为在 Android 10 及以上版本中,应用程序私有目录以外的文件路径是无用的,因为您没有访问权限。请参见https://developer.android.com/training/data-storage#scoped-storage。使用 contentResolver 获取 FileDescriptor 并将其传递给实用程序。请注意来自https://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#DATA的说明:该常量已在 API 级别 29 中被弃用。应用程序可能没有文件系统权限直接访问此路径。应用程序应使用 ContentResolver#openFileDescriptor(Uri, String) 来获得访问权限。

1

尝试使用此代码,我正在使用此函数从URI获取实际路径:

private String getRealPathFromURI(Context mContext, Uri contentURI) {
    String result = null;
    Cursor cursor = null;
    try {
        String[] proj = {MediaStore.Video.Media.DATA};
        ContentResolver mContentResolver = mContext.getContentResolver();
        String mime = mContentResolver.getType(contentURI);
        cursor = mContentResolver.query(contentURI, proj, null, null, null);
        if (cursor == null) {
            return null;
        } else {
            cursor.moveToFirst();
            int column_index = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
            if (column_index > -1)
                result = cursor.getString(column_index);
            cursor.close();
        }
    } catch (Exception e) {
        return null;
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return result;
}

它会返回一个字符串,这个字符串是你的文件的真实路径。
希望它能帮到你。

Milan,感谢您的回复。然而,光标没有获取我在问题中提到的“DATA”列。这是奇怪的部分。 - Krishnan V S
只需尝试此函数一次,然后回复我发生了什么,好吗? - Milan Tejani
结果为null,列索引为-1。uri.getAuthority返回“com.lenovo.FileBrowser.FileProvider”。方案是“content”。 - Krishnan V S
更新:当我尝试使用另一个文件管理器应用程序共享时,我获得了“媒体”权限并获得了路径。股票文件管理器应用程序导致了这个问题。 - Krishnan V S
默认的文件管理器是导致这个问题的原因。我尝试了另一个文件管理器,那个可以正常工作。感谢您抽出时间来帮助。 - Krishnan V S
请查看此链接 https://dev59.com/fWMm5IYBdhLWcg3whfWe 以及其他的 Stack Overflow 链接。 - Milan Tejani

0
默认文件管理器是导致这个问题的罪魁祸首 - 它没有返回“DATA”列,并返回“com.lenovo.FileBrowser.FileProvider”作为权限。当我使用另一个文件管理器时,权限是“media”。同时,在运行ContentResolver时,使用“DATA”获取路径列。感谢大家付出努力帮忙。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接