关于android7.0的FileProvider获取File路径
2018-01-30 14:51
1151 查看
关于FileProvider的使用,网上随便搜索一下,都有一堆使用的教程说明,但这些说明,都只是告诉我们配置FileProvider,使系统认识这个FileProvider. 但是在我的项目中需要的是获取文件的绝对路径,于是就有了这个文章.
7.0应用(仅仅对于android 7.0版本的sdk而言,若是编译版本低于25仍然不会受到影响),android框架使用StrictMode Api禁止我们的应用对外部(跨越应用分享)公开file://,若使用file://格式共享文件则会报FileUriExposedException异常,android
7.0应用间的文件共享需要使用content://类型的URI分享,并且需要为其提供临时的文件访问权限
(Intent.FLAG_GRANT_READ_URI_PERMISSION和Intent.FLAG_GRANT_WRITE_URI_PERMISSION),对此,官方给我们的建议是使用FileProvider类进行分享.
由于android7.0的处理,
我们使用这句话获取到的uri是一个content类型的uri,而不是file类型了,这与我们需要的(文件路径)是不一样的,在网上查询无果后,开始自己查看源码FileProvider
值得我们注意的是
这个FileProvider 继承自我们的ContentProvider,
还有这个接口 这个接口看起来就是用来封装uri和File的,
查看源码发现我们对我们开放的只有获取uri的方法并没有获取file的方法
于是想到了使用反射大法:
直接贴上代码 当然这代码中我们必须要先拿到一个uri才行
这样我们就能拿到了 File对象进而拿到绝对路径了
有什么没考虑到的地方欢迎指出
文笔不好 哪里看不明白可以评论提问
说明
Android 7.0的新特性规定,对于android7.0应用(仅仅对于android 7.0版本的sdk而言,若是编译版本低于25仍然不会受到影响),android框架使用StrictMode Api禁止我们的应用对外部(跨越应用分享)公开file://,若使用file://格式共享文件则会报FileUriExposedException异常,android
7.0应用间的文件共享需要使用content://类型的URI分享,并且需要为其提供临时的文件访问权限
(Intent.FLAG_GRANT_READ_URI_PERMISSION和Intent.FLAG_GRANT_WRITE_URI_PERMISSION),对此,官方给我们的建议是使用FileProvider类进行分享.
由于android7.0的处理,
Uri uri = intent.getData();
我们使用这句话获取到的uri是一个content类型的uri,而不是file类型了,这与我们需要的(文件路径)是不一样的,在网上查询无果后,开始自己查看源码FileProvider
值得我们注意的是
public class FileProvider extends ContentProvider
这个FileProvider 继承自我们的ContentProvider,
interface PathStrategy { Uri getUriForFile(File var1); File getFileForUri(Uri var1); }
还有这个接口 这个接口看起来就是用来封装uri和File的,
查看源码发现我们对我们开放的只有获取uri的方法并没有获取file的方法
public static Uri getUriForFile(Context context, String authority, File file) { FileProvider.PathStrategy strategy = getPathStrategy(context, authority); return strategy.getUriForFile(file); }
于是想到了使用反射大法:
直接贴上代码 当然这代码中我们必须要先拿到一个uri才行
List<PackageInfo> packs = this.getPackageManager().getInstalledPackages(PackageManager.GET_PROVIDERS); if (packs != null) { String fileProviderClassName = FileProvider.class.getName(); for (PackageInfo pack : packs) { ProviderInfo[] providers = pack.providers; if (providers != null) { for (ProviderInfo provider : providers) { if (uri.getAuthority().equals(provider.authority)){ if (provider.name.equalsIgnoreCase(fileProviderClassName)) { Class<FileProvider> fileProviderClass = FileProvider.class; try { Method getPathStrategy = fileProviderClass.getDeclaredMethod("getPathStrategy", Context.class , String.class); getPathStrategy.setAccessible(true); Object invoke = getPathStrategy.invoke(null, this, uri.getAuthority()); if (invoke != null) { String PathStrategyStringClass = FileProvider.class.getName()+"$PathStrategy"; Class<?> PathStrategy = Class.forName(PathStrategyStringClass); Method getFileForUri = PathStrategy.getDeclaredMethod("getFileForUri", Uri.class); getFileForUri.setAccessible(true); Object invoke1 = getFileForUri.invoke(invoke, uri); if (invoke1 instanceof File) { filePath = ((File) invoke1).getAbsolutePath(); } } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } break; } Log.e(provider); break; } } } } }
这样我们就能拿到了 File对象进而拿到绝对路径了
有什么没考虑到的地方欢迎指出
文笔不好 哪里看不明白可以评论提问
相关文章推荐
- 关于使用file上传图片获取图片绝对路径
- 关于获取<input type='file'>获取文件的路径问题
- 关于firefox获取不到HTML标签的file控件的完整路径解决方案
- 关于Bugly版本兼容Android7.0 FileProvider与PhotoPicker冲突问题
- 关于jsp中<input type="file">获取路径问文件名,获取完全路径问题
- 关于jsp中<input type="file">获取路径问文件名,获取完全路径问题
- Android学习笔记(5)---关于获取File路径、文件过滤
- 关于使用input type=file 标签上传文件的注意细节(上传文件 无法获取文件 问题)
- android7.0 SD Card 路径获取
- 如何获取当前运行的.exe所在路径的双斜线形式?---利用GetModuleFileName
- 如何获取data的路径-@ConfigFile
- <input type="file">定义样式并获取上传文件路径及指定文件类型
- File 获取文件名 路径 测试结果
- 获取文件的绝对路径, GetCurrentDirectory()和GetModuleFileName()函数的区别
- php dirname(__FILE__) 获取当前文件的绝对路径
- js如何获取file控件的完整路径具体实现代码
- OpenFileDialog获取文件名和文件路径问题
- 关于File控件上传图片,java代码获取图片宽高
- 关于 Android 7.0 适配中 FileProvider 部分的总结
- Js获取file上传控件的文件路径总结