Environment.getExternalStorageDirectory().getPath()=/storage/emulated/0
Environment.getRootDirectory()=/system
二、
提供了三個public方法, 分別獲取內部存儲路徑、外部存儲路徑和應用程序文件路徑(/data/data/com.xxx.xxx/files)。
如果那個路徑不存在就返回null。
public String getExternalStoragePath();
public String getInternalStoragePath();
public String getAppStoragePath();
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import android.content.Context;
import android.os.Environment;
import android.os.storage.StorageManager;
import android.util.Log;
/**
* @description Get the internal or external storage path.
* This class used three ways to obtain the storage path.
* reflect:
* major method is getVolumePaths and getVolumeState. this two method is hidden for programmer, so we must to use this way.
* if either getVolumePaths or getVolumeState can not be found (e.g. in some sdk version), then use next way.
* command:
* By filter the output of command "mount", may be we can get the storage path that we want. if didn't, then use next way.
* Api:
* As is known to all, we use getExternalStorageDirectory method.
*/
public class StoragePathsManager {
private static final String LOG_TAG = "StoragePathsManager";
private Context mContext;
private StorageManager mStorageManager;
private Method mMethodGetPaths;
private Method mMethodGetPathsState;
private boolean mIsReflectValide = true;
private List<String> mAllStoragePathsByMountCommand = new ArrayList<String>();
public StoragePathsManager(Context context)
{
mContext = context;
init();
}
private void init()
{
Log.i(LOG_TAG, "init");
mStorageManager=(StorageManager)mContext.
getSystemService(Context.STORAGE_SERVICE);
try{
mMethodGetPaths = mStorageManager.getClass().getMethod("getVolumePaths");
mMethodGetPathsState=mStorageManager.getClass().getMethod("getVolumeState",String.class);
}catch(NoSuchMethodException ex){
ex.printStackTrace();
}
if (mMethodGetPaths == null || mMethodGetPathsState == null)
{
mIsReflectValide = false;
}
if (false == mIsReflectValide)
{
Set<String> set = getStoragePathsByCommand();
mAllStoragePathsByMountCommand.addAll(set);
for (String s : mAllStoragePathsByMountCommand)
{
Log.i(LOG_TAG, "abtain by command: " + s);
}
if (mAllStoragePathsByMountCommand.size() == 0)
{
if (Environment.getExternalStorageDirectory().getPath() != null)
{
mAllStoragePathsByMountCommand.add(Environment.getExternalStorageDirectory().getPath());
}
}
for (String s : mAllStoragePathsByMountCommand)
{
Log.i(LOG_TAG, "abtain by Environment: " + s);
}
}
}
private HashSet<String> getStoragePathsByCommand() {
final HashSet<String> out = new HashSet<String>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try {
final Process process = new ProcessBuilder().command("mount")
.redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1) {
s = s + new String(buffer);
}
is.close();
} catch (final Exception e) {
e.printStackTrace();
}
// parse output
final String[] lines = s.split("\n");
for (String line : lines) {
if (!line.toLowerCase(Locale.US).contains("asec")) {
if (line.matches(reg)) {
String[] parts = line.split(" ");
for (String part : parts) {
if (part.startsWith("/"))
if (!part.toLowerCase(Locale.US).contains("vold"))
out.add(part);
}
}
}
}
return out;
}
/**
* @return String. for example /mnt/sdcard
*/
public String getExternalStoragePath()
{
String path = null;
List<String> allMountedPaths = getMountedStoragePaths();
String internal = getInternalStoragePath();
for (String s : allMountedPaths)
{
if (!s.equals(internal))
{
path = s;
break;
}
}
return path;
}
public String getInternalStoragePath()
{
// get external path
String pathExtNotRemovable = null;
String pathExtRemovable = null;
String ext = Environment.getExternalStorageDirectory().getPath();
// if it is removable, the storage is external storage, otherwise internal storage.
boolean isExtRemovable = Environment.isExternalStorageRemovable();
List<String> allMountedPaths = getMountedStoragePaths();
for (String s : allMountedPaths)
{
if (s.equals(ext))
{
if (isExtRemovable)
{
pathExtRemovable = s;
}
else
{
pathExtNotRemovable = s;
}
break;
}
}
String intr = null;
String refPath = null;
if (pathExtRemovable != null)
{
refPath = pathExtRemovable;
}
else if (pathExtNotRemovable != null)
{
intr = pathExtNotRemovable;
return intr;
}
for (String s : allMountedPaths)
{
if (!s.equals(refPath))
{
intr = s;
break;
}
}
return intr;
}
/**
* @return /data/data/com.xxx.xxx/files
*/
public String getAppStoragePath()
{
String path = mContext.getApplicationContext().getFilesDir().getAbsolutePath();
Log.i(LOG_TAG, "getAppStoragePath: " + path);
return path;
}
private List<String> getMountedStoragePaths()
{
if (false == mIsReflectValide)
{
return mAllStoragePathsByMountCommand;
}
List<String> mountedPaths = new ArrayList<String>();
String[] paths = getAllStoragePaths();
Log.i(LOG_TAG, "all paths:");
if (paths!=null)
{
for (String path : paths)
{
Log.i(LOG_TAG, "-- path: " + path);
}
}
for (String path : paths)
{
if (isMounted(path))
{
Log.i(LOG_TAG, "path: " + path + " is mounted");
mountedPaths.add(path);
}
}
return mountedPaths;
}
private String[] getAllStoragePaths()
{
String[] paths =null;
try{
paths=(String[])mMethodGetPaths.invoke(mStorageManager);
}catch(IllegalArgumentException ex){
ex.printStackTrace();
}catch(IllegalAccessException ex){
ex.printStackTrace();
}catch(InvocationTargetException ex){
ex.printStackTrace();
}
return paths;
}
private String getVolumeState(String mountPoint){
String status=null;
try{
status=(String)mMethodGetPathsState.invoke(mStorageManager, mountPoint);
}catch(IllegalArgumentException ex){
ex.printStackTrace();
}catch(IllegalAccessException ex){
ex.printStackTrace();
}catch(InvocationTargetException ex){
ex.printStackTrace();
}
return status;
}
private boolean isMounted(String mountPoint)
{
String status=null;
boolean result = false;
status = getVolumeState(mountPoint);
if(Environment.MEDIA_MOUNTED.equals(status)){
result = true;
}
return result;
}
}
三、
以前的Android(4.1之前的版本)中,SDcard跟路徑通過“/sdcard”或者“/mnt/sdcard”來表示存儲卡,而在Jelly Bean系統中修改爲了“/storage/sdcard0”,以後可能還會有多個SDcard的情況。
目前爲了保持和之前代碼的兼容,sdcard路徑做了link映射。
爲了使您的代碼更加健壯並且能夠兼容以後的Android版本和新的設備,請通過Environment.getExternalStorageDirectory().getPath()來獲取sdcard路徑,
如果您需要往sdcard中保存特定類型的內容,可以考慮使用Environment.getExternalStoragePublicDirectory(String type)函數,該函數可以返回特定類型的目錄,目前支持如下類型:
DIRECTORY_ALARMS //警報的鈴聲
DIRECTORY_DCIM //相機拍攝的圖片和視頻保存的位置
DIRECTORY_DOWNLOADS //下載文件保存的位置
DIRECTORY_MOVIES //電影保存的位置, 比如 通過google play下載的電影
DIRECTORY_MUSIC //音樂保存的位置
DIRECTORY_NOTIFICATIONS //通知音保存的位置
DIRECTORY_PICTURES //下載的圖片保存的位置
DIRECTORY_PODCASTS //用於保存podcast(博客)的音頻文件
DIRECTORY_RINGTONES //保存鈴聲的位置
如果您的應用需要下載以上類型的文件,則可以放到上面對應的目錄中去來幫助用戶查找,比如最常用的就是下載文件了。如果您開發了一個瀏覽器,在下載文件的時候把文件下載到Download目錄則方便用戶以後查找該文件,當然如果你希望用戶需要通過啓動您的程序來查看他們下載的文件,您也可以不這麼做 ^_^。
在使用這些目錄保存文件的時候,需要注意一點:其他程序也有可能在使用這些目錄,在保存文件前,注意判斷下文件是否已經存在,不要覆蓋了用戶之前的數據。
Android4.1之後Android增加了多存儲卡的支持,一般手機會存在內置存儲卡和外置存儲卡,也可能有多個外置存儲卡。如何獲取存儲卡路徑呢?
特別是各種android設備的存儲器路徑,是不一樣的,比如T卡路徑,可能是/mnt/sdcard、/mnt/extsd、/mnt/external_sd 或者/mnt/sdcard2。有時內置存儲器的路徑也可能是/mnt/sdcard,而host usb存儲器的路徑也是各種各樣的。
下面方法是通過反射,調用StorageManager的隱藏接口getVolumePaths(),實現獲取存儲器列表。
package ckl.storage.list;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.os.storage.StorageManager;
public class StorageList {
private Activity mActivity;
private StorageManager mStorageManager;
private Method mMethodGetPaths;
public StorageList(Activity activity) {
mActivity = activity;
if (mActivity != null) {
mStorageManager = (StorageManager)mActivity
.getSystemService(Activity.STORAGE_SERVICE);
try {
mMethodGetPaths = mStorageManager.getClass()
.getMethod("getVolumePaths");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
public String[] getVolumePaths() {
String[] paths = null;
try {
paths = (String[]) mMethodGetPaths.invoke(mStorageManager);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return paths;
}
}
在android2.3中,判斷內置SD卡是否掛載:
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
//爲true的話,內置sd卡存在
}
判斷外置SD卡是否掛載:
if(Environment.getStorageState(Environment.STORAGE_PATH_SD2).equals(Environment.MEDIA_MOUNTED))
{
//爲true的話,外置sd卡存在
}
順帶描述怎麼取得sdcard的空間大小,
File sdcardDir = Environment.getExternalStorageDirectory();
StatFs sf = new StatFs(sdcardDir.getPath()); //sdcardDir.getPath())值爲/mnt/sdcard,想取外置sd卡大小的話,直接代入/mnt/sdcard2
long blockSize = sf.getBlockSize(); //總大小
long blockCount = sf.getBlockCount();
long availCount = sf.getAvailableBlocks(); //有效大小