java - 给定用户所选目录的 URI,如何根据参数化文件名读取文件?

标签 java android storage-access-framework

我正在尝试构建一个 Android 应用程序,允许用户选择包含图像的文件夹,从那时起,该应用程序就能够通过放置在该用户选择的文件夹中的预先确定的图像名称来加载特定图像。该用例使应用程序用户能够通过提供自己的 Assets 来自定义应用程序的主题/图像。

我可以获取用户选择的文件夹的 URI。假设具有所需文件名的所需图像文件始终存在于用户选择的文件夹中(我已经实现了 try-catch block 来处理此问题),我如何为图像文件构造一个 Uri 以便我可以使用它(例如设置 ImageView?)

用户必须能够从一系列 Assets 位置中进行选择,包括 SD 卡。

//Key variables
ImageView myImageView;
String myImageFilename = "foobar.png"; //image to be loaded
Uri imageUri;
Integer MYREQUESTID = 100000000;

//This is how the user selects a directory:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, MYREQUESTID);

//Use on activity result to capture the user selected folder;
URI userSelectedDirUri = data.getData();

尝试以下方法将文件名附加到用户选择的目录中,但会导致无效的 Uri。我注意到 Uri 是用 %2F 而不是/进行编码的,但是使用这种方法,文件名会附加/,我不知道如何使用 %2F 来代替

imageUri = userSelectedDirUri.buildUpon().appendPath(myImageFilename).build();

以下方法有效,但 pickDir.findFile(...) 会导致对 listFile() 和 findFile() 方法的 50,000 多次调用,从而导致持续的垃圾收集。用户的文件夹可能包含 100 多个文件。

DocumentFile pickedDir = DocumentFile.fromTreeUri(context, directoryUri);
DocumentFile theFile = pickedDir.findFile(myImageFilename);
imageUri = theFile.getUri();

目标

myImageView.setContentUri(imageUri);

代码的最后一行应使用名为 myImageFilename 的图像更新 ImageView myImageView,该图像位于 userSelectedDirUri 描述的目录中。

任何帮助表示赞赏!我也没有将其实现为 asyncTask,我认为我应该这样做。对于使用和不使用 asyncTask 的示例给予额外的荣誉/点/感激,但不是必需的(一旦核心逻辑修复,我会自己解决)。

谢谢!

最佳答案

使用@CommonsWare建议的方法解决。

Hashmap<String, Uri> imageUriMap = new Hashmap<>; //Defined outside of this method

public String indexImages(Uri userSelectedDirUri){

    ContentResolver contentResolver = this.getContentResolver(); //When this method is used in the context of an Activity.
    Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri,
            DocumentsContract.getTreeDocumentId(uri));

    Cursor c = null;

    c = contentResolver.query(childrenUri, new String[] {
            DocumentsContract.Document.COLUMN_DISPLAY_NAME,
            DocumentsContract.Document.COLUMN_DOCUMENT_ID}, null, null, null);

    Integer count = 0;
    try {
        while (c.moveToNext()) {
            final String documentName = c.getString(0);
            final String documentId = c.getString(1);
            final Uri documentUri = DocumentsContract.buildDocumentUriUsingTree(uri,
                    documentId);
            imageUriMap.put(documentName, documentUri);
            count++;
        }
    } finally {
        c.close();

    }
    return (count.toString() + " images indexed");
}

然后使用以下方法设置图像:

imageView.setImageUri(imageUriMap.get(myImageFilename));

关于java - 给定用户所选目录的 URI,如何根据参数化文件名读取文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57029106/

相关文章:

java - 我可以抢占类路径吗?

java - 用java计算月份和时差?

java - Android 语音识别 react 时间过长

Android FragmentBreadCrumbs 已弃用?为什么?

android - 如何在使用加速计传感器检测到运动时拍照

android - 使用 KitKat 存储访问框架后打开 Google Drive File Content URI

java - 在javascript中使用json对象在确认窗口中显示

java - Java 8 中使用可选参数调用方法

android - 与此操作关联的所有应用已被禁用、阻止或未安装存储访问框架

java - 如何在 android API 19 (KitKat) 中保留权限?