无法使用 FileProvider 打开普通文本文件

Unable to open trivial text file with FileProvider

我要疯了,我过去使用过新的 Android FileProvider,但我无法使用下载文件夹中刚刚创建的(微不足道的)文件.

在我的 AsyncTask.onPostExecute 我叫

Intent myIntent = new Intent(Intent.ACTION_VIEW, FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".fileprovider", output));
myIntent.setType("text/plain");
myIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(myIntent);

我的FileProvider XML是这样的

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="Download" path="Download"/>
</paths>

我总是在 Genymotion 模拟器中选择 Amaze Text Editor 作为目标应用程序:

虽然我可以使用 HTML 查看器查看文件内容:

我无法理解这种行为并修复了一些应该是微不足道的事情,例如使用所需的文本编辑器打开纯文本文件。

非常感谢 尼古拉

OK,这里有两个问题。一个是您的代码中的错误触发了 Amaze 中的错误,另一个是您可以解决的 Amaze 中的错误。

setType() 有一个严重的副作用:它会在 Intent 中抹去你的 Uri。它相当于调用 setDataAndType(null, ...)(其中 ... 是您的 MIME 类型)。这不好。因此,与其将 Uri 放入构造函数并调用 setType(),不如调用 setDataAndType() 并在其中提供 Uri。 这会让您克服最初的 Amaze 错误,其中 they fail to handle a null Uri correctly.

然后,他们尝试以读写模式打开 Uri。您只授予读取权限,因此失败。他们的第二个错误是,当他们无法以读写模式打开文件时,他们认为他们得到了一个 FileNotFoundException,然后他们尝试了只读模式。实际上,至少 Android 8.1,they get a SecurityException。您可以通过提供读取和写入权限来解决此问题。

因此,除非您特别想阻止写入访问,否则此代码有效:

Intent myIntent = new Intent(Intent.ACTION_VIEW);
myIntent.setDataAndType(FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".fileprovider", output), "text/plain");
myIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivity(myIntent);