使用Runtime类 识别 sdcard和U盘android 6.0 存储路径识别

来源:互联网 发布:淘宝托管真的有用吗 编辑:程序博客网 时间:2024/05/21 07:09

不需要系统权限!!!

理论:proc/partitions可以获取主设备和次设备号(sd[a/b/c]为u盘,mmcblk[数字][p为分区]),

proc/mounts可以获取/dev/block/vold/public:179,129 /mnt/media_rw/0403-0201 也包含了主设备和次设备号

(注意凡是外部存储(sdcard 和u盘)都是/dev/block/vold/...形式,android 6.0后形式有所变化为/dev/block/vold/public:179,129)

linux执行方法:

public static String execRootCmd(String cmd) {String result = "";DataOutputStream dos = null;DataInputStream dis = null;try {Process p = Runtime.getRuntime().exec(cmd);dos = new DataOutputStream(p.getOutputStream());dis = new DataInputStream(p.getInputStream());dos.writeBytes("exit\n");dos.flush();String line = null;while ((line = dis.readLine()) != null) {result += line;}p.waitFor();} catch (Exception e) {e.printStackTrace();} finally {if (dos != null) {try {dos.close();} catch (IOException e) {e.printStackTrace();}}if (dis != null) {try {dis.close();} catch (IOException e) {e.printStackTrace();}}}return result;}

识别方法:

  private final static String ROOT_PATH="/storage/";    public static void distinguishExternalPath(List<String> externalSdcardPathParam, List<String> externalUsbPathParam) {        List<String> externalSdcardPath = new ArrayList<String>();        List<String> externalUsbPath = new ArrayList<String>();        String s = LinuxCmdUtil.execRootCmd("cat proc/partitions");        s = s.replaceAll("\\s+", "|");             String[] partitions = s.split("\\|");        final List<String> usbStoreMajorMinor = new ArrayList<>();        int repeatCurrent = 0;        for (String item : partitions) {//get usb storage major and minor!!!!            if (item.contains("sd")) {                String majorMinor = partitions[repeatCurrent - 3] + "|" + partitions[repeatCurrent - 2];                               usbStoreMajorMinor.add(majorMinor);            }            repeatCurrent++;        }        String condition = "/dev/block/vold";        String s1 = LinuxCmdUtil.execRootCmd("cat proc/mounts");              String[] mounts = s1.split(" ");        int currentRepeatCount = 0;        for (String item : mounts) {            if (item.length() > condition.length() && item.contains(condition)) {                boolean contains = false;                for (String usbMajorMinor : usbStoreMajorMinor) {                    String[] split = usbMajorMinor.split("\\|");                    contains = item.contains(split[0]) && item.contains(split[1]);                    if (contains)break;                }                if (contains) {                    String mount = mounts[currentRepeatCount + 1];                    if (!externalUsbPath.contains(mount)) {                                             externalUsbPath.add(mounts[currentRepeatCount + 1]);                    }                } else {                    String mount = mounts[currentRepeatCount + 1];                    if (!externalSdcardPath.contains(mount)) {                                              externalSdcardPath.add(mount);                    }                }            }            currentRepeatCount++;        }        for(String usbItemPath:externalUsbPath){            String[] split = usbItemPath.split("/");            String dirName=split[split.length-1];            String storagePath=ROOT_PATH+dirName;            File file=new File(storagePath);            boolean b = file.exists() && file.isDirectory();                    if (b){                externalUsbPathParam.add(storagePath);            }        }        for(String sdcardPath:externalSdcardPath){            String[] split = sdcardPath.split("/");            String dirName=split[split.length-1];            String storagePath=ROOT_PATH+dirName;            File file=new File(storagePath);            boolean b = file.exists() && file.isDirectory();                     if (b){                externalSdcardPathParam.add(storagePath);            }        }    }
由于测试时发现mnt/media_rw/....用File.exist 和File.isDirectory发现不认为是文件夹(都是false),所以不能直接使用这种路径,所以后面的两个for循环就是为了解决这个问题的(/storage目录下是可以识别为文件夹的)