java - 如何从内容 uri 获取 zip 文件的文件路径?
问题描述
我正在触发选择 zip 文件的意图,并且在 onActivityResult 中,它为我提供了一个内容 URI。例如 :: (content://com.android.providers.downloads.documents/document/197)。选择的文件来自下载文件夹。谁能解释一下,如何查询内容解析器以获取文件路径?谢谢。
Already tried code :-
Cursor cursor = getActivity().getContentResolver()
.query(contentUri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
String path=cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
Log.i(TAG, "path Name: " + path);
}
// NOTE :: Here I am getting the file name, But i want the file path.
} finally {
cursor.close();
}
解决方案
我尝试了很多方法来从下载文件夹中的选定文件中检索文件路径。由于从 android Q 开始,谷歌建议 SAF(存储访问框架)从用户那里获取数据。我们不能使用 Environment.getExternalStoragePublicDirectory() 从 android Q 及更高版本获取文件路径。
对于 android Q 及更高版本,您可以按照以下步骤操作。
1)从您要触发的活动或片段开始意图。
例如 :
public void performFileSearch() { //from developer docs
// ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
// browser.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
// Filter to only show results that can be "opened", such as a
// file (as opposed to a list of contacts or timezones)
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Filter to show only images, using the image MIME data type.
// If one wanted to search for ogg vorbis files, the type would be "audio/ogg".
// To search for all documents available via installed storage providers,
// it would be "*/*".
intent.setType("application/pdf"); // MIME type for what file you required
startActivityForResult(intent, READ_REQUEST_CODE);
}
2)然后结果将出现在您的活动或片段的onActivityResult中
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) { // from developer docs
// The ACTION_OPEN_DOCUMENT intent was sent with the request code
// READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
// response to some other intent, and the code below shouldn't run at all.
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
// The document selected by the user won't be returned in the intent.
// Instead, a URI to that document will be contained in the return intent
// provided to this method as a parameter.
// Pull that URI using resultData.getData().
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
Log.i(TAG, "Uri: " + uri.toString());
processWithUriToGetPath(uri);
}
}
}
从 uri 中提取数据(注意:对于图像、视频和音频,您可以参考开发者文档。由于没有找到任何合适的文件文档,因此给出了此示例)。
private void processWithUriToGetPath(Uri contentUri) {
//Use content Resolver to get the input stream that it holds the data and copy that in a temp file of your app file directory for your references
File selectedFile = new File(getActivity().getFilesDir(), "your file name"); //your app file dir or cache dir you can use
InputStream in = getActivity().getContentResolver().openInputStream(contentUri);
OutputStream out = new FileOutputStream(selectedFile);
try {
byte[] buf = new byte[1024];
int len;
if (in != null) {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
} catch (IOException ie) {
ie.printStackTrace();
}
//after this you will get file from the selected file and you can do
whatever with your wish.
// Hope it helps...
}
推荐阅读
- cytoscape.js - Cytoscape - 添加动态高度,然后使用拟合功能
- java - 如何从 MySQL 数据库中获取数据并将其设置在 Java 中的 HashMap 中(注册/登录 GUI 程序)
- cmd - 以编程方式从命令行窗口复制所有文本
- flutter - 如何在我的 Flutter 中实现 Provider
- mysql - 如何从不同的虚拟机连接到 Docker MySQL 数据库
- c# - 在 ASP.NET 5 C# 中格式化货币
- bash - Linux cli pipe output of command into another command
- c# - 如何在 C# 中 POST 后更改页面
- php - 我想使用本地存储以符合 GDPR 的方式存储回访者
- c# - 双精度值设置为 +Infinity 或 NaN