一 : 内部存储
这里内部存储,对应的路径为:Environment.getDataDirectory().getParentFile();
也就是根目录,这个目录下还有一些重要的数据,例如:数据库databases
,shared_prefs(SharedPreferences)
等
注:没有root的手机,无法打开该文件夹!
二 : 外部存储
外部存储又分为SD卡
和扩展卡内存
1,SD卡
Environment.getExternalStorageDirectory()
对应的路径为: /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.
*
* 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.
*
*
* Here is an example of typical code to manipulate a picture on the public
* shared storage:
*
* {@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];
}
以上方法,对应的就是SD卡公有的目录,google官方建议数据应该存储在私有目录下面,不建议存储在公有目录或者其他地方;
私有目录
就是在外部存储的App包名下面。例如:/storage/emulated/0/Android/data/(包名)/files/
//私有存储,缓存路径: /storage/emulated/0/Android/data/com.csx.mytestdemo/cache
Log.d(TAG, "缓存路径: " + this.getExternalCacheDir());
//图片存储路径: /storage/emulated/0/Android/data/com.csx.mytestdemo/files/Pictures
Log.d(TAG, "图片存储路径: " + this.getExternalFilesDir(Environment.DIRECTORY_PICTURES));
一般情况下,有包名的路径,我们都是调用Context中的方法来获取,没有的话,直接调用Environment中的方法获得。
2,外置SD卡
获取外置SD卡路径:
/**
* 获取外置sd卡路径
* @param mContext
* @return 如果返回null,则没有外置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;
}
三 : 实际使用
建议:使用私有目录存储,删除应用时,对应的文件都会被删除,并且手机自带的文件管理器都可以查看到;
- 查找步骤:Android - > data -> 对应包名(“com.csx.test”) 可以看到对应的 cache / files文件夹(如下图)。
私有目录存储数据.png
代码示例:
//使用手机自带文件管理器对应查看目录为:Android - data - 包名- files - Music -
mFileName
getExternalFilesDir(Environment.DIRECTORY_MUSIC) + File.separator + mFileName
实际使用的时候,需要判断一下是否存在外部存储,4.4以前的系统中getExternalFilesDir(“”)
和getExternalCacheDir()
将返回null,所以最好加上判断(如下代码),存在外部存储的时候,没有的时候就使用内部存储****。
public static String getFilePath(Context context,String dir) {
String directoryPath="";
if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ) {//判断外部存储是否可用
directoryPath =context.getExternalFilesDir(dir).getAbsolutePath();
}else{//没外部存储就使用内部存储
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
四、误区纠正
1,内部存储,外部存储
- 4.4以前的手机,内部存储就是内部存储;外部存储就是指的是SD卡。
- 4.4以后的手机,外部存储分为两部分,1个是手机内置的外部存储可以用Environment的getExternalStorageDirectory等方法获取到。2,另外的就是我们自己插入手机的SD卡,需要通过
getExternalDirs
遍历来获取了。