Android判断获取内置外置sd卡

来源:互联网 发布:淘宝开放平台有什么用 编辑:程序博客网 时间:2024/04/29 17:38

项目有下载任务,需求可以选择下载路径到内置存储还是外置sd卡,网上查了很多内容,大致有:

1.注册sd卡插拔广播

在广播中调用

intent.getData().getPath()

 获取sd卡路径,顺便判断挂载状态。

 内置存储路径则调用系统api:

 Environment.getExternalStorageDirectory().getPath()

2. 4.0和以上系统通过反射调用系统隐藏api:

String extSdCard="";StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);// 获取sdcard的路径:外置和内置String[] paths = (String[]) sm.getClass().getMethod("getVolumePaths", null).invoke(sm, null);String esd = Environment.getExternalStorageDirectory().getPath();for (int i = 0; i < paths.length; i++) {    if (paths[i].equals(esd)) {        continue;    }    File sdFile = new File(paths[i]);    if (sdFile.canWrite()) {         extSdCard = paths[i];          }}

    判断挂载状态可判断该路径文件是否存在或者通过StorageManager的另一隐藏方法getVolumeState()来判断。必要时也要注册广播来监听状态。然而2.3上却没有给出能兼容的方法。

     参考文章:http://blog.csdn.net/LilySea2012/article/details/16967311 

3.执行mount命令,根据返回的信息来获取文件路径:

private String getPath_mount() {    String sdcard_path="";    // 得到路径    try {        Runtime runtime = Runtime.getRuntime();        Process proc = runtime.exec("mount");        InputStream is = proc.getInputStream();        InputStreamReader isr = new InputStreamReader(is);        String line;        BufferedReader br = new BufferedReader(isr);        while ((line = br.readLine()) != null) {            if (line.contains("secure"))                continue;            if (line.contains("asec"))                continue;            if (line.contains("fat")) {                String columns[] = line.split(" ");                if (columns != null && columns.length > 1) {                    sdcard_path = sdcard_path.concat("*" + columns[1]);                }            } else if (line.contains("fuse")) {                String columns[] = line.split(" ");                if (columns != null && columns.length > 1) {                    sdcard_path = sdcard_path.concat(columns[1]);                }            }        }    } catch (Exception e) {        e.printStackTrace();    }    return sdcard_path;}
         此方法可以得出路径,但现在不知道如何判断哪个路径是外置sd卡的路径。
 参考文章:http://www.eoeandroid.com/thread-275560-1-1.html

4.根据读取system/etc/vold.fstab文件信息来获知:

private String getPath_fstab(){    Dev_MountInfo dev = Dev_MountInfo.getInstance();    DevInfo info1 = dev.getInternalInfo();//Internal SD Card Informations    DevInfo info2 = dev.getExternalInfo();//External SD Card Informations        if(info2!=null){        info2.getLabel(); // SD 卡的名称        info2.getMount_point();//SD 卡挂载点        info2.getPath(); //SD 卡路径        info2.getSysfs_path(); // ....没弄清楚什么意思                return "exter:" +info2.getPath();    }    return "inner:"+info1.getPath();}

该方法基于以下几点猜测:

1.挂载盘符的文件一定是 system/etc/vold.fstab

2.挂载盘符顺序一定是 内置卡 外置卡 U盘,而且前面必须有

3.每个盘符挂载信息都是如下排序 Format: dev_mount <label> <mount_point> <part> <sysfs_path1...

 参考文章:http://blog.csdn.net/bbmiku/article/details/7937745

5.读取系统环境变量来获取:

private String getPath_env(){        Map<String, String> map = System.getenv();        //遍历出来可以看到最后一项是外置SD卡路径        String innerPath="";        String exterPath="";        boolean hasExter=false;                Set<String> set = map.keySet();        Iterator<String> keys = set.iterator();        while(keys.hasNext()){            String key=keys.next();            String value=map.get(key);            Log.i("pop", key+":"+value);                        if("SECONDARY_STORAGE".equals(key)){                hasExter=true;                exterPath=value;            }                        if("EXTERNAL_STORAGE".equals(key)){                innerPath=value;            }        }                if(hasExter){            return "exter:"+exterPath;        }        return "inner:"+innerPath;    }
          参考文章:http://blog.csdn.net/bbmiku/article/details/7937745

          用两台拥有内置和外置sd卡的4.x机器测试以上方法,其中一台红米对调过内置和外置sd卡路径。根据测试结果现在还是无法确定某一种方法能够完全在所有机器上运行正确,希望有研究过此问题的人能给指点一二。
   测试demo下载

          经过测试更新之后的版本,基本上大多是可行的,不敢保证百分之百靠谱,可能有些小偏差,各种山寨机很强大。。。
   测试修正版

0 0