飞鱼相册笔记(1)----外置SD卡文件夹名称不区分大小写
飞鱼相册笔记(1)----外置SD卡文件夹名称不区分大小写
在飞鱼相册发布的第一个测试版中,很多用户表示无法查看外置SD卡中的照片。乍一听觉得加个外置SD卡的根目录,然后在扫描所有图片的时候把这个根目录加进去,直接遍历就是了。然而实际情况是,你确实可以加载SD卡中的照片,但是如果你想修改,那就不行了,除非你申请外置储存卡的写权限。(看到这里有的同学肯定很急躁的说,我已经在清单里什么的文件读写权限了,而且动态申请也做了相应的处理,怎么外置存储卡还需要申请权限?这个不好说,你得直接问谷歌爸爸,没办法,谷歌真的可以为所欲为🤷♀️)
本篇文章并不是要讲如何申请外置储存卡的权限申请,如果你还不清楚的话建议你查看我的早期文章,或者通过此链接阅读:如何使用新的SD卡访问机制(从5.0开始)。这里讲一个细节,俗话说细节决定成败不是没有道理的,下面看我细细道来。
1. 环境背景交代
1. 外置SD卡路径:/storage/B4AD-3FC1/
2. 想要删除的文件路径:/storage/B4AD-3FC1/dcim/demo.jpg
3. 已经获取了外置SD卡的权限,并储存了对应的**Uri**
2. 对外置SD的文件执行删除操作
外置SD卡默认是有读权限的,也就是你不用申请就有,你可以理解为一个标准的java文件系统。当时当你修改文件时,android文件系统就会对你的操作进行一些限制。
我的删除文件的代码如下:
public static boolean deleteFile(@NonNull final File file) {
// First try the normal deletion.
if (file.delete()) {
return true;
}
// Try with Storage Access Framework.
if (isAndroid5()) {
DocumentFile document = getDocumentFile(file, false, true);
if (document != null) {
boolean deleteDocument = document.delete();
return deleteDocument;
}
}
return !file.exists();
}
这里我做了两个处理,先按照默认java文件系统来处理,调用file.delete()
来进行删除操作。如果删除了失败了,我再判断是否是5.0以上手机,然后使用SAF
进行删除操作,其中的重点是通过File
来得到一个DocumentFile
,然后调用DocumentFile.delete()
来进行删除操作。看上去很完美,但还是有坑。
外置SD卡文件夹名称不区分大小写
起初,我进行删除操作,系统返回true
,然后会相册一看,照片还在。。。多次调试没找到问题在哪里,然后用文件管理器去SD卡目录看看发现:
Fuck,这是什么鬼。多出这么多DCIM的副本。
先介绍下getDocumentFile()
方法,他有三个参数,第一个是你传入的文件,第二个参数是否是文件夹,第三个参数是否自动创建。第三个参数我传的true
,然后就有这么多新的文件夹。。。
原因出在这里:
要删除的文件路径为: **/storage/B4AD-3FC1/dcim/demo.jpg**
然而实际代码中读取到的路径为:**/storage/B4AD-3FC1/DCIM/demo.jpg**
在通过DocumentFile.findFile()
查找的时候:
public DocumentFile findFile(String displayName) {
for (DocumentFile doc : listFiles()) {
if (displayName.equals(doc.getName())) {
return doc;
}
}
return null;
}
displayName.equals(doc.getName()
是区分大小写的,然而你的到的路径是:
/storage/B4AD-3FC1/DCIM/demo.jpg
,而文件的真实地址为:/storage/B4AD-3FC1/dcim/demo.jpg
。这就导致我每次都找不到文件,一个不存在的文件去删除,结果肯定是ture。
于是我将查找的方法改为:
String displayName = parts[i];
DocumentFile nextDocument = document.findFile(displayName);
if (nextDocument == null) {
nextDocument = document.findFile(displayName.toLowerCase());
}
if (nextDocument == null) {
nextDocument = document.findFile(displayName.toUpperCase());
}
当然,这样写还是有问题的,我只考虑了全部大写和全部小写的情况。
最后验证一下
我使用系统自带的文件管理器新建一个文件夹:
已经有了: /SDCard/dcim/
准备新建: /SDCard/DCIM/
得到的结果是:
文件夹名称被占用,无法新建。