【问题标题】:FileProvider sharing file on Android 11Android 11 上的 FileProvider 共享文件
【发布时间】:2021-05-25 11:23:22
【问题描述】:

我遇到了一个奇怪的问题。我在三星 Galaxy S20FE Android 11 上运行。 我想从我的应用程序中打开一个 PDF 文件,所以当我四处搜索时,我需要使用 fileProvider。 这就是我在清单中声明它的方式:

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

这是 XML 文件:

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

该文件位于应用程序的目录中,但在 SD 上,而不是在设备的内部存储中。 我正在调用函数来打开 PDF 文件:

File file = new File(pdfpath);
Uri path = FileProvider.getUriForFile(this, "package.myapp.provider", file);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(path, "application/pdf");
        intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_GRANT_READ_URI_PERMISSION);

        try {
            startActivity(intent);
        }
        catch (ActivityNotFoundException e) {
            Toast.makeText(MainActivity.this,
                    "No Application Available to View PDF",
                    Toast.LENGTH_SHORT).show();
        }
    }

根据我搜索过的任何地方,我看不到我缺少什么。我还为旧版本尝试了一些东西,应该为所有需要的包提供 UriPermissions:

List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);


for (ResolveInfo resolveInfo : resInfoList) {
    String packageName = resolveInfo.activityInfo.packageName;
    context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | 
         Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

但无论我尝试什么,我总是以同样的异常告终:

2021-05-25 18:04:03.556 8873-8907/package.myapp E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: Permission Denial: writing android.support.v4.content.FileProvider uri content://package.myapp.provider/root/0A18-B25A/Android/Data/package.myapp/gis/pdf/dragunov.pdf from pid=13365, uid=10104 requires the provider be exported, or grantUriPermission()

我不明白为什么我的权限被拒绝。此外,我尝试设置 XML 属性以导出 FileProvider,但最终得到一个异常,即由于安全原因无法导出提供程序,因此我决定不尝试朝那个方向发展。

任何帮助将不胜感激。

【问题讨论】:

  • "这是 XML 文件" -- root-path 未记录。 “我不明白为什么我的权限被拒绝”——似乎有东西试图写入Uri 标识的位置,但您只授予了FLAG_GRANT_READ_URI_PERMISSION。如果需要写操作,您是否尝试过添加FLAG_GRANT_WRITE_URI_PERMISSION?
  • 不,没有人在尝试编写,我正在尝试将 PDF 文件从我的应用程序共享到另一个应用程序。那个不同的应用程序只是一个阅读器
  • @CommonsWare 我尝试添加它(写入权限)仍然是同样的问题。另外,我知道它是无证的,我在搜索的其他地方找到了它。问题是,记录在案的路径变量都指向与我无关的目录,而 root-path 是唯一似乎没问题的目录。
  • “记录的路径变量都指向与我无关的目录”——然后也许将您的 PDF 放在这些目录之一中。或者,也许写你自己的ContentProvider 来提供 PDF。除此之外,您是否尝试过删除FLAG_ACTIVITY_NO_HISTORY,看看是否有影响?
  • @CommonsWare 我试图避免这种情况,因为它会破坏很多应用程序的逻辑,如果我找不到解决方案,我猜我会的。是的,我已经尝试删除 ACTIVITY_NO_HISTORY,但仍然不会改变任何内容。即使我要实现自己的 ContentProvider,除了指定的路径之外,我仍然无法为其提供路径?根据调试器的说法,即使我可以,我仍然会在 URI 部分失败,因为通用 fileProvider 现在为我提供了一个有效的 URI

标签: android android-fileprovider


【解决方案1】:

&lt;root-path name="root" path="/storage/" /&gt;

您不能再在 Android 11 设备上使用 root-path。

认为自 Android Q 以来这甚至是不可能的。

所以现在 FileProvider 无法从可移动媒体中提供服务。

使用您自己的 ContentProvider 来执行此操作。

【讨论】:

  • 好吧,如果我将文件放在 SD 卡内的目录中,但不在 android/data 下,则此代码确实可以工作,所以我不会说它不工作。
  • 请给出完整路径的例子。 pdfpath 的值。
  • 我现在面临的情况的完整路径,它不起作用:/storage/card_id/android/data/app_dir/pdf/pdffile.pdf 我描述的情况的完整路径并且正在工作: /storage/card_id/directory/pdffile.pdf
  • &lt;root-path 在 Android 11 上不可用。因为没有文件。与可移动存储无关。嗯......这是我到现在为止的经验......但我没有那个三星。将path="/storage/" 更改为path="." 进行测试。
  • 好吧,我想我会尝试实现我自己的 FileProvider,看看效果如何。正如我所说,当我将 PDF 文件放在 SD 卡内的目录中时,我能够打开它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多