*認(rèn)識Android文件系統(tǒng)
*了解分區(qū)存儲
*分區(qū)存儲的適配
一、Android文件系統(tǒng)
Android文件系統(tǒng)分為 內(nèi)部存儲(internal storage) 和外部存儲(external storage)
1.1 用一個表格來直觀對比一下兩者:
1.2 應(yīng)用的私有路徑
應(yīng)用在安裝之后炬守,系統(tǒng)會自動在內(nèi)部存儲和外部存儲净赴,分別建立應(yīng)用的私有存儲區(qū)域卖鲤。
內(nèi)部存儲 : data/user/0/packageName
外部存儲 : storage/emulated/0/android/data/packageName
當(dāng)應(yīng)用卸載或者清除數(shù)據(jù)后孕暇,該區(qū)域文件會被刪除业稼。
1.3 內(nèi)外部存儲圖解
二溪猿、 了解分區(qū)存儲
Android 10版本中刃跛,Google推出 分區(qū)存儲(scoped storage)的功能抠艾。
背景:
分區(qū)存儲功能是針對內(nèi)置的外部存儲來說的,很多應(yīng)用喜歡在外部存儲的根目錄創(chuàng)建自己的文件夾桨昙,比如:storage/emulated/0/***
這樣做的好處:1. 當(dāng)不斷向該目錄存儲時检号,應(yīng)用自己的容量不會變化; 2. 當(dāng)應(yīng)用卸載時蛙酪,該目錄下文件不會被刪除齐苛,可用于保存一些可持久性的文件。
但是也有壞處: 1. 對用戶來說桂塞,會有很多垃圾文件存在于手機(jī)中凹蜂;2. 只要獲取到Read 和 Write權(quán)限,就可以隨意訪問外部存儲的任何目錄阁危,信息安全存在隱患玛痊。
分區(qū)存儲:
每個應(yīng)用向自己的私有目錄讀寫文件,不需要讀寫權(quán)限狂打。私有文件目錄具體路徑: storage/emulated/0/android/data/packageName/ 擂煞,獲取方法: Context#getExternalFilesDir()
應(yīng)用即使獲取了讀寫權(quán)限,也無法訪問其他應(yīng)用的私有目錄趴乡。
當(dāng)應(yīng)用需要獲取媒體文件時对省,通過 MediaStore API 向公共存儲目錄DCIM、Music或者M(jìn)ovie獲取晾捏。同樣寫媒體文件也是如此蒿涎。并且讀寫自己的文件時不需要申請權(quán)限。 只有讀其他應(yīng)用的媒體文件時才會需要申請READ_EXTERNAL_STORAGE權(quán)限惦辛。
(更新:Android11為目標(biāo)平臺時劳秋,可以使用文件直接路徑去訪問媒體,這是在Android10上沒有的裙品,應(yīng)用的性能會略有下降俗批,還是推薦使用MediaStore )當(dāng)應(yīng)用需要獲取其他非媒體文件時,比如doc市怎、pdf文件岁忘,需要使用 系統(tǒng)的文件選擇器SAF 來進(jìn)行訪問。
所以WRITE_EXTERNAL_STORAGE權(quán)限区匠,在未來的Android11版本里干像,會被廢棄帅腌。 (寫文件不需要權(quán)限,只能在私有目錄和公共目錄寫文件)
三麻汰、分區(qū)存儲適配
舊版存儲位置遷移
除了應(yīng)用的私有目錄和公共目錄速客,其他位置都稱為 舊版存儲位置,我們需要將舊版存儲位置的數(shù)據(jù)遷移到能兼容分區(qū)存儲的位置五鲫。
如果以Android 11為目標(biāo)平臺的應(yīng)用溺职,需要在manifest清單中標(biāo)記preserveLegacyExternalStorage 為true,這樣在Android11的機(jī)器上覆蓋安裝時位喂,才能訪問舊版存儲位置浪耘,卸載重裝會失效。
如果以Android10為目標(biāo)平臺塑崖,覆蓋安裝可以訪問舊版存儲七冲,且將manifest清單中標(biāo)記requestLegacyExternalStorage 為true,在Android10機(jī)器上重新安裝也能訪問舊版存儲位置规婆。在Android11的機(jī)器上兩種安裝方式都會失效澜躺,需要加上preserveLegacyExternalStorage = true,且覆蓋安裝才能訪問舊版存儲位置抒蚜。卸載重裝會失效掘鄙。
如果以Android 9及以下為目標(biāo)平臺時,就能正常的進(jìn)行文件移動削锰。將應(yīng)用在外部存儲器根目錄的保存的數(shù)據(jù)中通铲,如果能接受隨應(yīng)用的卸載而刪除的文件,遷移至storage/emulated/0/android/data/packageName/目錄下器贩。需要和其他應(yīng)用共享的媒體文件颅夺,遷移至媒體存儲位置。
正確使用讀寫API
- 只在外部存儲的應(yīng)用私有目錄下蛹稍,用直接路徑讀寫文件
- 訪問或者共享媒體文件吧黄,使用MediaStore在公共目錄下讀寫文件
- 訪問或者共享非媒體文件,使用系統(tǒng)的文件選擇器SAF在公共目錄Download下讀寫文件