高版本的对文件权限的管控抓的很严格,理论上两个应用之间的文件传递现在都应该是用去实现,这篇博客来一起了解下它的实现原理 。
首先我们要明确一点,就是一个,所以需要在.xml里面对它进行声明:
和普通的不一样的是他多了一个..的meta-data指定了一个xml资源:
【系统应用使用FileProvider的坑】
文件URI
这个xml的作用在于为文件生成URI,root-path、files-path、cache-path这些标签代表父路径:
root-path : File("/")files-path : Context.getFilesDir()cache-path : context.getCacheDir()external-path : Environment.getExternalStorageDirectory()external-files-path : ContextCompat.getExternalFilesDirs(context, null)[0]external-cache-path :ContextCompat.getExternalCacheDirs(context)[0]external-media-path :context.getExternalMediaDirs()[0]
path属性代表子路径,name代表为"父路径/子路径"起的名字,
例如上面配置代表的就是我们为 new File(.(), "/") 这个路径起了个名字叫做files
val filesDir = File(context.getFilesDir(), "images/")val uri = FileProvider.getUriForFile(this, "me.linjw.demo.fileprovider.provider", File(filesDir, "test.jpg"))// uri就是把filesDir的路径转换"files",然后加上content://me.linjw.demo.fileprovider.provider// 即 "content://me.linjw.demo.fileprovider.provider/files/test.jpg"
从FileProvider的源码里面就能看到这部分的转换逻辑:
private static final String TAG_ROOT_PATH = "root-path";private static final String TAG_FILES_PATH = "files-path";private static final String TAG_CACHE_PATH = "cache-path";private static final String TAG_EXTERNAL = "external-path";private static final String TAG_EXTERNAL_FILES = "external-files-path";private static final String TAG_EXTERNAL_CACHE = "external-cache-path";private static final String TAG_EXTERNAL_MEDIA = "external-media-path";...int type;while ((type = in.next()) != END_DOCUMENT) {if (type == START_TAG) {final String tag = in.getName();final String name = in.getAttributeValue(null, ATTR_NAME);String path = in.getAttributeValue(null, ATTR_PATH);File target = null;if (TAG_ROOT_PATH.equals(tag)) {target = DEVICE_ROOT;} else if (TAG_FILES_PATH.equals(tag)) {target = context.getFilesDir();} else if (TAG_CACHE_PATH.equals(tag)) {target = context.getCacheDir();} else if (TAG_EXTERNAL.equals(tag)) {target = Environment.getExternalStorageDirectory();} else if (TAG_EXTERNAL_FILES.equals(tag)) {File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null);if (externalFilesDirs.length > 0) {target = externalFilesDirs[0];}} else if (TAG_EXTERNAL_CACHE.equals(tag)) {File[] externalCacheDirs = ContextCompat.getExternalCacheDirs(context);if (externalCacheDirs.length > 0) {target = externalCacheDirs[0];}} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP&& TAG_EXTERNAL_MEDIA.equals(tag)) {File[] externalMediaDirs = context.getExternalMediaDirs();if (externalMediaDirs.length > 0) {target = externalMediaDirs[0];}}if (target != null) {strat.addRoot(name, buildPath(target, path));}}}...private static File buildPath(File base, String... segments) {File cur = base;for (String segment : segments) {if (segment != null) {cur = new File(cur, segment);}}return cur;}
- vagrant使用_使用Vagrant的Kubernetes上的Java EE
- 一 Python自动化运维笔记:系统性能信息模块psutil
- 智慧客流系统助力市场竞争中立于不败之地
- #####笔记##### Android P新特性---应用待机群组
- 使用Vagrant的Kubernetes上的Java EE 7和WildFly
- 32位单总线计算机系统中,【计算机类职业资格】软件设计师
- android 美团多渠道打包,美团多渠道打包原理以及使用
- win10 重置电脑 linux,win10系统如何重置Linux子系统
- windows系统编程2——内存管理和网络
- 【PET材料的生产设备】——导电滑环应用实例,厂家讲解