利用DataAbility通过可访问的uri共享文件给其他应用 原创

拓维云创易乘民
发布于 2021-7-27 09:26
浏览
2收藏

最近在做鸿蒙文件分享时碰到一个访问文件的权限问题,不同的应用间不管是共有路径还是私有路径,你只知道文件的具体路径,不论通过路径new File还是通过路径生成的uri去访问其他应用生成的文件,都会得到一个permission denied的错误,导致文件无法访问。

这个问题困扰了我很久,一直没有找到好的解决方案,于是发帖求助https://developer.huawei.com/consumer/cn/forum/topic/0201460287319530909?fid=0101303901040230869。最终版主给我指了个方向参考——DataAbility。

之前做过一点数据库共享的工作,DataAbility也看过,确实注意到有共享文件的方法,但是示例代码太少,不知道该如何使用这个功能,主要是不知道文件的uri该如何写,细看文档关于uri的介绍:
利用DataAbility通过可访问的uri共享文件给其他应用-鸿蒙开发者社区

这里给出的是数据库uri的示例,文件uri我们这里主要用到了scheme、authority和path这三个参数,DataAbility中我们需要重写FileDescriptor openFile(Uri uri, String mode)方法来操作文件:
利用DataAbility通过可访问的uri共享文件给其他应用-鸿蒙开发者社区

这里的getFilesDir()要和我们存放文件的目录一致,既可以是私有目录也可以是公共目录。这里pathList的index0所指authority的不是文档中的设备ID而是com.example.myapplication.DataAbility这个在config.json的DataAbility中配置的uri路径,在安卓中叫authority,后面的路径是我们存放文件的目录下文件的相对路径,还要加上自定义权限:
利用DataAbility通过可访问的uri共享文件给其他应用-鸿蒙开发者社区

这里permissions和defPermissions都不可缺少,否则会报权限错误。这样,我们的数据提供方DataAbility的主要实现就写完了,接下来看其他应用如何访问我们通过DataAbility提供的文件。首先是鸿蒙应用,我们需要在请求访问的应用config.json中加上刚才在DataAbility声明的自定义权限:
利用DataAbility通过可访问的uri共享文件给其他应用-鸿蒙开发者社区

这里以访问一个图片为例:
利用DataAbility通过可访问的uri共享文件给其他应用-鸿蒙开发者社区

这里调用helper.openFile方法就会回调之前DataAbility中复写的openFile方法获取到相应文件的描述符包装成文件流之后就可以进行文件读取操作,这样就不会报权限错误而无法访问了。

接下来看安卓应用如何访问,安卓的做法和鸿蒙有很大区别,毕竟SDK不同。同样,我们需要在AndroidManifest.xml中加上自定义权限:
<uses-permission android:name=“com.example.myapplication.DataAbility.DATA”/>
我们这里访问同样一张图片,示例代码是kotlin,java所用方法一样:
利用DataAbility通过可访问的uri共享文件给其他应用-鸿蒙开发者社区

安卓的uri需要以content作为scheme,不然无法定位到DataAbility,注意这里不能直接用resolver.openFile(),虽然有这个方法,但是直接调用会报错,这里需要调用contentProviderClient的openFile方法,这里的操作步骤是根据偶然的一次报错信息看到安卓contentProvider部分的堆栈信息模仿这样的调用方式得来的,具体为什么要这样写我也不是很清楚,contentProviderClient使用完后要及时释放。至此,鸿蒙应用和安卓应用都能通过指定的uri来访问第三方鸿蒙应用提供的文件了,只是两个SDK的Uri不是同一个类,因此不能通用,只能通过路径字符串来拼接。

下面是鸿蒙和安卓访问图片的demo结果:
利用DataAbility通过可访问的uri共享文件给其他应用-鸿蒙开发者社区利用DataAbility通过可访问的uri共享文件给其他应用-鸿蒙开发者社区

总的来说,DataAbility的使用方法和安卓的ContentProvider是一致的,通过查看打包生成的源文件可知DataAbility最后的实现确实是一个ContentProvider,走了太多弯路主要还是因为安卓四大组件中ContentProvider是接触的最少的一个,对用法不太熟悉,这次也算复习了一下ContentProvider的用法。

(此文章是本人之前在鸿蒙论坛发的贴子,我会把之前的文章先挪过来,今后关于鸿蒙的技术文章会转移到此处,附上原文链接
https://developer.huawei.com/consumer/cn/forum/topic/0203466327475580151?fid=0101303901040230869)

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
2
收藏 2
回复
举报
回复
    相关推荐