Android 7.0 应用间文件访问方法(FileProvider)

来源:互联网 发布:mac无法抹掉u盘 编辑:程序博客网 时间:2024/06/14 10:18

在安卓7.0以前,应用之间的文件共享可通过intent+”file:// Uri” 的形式进行访问(代码如下),但在安卓N之后,便收回了文件访问的权限,若要在应用间建立临时文件共享,必须通过FileProvider类来进行操作,使用FileProvider类生成content:// Uri来替代file:// Uri;

本文为大家提供两种解决方案,第一种相对麻烦一点,需要自己配置各种文件,第二种是直接引用库文件,仅需一行代码即可搞定;


安卓版本<N

        //APK升级        Intent i = new Intent(Intent.ACTION_VIEW);        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");        mContext.startActivity(i);

异常

android.os.FileUriExposedException: file:///mnt/sdcard/XXX/XXX.apk exposed beyond app through Intent.getData()

安卓版本>=N

首先在配置文件中声明:

<manifest>    ...    <application>        ...        <provider            android:name="android.support.v4.content.FileProvider"            android:authorities="com.mydomain.fileprovider"            android:exported="false"            android:grantUriPermissions="true">            ...        </provider>        ...    </application></manifest>

。 android:name 固定写法。
。 android:authorities 可自定义,最好使用包名来区分
。 android:exported 必须设置成 false,否则运行时会报错java.lang.SecurityException: Provider must not be exported 。
。 android:grantUriPermissions 共享文件访问权限。
。 节点中的android:resource指定了共享文件的路径

file_paths:file_paths即是该Provider对外提供文件的目录的配置文件,存放在res/xml/下

<paths xmlns:android="http://schemas.android.com/apk/res/android">    <files-path name="my_images" path="images/"/>    ...</paths>

内部节点:

//getFilesDir()<files-path name="name" path="path" />//getCacheDir()<cache-path name="name" path="path" />//Environment.getExternalStorageDirectory()<external-path name="name" path="path" />//getExternalFilesDir()<external-files-path name="name" path="path" />//getExternalCacheDir()<external-cache-path name="name" path="path" />

兼容后的代码:

        //APK升级        Intent i = new Intent(Intent.ACTION_VIEW);        Uri uri;        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        // 判断版本大于6.0        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {            uri = FileProvider.getUriForFile(mContext,"配置文件的authorities",new File("file://" + apkfile.toString()));        }else {            uri = Uri.parse("file://" + apkfile.toString());        }        i.setDataAndType(uri, "application/vnd.android.package-archive");        mContext.startActivity(i);

还有一种更简便的方法是直接使用库,仅一行代码即可,不需要额外对配置文件进行修改,也不用新建XML文件:

在配置中引入:compile 'com.zhy.base:fileprovider:1.0.0'

代码:

            Intent intent = new Intent(Intent.ACTION_VIEW);            //APKfile为你的安装包文件url            FileProvider7.setIntentDataAndType(mContext,intent, "application/vnd.android.package-archive", apkfile, true);            mContext.startActivity(intent);

不过在使用库之后在编译时遇到一个bug,无法通过,不知道是不是因为库文件引起的:Error:Execution failed for task ‘:app:incrementalDebugJavaCompilationSafegua

以下为两个解决办法:

1.在项目配置中将API升级至7.0
2.在引入库文件时将compile改为provided

0.0


官方文档:
https://developer.android.google.cn/reference/android/support/v4/content/FileProvider.html

FileProvider详解:
http://blog.csdn.net/lmj623565791/article/details/72859156

FileProvider库:
https://github.com/hongyangAndroid/FitAndroid7

阅读全文
1 0