How can I properly obtain the external SD card pat

2020-03-31 05:41发布

问题:

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.

回答1:

What is wrong with this?

Environment.getExternalStoreDirectory()

Why are you ignoring this when it's the SD Card?

OK - In the case of devices with /sdcard (Internal) and an external SD card (??) you could always scan the fstab file and look for "sdhci" which is the SD Host Controller bridge driver.

Something like:

dev_mount sdcard /mnt/external_sdcard auto /devices/platform/sdhci.2/mmc_host/mmc2

Then just parse as necessary.

Why the "necessity" to find the actual SD card though when it's not actually treated as such by the OS? (Won't be mounted as mass storage)

Is your application only available for devices where this is the case? What is wrong with using whatever Android believes is the SD storage space?



回答2:

I use the following code to first detect wether the sdCard exists and then run the relevent code:

Detecting whether SD card exists:

Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
if(isSDPresent)
{
    // file path = "/mnt/sdcard/Android/data/PACKAGE_NAME/..."
}
else
{
    // file path = "/data/data/PACKAGE_NAME/..."
}

Think this is what you are after?



回答3:

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;
}