Android 内容提供商安全异常

Android Content Provider Security Exception

我正在尝试使用其他 reader 应用程序(例如 Google Drive PDF 查看器等)从我的应用程序打开 PDF 或文本文件。但它显示以下错误。

java.lang.SecurityException: Permission Denial: opening provider com.my.app.provider.GenericFileProvider from ProcessRecord{87fdcbb 31761:com.google.android.apps.docs/u0a37} (pid=31761, uid=10037) that is not exported from uid 10081

清单文件:

<provider
        android:name="com.my.app.provider.GenericFileProvider"
        android:authorities="${applicationId}.my.package.name.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

provider_paths 文件:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

代码:

Intent intent = new Intent(Intent.ACTION_VIEW);
String mimeType = myMime.getMimeTypeFromExtension(ChatAdapterHelper.Document.getDocumentExtension(message.content));

String authority = AppContext.getAccess().getContext().getPackageName() + ".my.package.name.provider";

Uri fileUri = GenericFileProvider.getUriForFile(AppContext.getAccess().getContext(), authority, file);
Log.d("fileUri", "openDocument: fileUri " + fileUri);

intent.setDataAndType(fileUri, mimeType);
Intent chooser = Intent.createChooser(intent, context.getString(R.string.open_file_with));

chooser.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
chooser.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

AppContext.getAccess().getContext().startActivity(chooser);

SDK 版本:

minSdkVersion 16
targetSdkVersion 27

我正在尝试按照 Android 开发者网站和其他论坛帖子中说明的使用内容提供程序的过程进行操作,但无法弄清楚这里有什么问题!

需要在传递给createChooser()Intent上设置FLAG_GRANT_*_URI_PERMISSION标志;在这种情况下,intent.

另外,请注意 setFlags() 将取代之前对它的任何调用。也就是说,最后一次调用的标志将完全替换任何先前的调用。您可以使用 | 在一次调用中组合多个标志,或者单独使用 addFlags() 方法。例如:

intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

或者:

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

此外,请确保对 chooser Intent 上的 FLAG_ACTIVITY_NEW_TASK 使用 addFlags(),因为授予权限标志也将添加到其中它是在 createChooser() 方法中构造的。

chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);