如何使用支持FileProvider分享内容到其他应用程序? [英] How to use support FileProvider for sharing content to other apps?

查看:486
本文介绍了如何使用支持FileProvider分享内容到其他应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在寻找一种方式使用正确共享(未开放)与外部应用程序的内部文件支持Android库的<一个href="http://developer.android.com/reference/android/support/v4/content/FileProvider.html">FileProvider.

I'm looking for a way to correctly share (not OPEN) an internal file with external application using Android Support library's FileProvider.

在对该文档的例子中,

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.example.android.supportv4.my_files"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/my_paths" />
</provider>

和使用ShareCompat共享文件,其他应用程序如下:

and using ShareCompat to share a file to other apps as follows:

ShareCompat.IntentBuilder.from(activity)
.setStream(uri) // uri from FileProvider
.setType("text/html")
.getIntent()
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

不起作用,因为FLAG_GRANT_READ_URI_PERMISSION只授予权限的URI的数据的意图,对 EXTRA_STREAM <不是值规定/ code>额外的(如通过设置 setStream )。

我试图通过设置 Android的破坏安全性:出口的供应商,但 FileProvider 内部检查,如果本身是出口,如果是这样,它抛出一个异常。

I tried to compromise security by setting android:exported to true for the provider, but FileProvider internally checks if itself is exported, when so, it throws an exception.

推荐答案

从支持库,你必须手动授予和撤销权限(在运行时)的其他应用程序使用 FileProvider 阅读特定的URI。使用<一个href="http://developer.android.com/reference/android/content/Context.html#grantUriPermission%28java.lang.String,%20android.net.Uri,%20int%29">Context.grantUriPermission和<一href="http://developer.android.com/reference/android/content/Context.html#revokeUriPermission%28android.net.Uri,%20int%29">Context.revokeUriPermission的方法。

Using FileProvider from support library you have to manually grant and revoke permissions(at runtime) for other apps to read specific Uri. Use Context.grantUriPermission and Context.revokeUriPermission methods.

例如:

//grant permision for app with package "packegeName", eg. before starting other app via intent
context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

//revoke permisions
context.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

作为最后的手段,如果你不能提供软件包名称,你可以授予的权限,所有的应用程序,可以处理具体意图:

As a last resort, if you can't provide package name you can grant the permission to all apps that can handle specific intent:

//grant permisions for all apps that can handle given intent
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
...
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
    String packageName = resolveInfo.activityInfo.packageName;
    context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

根据<一个替代方法href="https://developer.android.com/reference/android/support/v4/content/FileProvider.html">documentation:

      
  • 放入一个Intent内容URI通过调用setData()。
  •   
  • 接下来,调用方法Intent.setFlags()与任何FLAG_GRANT_READ_URI_PERMISSION或FLAG_GRANT_WRITE_URI_PERMISSION   或两者。
  •   
  • 最后,发送意向到另一个应用程序。大多数情况下,通过调用的setResult()做到这一点。

  • Put the content URI in an Intent by calling setData().
  • Next, call the method Intent.setFlags() with either FLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION or both.
  • Finally, send the Intent to another app. Most often, you do this by calling setResult().

在一个Intent授予的权限留在,而烟囱效应   接收活动的是活动的。当堆栈完成时,
  权限被自动删除。权限一个
授予   在客户端应用程序的活动会自动扩展到其他
  该应用程序的组件。

Permissions granted in an Intent remain in effect while the stack of the receiving Activity is active. When the stack finishes, the
permissions are automatically removed. Permissions granted to one
Activity in a client app are automatically extended to other
components of that app.

顺便说一句。如果你需要,你可以复制<一个href="https://github.com/android/platform_frameworks_support/blob/911c869042ab71fe4f27b525f49a4d7f6ce08af6/v4/java/android/support/v4/content/FileProvider.java">source的FileProvider 并以prevent提供商变化 attachInfo 方法,从如果出口检查。

Btw. if you need to, you can copy source of FileProvider and change attachInfo method to prevent provider from checking if it is exported.

这篇关于如何使用支持FileProvider分享内容到其他应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆