There are devices that have both an emulated and a physical SD. (eg Sony Xperia Z).
It won't expose the physical SD card because methods like getExternalFilesDir(null) will return the emulated SD card.
I use the following code to get the directory for the physical SD.
The call returns all mountpoints and the online SD cards. You will have to figure out which mountpoint refers to a OFFLINE SD card (if any), but most of the time you are only interested in ONLINE SD cards.
public static boolean getMountPointsAndOnlineSDCardDirectories(ArrayList<String> mountPoints, ArrayList<String> sdCardsOnline)
{
boolean ok = true;
mountPoints.clear();
sdCardsOnline.clear();
try
{
// File that contains the filesystems to be mounted at system startup
FileInputStream fs = new FileInputStream("/etc/vold.fstab");
DataInputStream in = new DataInputStream(fs);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null)
{
// Skip comments and empty lines
line = line.trim();
if ((line.length() == 0) || (line.startsWith("#"))) continue;
// Fields are separated by whitespace
String[] parts = line.split("\\s+");
if (parts.length >= 3)
{
// Add mountpoint
mountPoints.add(parts[2]);
}
}
in.close();
}
catch (Exception e)
{
ok = false;
e.printStackTrace();
}
try
{
// Pseudo file that holds the CURRENTLY mounted filesystems
FileInputStream fs = new FileInputStream("//proc/mounts");
DataInputStream in = new DataInputStream(fs);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null)
{
// A sdcard would typically contain these...
if (line.toLowerCase().contains("dirsync") && line.toLowerCase().contains("fmask"))
{
String[] parts = line.split("\\s+");
sdCardsOnline.add(parts[1]);
}
}
//Close the stream
in.close();
}
catch (Exception e)
{
e.printStackTrace();
ok = false;
}
return (ok);
}