.getPath()与游标之间的区别在于Android中从uri获取文件的真实路径
该问题的主要思想与标题相同-当您从Android中的uri获取文件的真实路径时,.getPath()与游标之间有什么区别?
The main idea of the question is just same as the title - what is the difference between .getPath() vs cursor, when you get the real path of a file from uri in Android?
如果您没有理解使用游标的含义,请参见此处的示例.
In case you don't get what I meant by using cursor, the example is here.
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;
}
这两种最常见的方法是这两种,但是使用游标似乎有点复杂,尽管您可以使用一种简单的方法.getPath()获得相同的结果.因此,我认为在某些情况下应该使用游标是有一定原因的,但是我无法获得它.
The two most frequent ways were these two, but it seems a bit too complicated using cursor, while you can get the same result with one simple method, .getPath(). So, I think there must be the reason I should use the cursor in some cases, but I can't get it.
您能解释一下这是什么吗?
Could you explain me what it would be?
当您从Android中的uri获取文件的真实路径时,.getPath()与游标之间有什么区别?
what is the difference between .getPath() vs cursor, when you get the real path of a file from uri in Android?
Uri
不是文件.没有真实路径".
A Uri
is not a file. There is no "real path".
如果 Uri
的方案为file
,则然后表示文件系统上的一个文件,从理论上讲,您的应用应该能够访问.使用getPath()
获取文件系统路径.
If the scheme of the Uri
is file
, then it represents a file on the filesystem that, in theory, your app should be able to access. Use getPath()
to get the filesystem path.
如果该方案是其他方案,则不一定代表您的应用程序可以访问的文件系统上的文件.例如,如果方案是http
或https
,则Uri
表示将从Web服务器下载的内容.
If the scheme is anything else, it does not necessarily represent a file on the filesystem that your app can access. For example, if the scheme is http
or https
, the Uri
represents something that would be downloaded from a Web server.
如果方案为content
,则由ContentProvider
支持.使用ContentResolver
和openInputStream()
在Uri
所标识的内容上获取InputStream
.
If the scheme is content
, then it is backed by a ContentProvider
. Use a ContentResolver
and openInputStream()
to get an InputStream
on the content identified by the Uri
.
如果方案为content
,并且您是从MediaStore
专门获得的Uri
,那么然后也许是您的null
,并且您可能无法访问获得的路径(仅因为系统的MediaStore
可以为文件建立索引并不意味着您的应用程序可以访问该文件).这在Android 10上更糟,默认情况下,Android 10上您没有对外部存储的读取权限.因此,该技术不可靠,不应该使用.
If the scheme is content
and you specifically obtained the Uri
from the MediaStore
, then perhaps your Cursor
approach will give you a path. It also might give you null
, and the path that you get may not be accessible to you (just because the system's MediaStore
can index a file does not imply that your app has access to that same file). This is worse on Android 10, where you do not have read access to external storage by default. Hence, this technique is unreliable and should not be used.
但是,除此之外,您不能对用于支持content
Uri
的数据进行任何假设.可能是:
Beyond that, though, you cannot make any assumptions about what data is used to support that content
Uri
. It could be:
- 外部存储中的本地文件
- 内部存储中另一个应用程序的本地文件(例如,由
FileProvider
提供) - 可移动存储中的本地文件
- 已加密的本地文件,需要由
ContentProvider
快速解密
- 需要由
ContentProvider
提供服务的数据库的 - 需要先由其他应用下载的内容(例如Dropbox)
- ...等等
BLOB
列中保存的字节流
- A local file on external storage
- A local file on internal storage for the other app (e.g., served by
FileProvider
) - A local file on removable storage
- A local file that is encrypted and needs to be decrypted on the fly by the
ContentProvider
- A stream of bytes held in a
BLOB
column in a database that needs to be served by theContentProvider
- A piece of content that needs to be downloaded by the other app first (e.g., Dropbox)
- ...and so on
因此,回顾一下:Uri
不是文件.没有真正的道路".
So, to recap: a Uri
is not a file. There is no "real path".