RxHttp 完美适配Android 10/11 上传/下载/进度监听
苦逼码农xisdn
2020年12月26日 23:39

1、前言

随着Android 11的正式发布,适配Android 10/11 分区存储就更加的迫切了,因为Android 11开始,将强制开启分区存储,我们就无法再以绝对路径的方式去读写非沙盒目录下的文件,为此,RxHttp 在版本中就正式适配了分区存储,并且,可以非常优雅的实现文件上传/下载/进度监听,三步即可搞懂任意请求。

老规矩,先看看请求三部曲

如果你想了解RxHttp更过功能,请查看以下系列文章

RxHttp 2000+star,协程请求,仅需三步

RxHttp 让你眼前一亮的Http请求框架

gradle依赖

必须

可选

2、Android 10/11 分区存储

当我们App的更改为28以上,并且运行在Android 10以上设备时,我们无法再以绝对路径的方式,去读写非沙盒目录下的文件,当然,如果App是覆盖安装(如:targetSdkVersion 28 覆盖安装为 29),则会保持原来的访问方式。

requestLegacyExternalStorage属性

如果我们的app将targetSdkVersion更改为28以上,且想保持原来的访问方式,则需要在清单文件中将  的值设置为 ,如下:

此时,便可继续以原来的方式去读写文件,然而,在Android 11上,Google又给了它新的含义,来看看官网的原话

也就是说,在Android 11设备上,为29以上的app,将强制开启分区存储,属性失效

注意,只要同时满足以上两个条件,不管是覆盖安装还是requestLegacyExternalStorage = true,都会强制开启分区存储

分区存储优势

  • 对用户来说,解决了文件乱放的现象

  • 对于开发者来说,我们无需写权限,就可以在分区目录下创建文件,并且访问自己创建的文件,不需要读权限(访问其它应用创建的文件,还是需要读权限)

新的文件访问方式

此图来源于作者[连续三届村草]分享的Android 10(Q)/11(R) 分区存储适配一文,感谢作者的总结

3、上传

3.1、简单上传

在介绍Android 10文件上传前,我们先来看看Android 10之前是如何上传文件的,如下:

以上,我们仅需调用 方法添加文件对象即可,RxHttp提供了一系列方法,列出几个常用的,如下:

在Android 10,我们需要通过Uri对象去上传文件,在RxHttp中,通过方法添加对象,如下:

同样的,RxHttp内部提供了一系列方法供大家选择,列出几个常用的,如下:

3.2、带进度上传

老规矩,看看Android 10之前是如何监听上传进度的,如下:

相比于单纯的上传文件,我们仅需额外调用操作符,传入线程调度器及进度回调即可。

同样的,对于Andorid 10,我们仅需要将File对象换成Uri对象即可,如下:

怎么样?是不是so easy!!

4、下载

下载较于上传,要丰富很多,内部提供类一系列下载方法来满足不同的需求,如下:

4.1、简单下载

在Android 10之前,我们仅需传入一个本地文件路径即可,如下:

而到了Android 10,我们需要自定义一个类,继承类,如下:

这里简单介绍下上面的代码,本文后续会详细介绍为啥定义这样一个类,以及如何构建一个对象。

  • 首先就是继承UriFactory抽象类,实现getUri(Response)方法

  • 接着就在实现方法里判断SDK版本,Android 10以上,就通过contentResolver构建Uri对象,否则就根据File对象构建Uri对象,这样就可以兼容到所有系统版本

  • 最后返回Uri对象即可

有了类,执行下载就会及其方便,如下:

以上方法都接收一个类型参数,故我们可以直接传入对象。

4.2、带进度下载

对于带进度下载,我们只需要调用方法时,传入线程调度器及进度回调即可,如下:

Android 10之前

Android 10以上,传入我们定义的对象的同时,再传入传入线程调度器及进度监听即可,如下:

4.3、带进度断点下载

对于断点下载,我们需要调用一系列方法,可以把它们理解为追加下载,实现如下:

Android 10之前

在Android 10上,有一点需要注意的是,我们在构建对象时,需要传入第三个参数,可以把它理解为要查询的文件夹,断点下载,RxHttp内部会根据文件名在指定的文件夹下查找对应的文件,得到当前文件的长度,也就是断点位置,从而告诉服务端从哪里开始下载,如下:

5、如何构建Uri对象?

在上面代码中,我们自定义了类,其中最为关键的代码就是如何构建一个对象,接下来,就教大家如何去构建一个,马上开始,如下:

  • 第一步,配置文件名称,这个就没啥好说的了

  • 第二步,配置文件类型,每个文件都应该有一个类型描述,这样,后续查找时,就可以根据这个类型去查找出同一类型的文件,如:查找相册,此属性是可选的,如果不配置,后续就无法根据类型查找到这个文件

  • 第三步,配置存储目录,这个是相对路径,总共有10个目录可选,如下:

    • Environment.DIRECTORY_DOCUMENTS 对应路径:/storage/emulated/0/Documents/

    • Environment.DIRECTORY_DOWNLOADS 对应路径:/storage/emulated/0/Download/

    • Environment.DIRECTORY_DCIM 对应路径:/storage/emulated/0/DCIM/

    • Environment.DIRECTORY_PICTURES 对应路径:/storage/emulated/0/Pictures/

    • Environment.DIRECTORY_MOVIES 对应路径:/storage/emulated/0/Movies/

    • Environment.DIRECTORY_ALARMS 对应路径:/storage/emulated/0/Alrams/

    • Environment.DIRECTORY_MUSIC 对应路径:/storage/emulated/0/Music/

    • Environment.DIRECTORY_NOTIFICATIONS 对应路径:/storage/emulated/0/Notifications/

    • Environment.DIRECTORY_PODCASTS 对应路径:/storage/emulated/0/Podcasts/

    • Environment.DIRECTORY_RINGTONES 对应路径:/storage/emulated/0/Ringtones/

如果需要在以上目录下,创建子目录,则传入的时候,直接带上即可,如下

  • 第四步,插入到对应的表中,总共有5张表可选,如下:

    • 存储图片:MediaStore.Images.Media.EXTERNAL_CONTENT_URI

    • 存储视频:MediaStore.Video.Media.EXTERNAL_CONTENT_URI

    • 存储音频:MediaStore.Audio.Media.EXTERNAL_CONTENT_URI

    • 存储任意文件:MediaStore.Downloads.EXTERNAL_CONTENT_URI

    • 存储任意文件:MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL)

需要特殊说明下,以上5张表中,只能存入对应文件类型的信息,如我们不能将音频文件信息,插入到图片表中,插入时,系统会直接抛出异常

注意事项

以上5张表中,除了对插入的文件类型有限制外,还对要插入的相对路径有限制,如,我们将一个apk文件下载目录下,并插入到图片表中,如下:

当执行到操作时,系统将会直接报错,报错信息如下:

大致意思就是,目录不允许插入到表中,该表只允许插入目录

6、小结

开源不易,写文章更不易,喜欢的话,还需劳烦大家给本文点个赞,可以的话,再给个star,我将感激不尽

www.cnblogs.com/laolv4519/p/14194819.html

www.tianya.cn/143525403/profile

www.tianya.cn/143525409/profile

www.tianya.cn/143525422/profile

www.tianya.cn/143525420/profile

www.tianya.cn/143525426/profile

www.tianya.cn/143525432/profile

www.tianya.cn/143525443/profile

www.tianya.cn/143525450/profile

www.tianya.cn/143525483/profile

www.tianya.cn/143525521/profile

www.tianya.cn/143525524/profile

www.tianya.cn/143525528/profile

www.tianya.cn/143525536/profile

www.tianya.cn/143525543/profile

www.tianya.cn/143525555/profile

www.tianya.cn/143525586/profile

www.tianya.cn/143525577/profile

www.tianya.cn/143525589/profile

www.tianya.cn/143525602/profile

www.tianya.cn/143525624/profile

www.tianya.cn/143525608/profile

www.tianya.cn/143525645/profile

www.tianya.cn/143525649/profile

www.tianya.cn/143525654/profile

www.tianya.cn/143525660/profile

www.tianya.cn/143525665/profile

www.tianya.cn/143525670/profile

www.tianya.cn/143525678/profile

www.tianya.cn/143525681/profile

www.tianya.cn/143525694/profile

www.tianya.cn/143525699/profile

www.tianya.cn/143525704/profile

www.tianya.cn/143525708/profile

www.tianya.cn/143525720/profile

www.tianya.cn/143525403

www.tianya.cn/143525409

www.tianya.cn/143525422

www.tianya.cn/143525420

www.tianya.cn/143525426

www.tianya.cn/143525432

www.tianya.cn/143525443

www.tianya.cn/143525450

www.tianya.cn/143525483

www.tianya.cn/143525521

www.tianya.cn/143525524

www.tianya.cn/143525528

www.tianya.cn/143525536

www.tianya.cn/143525543

www.tianya.cn/143525555

www.tianya.cn/143525586

www.tianya.cn/143525577

www.tianya.cn/143525589

www.tianya.cn/143525602

www.tianya.cn/143525624

www.tianya.cn/143525608

www.tianya.cn/143525645

www.tianya.cn/143525649

www.tianya.cn/143525654

www.tianya.cn/143525660

www.tianya.cn/143525665

www.tianya.cn/143525670

www.tianya.cn/143525678

www.tianya.cn/143525681

www.tianya.cn/143525694

www.tianya.cn/143525699

www.tianya.cn/143525704

www.tianya.cn/143525708

www.tianya.cn/143525720