Last active
October 31, 2022 07:02
-
-
Save PauloLuan/4bcecc086095bce28e22 to your computer and use it in GitHub Desktop.
how to get the external sd card path on android.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 Thank you, very much
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
Thanks, @lovelyelfpop this worked on my Samsung SM-T320 running Android version 4.4.2.
Thanks again. This worked like a champ