在之前的開發過程中,對於應用存儲目錄存在一些模糊的觀念,在AndroidQ版本中,Google對應用存儲空間又做了調整,藉此機會梳理一下。
移動設備存儲空間大致可劃分爲內部存儲 與 外部存儲,而外部存儲又可細分爲外部私有存儲與外部共享存儲,具體區別如下
內部存儲
存儲結構
訪問方式
/**
*獲取應用內部存儲的files路徑
*/
String filesPath = context.getFilesDir().getAbsolutePath();
filesPath = /data/data/{應用包名}/files
//或者(Android4.2以後增加多用戶,更改了用戶數據掛載結構,但是文件還是按照上述data/data/結構存儲)
filesPath = /data/user/0/{應用包名}/files
/**
*獲取應用內部存儲的cache路徑
*/
String cachePath = context.getCacheDir().getAbsolutePath();
cachePath = /data/data/{應用包名}/cache
//或者(原因同上)
cachePath = /data/user/0/{應用包名}/files
/**
*獲取應用內部存儲根目錄下指定目錄路徑,如果目錄不存在,系統則會自動創建
*@param name:目錄名稱
*@param mode:目錄操作模式-私有(默認)僅自己可訪問
*/
String targetPath = context.getDir(name,Context.MODE_PRIVATE).getAbsolutePath();
targetPath = /data/data/{應用包名}/{name}
//或者
targetPath = /data/user/0/{應用包名}/{name}
擴展:在內部存儲files目錄下創建自定義目錄
/**
*在應用內部存儲files目錄下創建子文件夾
*/
String customDirPath = context.getFilesDir().getAbsolutePath() + "/customDir"
File customDirFile = new File(customDirPath);
//如果文件不存在,則創建
if(!customDirFile.exists()){
customFile2.mkdir();
}
customDirPath = /data/data/{應用包名}/files/customDir
//或者
customDirPath = /data/user/0/{應用包名}/files/customDir
存儲特點
- 應用訪問無需(靜態&動態)申請權限(如果訪問目錄不存在,系統會自動創建)
- 存儲區域內的文件私有,僅有自己可訪問,其他App無權訪問
- 應用卸載後,數據也同步刪除
- 存儲空間有限
由於內部存儲大小有限制的,因此我們用來保存比較重要的數據,例如用戶信息資料,口令祕碼等不需要與其他應用程序共享的數據。
外部存儲
注意,由於用戶可以彈出外部存儲,因此外部存儲可能並不總是可用。可以使用Environment#getExternalStorageState(File)
檢查媒體狀態。
私有目錄
存儲結構
訪問方式
/**
*獲取應用外部存儲私有files下指定目錄路徑,如果不指定type則獲取的是files根路徑
*type:系統默認提供內部存儲目錄類型,有如下(也可自定目錄):
* {@link android.os.Environment#DIRECTORY_MUSIC}
* {@link android.os.Environment#DIRECTORY_PODCASTS}
* {@link android.os.Environment#DIRECTORY_RINGTONES}
* {@link android.os.Environment#DIRECTORY_ALARMS}
* {@link android.os.Environment#DIRECTORY_NOTIFICATIONS}
* {@link android.os.Environment#DIRECTORY_PICTURES}
* {@link android.os.Environment#DIRECTORY_MOVIES}
*提示:目錄如果不存在,則系統會自動創建
*/
String externalFiles = context.getExternalFilesDir(type).getAbsolutePath();
externalFiles = /mnt/sdcard/Android/data/{應用包名}/files/{type}
//或者
externalFiles = /storage/emulated/0/Android/data/{應用包名}/files/{type}
/**
*獲取應用外部存儲私有cache路徑
*/
String externalCache = context.getExternalCacheDir().getAbsolutePath();
externalCache = /mnt/sdcard/Android/data/{應用包名}/cache
//或者
externalFiles = /storage/emulated/0/Android/data/{應用包名}/cache
存儲特點
- Android4.4以後,應用自身訪問無需(靜態&動態)申請權限(如果訪問目錄不存在,系統會自動創建)
- 文件公開,第三方應用可以訪問
- 應用卸載後數據同步刪除
公共(共享)目錄
存儲結構
訪問方式
注意:
-
從AndoridQ開始,此方法已經過時。爲了改善用戶隱私,不推薦直接訪問設備的外部公共存儲目錄,應使用外部私有目錄(context.getExternalFilesDir(type)方案來替代。
-
在開發中,Google官方建議App數據存儲在外部存儲的私有目錄中對應App的包名下
storage/sdcard/Android/data/包名/
,這樣當用戶卸載掉App之後,相關的數據會一併刪除!
/**
*獲取外部存儲根目錄
*/
String externalRoot = Environment.getExternalStorageDirectory().getAbsolutePath();
externalRoot = /mnt/sdcard
//或者
externalRoot = /storage/emulated/0
/**
*獲取外部存儲根目錄下指定目錄
*type:系統默認提供的外部存儲目錄類型,有如下(也可自定目錄):
* {@link #DIRECTORY_MUSIC},
* {@link #DIRECTORY_PODCASTS},
* {@link #DIRECTORY_RINGTONES},
* {@link #DIRECTORY_ALARMS},
* {@link #DIRECTORY_NOTIFICATIONS},
* {@link #DIRECTORY_PICTURES},
* {@link #DIRECTORY_MOVIES},
* {@link #DIRECTORY_DOWNLOADS},
* {@link #DIRECTORY_DCIM},
* {@link #DIRECTORY_DOCUMENTS}
*提示:返回目錄的文件路徑。注意,這個目錄可能還不存在,所以在使用之前必須確保它存在
*。 例如使用{@link File#mkdirs File.mkdirs()}
*/
String targetPath = Envrionment.getExternalStoragePublicDirectory(type).getAbsolutePath();
File targetFile = new File(targetPath);
//如果不存在,則創建
if(!targetFile.exists()){
targetFile.mkdir();
}
targetPath = /mnt/sdcard/{type}
//或者
targetPath = /storage/emulated/0/{type}
存儲特點
- 訪問需要申請(靜態&動態)權限(如果目錄不存在需要提前判斷並創建)
- 文件公開,任何應用都可訪問
- 應用卸載,數據不會清除
參考文章