首页 > 解决方案 > 如何与其他应用程序共享(ACTION_VIEW)文件?

问题描述

用例:从我的应用程序下载文件使用适当的编辑应用程序打开它,并在用户完成编辑后将文件上传回我的应用程序。

示例:我将 docx 文件从我的应用程序下载到公共文件夹(例如“文档”),并在使用 FileProvider 获取 uri 后发送 ACTION_VIEW 意图(授予写入权限)。然后用word app打开它并编辑它。但是问题来了 - word app 说我需要将文件另存为新副本,并且不允许我覆盖原始文件。奇怪的是,如果我从文件浏览器打开下载的文件,一切正常,我可以覆盖该文件。但是当我从我的应用程序中使用 Intent 时,应用程序决定在他们的私有目录中创建一个副本。他们为什么要这样做?是否有可能将新保存的文件返回到我的应用程序(从 startActivityForResult)或以某种方式让它们覆盖公用文件夹中的原始文件?

编辑:正如 blackapps 所建议的那样,我尝试使用“Intent-Interceptor”检查意图。结果如下:

我的应用程序:

intent://com.android.externalstorage.documents/tree/primary%3ADocuments/document/primary%3ADocuments%2FDocument.docx#Intent;scheme=content;type=application/vnd.openxmlformats-officedocument.wordprocessingml.document;launchFlags=0x13000000;end 
------------ 
ACTION: android.intent.action.VIEW 
DATA: content://com.android.externalstorage.documents/tree/primary%3ADocuments/document/primary%3ADocuments%2FDocument.docx 
MIME: application/vnd.openxmlformats-officedocument.wordprocessingml.document 
URI: intent://com.android.externalstorage.documents/tree/primary%3ADocuments/document/primary%3ADocuments%2FDocument.docx#Intent;scheme=content;type=application/vnd.openxmlformats-officedocument.wordprocessingml.document;launchFlags=0x13000000;end 
FLAGS: 
FLAG_RECEIVER_FOREGROUND 
FLAG_ACTIVITY_FORWARD_RESULT 
FLAG_ACTIVITY_PREVIOUS_IS_TOP 

------------ 
MATCHING ACTIVITIES: 
Word (com.microsoft.office.word - com.microsoft.office.word.WordActivity)

默认文件浏览器(谷歌“文件”):

intent://com.google.android.apps.nbu.files.provider/1/file%3A%2F%2F%2Fstorage%2Femulated%2F0%2FDocuments%2FDocument.docx#Intent;scheme=content;type=application/vnd.openxmlformats-officedocument.wordprocessingml.document;launchFlags=0x3000000;end 
------------ 
ACTION: android.intent.action.VIEW 
DATA: content://com.google.android.apps.nbu.files.provider/1/file%3A%2F%2F%2Fstorage%2Femulated%2F0%2FDocuments%2FDocument.docx 
MIME: application/vnd.openxmlformats-officedocument.wordprocessingml.document 
URI: intent://com.google.android.apps.nbu.files.provider/1/file%3A%2F%2F%2Fstorage%2Femulated%2F0%2FDocuments%2FDocument.docx#Intent;scheme=content;type=application/vnd.openxmlformats-officedocument.wordprocessingml.document;launchFlags=0x3000000;end 
FLAGS: 
FLAG_ACTIVITY_FORWARD_RESULT 
FLAG_ACTIVITY_PREVIOUS_IS_TOP 

------------ 
MATCHING ACTIVITIES: 
Word (com.microsoft.office.word - com.microsoft.office.word.WordActivity)

这是我获取保存文件的目录的方法(我使用ActivityResultContracts):

directoryResultLauncher = registerForActivityResult(OpenDocumentTree()) { uri ->
    if (uri == null) return@registerForActivityResult

    requireContext().contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
    authentication.publicDirectory = uri.toString()
}

下载方式:

val directoryUriString = authentication.publicDirectory
val directory = DocumentFile.fromTreeUri(context, directoryUriString.toUri())
val file = directory!!.createFile(mimeType, title)
val fileResult = getFileContent(context.contentResolver.openOutputStream(file!!.uri)!!)

if (!fileResult.isError()) {
    val intent = Intent(Intent.ACTION_VIEW, file.uri).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
    startActivity(intent)
}

标签: androidandroid-intentandroid-contentprovider

解决方案


推荐阅读