从 Android 11 上的内存直接访问文件

问题描述

我的应用程序与来自“外部”并保留在下载文件夹中的一些 pdf 报告交互(报告由用户通过浏览器下载)。

我的目标是使用外部 PDF 查看器打开此 pdf 报告。就像 Google 文档(或其他)一样。

我的代码如下所示:

    final String reportName="/storage/emulated/0/Download/1.pdf";
    File file = new File(reportName);
    Intent target = new Intent(Intent.ACTION_VIEW);

    Uri fileURI = FileProvider.getUriForFile(context,context.getApplicationContext().getPackageName() + ".provider",file);
    target.setDataAndType(fileURI,"application/pdf");
    target.setFlags(target.getFlags() | Intent.FLAG_GRANT_READ_URI_PERMISSION );

    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(target,PackageManager.MATCH_DEFAULT_ONLY);
    Log.d("FileWorker","Size is"+resInfoList.size());
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName
        context.grantUriPermission(packageName,fileURI,Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
    startActivity(target);

在 API 级别低于 30 时一切正常。 在 Android 30 上这不起作用,失败(来自日志):

com.google.android.apps.docs E/displayData: openFd: java.io.FileNotFoundException: open Failed: EACCES (Permission denied)
com.google.android.apps.docs E/PdfLoader: Can't load file (doesn't open)  display Data [PDF : 1.pdf] +ContentOpenable,uri: content://org.qtproject.example.provider/root/storage/emulated/0/Download/1.pdf

我猜这是因为范围存储政治。

我的尝试

  • 使用 ACTION_OPEN_DOCUMENT 和文件选择器获取 PDF 文件 URI。然后将此 URI 与 ACTION_VIEW 一起使用。这工作正常,但我真的不想使用文件选择器。

  • 我知道 android:requestLegacyExternalStorage="true",但它不适用于 Android 30。

  • 我试过在 Manifest 中添加这样的查询

       <queries>
         <package android:name="com.google.android.apps.docs"/>
         <intent>
         <action android:name="android.intent.action.VIEW"/>
    
        <data android:mimeType="application/pdf"/>
        </intent>
       </queries>
    

也无济于事。

除了使用 ACTION_OPEN_DOCUMENT 之外,我还能做些什么来解决这个问题?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)