其實很多人並不能分清Android中內存存儲和外部存儲和sdcard,大部分人分不清的主要原因在原Environment.getExternalStorageDirectory(),總認爲這個是獲取sdcard的,在api中getExternalStorageDirectory()備註是這麼說的
Note: don’t be confused by the word “external” here. This directory can better be thought as media/shared storage.
大致的意思就是不要被external迷惑了,這個目錄最好被理解位媒體/共享存儲。出現這個原因的還有就是各大定製rom的大廠,把內置的sd卡叫做內部存儲,導致這個內部存儲和Google定義的內部存儲就混淆了。
在區分這些目錄之前,首先看看Android 是怎麼區分這些存儲的,清空大腦,不要想那些sdcard,內部存儲,我們現在要重新梳理下這些東西,並對應於environment中那個函數。
Android 中對存儲分爲兩類,一類就是內部存儲,另一類是外部存儲,
- 內部存儲
內部存儲存放app私有數據,不與其他app共享數據,但是空間小,而且在刪除app的時候對應的數據也會刪除,清理緩存的時候也會丟失部分數據。
方法 | 路徑 |
---|---|
Environment.getDataDirectory().getAbsolutePath() | /data |
Environment.getDownloadCacheDirectory().getAbsolutePath() | /data/cache |
Environment.getRootDirectory().getAbsolutePath() | /system |
- 外置存儲-SD卡
外置存儲空間大,但是其他app都可訪問,導致數據的泄露等問題
方法 | 路徑 |
---|---|
Environment.getExternalStorageDirectory().getAbsolutePath() | /storage/emulated/0 |
Environment.getExternalStoragePublicDirectory(DIRECTORY_MUSIC).getAbsolutePath() | /storage/emulated/0/Music |
Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOAD).getAbsolutePath() | /storage/emulated/0/Download |
打開Android Studio 中device explorer 可以清晰找到對應的目錄,內部存儲
- 外置存儲-外置卡
外置卡,也就是我們所說的真正的sd卡,因爲Android的開源,導致外置卡在系統的存放路徑各大廠商不一樣,所以處理起來比較麻煩,好在Google給瞭解決方案,可以通過storagemanager來實現。
private 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;
}
系統中各個函數對應的目錄
Log.i("storage:", "內部存儲:");
Log.i("storage:", Environment.getDataDirectory().getAbsolutePath());
Log.i("storage:", Environment.getDownloadCacheDirectory().getAbsolutePath());
Log.i("storage:", Environment.getRootDirectory().getAbsolutePath());
Log.i("storage:", "內嵌的Sdcard存儲:");
Log.i("storage:", Environment.getExternalStorageDirectory().getAbsolutePath());
Log.i("storage:", + Environment.getExternalStoragePublicDirectory(DIRECTORY_MUSIC).getAbsolutePath());
Log.i("storage:", "外置的sdcard");
Log.i("storage:", SDCardHelper.getUsbPath(this));
內部存儲:
/data
/data/cache
/system
內嵌的Sdcard存儲:
/storage/emulated/0
/storage/emulated/0/Music
外置的sdcard
/storage/sd89-8768
打開Android Studio device explorer 會看到有兩個sdcard目錄,而storage/sdcard0纔是真正的目錄,也就是我們常說的“內部存儲”,sdcard是它的快捷方式。在我這個目錄你還發現有sdcard1,他是外置sdcard的目錄,就是我們常說的sdcard目錄,還有個usbotg目錄,這個目錄是usb的目錄。
要是你在目錄找找,你會找到如下的目錄:
mnt 全稱爲mount,掛載的目錄,爲什麼是sdcard0,1……,請看參考博客,寫的不錯。
參考
Android存儲路徑你瞭解多少?
Android內、外存儲 易混淆點剖析
邀請你加入,我們一起免費成長,改變只需一秒鐘