How To Get Sdcard(secondary) Storage Path In Android?
I'm developing a File Manager app. I want show to the user the internal storage and the sdcard storage if it exists. For internal storage I use Environment.getExternalStorageDirect
Solution 1:
not sure this solution fits a File Manager but after many years trying to get the right code, this is my most recent one:
/**
* Returns all available SD-Cards in the system (include emulated)
*
* Warning: Hack! Based on Android source code of version 4.3 (API 18)
* Because there is no standard way to get it.
*
* @return paths to all available SD-Cards in the system (include emulated)
*/publicstaticString[] getStorageDirectories(Context pContext)
{
// Final set of pathsfinal Set<String> rv = new HashSet<>();
//Get primary & secondary external device storage (internal storage & micro SDCARD slot...)
File[] listExternalDirs = ContextCompat.getExternalFilesDirs(pContext, null);
for(int i=0;i<listExternalDirs.length;i++){
if(listExternalDirs[i] != null) {
String path = listExternalDirs[i].getAbsolutePath();
int indexMountRoot = path.indexOf("/Android/data/");
if(indexMountRoot >= 0 && indexMountRoot <= path.length()){
//Get the root path for the external directory
rv.add(path.substring(0, indexMountRoot));
}
}
}
return rv.toArray(newString[rv.size()]);
}
Solution 2:
If you worked on only Android 4.0+.These answers here will help you:
how-can-i-get-external-sd-card-path-for-android-4-0
Some code example from the answers:
publicstatic 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 + newString(buffer);
}
is.close();
} catch (finalException e) {
e.printStackTrace();
}
// parse outputfinalString[] 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;
}
Another answer here.
privatestaticfinal Pattern DIR_SEPORATOR = Pattern.compile("/");
/**
* Raturns all available SD-Cards in the system (include emulated)
*
* Warning: Hack! Based on Android source code of version 4.3 (API 18)
* Because there is no standart way to get it.
* TODO: Test on future Android versions 4.4+
*
* @return paths to all available SD-Cards in the system (include emulated)
*/publicstaticString[] getStorageDirectories()
{
// Final set of pathsfinal Set<String> rv = new HashSet<String>();
// Primary physical SD-CARD (not emulated)finalString rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
// All Secondary SD-CARDs (all exclude primary) separated by ":"finalString rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
// Primary emulated SD-CARDfinalString rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
if(TextUtils.isEmpty(rawEmulatedStorageTarget))
{
// Device has physical external storage; use plain paths.if(TextUtils.isEmpty(rawExternalStorage))
{
// EXTERNAL_STORAGE undefined; falling back to default.
rv.add("/storage/sdcard0");
}
else
{
rv.add(rawExternalStorage);
}
}
else
{
// Device has emulated storage; external storage paths should have// userId burned into them.finalString rawUserId;
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
{
rawUserId = "";
}
else
{
finalString path = Environment.getExternalStorageDirectory().getAbsolutePath();
finalString[] folders = DIR_SEPORATOR.split(path);
finalString lastFolder = folders[folders.length - 1];
boolean isDigit = false;
try
{
Integer.valueOf(lastFolder);
isDigit = true;
}
catch(NumberFormatException ignored)
{
}
rawUserId = isDigit ? lastFolder : "";
}
// /storage/emulated/0[1,2,...]if(TextUtils.isEmpty(rawUserId))
{
rv.add(rawEmulatedStorageTarget);
}
else
{
rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
}
}
// Add all secondary storagesif(!TextUtils.isEmpty(rawSecondaryStoragesStr))
{
// All Secondary SD-CARDs splited into arrayfinalString[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
Collections.addAll(rv, rawSecondaryStorages);
}
return rv.toArray(newString[rv.size()]);
}
The third answer is:
finalStringstate= Environment.getExternalStorageState();
if ( Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state) ) { // we can read the External Storage... //Retrieve the primary External Storage:finalFileprimaryExternalStorage= Environment.getExternalStorageDirectory();
//Retrieve the External Storages root directory:final String externalStorageRootDir;
if ( (externalStorageRootDir = primaryExternalStorage.getParent()) == null ) { // no parent...
Log.d(TAG, "External Storage: " + primaryExternalStorage + "\n");
}
else {
finalFileexternalStorageRoot=newFile( externalStorageRootDir );
final File[] files = externalStorageRoot.listFiles();
for ( final File file : files ) {
if ( file.isDirectory() && file.canRead() && (file.listFiles().length > 0) ) { // it is a real directory (not a USB drive)...
Log.d(TAG, "External Storage: " + file.getAbsolutePath() + "\n");
}
}
}
}
Solution 3:
Similar to code above but without harcoded "/Android/data"
public List<File> getAllStorageLocations() {
List<File> storageLocations = newArrayList<>();
FilestorageDir= Environment.getExternalStorageDirectory();
StringstoragePath= storageDir.getAbsolutePath();
File[] extFileDirs = getContext().getExternalFilesDirs(null);
StringsuffixToStrip=null;
for (File nextFile : extFileDirs) {
StringnextPath= nextFile.getAbsolutePath();
if (nextPath.startsWith(storagePath)) {
suffixToStrip = nextPath.substring(storagePath.length());
break;
}
}
if (suffixToStrip != null) {
for (File nextFile : extFileDirs) {
StringnextPath= nextFile.getAbsolutePath();
intstripIndex= nextPath.lastIndexOf(suffixToStrip);
if (stripIndex > -1) {
Filepath=newFile(nextPath.substring(0, stripIndex));
storageLocations.add(path);
}
}
}
if (storageLocations.size() == 0) {
storageLocations.add(storageDir);
}
return storageLocations;
}
Solution 4:
Try this, iterate from root folder.
FilerootFolder=newFile("/");
booleanisSdcardRemovable=false;
Stringpath=null;
loop:
for(int i=0; i<rootFolder.listFiles().length; i++) {
if(rootFolder.listFiles()[i].listFiles() != null &&
!rootFolder.listFiles()[i].toString().contains("system") &&
!rootFolder.listFiles()[i].toString().contains("etc") &&
!rootFolder.listFiles()[i].toString().contains("dev") ) {
FiledataDir=newFile(Environment.getDataDirectory().getAbsolutePath());
longdataDirSize= dataDir.getFreeSpace()/(1000*1000);
longfolderSize= rootFolder.listFiles()[i].getFreeSpace()/(1000*1000);
if(dataDirSize == folderSize || (dataDirSize > folderSize &&
folderSize > (dataDirSize-80))) {
System.err.println("INTERNAL1 "+rootFolder.listFiles()[i]);
System.err.println(dataDirSize);
System.err.println(folderSize);
}
else {
FilerootSubFolder1=newFile(rootFolder.listFiles()[i].getAbsolutePath());
if(rootSubFolder1.listFiles() != null) {
for(int j=0; j<rootSubFolder1.listFiles().length; j++) {
if(rootSubFolder1.listFiles()[j].getTotalSpace() != 0 &&
rootSubFolder1.listFiles()[j].getFreeSpace() != 0 &&
rootSubFolder1.listFiles()[j].listFiles() != null) {
Log.i(TAG, "" + rootSubFolder1.listFiles()[j]);
if(rootSubFolder1.listFiles()[j].toString().contains("sdcard") ||
rootSubFolder1.listFiles()[j].toString().contains("storage") ||
rootSubFolder1.listFiles()[j].toString().contains("mnt")) {
folderSize = rootSubFolder1.listFiles()[j].getFreeSpace()/(1000*1000);
if(dataDirSize == folderSize || (dataDirSize > folderSize &&
folderSize > (dataDirSize-80))) {
System.err.println("INTERNAL2 " + rootSubFolder1.listFiles()[j]);
System.err.println(dataDirSize);
System.err.println(folderSize);
}
else {
intpos= rootSubFolder1.listFiles()[j].getAbsolutePath().lastIndexOf('/');
Stringstr= rootSubFolder1.listFiles()[j].getAbsolutePath().substring(pos+1);
if(str.matches("(sd|ext|3039|m_external_sd).*")) {
isSdcardRemovable = true;
System.err.println("EXTERNAL "+rootSubFolder1.listFiles()[j]);
System.err.println(dataDirSize);
System.err.println(folderSize);
path = rootSubFolder1.listFiles()[j].getAbsolutePath()+"/";
break loop;
}
}
}
}
}
}
}
}
}
if(isSdcardRemovable) {
if(path != null) {
getMemoryDetails(path);
finish();
}
else {
saveResult("fail", "External memory not found.");
Log.e(TAG, "External memory not found.");
finish();
}
} else {
saveResult("fail", "External memory not available.");
Log.e(TAG, "External memory not available.");
finish();
}
Post a Comment for "How To Get Sdcard(secondary) Storage Path In Android?"