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

标签 java android android-intent uri android-securityexception

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

Uri 作为额外的 (Intent.EXTRA_STREAM) 传递给 Intent (Intent.ACTION_SEND) )以便发送。然而,这样做时,它会间歇性地失败,并出现以下异常:

E/DatabaseUtils(26058):java.lang.SecurityException:权限拒绝:从 pid=26141、uid=10038 读取 MyContentProvider uri content://spinner.myapp.db/file/stream/zip/1要求导出提供程序,或 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);

最佳答案

Ah, I see, so the sending apps have to have their own permissions granted for each Uri, rather than it being implicitly provided by the calling app's Intent?

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

有四种基本方法来实现 ContentProvider:

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

  2. 将其导出,但受权限保护(例如,android:readPermissionandroid:writePermission 属性)。这很有效,但仅适用于专门为与您的 ContentProvider 通信而编写的应用。它不适用于那些ContentProvider先验知识的应用,例如大多数ACTION_SEND支持 Activity 的实现者。

  3. 不将其导出,而是让您针对特定请求授予 Uri 权限。通常,这是通过 activity flags like FLAG_GRANT_READ_URI_PERMISSION 完成的添加到与 startActivity() 一起使用的 Intent 中,尽管还有其他方法,例如自己调用 grantUriPermission() 。当您需要第三方访问您的提供商时(例如使用 ACTION_SEND Intent 启动 Activity ),此方法非常有效。

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

How can I grant permissions for the app that ends up being chosen to perform the sending, or do I have to grant it to all possible apps?

这导致我的一条评论出现错误,对此我深表歉意。

FLAG_GRANT_READ_URI_PERMISSION 现在会授予对 Intent 中的 Uri 的读取权限,无论该 Uri 是“数据” ” 的Intent或者是在一个额外的内容中。这将被授予 Intent 的最终使用者——换句话说,选择器不会以某种方式消耗该权限,并且所选 Activity 没有权限。但是,过去,FLAG_GRANT_READ_URI_PERMISSION 只适用于“数据”,而不适用于附加内容中的 Uri 值,而且我完全忘记了该缺陷何时出现已修复。

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

FWIW,here is a sample app演示了如何使用 FLAG_GRANT_READ_URI_PERMISSION 来查看由 FileProvider 提供的 PDF。

关于java - 有哪些选项可用于解决间歇性 Permission Denial SecurityException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26064379/

相关文章:

android - 如何在 Android 上自动发送电子邮件?

java - 从 Android 项目创建 jar

android - 缩小 Google Play 服务库以仅与 Google Analytics 一起使用

java - 从 Activity 外的类(class)发起 Intent

android - 不要破坏 android Activity ,不应该在历史中

java - 为 Eclipse Neon 安装 Checkstyle-Plugin (7.2.0) 失败

java - 如何将 Java 依赖项添加到 Google Dataflow 项目?

java - 在Elasticsearch的Java客户端中编写查询

android - 在启动外部 Activity/Intent 后返回应用程序时显示应用程序主菜单/主屏幕

java - 从 Java 导入到 C++ 包括