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

时间:2014-09-26 16:42:33

标签: java android android-intent uri android-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);

1 个答案:

答案 0 :(得分:0)

  

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

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

实施ContentProvider有四种基本方法:

  1. 导出它并且不受任何权限的保护。这是愚蠢的。不要这样做。

  2. 是否已导出但受权限保护(例如android:readPermissionandroid:writePermission属性)。这种方法效果很好,但仅适用于专门用于与ContentProvider通信的应用。对于ContentProvider没有先验知识的应用程序,它不适用于大多数ACTION_SEND支持活动的实施者。

  3. 不能导出它,但是您可以为{1}}授予特定请求的权限。通常情况下,这是通过添加到Uri Intent的{​​{1}}来完成的,尽管还有其他方法,例如自己调用startActivity()。如果您是第三方访问提供商的发起人,例如使用grantUriPermission() ACTION_SEND启动活动,则此功能非常有用。

  4. 是否已将其导出,并且未授予Intent的权限。在这种情况下,Uri仅在您自己的应用中可用,即使您要求(例如,您的ContentProvider请求),第三方也无法访问{。}}。

  5.   

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

    我的一条评论中出现了错误,我为此道歉。

    ACTION_SEND现在授予您FLAG_GRANT_READ_URI_PERMISSIONUri的读取权限,无论Intent是"数据"那个Uri或者是额外的。这将被授予Intent的最终消费者 - 换句话说,选择器不会以某种方式使用权限,并且所选择的活动没有权限。但是,以前只有Intent只能处理"数据"而不是FLAG_GRANT_READ_URI_PERMISSION值的额外内容,而且在我的脑海中我完全忘记了这个缺陷是什么时候固定的。

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

    FWIW,activity flags like FLAG_GRANT_READ_URI_PERMISSION,演示使用ACTION_SEND来查看由FLAG_GRANT_READ_URI_PERMISSION提供的PDF。