我为我的应用程序内部使用设置了ContentProvider
,以响应带有流的URI,我通过它构建并提供zip文件。
Uri
作为额外的Intent.EXTRA_STREAM
传递给Intent
(Intent.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);
答案 0 :(得分:0)
啊,我明白了,所以发送应用必须为每个Uri授予自己的权限,而不是由调用应用程序的Intent隐式提供?
我对你的术语感到困惑,所以让我试试这个方法:
实施ContentProvider
有四种基本方法:
导出它并且不受任何权限的保护。这是愚蠢的。不要这样做。
是否已导出但受权限保护(例如android:readPermission
和android:writePermission
属性)。这种方法效果很好,但仅适用于专门用于与ContentProvider
通信的应用。对于ContentProvider
没有先验知识的应用程序,它不适用于大多数ACTION_SEND
支持活动的实施者。
不能导出它,但是您可以为{1}}授予特定请求的权限。通常情况下,这是通过添加到Uri
Intent
的{{1}}来完成的,尽管还有其他方法,例如自己调用startActivity()
。如果您是第三方访问提供商的发起人,例如使用grantUriPermission()
ACTION_SEND
启动活动,则此功能非常有用。
是否已将其导出,并且未授予Intent
的权限。在这种情况下,Uri
仅在您自己的应用中可用,即使您要求(例如,您的ContentProvider
请求),第三方也无法访问{。}}。
如何为最终被选择执行发送的应用授予权限,还是必须将其授予所有可能的应用?
我的一条评论中出现了错误,我为此道歉。
ACTION_SEND
现在授予您FLAG_GRANT_READ_URI_PERMISSION
中Uri
的读取权限,无论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。