【问题标题】:Can't figure out how to use ACTION_VIEW and Storage Access Framework together不知道如何一起使用 ACTION_VIEW 和 Storage Access Framework
【发布时间】:2020-02-19 21:19:23
【问题描述】:

在拔掉头发大约一周后,我终于完成并准备寻求帮助。

基本上在我的应用程序中,我使用下面的 Intent 创建一个新的 PDF,这是通过 Storage Access Framework 完成的。

val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "application/pdf"
intent.putExtra(Intent.EXTRA_TITLE, title)
startActivityForResult(intent, 1234)

之后,我在 onActivityResult() 方法上获取 Uri,如下所示:

uri = dataIntent.data
if (uri != null) {
    val takeFlags = data.flags and (Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
    contentResolver.takePersistableUriPermission(uri, takeFlags)
    generatePdf(uri)
}

PDF 生成没问题,当我需要调用 ACTION_VIEW 让用户查看生成的文件或使用 ACTION_SEND 共享文件时,问题就来了。

ACTION_VIEW 使用示例(是的,我同时使用 Kotlin 和 Java):

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, mimeType);
startActivity(intent);

我这辈子都不知道如何获得另一个应用可以使用的 Uri。

到目前为止我尝试了什么:

  • This answer,但会引发以下异常:java.lang.IllegalArgumentException:列“_data”不存在。可用列:[_display_name, _size]
  • DocumentFile,使用 DocumentFile.fromFile(file),它将 Uri 从 content://com.myapp.provider/root/document/primary:folder-created-by- the-user/generated-pdf.pdffile:///root/document/primary:folder-created-by-the-user/generated-pdf.pdf,仍然没有应用可以打开它
  • 许多其他事情我什至不记得了

如果有人能对这个问题有所了解,将不胜感激。

【问题讨论】:

    标签: android storage-access-framework


    【解决方案1】:

    原则上使用与创建文件时相同的 uri。但是......您不能授予对该 uri 的读取 uri 权限。你说对了。但您不能将此类权限转发给文档的查看者。

    相反,您应该实现一个 ContentProvider。然后您就可以提供文件的内容了。

    【讨论】:

    • 太好了,您自己找到了解决方案。您使用 ACTION_CREATE_DOCUMENT 让用户创建文档。现在您要求提供该文档(使用获得的内容方案)。所以你需要一个提供者。但是您现在谈论的是 getFilesDir() 中的文件。那是一个完全不同的故事,因为它与原始文件有什么关系? getFilesDIr 中的文件可以使用一个简单的 FileProvider 来提供。好吧,只有一个。
    • 我改变了我的方法,所以我不再使用 ACTION_CREATE_DOCUMENT。在我看来,我最终得到的是一个更优雅的解决方案,因为用户不需要选择文件夹和/或文件名,我创建的所有文件都存储在我的应用程序的提供程序中。
    • @blackapps 我同意你的观点,Lucas 的解决方案是针对在私人存储中创建的文件。您能否提供一个代码解决方案来通过 Action_View 打开共享文件(取自 ACTION_CREATE_DOCUMENT)?我还为它发布了一个单独的问题here
    【解决方案2】:

    就像 blackapps 在他的回复中所说,我要做的是实现一个 ContentProvider,更具体地说是一个 DocumentProvider。

    遵循this linkthis link 最终成功了。我实现了一个 CustomDocumentProvider,它在我的应用程序的私有文件 (context.getFilesDir().getAbsolutePath() + "/folderToExpose") 中公开一个文件夹,之后在该文件夹中创建的所有文件都暴露给其他应用程序,我可以使用 ACTION_VIEW 和 ACTION_SEND正常。

    如果有人碰巧遇到此问题,请确保您要公开的文件夹不包含任何对您的应用至关重要的文件,例如数据库文件,因为用户将拥有对其所有内容的完全访问权限.如果它是一个新文件夹,请确保通过调用 mkdirs() 来创建它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-20
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多