在飛魚相冊發佈的第一個測試版中,不少用戶表示沒法查看外置SD卡中的照片。乍一聽以爲加個外置SD卡的根目錄,而後在掃描全部圖片的時候把這個根目錄加進去,直接遍歷就是了。然而實際狀況是,你確實能夠加載SD卡中的照片,可是若是你想修改,那就不行了,除非你申請外置儲存卡的寫權限。(看到這裏有的同窗確定很急躁的說,我已經在清單裏什麼的文件讀寫權限了,並且動態申請也作了相應的處理,怎麼外置存儲卡還須要申請權限?這個很差說,你得直接問谷歌爸爸,沒辦法,谷歌真的能夠隨心所欲🤷♀️)java
本篇文章並非要講如何申請外置儲存卡的權限申請,若是你還不清楚的話建議你查看個人早期文章,或者經過此連接閱讀:如何使用新的SD卡訪問機制(從5.0開始)。這裏講一個細節,俗話說細節決定成敗不是沒有道理的,下面看我細細道來。android
1. 外置SD卡路徑:/storage/B4AD-3FC1/ 2. 想要刪除的文件路徑:/storage/B4AD-3FC1/dcim/demo.jpg 3. 已經獲取了外置SD卡的權限,並儲存了對應的**Uri**
外置SD卡默認是有讀權限的,也就是你不用申請就有,你能夠理解爲一個標準的java文件系統。當時當你修改文件時,android文件系統就會對你的操做進行一些限制。api
個人刪除文件的代碼以下:測試
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()
來進行刪除操做。看上去很完美,但仍是有坑。3d
起初,我進行刪除操做,系統返回true
,而後會相冊一看,照片還在。。。屢次調試沒找到問題在哪裏,而後用文件管理器去SD卡目錄看看發現:調試
Fuck,這是什麼鬼。多出這麼多DCIM的副本。code
先介紹下getDocumentFile()
方法,他有三個參數,第一個是你傳入的文件,第二個參數是不是文件夾,第三個參數是否自動建立。第三個參數我傳的true
,而後就有這麼多新的文件夾。。。orm
緣由出在這裏:blog
要刪除的文件路徑爲: **/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/
獲得的結果是:
文件夾名稱被佔用,沒法新建。