前言
本篇是為了記錄在適配Android6.0和7.0的時(shí)候出現(xiàn)的思考,以下內(nèi)容大多數(shù)參考了大佬們的文章,僅做記錄.
看完之后希望能解決以下問(wèn)題.
疑問(wèn):
- Android內(nèi)部存儲(chǔ)、外部存儲(chǔ)、SD卡區(qū)別在哪里?
- getDataDirectory,getFilesDir,getCacheDir,getDir,getExternalStorageDirectory,getExternalStoragePublicDirectory,getExternalFilesDir,getExternalCacheDir,getExternalCacheDir,getRootDirectory等方法的區(qū)別和關(guān)聯(lián)?
- 哪些目錄需要讀寫(xiě)權(quán)限?讀寫(xiě)SD卡一定要權(quán)限?
問(wèn)題一
內(nèi)部存儲(chǔ),外部存儲(chǔ),SD卡區(qū)別;
在Android4.4以下的時(shí)候,系統(tǒng)僅有內(nèi)部存儲(chǔ)和外部存儲(chǔ)(SD卡),然后再4.4之后,系統(tǒng)支持了手機(jī)內(nèi)置外部存儲(chǔ)和外置外部存儲(chǔ)(SD卡);到這里可能有個(gè)疑問(wèn)getExternalStorageDirectory(),到底是SD卡還是手機(jī)內(nèi)置外部存儲(chǔ)?這個(gè)問(wèn)題引入第二個(gè)問(wèn)題.
問(wèn)題二
不同安卓版本下getDataDirectory,getFilesDir,getCacheDir,getDir,getExternalStorageDirectory,getExternalStoragePublicDirectory,getExternalFilesDir,getExternalCacheDir,getExternalCacheDir,getRootDirectory
-
getExternalStorageDirectory(),到底是SD卡還是手機(jī)內(nèi)置外部存儲(chǔ)?
Android4.4以前,getExternalStorageDirectory可以獲取外置SD卡根路徑;4.4之后外部存儲(chǔ)就包含兩部分了(內(nèi)置外部存儲(chǔ)和外置SD卡),其中通過(guò)getExternalStorageDirectory獲取的內(nèi)置外部存儲(chǔ),而外置SD卡的根路徑系統(tǒng)并沒(méi)有明確給出方法,網(wǎng)上有許多方案,但是可以使用getExternalFilesDirs來(lái)獲取,雖然不是SD卡的根路徑,但是可以選擇使用sd卡上的私有路徑.而且上述方法是獲取文件夾的絕對(duì)路徑,那么想想辦法根路徑還是能拿得到的,但是感覺(jué)不優(yōu)雅.
Environment.getDataDirectory()
內(nèi)部存儲(chǔ)的根路徑,/data
- Context.getFilesDir
這個(gè)方法是獲取某個(gè)應(yīng)用在內(nèi)部存儲(chǔ)中的files路徑,/data/user/0/pakageName/files
- Context.getCacheDir
這個(gè)方法是獲取某個(gè)應(yīng)用在內(nèi)部存儲(chǔ)中的cache路徑,/data/user/0/pakageName/cache
- Context.getDir("storage", Context.MODE_PRIVATE)
這個(gè)方法是獲取某個(gè)應(yīng)用在內(nèi)部存儲(chǔ)中的自定義路徑,/data/user/0/pakageName/app_storage
- Environment.getExternalStorageDirectory
獲取外部存儲(chǔ)的根路徑,4.4以下指的是sd卡,4.4開(kāi)始值得是內(nèi)部外置存儲(chǔ),/storage/emulated/0
- Environment.getExternalStoragePublicDirectory
外部共有目錄,例如圖像,音樂(lè),用戶(hù)可以看到,圖庫(kù)可以檢索到;/storage/emulated/0/type
- Context.getExternalFilesDir
某個(gè)應(yīng)用在外部存儲(chǔ)中的files路徑, /storage/emulated/0/Android/data/pakageName/files/
- Context.getExternalCacheDir
這個(gè)方法是獲取某個(gè)應(yīng)用在外部存儲(chǔ)中的cache路徑
- Environment.getDownloadCacheDirectory()
/data/cache,內(nèi)部存儲(chǔ)的cache目錄
- Environment.getRootDirectory() = /system
存放系統(tǒng)文件,物理上在內(nèi)部存儲(chǔ)
問(wèn)題三
哪些目錄需要讀寫(xiě)權(quán)限?
從上面可以觀察到:用Context都與App自己的存儲(chǔ)路徑有關(guān),Environment都是公共的,從4.4開(kāi)始,讀取或?qū)懭霊?yīng)用私有目錄中的文件不再需要 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE 權(quán)限!當(dāng)然包括在外部存儲(chǔ)里的;但是要注意,既然app相關(guān)的路徑,app卸載的時(shí)候會(huì)對(duì)應(yīng)的路徑下的文件會(huì)被刪除,而且不會(huì)被系統(tǒng)圖庫(kù)所掃描到,如果想讓系統(tǒng)掃描到,那就放到Evironment相關(guān)的路徑下。值得注意的是:不是私有路徑下的存儲(chǔ)是需要?jiǎng)討B(tài)獲取讀寫(xiě)權(quán)限的.
額外補(bǔ)充
我們開(kāi)發(fā)的時(shí)候應(yīng)該怎么合理的使用存儲(chǔ):
- 隱私
- 功能
考慮因素:隱私;如果你不想讓其它app掃描到或者被用戶(hù)刪除,那么你可以放到內(nèi)部存儲(chǔ)里(當(dāng)內(nèi)部存儲(chǔ)不足的時(shí)候系統(tǒng)會(huì)幫你刪了,而且不打招呼,所以存儲(chǔ)的文件要小),如果并不是那么重要,而且也不需要暴露給外部展示,放在外部存儲(chǔ)的私有目錄下是極好的,優(yōu)點(diǎn):不用權(quán)限,存儲(chǔ)比較大,安全性相對(duì)較高。放在外部公共目錄下的,那就沒(méi)有啥子安全性了,誰(shuí)都能看。
考慮因素:功能;SD卡和外部存儲(chǔ)的選用,外部存儲(chǔ)比SD卡可靠,當(dāng)外部存儲(chǔ)不足的時(shí)候考慮外部SD卡存儲(chǔ)(自己的想法),還有用戶(hù)想保存圖片(此時(shí)需要權(quán)限),要么放到共有的圖片路徑下,要么放到自己外部文件夾下,而且用的文件一定要記得用完刪除.這里我們?cè)谶m配6.0讀寫(xiě)權(quán)限的時(shí)候就能省下很多力氣,因?yàn)樵诖酥?很多文件都放到了,getExternalStorageDirectory,導(dǎo)致要添加權(quán)限檢查的地方很多,這是個(gè)契機(jī),修改存儲(chǔ)路徑到外部的私有路徑下,一是不要權(quán)限,二是避免了App刪除的時(shí)候留下很多垃圾,對(duì)用戶(hù)好,你也輕松.
此外:
Android為了兼容類(lèi)SD卡,外部存儲(chǔ),ContextCompat.getExternalFilesDirs(),建議使用這個(gè)方法獲取外部存儲(chǔ)的位置。
因?yàn)閺?Android 4.4 開(kāi)始,可通過(guò)調(diào)用 getExternalFilesDirs() 來(lái)同時(shí)訪問(wèn)兩個(gè)位置(外部存儲(chǔ)和sd卡),該方法將會(huì)返回包含各個(gè)位置條目的 File 數(shù)組。 數(shù)組中的第一個(gè)條目被視為外部主存儲(chǔ);除非該位置已滿(mǎn)或不可用,否則應(yīng)該使用該位置。 如果您希望在支持 Android 4.3 和更低版本的同時(shí)訪問(wèn)兩個(gè)可能的位置,請(qǐng)使用支持庫(kù)中的靜態(tài)方法 ContextCompat.getExternalFilesDirs()。 在 Android 4.3 和更低版本中,此方法也會(huì)返回一個(gè) File 數(shù)組,但其中始終僅包含一個(gè)條目。這句話(huà)是官方文檔上我Copy下來(lái)的。
最后
到這里基本就完了,如有不正確的地方,請(qǐng)指正。
參考
徹底搞懂Android文件存儲(chǔ)---內(nèi)部存儲(chǔ),外部存儲(chǔ)以及各種存儲(chǔ)路徑解惑
了解 Android 應(yīng)用的文件存儲(chǔ)目錄,掌握持久化數(shù)據(jù)的正確姿勢(shì)