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

在安卓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

首先在配置文件中声明:


    ...
    
        ...
        "android.support.v4.content.FileProvider"
            android:authorities="com.mydomain.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            ...
        
        ...
    

。 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/下

"http://schemas.android.com/apk/res/android">
    "my_images" path="images/"/>
    ...

内部节点:

//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

Android 7.0 应用间文件访问方法(FileProvider)_第1张图片


官方文档:
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

你可能感兴趣的:(Android,Intent)