获取手机文件路径

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




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