乐趣区

关于android:Android-70应用之间共享文件

原文首发于微信公众号:躬行之。

开发中常常须要将某个文件向另一个应用程序传递,如图片上传到另一个应用程序、文件在不同存储门路之间的复制粘贴等都须要共享文件,能够这样了解接管文件的利用是在向提供文件的利用发送申请。

从 Android 7.0 开始,Android 执行 StrictMode 策略,禁止在利用内部公开 file://URL,如果在 Android 7.0 以上的利用不应用 FileProvider,则会抛出 FileUriExposedException 异样,Android 7.0 当前要在利用之间共享文件要应用 content://URL 授予 URL 长期拜访权限,即要应用 FileProvider 的形式来授予长期拜访权限,具备长期拜访权限的 URL 是平安的,这种长期的 URL 会主动过期,其中 FileProvider 提供的 getUriForFile() 用于生成文件的内容。

在所有状况下,从您的应用程序向另一个应用程序提供文件的惟一平安办法是向接管应用程序发送文件的内容 URI,并授予该 URI 的长期拜访权限。具备长期 URI 拜访权限的内容 URI 是平安的,因为它们仅实用于接管 URI 的应用程序,并且它们会主动过期。Android FileProvider 组件提供 getUriForFile()办法,用于生成文件的内容 URI。

这里也会提到一个在 Android 7.0 及更高版本时经常出现的异样:FileUriExposedException,通过应用 FileProvider 就能够解决该异样,当然这也是 Android 零碎在安全性上不断完善的后果。

  1. 指定 FileProvider
  2. 指定文件共享门路

指定 FileProvider

在 AndroidManifest 文件中指定 Provider,参考如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application
        ...>
        
        <!--android:authorities="${applicationId}.yourname"-->
        <provider
            android:name="android.support.v4.content.FileProvider"
            <!--authorities 属性指定要用于 FileProvider 生成的内容 URI 的 URI 权限, 个别是 applicationId.yourname" 组成 -->
            android:authorities="com.example.myapp.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>
        ...
    </application>
</manifest>

指定文件共享门路

下面代码中在 meta-data 目录中指定了要共享的文件目录,文件目录在 filepathd.xml 中定义,可在相应的 xml 中定义的门路有以下几种,具体参考如下:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <paths>

        <!-- 示意设施的根目录 (new File("/"))-->
        <root-path name="root" path="" />
        <!-- 示意 context.getFileDir()-->
        <files-path name="files" path="" />
        <!-- 示意 context.getCacheDir()-->
        <cache-path name="cache" path="" />
        <!-- 示意 Environment.getExternalStorageDirectory()-->
        <external-path name="external" path="" />
        <!-- 示意 context.getExternalFilesDirs()-->
        <external-files-path name="name" path="path" />
        <!-- 示意 getExternalCacheDirs()-->
        <external-cache-path name="name" path="path" />

    </paths>
</resources>

在 xml 中示意某个门路须要两个属性,path 示意以后指定目录的子目录,如果不指定则示意的是以后指定目录下的根目录及子目录,name 示意会将 name 增加的 URL 前面作为该文件的拜访门路,参考如下:

// 示意以后要共享的文件会在 context.getFileDir() 目录下的 images 子目录下查找要共享的文件
<paths>
    <files-path path="images/" name="myImage" />
</paths>

// 示意最终生成的共享的文件 URL
content://com.example.myapp.fileprovider/myImage/image.jpg

获取 Uri

最初,配置实现之后,在所有须要应用文件相干的,在获取 Url 时应该依照如下形式获取,具体如下:

public Uri getUri(File file) {
    Uri uri = null;
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {uri = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".youName", file);
    } else {uri = Uri.fromFile(file);
    }
    return uri;
}

这样就能够在 Android 7.0 以上欢快的共享文件了,这个知识点也算是开发中常常会遇到到。

退出移动版