FileProvider控件的使用

导论

我们都知道ContentProvider用于App间的数据共享,那么如果App间想要共享文件该怎么办呢?别担心,Google为我们提供了一个类,是ContentProvider的子类——FileProvider用于在不同应用间共享文件。
既然是ContentProvider的子类,那么整个的共享流程其实也就差不了太多,共享文件的整个思路是:当一个app想向一个共享了文件的app发送请求获取文件时,大多数情况下,这个请求都会开启一个分享的文件列表的Activity(该Acitivity隶属于分享文件app,目的是为了让用户选择想要获取的文件,因为它可能分享了不止一个文件)。用户选择完文件之后,分享文件的app(以下称为Server app,请求文件app称为client app)返回文件的URI和权限给client app。client app就可以根据拿到的URI去找到文件,有了权限也能对对应文件进行读写操作了。
当然你可能会有疑惑为什么是返回URI而不是直接把文件传输给client app或者直接将文件地址给它呢?
这就涉及到了一些安全和一些传输的问题,如果我们直接把文件内容或者整个文件传输给client app,那么在这个文件非常大的时候,十分的消耗资源。但是如果我们直接把文件地址传给其他app,那么就相当于把自身app的文件共享地址暴露了出来,这是非常危险的,因为我们无法预估其他app拿到这个地址之后会做什么。如果我们在这个地址下也有其他的共享文件,我们并不能保证他们的安全。因此我们让app共享文件以一种提供content URI的形式提供一个对文件的安全的操作:在Android中FileProvider组件可以通过getUriForFile方法为File生成一个Contet URI。具体过程下面会提到。

先是Server App端的实现

  • 指定FileProvider

    为App定义一个FileProvider,和ContentProvider一样需要在manifest文件中登记。在manifest中指定authority属性用来生成content URI,这些都和ContentProvider一样,不同的在于我们还要额外指定一个分享xml文件的目录。即我们所分享的xml文件都应该在该目录之下。

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.zln.admin.fileprovider"
        android:grantUriPermissions="true"
        android:exported="false">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths"/>
    </provider>

其中<meta-data> resourece属性指向res/xml/filepaths文件,在这个文件中filepaths文件中存放的是我们想要分享的目录。

  • 指明可分享的目录

    一旦在manifest文件中添加了FileProvider,那么就必须指明想要分享的文件目录。要指明这个目录,首先在res/xml文件夹中创建一个filepaths.xml文件.在这个文件中通过添加xml元素来指明目录。

<paths>
    <files-path path="text/" name="text"/>
</paths>

在这里,<file-path> tag共享了app私有内存files目录下的一个目录。Path属性则说明分享的是files/下的text目录,也就是说我们共享的文件是在files/text/这个目录之下的。Name属性则是告诉FileProvider添加path段到Content URI中,这样就达到了隐藏地址的效果。这样说可能还是比较抽象,举个例子吧:
通过FileProvider的getUriForFile形成的URI的格式是: content://authorities/name/文件名,例如我们在files/text目录下有一个test.txt的文件需要共享,我们通过FileProvider形成传给其他app的URI形式就是:content://com.zln.admin.fileprovider/text/test.txt
<paths>元素有许多的子元素,每一个子元素都分别指明了不同的分享目录。除了<files-path>还是<external-path>元素分享外部内存中的目录,<cache-path>分享内部缓存中的目录。
注意:在xml文件指定是唯一指定分享目录的方法,不能在代码中设置和添加分享目录,并且只有在目录下的文件才能共享。
到此为止,FIleProvider的登记已经完成了,总结一下在manifest文件中登记FileProvider需要的几步:
1、先在Manifest中注册
2、通过的resources属性中指向filepaths文件
3、在res/xml/filepaths文件中,指定共享目录

  • 共享文件
    一旦你能使用Content URI来共享文件,那么就能对其他App的请求做出回应了,回应这些请求的方法就是提供一个client app可以调用的接口&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值