一 : 內(nèi)部存儲(chǔ)
這里內(nèi)部存儲(chǔ)睁壁,對(duì)應(yīng)的路徑為:Environment.getDataDirectory().getParentFile();
也就是根目錄募闲,這個(gè)目錄下還有一些重要的數(shù)據(jù),例如:數(shù)據(jù)庫(kù)databases
罗捎,shared_prefs(SharedPreferences)
等
注:沒(méi)有root的手機(jī),無(wú)法打開(kāi)該文件夾拉盾!
二 : 外部存儲(chǔ)
外部存儲(chǔ)又分為SD卡
和擴(kuò)展卡內(nèi)存
1桨菜,SD卡
Environment.getExternalStorageDirectory()
對(duì)應(yīng)的路徑為: /storage/sdcard0
/**
* Get a top-level shared/external storage directory for placing files of a
* particular type. This is where the user will typically place and manage
* their own files, so you should be careful about what you put here to
* ensure you don't erase their files or get in the way of their own
* organization.
* <p>
* On devices with multiple users (as described by {@link UserManager}),
* each user has their own isolated shared storage. Applications only have
* access to the shared storage for the user they're running as.
* </p>
* <p>
* Here is an example of typical code to manipulate a picture on the public
* shared storage:
* </p>
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* public_picture}
*
* @param type The type of storage directory to return. Should be one of
* {@link #DIRECTORY_MUSIC}, /storage/sdcard0/Music
* {@link #DIRECTORY_PODCASTS}, /storage/sdcard0/Podcasts
* {@link #DIRECTORY_RINGTONES}, /storage/sdcard0/Ringtones
* {@link #DIRECTORY_ALARMS}, /storage/sdcard0/DCIM
* {@link #DIRECTORY_NOTIFICATIONS}, /storage/sdcard0/Notifications
* {@link #DIRECTORY_PICTURES}, /storage/sdcard0/Pictures
* {@link #DIRECTORY_MOVIES}, /storage/sdcard0/Movies
* {@link #DIRECTORY_DOWNLOADS}, /storage/sdcard0/Download
* {@link #DIRECTORY_DCIM}, /storage/sdcard0/DCIM
* {@link #DIRECTORY_DOCUMENTS}. May not be null.
* @return Returns the File path for the directory. Note that this directory
* may not yet exist, so you must make sure it exists before using
* it such as with {@link File#mkdirs File.mkdirs()}.
*/
public static File getExternalStoragePublicDirectory(String type) {
throwIfUserRequired();
return sCurrentUser.buildExternalStoragePublicDirs(type)[0];
}
以上方法,對(duì)應(yīng)的就是SD卡公有的目錄捉偏,google官方建議數(shù)據(jù)應(yīng)該存儲(chǔ)在私有目錄下面倒得,不建議存儲(chǔ)在公有目錄或者其他地方;
私有目錄
就是在外部存儲(chǔ)的App包名下面夭禽。例如:/storage/emulated/0/Android/data/(包名)/files/
//私有存儲(chǔ)霞掺,緩存路徑: /storage/emulated/0/Android/data/com.csx.mytestdemo/cache
Log.d(TAG, "緩存路徑: " + this.getExternalCacheDir());
//圖片存儲(chǔ)路徑: /storage/emulated/0/Android/data/com.csx.mytestdemo/files/Pictures
Log.d(TAG, "圖片存儲(chǔ)路徑: " + this.getExternalFilesDir(Environment.DIRECTORY_PICTURES));
一般情況下,有包名的路徑讹躯,我們都是調(diào)用Context中的方法來(lái)獲取菩彬,沒(méi)有的話(huà),直接調(diào)用Environment中的方法獲得潮梯。
2骗灶,外置SD卡
獲取外置SD卡路徑:
/**
* 獲取外置sd卡路徑
* @param mContext
* @return 如果返回null,則沒(méi)有外置sd卡
*/
public static String getExtendedMemoryPath(Context mContext) {
StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
Class storageVolumeClazz = null;
try {
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
String path = (String) getPath.invoke(storageVolumeElement);
boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement);
if (removable) {
return path;
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
三 : 實(shí)際使用
建議:使用私有目錄存儲(chǔ)秉馏,刪除應(yīng)用時(shí)耙旦,對(duì)應(yīng)的文件都會(huì)被刪除,并且手機(jī)自帶的文件管理器都可以查看到萝究;
- 查找步驟:Android - > data -> 對(duì)應(yīng)包名(“com.csx.test”) 可以看到對(duì)應(yīng)的 cache / files文件夾(如下圖)免都。
代碼示例:
//使用手機(jī)自帶文件管理器對(duì)應(yīng)查看目錄為:Android - data - 包名- files - Music -
mFileName
getExternalFilesDir(Environment.DIRECTORY_MUSIC) + File.separator + mFileName
實(shí)際使用的時(shí)候,需要判斷一下是否存在外部存儲(chǔ)帆竹,4.4以前的系統(tǒng)中getExternalFilesDir(“”)
和getExternalCacheDir()
將返回null绕娘,所以最好加上判斷(如下代碼),存在外部存儲(chǔ)的時(shí)候馆揉,沒(méi)有的時(shí)候就使用內(nèi)部存儲(chǔ)****业舍。
public static String getFilePath(Context context,String dir) {
String directoryPath="";
if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ) {//判斷外部存儲(chǔ)是否可用
directoryPath =context.getExternalFilesDir(dir).getAbsolutePath();
}else{//沒(méi)外部存儲(chǔ)就使用內(nèi)部存儲(chǔ)
directoryPath=context.getFilesDir()+File.separator+dir;
}
File file = new File(directoryPath);
if(!file.exists()){//判斷文件目錄是否存在
file.mkdirs();
}
return directoryPath;
}
參考:http://blog.csdn.net/u012702547/article/details/50269639
四、誤區(qū)糾正
1升酣,內(nèi)部存儲(chǔ)舷暮,外部存儲(chǔ)
- 4.4以前的手機(jī),內(nèi)部存儲(chǔ)就是內(nèi)部存儲(chǔ)噩茄;外部存儲(chǔ)就是指的是SD卡下面。
- 4.4以后的手機(jī),外部存儲(chǔ)分為兩部分绩聘,1個(gè)是手機(jī)內(nèi)置的外部存儲(chǔ)可以用Environment的getExternalStorageDirectory等方法獲取到沥割。2耗啦,另外的就是我們自己插入手機(jī)的SD卡,需要通過(guò)
getExternalDirs
遍歷來(lái)獲取了机杜。