Android判断获取内置外置sd卡

项目有下载任务,需求可以选择下载路径到内置存储还是外置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卡的路径。

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...


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卡路径。根据测试结果现在还是无法确定某一种方法能够完全在所有机器上运行正确,希望有研究过此问题的人能给指点一二。

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值