1

I am looking for a way to find if the SD card is mounted. Before anyone else says so, Environment.getExternalStorageState() is not the answer.

Environment.getExternalStorageState() will tell you if the primary external storage is mounted. This is not necessarily (in fact, not usually) the SD card.

EnvironmentCompat.getStorageState(File file) seems like it would work, but it returns MEDIA_UNKNOWN if the location is not the external storage - see here for proof.

My best idea so far is just trying to create a file and take the result (success or failure) as MEDIA_MOUNTED or MEDIA_UNMOUNTED, but I was wondering if anyone has a more elegant solution.

As a side note, is there any issue with the code I am currently using to find the SD card path?

    public static File getExternalFilesDir(Context context) {
    File extFiles[] = ContextCompat.getExternalFilesDirs(context, null);
    File sd = null;

    int currentapiVersion = android.os.Build.VERSION.SDK_INT;

    if (currentapiVersion >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        // Use the isExternalStorageRemovable function added in Lollipop
        for (File file : extFiles) {
            if (Environment.isExternalStorageRemovable(file)) {
                sd = file;
            }
        }

    } else if (currentapiVersion >= android.os.Build.VERSION_CODES.KITKAT) {
        // getExternalFilesDirs will return all storages on KitKat. Assume
        // the second storage is the sd card
        if (Environment.isExternalStorageRemovable()) {
            sd = extFiles[0];
        } else if (extFiles.length > 2) {
            sd = extFiles[1];
        }

    } else if (currentapiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) {
        // Use the secondary storage if the primary one is not removable
        if (Environment.isExternalStorageRemovable()) {
            sd = extFiles[0];
        } else {
            String secStore = System.getenv("SECONDARY_STORAGE");
            String packageName = context.getPackageName();
            if (secStore != null) {
                sd = new File(secStore + "/Android/data/" + packageName + "/files");
            }
        }
    } else {
        // Froyo and Eclair do not have emulated storages
        sd = extFiles[0];
    }

    if (sd != null && !sd.exists()) {
        sd.mkdirs();
    }
    if (sd != null) {
        Log.v("getExternalFilesDir", sd.getAbsolutePath());
    }

    return sd;
}
  • 1
    There is no requirement that a device have a `SECONDARY_STORAGE` environment variable, let alone that the value is something that you can use successfully. – CommonsWare Jan 06 '15 at 01:01
  • Do you have any better recommendations for finding the SD card path then? I've successfully tested the code above in a Galaxy Tab 2. (Or how to determine if it is available) – Michael Chen Jan 06 '15 at 01:23
  • I've had what I think is a [very similar question from 2 years ago](http://stackoverflow.com/questions/10629523/building-a-utility-to-get-the-path-to-external-removable-storage-every-time). I haven't followed up on the problem but check if the comments can help you. – josephus Jan 06 '15 at 01:28
  • Since [removable storage was outside the Android SDK until API Level 19](http://commonsware.com/blog/2014/04/09/storage-situation-removable-storage.html), I would recommend focusing instead on using `MediaStore` and its index of files. On most devices with removable media, the manufacturer adds files on the removable media to `MediaStore` when the media is mounted and removes it when the media is unmounted. – CommonsWare Jan 06 '15 at 13:07

0 Answers0