Bowie
Bowie

Reputation: 1002

External SDCard file path for Android

Is it true that the file path to external SDCard on Android devices are always "/storage/extSdCard"? If not, how many variations are there?

I need it for my App to test the availability of external SDCard.

I am using Titanium, it has a method Titanium.Filesystem.isExternalStoragePresent( ) but it always return true even external SDCard is not mounted.

I think it detect SDCard at local storage thus return true. But what I really want is detect whether physical SDCard is mounted or not.

Can I do this by detecting the existence of file "/storage/extSdCard" alone?

Thanks.

Upvotes: 21

Views: 113848

Answers (5)

Mahadev Mane
Mahadev Mane

Reputation: 898

I have got solution on this after 4 days, Please note following points while giving path to File class in Android(Java):

  1. Use path for internal storage String path="/storage/sdcard0/myfile.txt";
  2. use path for external storage path="/storage/sdcard1/myfile.txt";
  3. mention permissions in Manifest file.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

  1. First check file length for confirmation.
  2. Check paths in ES File Explorer regarding sdcard0 & sdcard1 is this same or else...

e.g.:

File file = new File(path);
long = file.length();//in Bytes

Upvotes: 4

Paresh Kalinani
Paresh Kalinani

Reputation: 93

I just figured out something. At least for my Android Emulator, I had the SD Card Path like ' /storage/????-???? ' where every ? is a capital letter or a digit.

So, if /storage/ directory has a directory which is readable and that is not the internal storage directory, it must be the SD Card.

My code worked on my android emulator!

String removableStoragePath;
    File fileList[] = new File("/storage/").listFiles();
    for (File file : fileList)
  {     if(!file.getAbsolutePath().equalsIgnoreCase(Environment.getExternalStorageDirectory().getAbsolutePath()) && file.isDirectory() && file.canRead())
        removableStoragePath = file.getAbsolutePath();  }
    //If there is an SD Card, removableStoragePath will have it's path. If there isn't it will be an empty string.

If there is an SD Card, removableStoragePath will have it's path. If there isn't it will be an empty string.

Upvotes: 3

Honey Agarwal
Honey Agarwal

Reputation: 310

This is how I finally got sdcard path using :

public String getExternalStoragePath() {

        String internalPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        String[] paths = internalPath.split("/");
        String parentPath = "/";
        for (String s : paths) {
            if (s.trim().length() > 0) {
                parentPath = parentPath.concat(s);
                break;
            }
        }
        File parent = new File(parentPath);
        if (parent.exists()) {
            File[] files = parent.listFiles();
            for (File file : files) {
                String filePath = file.getAbsolutePath();
                Log.d(TAG, filePath);
                if (filePath.equals(internalPath)) {
                    continue;
                } else if (filePath.toLowerCase().contains("sdcard")) {
                    return filePath;
                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    try {
                        if (Environment.isExternalStorageRemovable(file)) {
                            return filePath;
                        }
                    } catch (RuntimeException e) {
                        Log.e(TAG, "RuntimeException: " + e);
                    }
                }
            }

        }
        return null;
    }

Upvotes: 5

sorry bro
sorry bro

Reputation: 77

I hope it will be useful for you :)

import android.os.Environment;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;


public class MemoryStorage {

    private MemoryStorage() {}

    public static final String SD_CARD = "sdCard";
    public static final String EXTERNAL_SD_CARD = "externalSdCard";

    /**
     * @return True if the external storage is available. False otherwise.
     */
    public static boolean isAvailable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            return true;
        }
        return false;
    }

    public static String getSdCardPath() {
        return Environment.getExternalStorageDirectory().getPath() + "/";
    }

    /**
     * @return True if the external storage is writable. False otherwise.
     */
    public static boolean isWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            return true;
        }
        return false;

    }

    /**
     * @return A map of all storage locations available
     */
    public static Map<String, File> getAllStorageLocations() {
        Map<String, File> map = new HashMap<String, File>(10);

        List<String> mMounts = new ArrayList<String>(10);
        List<String> mVold = new ArrayList<String>(10);
        mMounts.add("/mnt/sdcard");
        mVold.add("/mnt/sdcard");

        try {
            File mountFile = new File("/proc/mounts");
            if (mountFile.exists()) {
                Scanner scanner = new Scanner(mountFile);
                while (scanner.hasNext()) {
                    String line = scanner.nextLine();
                    if (line.startsWith("/dev/block/vold/")) {
                        String[] lineElements = line.split(" ");
                        String element = lineElements[1];

                        // don't add the default mount path
                        // it's already in the list.
                        if (!element.equals("/mnt/sdcard"))
                            mMounts.add(element);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            File voldFile = new File("/system/etc/vold.fstab");
            if (voldFile.exists()) {
                Scanner scanner = new Scanner(voldFile);
                while (scanner.hasNext()) {
                    String line = scanner.nextLine();
                    if (line.startsWith("dev_mount")) {
                        String[] lineElements = line.split(" ");
                        String element = lineElements[2];

                        if (element.contains(":"))
                            element = element.substring(0, element.indexOf(":"));
                        if (!element.equals("/mnt/sdcard"))
                            mVold.add(element);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        for (int i = 0; i < mMounts.size(); i++) {
            String mount = mMounts.get(i);
            if (!mVold.contains(mount))
                mMounts.remove(i--);
        }
        mVold.clear();

        List<String> mountHash = new ArrayList<String>(10);

        for (String mount : mMounts) {
            File root = new File(mount);
            if (root.exists() && root.isDirectory() && root.canWrite()) {
                File[] list = root.listFiles();
                String hash = "[";
                if (list != null) {
                    for (File f : list) {
                        hash += f.getName().hashCode() + ":" + f.length() + ", ";
                    }
                }
                hash += "]";
                if (!mountHash.contains(hash)) {
                    String key = SD_CARD + "_" + map.size();
                    if (map.size() == 0) {
                        key = SD_CARD;
                    } else if (map.size() == 1) {
                        key = EXTERNAL_SD_CARD;
                    }
                    mountHash.add(hash);
                    map.put(key, root);
                }
            }
        }

        mMounts.clear();

        if (map.isEmpty()) {
            map.put(SD_CARD, Environment.getExternalStorageDirectory());
        }
        return map;
    }
}

Upvotes: 4

Digoun
Digoun

Reputation: 383

Is it true that the file path to external SDCard on Android devices are always "/storage/extSdCard"? If not, how many variations are there?

Sadly the path to the external storage is not always the same according to manufacturer. Using Environment.getExternalStorageDirectory() will return you the normal path for SD card which is mnt/sdcard/. But for Samsung devices for example, the SD card path is either under mnt/extSdCard/ or under mnt/external_sd/.

So one way to proceed would be to check the existence of external directory according to the path used by each manufacturer. With something like this:

mExternalDirectory = Environment.getExternalStorageDirectory()
            .getAbsolutePath();
    if (android.os.Build.DEVICE.contains("samsung")
            || android.os.Build.MANUFACTURER.contains("samsung")) {
        File f = new File(Environment.getExternalStorageDirectory()
                .getParent() + "/extSdCard" + "/myDirectory");
        if (f.exists() && f.isDirectory()) {
            mExternalDirectory = Environment.getExternalStorageDirectory()
                    .getParent() + "/extSdCard";
        } else {
            f = new File(Environment.getExternalStorageDirectory()
                    .getAbsolutePath() + "/external_sd" + "/myDirectory");  
            if (f.exists() && f.isDirectory()) {
                mExternalDirectory = Environment
                        .getExternalStorageDirectory().getAbsolutePath()
                        + "/external_sd";
            }
        }
    }

But what I really want is detect whether physical SDCard is mounted or not.

I didn't try the code yet, but the approach of Dmitriy Lozenko in this answer is much more interesting. His method returns the path of all mounted SD cards on sytem regardless of the manufacturer.

Upvotes: 10

Related Questions