Search code examples
androidstorageexternalsd-card

How can I properly obtain the external SD card path?


I'm faced with the well-known problem of obtaining the path of an external SD card mounted on some Android devices. (see this question for understanding what I mean)

I've thought to solve the problem by reading the content of /etc/vold.fstab, then taking just lines representing partitions, but I don't have a device for doing tests. What I want to do is to read that file, ignore the row which refers to the address returned by Environment.getExternalStorageDirectory(), and take the other row (if present).

What I don't know (and I don't have the possibility to test it) is: are there cases in which I can have other lines which are not the external SD card? The SD card, if present, appears on the file vold.fstab?

edit: The answer is: YES. Read the accepted answer.


Solution

  • This could be the right solution. Read it from /etc/vold.fstab, which lists all the partitions currently mounted on a Linux system (Android included)

    String getExternalSdcardDirectory() {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(new File("/etc/vold.fstab"));
        } catch (FileNotFoundException e) {
            return null;    // should never be reached
        }
    
        try {
            byte[] buffer = new byte[4096];
            int n=0;
    
            String file = "";
            while ((n=fis.read(buffer, 0, 4096))>0) {
                file += new String(buffer, 0, n);
            }
            fis.close();
    
            String[] rows = file.split("\n");
            for (String row: rows) {
                String trimmedRow = row.trim();
                if (trimmedRow.startsWith("#") || trimmedRow.equals(""))
                    continue;
                else if (trimmedRow.equals(Environment.getExternalStorageDirectory().getAbsolutePath()))
                    continue;
                else
                    return trimmedRow.split(" ")[2];
    
            }
        } catch (IOException e) {
            // nothing
        }
        return null;
    }