简体   繁体   中英

Get the public/root directory of a secondary external storage device in Android?

In android I am able to get my phone's removable external storage by use of:

for (File f : context.getExternalFilesDirs("/")) 
    if (Environment.isExternalStorageRemovable(f))
        Log.println(Log.DEBUG, "#", f.getAbsolutePath());

However, this returns /storage/8E6A-06FF/Android/data/test.application/files which isn't what I want as I simply want the removable's root path /storage/8E6A-06FF/ . How can I can get the root path of my phone's removable storage?

You can try this one it is works perfectly for me.It works like a charm with all Os's version.I didn't found any issue so far with this function.

public static String getSDPath() {
    String filepath = "";
    String[] strPath = {"/storage/sdcard1", "/storage/extsdcard",
            "/storage/sdcard0/external_sdcard", "/mnt/extsdcard",
            "/mnt/sdcard/external_sd", "/mnt/external_sd",
            "/mnt/media_rw/sdcard1", "/removable/microsd", "/mnt/emmc",
            "/storage/external_SD", "/storage/ext_sd",
            "/storage/removable/sdcard1", "/data/sdext", "/data/sdext2",
            "/data/sdext3", "/data/sdext4", "/emmc", "/sdcard/sd",
            "/mnt/sdcard/bpemmctest", "/mnt/sdcard/_ExternalSD",
            "/mnt/sdcard-ext", "/mnt/Removable/MicroSD",
            "/Removable/MicroSD", "/mnt/external1", "/mnt/extSdCard",
            "/mnt/extsd", "/mnt/usb_storage", "/mnt/extSdCard",
            "/mnt/UsbDriveA", "/mnt/UsbDriveB"};

    for (String value : strPath) {
        File f = null;
        f = new File(value);
        if (f.exists() && f.isDirectory()) {
            filepath = value;
            break;
        }
    }
    return filepath;
}

Try this:

for (File f : context.getExternalFilesDirs("/")) 
    if (Environment.isExternalStorageRemovable(f))
        Log.println(Log.DEBUG, "#", f.getParentFile().getParentFile().getParentFile().getParent());

context.getExternalFilesDirs() will always returns application-specific directory. But the good thing is that application-specific directories are always 4 level deep from the root folder of the storage device. So calling getParentFile() four times on the File f instead of f.getAbsolutePath() will get you the root path of your phone's removable storage.

Maybe just split it at Android ?

I tested it, and it works after I request for permission - WRITE_EXTERNAL_STORAGE .

fun getBaseDir(dir: File): String {
    val absPath = dir.absolutePath
    return if (absPath.contains("/Android")) {
        absPath.split("/Android")[0]
    } else {
        absPath
    }
}

This will loop through files on sdcard root directory. If you want primary storage, just change [1] to [0]. getExternalFilesDirs returns paths to your app directory on primary and secondary storage. After splitting the second path by "Android", the first string will contain path to your secondary storage root. for example in my case it was "/storage/B242-37B2/". Working with minSdkVersion 19+ .

            String sdCardRoot = ContextCompat.getExternalFilesDirs(getApplicationContext(), null)[1].getAbsolutePath().split("Android")[0];

            File f = new File(sdCardRoot);
            File[] files = f.listFiles();

            for (File inFile : files){
                Log.d("Files", inFile.getName());
            }

Try this one if it helps you. For more information refer this link .

public static HashSet<String> getExternalMounts() {
    final HashSet<String> out = new HashSet<String>();
    String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
    String s = "";
    try {
        final Process process = new ProcessBuilder().command("mount")
                .redirectErrorStream(true).start();
        process.waitFor();
        final InputStream is = process.getInputStream();
        final byte[] buffer = new byte[1024];
        while (is.read(buffer) != -1) {
            s = s + new String(buffer);
        }
        is.close();
    } catch (final Exception e) {
        e.printStackTrace();
    }

    // parse output
    final String[] lines = s.split("\n");
    for (String line : lines) {
        if (!line.toLowerCase(Locale.US).contains("asec")) {
            if (line.matches(reg)) {
                String[] parts = line.split(" ");
                for (String part : parts) {
                    if (part.startsWith("/"))
                        if (!part.toLowerCase(Locale.US).contains("vold"))
                            out.add(part);
                }
            }
        }
    }
    return out;
}

Here is another approach for the same. Source from here .

Environment.getExternalStorageState() returns path to internal SD mount point like "/mnt/sdcard"

But the question is about external SD. How to get a path like "/mnt/sdcard/external_sd" (it may differ from device to device)?

Android has no concept of "external SD", aside from external storage, as described above.

If a device manufacturer has elected to have external storage be on-board flash and also has an SD card, you will need to contact that manufacturer to determine whether or not you can use the SD card (not guaranteed) and what the rules are for using it, such as what path to use for it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM