【问题标题】:Intent.ACTION_OPEN_DOCUMENT and app-private filesIntent.ACTION_OPEN_DOCUMENT 和应用程序私有文件
【发布时间】:2021-04-07 23:07:48
【问题描述】:

我正在努力将我的应用程序转移到范围存储。该应用程序的一项功能是它包含存储为应用程序资产的文档模板。在运行时,它们被复制到本地存储,这里:(代码是 Java)

String path = Environment.getExternalStoragePublicDirectory(
                              Environment.DIRECTORY_DOWNLOADS)
                              .getAbsolutePath() +
                              File.separator + "Templates";

由于这些文件是应用程序私有的,我很乐意将它们放入

String path = context.getFilesDir()
            .getAbsolutePath() +
             File.separator + "Templates";

但我也打算这样做(或类似的)让用户浏览文件:

Intent newIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
newIntent.addCategory(Intent.CATEGORY_OPENABLE);
newIntent.setType("*/*");
startActivityForResult(newIntent, 0);

我的问题是,如何让 ACTION_OPEN_DOCUMENT 将我放置模板的位置包含为可浏览?

【问题讨论】:

    标签: android scoped-storage


    【解决方案1】:

    在系统文件选择器中公开您的应用程序的私有文件的唯一方法是create a custom DocumentsProvider。这会将您的应用添加为用户可以从中选择的文件源。

    请注意,使用这种方法,根本不需要将文件复制到本地存储 - 您的 opening a document 代码可以使用 AssetManageropenFd() 方法和 getParcelFileDescriptor() 直接将其传递给调用应用程序根本无需通过 File API。

    【讨论】:

    • 但是,AFAIK,DocumentsProvider 方法意味着 设备上的每个应用程序 使用存储访问框架也将您的应用程序视为文档提供者。您可以use some tricks 表示您的应用程序的文档只能从您的应用程序中获得,但您的应用程序仍会显示为一个选项。这可能是一个特性,也可能是一个错误,具体取决于场景。不过,如果有一些技巧可以让我的应用程序内使用 DocumentsProvider,我很想听听!
    • @CommonsWare - 是的,将您的文件提供给用户意味着它们成为用户可以随时访问的东西。事实上,只有在 EXTRA_EXCLUDE_SELF 中完全相反的 API 才能从您自己对 ACTION_OPEN_DOCUMENT 的调用中删除您自己的文档提供程序,等等。
    • 有没有办法使用 SAF 获取不同位置的 URI 列表,并呈现我自己的选择器?现在我正在使用 File.listFiles() 来填充我自己的文件导航器。
    • 范围存储和沙盒化每个应用存储的全部意义在于,用户明确参与选择他们授予应用访问权限的文件(或文件夹,如果您使用ACTION_OPEN_DOCUMENT_TREE)。您当然可以要求用户手动选择他们认为与您的应用相关的文件和文件夹,然后您可以在您的应用中显示所有这些文件的列表,但建议始终使用ACTION_OPEN_DOCUMENT作为“文件->打开”等效项。即,让用户直接选择他们想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 2016-01-07
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多