大话FileProvider

戏说江湖静如水,游荡江湖才有情。我就是江湖中的一个戏子。

最近android N出来了,可是呢,原有的程序在androidN上运行却行不通了,最近楼主就遇到这样的一个问题。android.os.FileUriExposedException,网上一查,原来androidN加强了文件共享机制,当传递file:///开头的uri时会抛出SecurityException。需要通过FileProvider来将File转换为content://类型的uri。下面我们就来了解一下今天的主人公FileProvider吧。


what and why

FileProvider是ContentProvider的一个子类,不懂ContentProvider出门右拐上google,FileProvider能够很轻易的通过创建content://类型的uri而不是file:///类型的uri来分享文件,那么为什么通过content://类型uri就更安全呢,是因为分享file:///类型的uri需要拥有文件系统权限,而这个文件系统的权限是针对任何应用都可以申请的,那么你就可以对该文件进行修改,而这种修改严格来说是不安全的。而通过content://来分享,需要获取临时权限,而这种权限是跟随接收的Activity或Service的生命周期来的。

How to use

那FileProvider要怎么使用呢?很简单只需要三步:

第一步:在AndroidMainfest.xml中声明FileProvider

        

authorities 一般是 包名+.fileprovider。resource是file_paths定义的是需要共享的文件夹路径

第二步:定义file_paths

           

该文件中files_path是共享文件夹路径,在google中定义了几个路径如 下:

参数 函数 地址
files-path context.getFilesDir() /data/user/0/包名/files
cache-path context.getCacheDir() data/user/0/包名/cache
external-path Environment.getExternalStorageDirectory() /storage/emulated/0
external-files-path context.getExternalFilesDir(null) /storage/emulated/0/Android/data/包名/files
external-cache-path Context.getExternalCacheDir() storage/emulated/0/Android/data/包名/cache

共享路径就是(上述地址+path后面的参数)所代表的实际地址。

第三步:获取uri

在需要获取uri的地方通过FileProvider获取uri

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      uri = FileProvider.getUriForFile(context,authority,file);
} else {
      uri = Uri.fromFile(file);
}

提醒

// 在传递Intent的时候一定要通过Intent的setFlags来给接收的应用读取权限哦
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

这里的authority就是我们在定义FileProvider中authority是一样的,一般都是以包名+.fileprovider来定义,以避免和其他应用定义的authority相混淆。

总结

通过这三步我们就获得了我们需要的uri,一般的格式为content://包名.provider/path_name/file_name的形式。
这里path_name就是我们在files_path.xml中定义的name。走到这一步就大功告成了,你有没有学会呢?

你可能感兴趣的:(大话FileProvider)