美文网首页
记一次使用FileProvider

记一次使用FileProvider

作者: 别却江南 | 来源:发表于2019-04-02 19:55 被阅读0次

    起因

    项目需要在下载文件后,使用其他app打开该文件,因为targetversion>24,由于众所周知的原因,需要使用ContentProvider来提供app内部文件给其他app使用,这里因为项目中是普通文件,所以选择了FileProvider。

    重点

    怎么使用FileProvider的文章网上已经很多了,大同小异,我就不多写了。
    具体可以看我想把 FileProvider 聊的更透彻一些.
    我单独说说filepaths文件的声明。
    之前也用过FileProvider,也声明过filepaths文件,就是照着网上的文章写,但是不知道为什么要这么写。

    经过

    根据我自己的总结,不一定对—— filepaths文件主要关乎两个:

    • 文件能否被外部应用访问
    • 文件生成的uri的路径名称

    先假设一个需求,然后来解决吧:

    根据给定url下载一个文件,并保存在内存中,然后使用别的app打开该文件。
    

    假设文件保存在内部存储中,文件名为“image.jpg”:

    File shareFile = new File(getFilesDir(), "image.jpg");
    

    需要使用其他app打开这个文件。
    首先
    1.在AndroidManifest文件中声明FileProvider:

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

    其中 @xml/filepaths 需要声明在res/xml文件中,内容为:

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <root-path
            name="root"
            path="" />
        <files-path
            name="files"
            path="." />
        <cache-path
            name="cache"
            path="." />
        <external-path
            name="external"
            path="." />
        <external-path
            name="external_files"
            path="." />
    </paths>
    

    这里主要讲讲filepaths文件中各个值的作用——我了解的部分。
    首先有一个对应关系,这是FileProvider的源码中规定的:

    • root-path:表示根目录,『/』。
    • files-path:表示 content.getFileDir() 获取到的目录。
    • cache-path:表示 content.getCacheDir() 获取到的目录
    • external-path:表示Environment.getExternalStorageDirectory() 指向的目录。
    • external-files-path:表示 ContextCompat.getExternalFilesDirs() 获取到的目录。
    • external-cache-path:表示 ContextCompat.getExternalCacheDirs() 获取到的目录。
      filepaths文件的目的之一:声明你允许外部应用临时访问的文件的目录。即:只有在这里声明了的目录才能被外部应用访问到,如果希望通过content.getFileDir()得到的文件能被访问,则声明中需包含
    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <files-path
            name="files"
            path="." />
    </paths>
    

    或者

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
       <root-path
            name="root"
            path="" />
    </paths>
    

    前者表示允许外部应用访问所有content.getFileDir()目前之下的文件,后者表示允许外部应用访问所有应用内部的文件,当然也就包括content.getFileDir()目前之下的文件。所以如果偷懒的话,可以只写后者也是可以的。
    同理,如果需要允许外部应用访问 content.getCacheDir() 目录下的文件,则声明中需包含

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
          <cache-path
            name="cache"
            path="." />
    </paths>
    

    或者

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
       <root-path
            name="root"
            path="" />
    </paths>
    

    以此类推。
    如果只允许外部应用访问content.getFileDir()内"cache/image/"目前下的文件,则可以由path来实现。
    如果文件的绝对路径为:

    /data/user/0/com.xxx.xxx/files/users/126357742779629568/cache/files/aboutaboutaboutaboutabout.html
    

    由前面的内容可知,如果要允许外部应用访问该文件,则filepaths文件可以为:

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <files-path
            name="files"
            path="." />
    </paths>
    

    此时生成的uri为:

    content://com.xxx.xxx.fileprovider/files/users/126357742779629568/cache/files/aboutaboutaboutaboutabout.html
    

    filepaths也可以是:

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <files-path
            name="files"
            path="./user" />
    </paths>
    

    此时生成的uri为:

    content://com.uneed.yuni.fileprovider/files/126357742779629568/cache/files/aboutaboutaboutaboutabout.html
    

    或者是:

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <files-path
            name="files"
            path="./user/126357742779629568/cache/files" />
    </paths>
    

    此时生成的uri为:

    content://com.uneed.yuni.fileprovider/files/aboutaboutaboutaboutabout.html
    

    或者其他你猜到的。
    即在生成的uri中,path所表示的路径(./user/126357742779629568/cache/files)整个由name字段的files所替代。
    最后,其实以上内容通过查看Fileprovide的源码都可以知道。
    完。

    相关文章

      网友评论

          本文标题:记一次使用FileProvider

          本文链接:https://www.haomeiwen.com/subject/jkcnbqtx.html