本文覆盖的问题场景:

  • 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.iouni.getFileInfouni.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即可访问文件副本)
  • 通过存储访问框架选择文件,未测试

注意

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

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐