有哪些选项可用于解决间歇性的Permission Denial SecurityException



我已经设置了一个ContentProvider,仅供我的应用程序内部使用,用流来响应URI,通过它我构建并提供了一个zip文件。

Uri作为额外的(Intent.EXTRA_STREAM)传递给IntentIntent.ACTION_SEND)以便发送。然而,当这样做时,它会间歇性地失败,例外情况如下:

E/DatabaseUtils(26058): java.lang.SecurityException: Permission Denial: reading MyContentProvider uri content://spinner.myapp.db/file/stream/zip/1 from pid=26141, uid=10038 requires the provider be exported, or grantUriPermission()

我尝试过通过intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);授予权限,但没有成功。我也不明白为什么我需要授予权限,因为只有我自己的应用程序在访问ContentProvider

更新:

我现在也尝试过使用setClipData(),但没有成功。Gmail显然忽略了Uri,Dropbox崩溃了。

String[] mimeTypes = { "application/x-compressed" };
ClipData clip = new ClipData("zip data", mimeTypes, new ClipData.Item(uri));
intent.setClipData(clip);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

啊,我明白了,所以发送应用程序必须为每个Uri授予自己的权限,而不是由调用应用程序的Intent隐式提供权限?

我对你的术语感到困惑,所以让我试试这种方法:

实现ContentProvider:有四种基本方法

  1. 将其导出,并且不受任何权限的保护。这太愚蠢了。不要这样做。

  2. 将其导出,但要使用权限(例如android:readPermissionandroid:writePermission属性)进行保护。这很有效,但仅适用于专门为与ContentProvider对话而编写的应用程序。它不适用于对ContentProvider没有先验知识的应用程序,就像大多数支持ACTION_SEND的活动的实现者一样。

  3. 不导出它,但允许您为特定请求授予Uri的权限。通常,这是通过将FLAG_GRANT_READ_URI_PERMISSION之类的活动标志添加到与startActivity()一起使用的Intent中来完成的,尽管还有其他方法,例如自己调用grantUriPermission()。当您是需要第三方访问提供商的发起人时,例如使用ACTION_SEND Intent启动活动时,这非常有效。

  4. 不导出它,也不授予对Uri的权限。在这种情况下,ContentProvider仅在您自己的应用程序中可用,第三方根本无法访问,即使您提出要求(例如ACTION_SEND请求)。

我如何为最终被选择执行发送的应用程序授予权限,还是必须将其授予所有可能的应用程序?

这导致了我的一条评论中的一个错误,对此我深表歉意。

如今,FLAG_GRANT_READ_URI_PERMISSIONIntent中授予对Uri的读取访问权限,无论该Uri是该Intent的"数据"还是在额外的数据中。这将被授予Intent的最终使用者——换句话说,选择器不会以某种方式使用权限,所选活动也没有权限。然而,过去FLAG_GRANT_READ_URI_PERMISSION只处理"数据",而不处理附加值中的Uri值,我突然忘记了这个缺陷是什么时候修复的。

grantUriPermission()要求您知道Intent的最终消费者是谁,这意味着您需要滚动自己的"选择器",这样您就可以找到用户想要处理您提出的ACTION_SEND请求的实际应用程序。

FWIW,这里是一个示例应用程序,演示了使用FLAG_GRANT_READ_URI_PERMISSION来查看由FileProvider提供的PDF。

相关内容

  • 没有找到相关文章

最新更新