推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

安卓开发学习之利用FileProvider获取文件uri

   2023-07-30 网络整理佚名1630
核心提示:最后的结果,就是外部app获取到的分享目录,不是路径,而是假名利用获取文件Uri由于类只有一个()方法对外开放,那么如果要通过的uri获取文件路径,就需要通过反射了。内部有一个类,这个类实现了接口,负责文件uri和文件路径的转换。然后调用这个对象的()方法,获取uri对应的文件对象,最后通过文件对象获取路径。

现在我们要创建一个与上面提到的标签对应的xml文件-->xml/.xml



    
        
        
        
        
        
        
    

其中,标签file-path和cache-path代表手机内存中的某个目录,path属性是该目录下的子目录,name属性是假名,会替换path目录的绝对路径

图中涉及到的子标签对应的路径如下:

子标签

子标签对应的绝对路径(不带路径)

子标签对应的绝对路径(添加路径)

笔名

文件路径

app私有存储区下的files目录

(.())

文件目录加路径

(.()/文件)

文件

缓存路径

应用私有目录下的缓存目录

(.())

私有缓存目录加路径

(.()/文件)

缓存

-小路

外部存储根目录

(.

())

外部存储根目录加路径

(.

()

/文件)

-文件路径

外部存储根目录下的文件目录

(.())

文件目录加路径

(.

()/文件)

-缓存路径

外部存储根目录下的缓存目录

(.())

缓存目录加路径

(.

()/文件)

最终结果是外部app获取到的共享目录,不是路径,而是假名

而且,每次添加共享目录时,都需要添加对应的子标签

例如,如果我添加一个新的共享目录,这是外部存储根目录下的文件夹,我添加一个子标签,如下所示:

就是这样

用于获取文件Uri

代码如下所示:

String path = Environment.getExternalStorageDirectory().getPath() + "/Pictures/dongqiudi/1523624189281.jpg";
File file = new File(path);
if (file.exists()) {
   Uri uri = FileProvider.getUriForFile(MainActivity.this, "com.example.songzeceng.myFileProvider", file);
   Log.i(TAG, "uri:" + uri.toString());
}

代码很简单,但是为了防止出错,我判断了文件是否存在(不存在怎么办,我没试过)

结果

正如您所看到的,它确实替换了我们用假名指定的共享目录路径。 这个uri和之前的路径uri不同,但是不影响使用,仍然会正确找到我们的文件。

通过uri获取文件路径

由于该类只有一个对外开放的()方法,所以如果想通过uri获取文件路径,就需要使用反射。

先说一下思路:

里面有一个类,实现了接口,负责文件uri和文件路径的转换。 通过调用对象自身的私有静态方法()来初始化对象,因此我们可以直接调用该方法来获取初始化后的对象。 然后调用这个对象的()方法获取uri对应的文件对象,最后通过文件对象获取路径。

代码看起来像这样

                Class clazz = FileProvider.class;
                Class simplePathStrategyClazz = clazz.getDeclaredClasses()[0];
                Method getPathStrategyMethod = clazz.getDeclaredMethod("getPathStrategy", Context.class, String.class);
                getPathStrategyMethod.setAccessible(true);
                Object simplePathStrategyObject = getPathStrategyMethod.invoke(null, MainActivity.this, "com.example.songzeceng.myFileProvider");
                Method method = simplePathStrategyClazz.getDeclaredMethod("getFileForUri", Uri.class);
                method.setAccessible(true);
                File destFile = (File) method.invoke(simplePathStrategyObject, uri);
                Log.i(TAG, "share: file path:" + destFile.getAbsolutePath());

首先获取类和类,我们需要的类就是这两个;

其次,获得()方法对象,方法输入参数是和,这个对象就是我们的身份。 当然,这个方法对象的可访问性应该设置为true;

再次调用()方法,传入上下文对象和标识字符串,获取对象。 这里只能使用类,因为外部不能访问任何类或类;

然后,获取类的()方法对象,以Uri对象作为输入参数,并将方法可访问性设置为true;

最后调用该对象的()方法,输入参数为Uri对象,强制类型转换为File后即可获取绝对路径。

程序运行的输出日志如下图所示

功能是可以实现的,但是反射的消耗非常高,使用时要三思。

结语

这个例子只是一个验证,看看文件uri是否被正确解析和转换,如果程序崩溃了,一切正常,那么我们就可以根据我们的业务使用新生成的uri

 
标签: uri 文件目录
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON