Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
how to get the external sd card path on android.
public static String getExternalSdCardPath() {
String path = null;
File sdCardFile = null;
List<String> sdCardPossiblePath = Arrays.asList("external_sd", "ext_sd", "external", "extSdCard");
for (String sdPath : sdCardPossiblePath) {
File file = new File("/mnt/", sdPath);
if (file.isDirectory() && file.canWrite()) {
path = file.getAbsolutePath();
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss").format(new Date());
File testWritable = new File(path, "test_" + timeStamp);
if (testWritable.mkdirs()) {
testWritable.delete();
}
else {
path = null;
}
}
}
if (path != null) {
sdCardFile = new File(path);
}
else {
sdCardFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
}
return sdCardFile.getAbsolutePath();
}
@lovelyelfpop
Copy link

lovelyelfpop commented May 16, 2018

/**
 * Get external sd card path using reflection
 * @param mContext
 * @param is_removable is external storage removable
 * @return
 */
private static String getExternalStoragePath(Context mContext, boolean is_removable) {

    StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
    Class<?> storageVolumeClazz = null;
    try {
        storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
        Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
        Method getPath = storageVolumeClazz.getMethod("getPath");
        Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
        Object result = getVolumeList.invoke(mStorageManager);
        final int length = Array.getLength(result);
        for (int i = 0; i < length; i++) {
            Object storageVolumeElement = Array.get(result, i);
            String path = (String) getPath.invoke(storageVolumeElement);
            boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement);
            if (is_removable == removable) {
                return path;
            }
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    return null;
}

@miszmaniac
Copy link

miszmaniac commented Jun 4, 2018

Kotlin version:

private fun getExternalCardDirectory(): File? {
        val storageManager = getSystemService(Context.STORAGE_SERVICE)
        try {
            val storageVolumeClazz = Class.forName("android.os.storage.StorageVolume")
            val getVolumeList = storageManager.javaClass.getMethod("getVolumeList")
            val getPath = storageVolumeClazz.getMethod("getPath")
            val isRemovable = storageVolumeClazz.getMethod("isRemovable")
            val result = getVolumeList.invoke(storageManager) as Array<StorageVolume>
            result.forEach {
                if (isRemovable.invoke(it) as Boolean) {
                    return File(getPath.invoke(it) as String)
                }
            }
        } catch (e: Throwable) {
            e.printStackTrace()
        }
        return null
    }

@feelgoodincorp
Copy link

feelgoodincorp commented Jun 8, 2018

lovelyelfpop's version works great, thank you!

@djkskqyr3
Copy link

djkskqyr3 commented Aug 5, 2018

@lovelyelfpop Great, it works

@zgrujic
Copy link

zgrujic commented Sep 26, 2019

@lovelyelfpop God bless you, seems this is the only working solution on internet currently. Thanks a bunch!!

@bhanubais
Copy link

bhanubais commented Sep 27, 2019

In Samsung external card location has changed as:
/storage/0000-0000/

@JoeCodeswell
Copy link

JoeCodeswell commented Mar 16, 2020

Thanks, @lovelyelfpop this worked on my Samsung SM-T320 running Android version 4.4.2.

  1. I followed get Context in non-Activity class [duplicate] to get the context into my Util class from the MainActivity.
  2. Here's some things I imported. there might have been a couple more.
import android.os.storage.StorageManager;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

Thanks again. This worked like a champ

Copy link

ghost commented Nov 10, 2020

@lovelyelfpop Thank you, very much

@Alkwin
Copy link

Alkwin commented Feb 14, 2022

Hi,

After Android Q, the method getPath cannot be called through reflection.

For me, the following code works. Tested on around 6-7 devices, ranging from Android 4.3 up to Android 12.

private fun getExternalCardDirectory(): String {
        val storageManager = context.getSystemService(Context.STORAGE_SERVICE)
        try {
            val storageVolumeClassReflection = Class.forName("android.os.storage.StorageVolume")
            val getVolumeList = storageManager.javaClass.getMethod("getVolumeList")
            val getPath = if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                storageVolumeClassReflection.getMethod("getDirectory")
            } else {
                storageVolumeClassReflection.getMethod("getPath")
            }
            val isRemovable = storageVolumeClassReflection.getMethod("isRemovable")
            val result = getVolumeList.invoke(storageManager) as Array<StorageVolume>
            result.forEach {
                if (isRemovable.invoke(it) as Boolean) {
                    return when(val invokeResult = getPath.invoke(it)) {
                        is File -> invokeResult.absolutePath

                        is String -> invokeResult

                        else -> DEFAULT_VALUE.also {
                            log.debug { "Reflection unsupported type; Invoke result: $invokeResult" }
                        }
                    }
                }
            }
        } catch (e: Throwable) {
            log.debug { "Could not get SD card path; Exception: $e" }
        }
        return DEFAULT_VALUE
    }

With DEFAULT_VALUE = "N/A"
Credit @lovelyelfpop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment