.getPath() 与游标在从 Android 中的 uri 获取文件的真实路径方面的区别

Rhe*_*hee 4 android

问题的主要思想与标题相同 - 当您从 Android 中的 uri 获取文件的真实路径时,.getPath() 与光标之间有什么区别?

如果您没有理解我使用游标的意思,示例在此处。

private String getRealPathFromURI(Uri contentURI) {
    String result;
    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
    if (cursor == null) { // Source is Dropbox or other similar local file path
        result = contentURI.getPath();
    } else { 
        cursor.moveToFirst(); 
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
        result = cursor.getString(idx);
        cursor.close();
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

最常用的两种方式是这两种,但是使用游标似乎有点太复杂了,而您可以通过一种简单的方法 .getPath() 获得相同的结果。所以,我认为在某些情况下我应该使用光标肯定是有原因的,但我无法理解。

你能解释一下它会是什么吗?

Com*_*are 6

当您从 Android 中的 uri 获取文件的真实路径时,.getPath() 与光标之间有什么区别?

AUri不是文件。没有“真正的道路”。

如果的方案Urifile那么它代表文件系统上的一个文件,理论上,您的应用程序应该能够访问该文件。使用getPath()来获取文件系统路径。

如果方案是其他任何东西,它不一定代表您的应用程序可以访问的文件系统上的文件。例如,如果方案是httphttps,则Uri表示将从 Web 服务器下载的内容。

如果该方案是content,则它由 支持ContentProvider。使用ContentResolveropenInputStream()来获取InputStream由 标识的内容Uri

如果该方案是content 并且您专门Uri从 中获得MediaStore那么您的Cursor方法可能会给您提供一条路径。它也可能给你null,并且你可能无法访问你获得的路径(仅仅因为系统MediaStore可以索引文件并不意味着你的应用程序可以访问同一个文件)。这在 Android 10 上更糟,默认情况下您没有对外部存储的读取访问权限。因此,这种技术是不可靠的,不应使用。

但是,除此之外,您无法对使用哪些数据来支持这一点做出任何假设content Uri。它可能是:

  • 外部存储上的本地文件
  • 其他应用程序的内部存储上的本地文件(例如,由 提供FileProvider
  • 可移动存储上的本地文件
  • 加密的本地文件,需要实时解密 ContentProvider
  • 保存在BLOB数据库列中的字节流,需要由ContentProvider
  • 需要由其他应用(例如 Dropbox)首先下载的一段内容
  • ...等等

所以,总结一下: aUri不是文件。没有“真正的道路”。