uniapp在Android 10对公共目录的非媒体文件读取上传失败问题

  • Post author:
  • Post category:uniapp




本文覆盖的问题场景:

  • uniapp的文件IO接口报“targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径。请更改为应用运行路径!具体请看…”错误
  • uni.uploadFile接口上传图片视频正常,上传pdf,doc等非媒体文件报400,但无明确错误原因。
  • Android 10及以上,使用uni或plus读取公共目录文件报错。(或Android 11及以上正常,Android 10报错)



关于外部存储读写

我们知道Android开发中关于存储主要分两大部分:内部存储和外部存储。

内部存储是给每个应用自动授权的一个仅供此应用自身读写的目录,无需申请。

外部存储则包括了:

本应用外部存储目录、其他应用外部存储目录、公共目录媒体文件、公共目录非媒体文件四类。

在最初的Android开发中,应用可以随意读取上面的四类文件。

从Android 4.4(API 19)开始,默认授予

本应用外部存储目录访问

权限,无需申请;但如果需要访问

公共目录的媒体文件或非媒体文件

,必须申请外部存储的读取权限。(

其他应用外部存储目录

是申请任何权限也无法访问的)

出于安全考虑,从Android 10开始,对外部存储的读取权限进行了限制,默认只能访问:

公共目录媒体文件

但为了方便过度,在Android 10和Android 11下,如果应用在AndroidManifest.xml注册了

android:requestLegacyExternalStorage="true"

的话,应用可以暂时停用分区存储,继续上面除了其他应用外部存储目录外的其他三类文件。(如果目标版本是Android 11+,则在Android 11+上这个属性不生效。)

从Android 11开始,新增了【管理所有文件】(也叫:所有文件访问权限)权限,如果应用申请了这个权限,可以访问

本应用外部存储目录、公共目录媒体文件、公共目录非媒体文件

三类文件。多了一个公共目录非媒体文件的访问。

但这个权限授予条件比较苛刻,建议如果选择单个文件的话,尽量使用


存储访问框架



Uniapp中对外部存储的访问

主要可以参考

适配Android10+设备注意事项



uniapp中访问文件相关的包括

plus.io



uni.getFileInfo



uni.uploadFile

等一些API。

uniapp为了适配Android 10+,针对外部存储的访问,默认也是只能访问

本应用外部存储目录、公共目录媒体文件



针对Android 11+,如果应用有管理所有文件权限的话,也可以访问

公共目录非媒体文件

,就是有三类权限。

但uniapp没有兼容

android:requestLegacyExternalStorage

,所以即使添加了这个标签,在Android 10上面,uniapp的文件API依然无法访问公共目录非媒体权限。


针对公共目录非媒体文件的访问:

版本 管理所有文件 原生APP开发 uniapp开发
Android 10 可读 不可读
Android 11 可申请 可读 申请后可读
Android 12 可申请 申请后可读 申请后可读



公共目录非媒体文件访问实践

针对Android 11及以上的设备,有两种方法:

  • 申请管理所有文件权限,原生开发和uniapp都可以访问
  • 通过存储访问框架选择文件,未测试

针对Android 10,也有两种方法:

  • 添加

    android:requestLegacyExternalStorage

    ,原生开发可访问,uniapp开发依然不可访问。(可将对文件的操作读取上传等转移到原生逻辑实现,或者可通过原生插件将文件复制到本应用外部存储私有目录下,uniapp即可访问文件副本)
  • 通过存储访问框架选择文件,未测试



注意

上面总结的内容可能部分有误,如果发现请评论告知更新~



版权声明:本文为anjingshen原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。