獲取手機文件路徑

一、
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(); //有效大小




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章