How can I get the external SD card path for Android 4.0+?

前端 未结 26 2723
清歌不尽
清歌不尽 2020-11-22 04:48

Samsung Galaxy S3 has an external SD card slot, which is mounted to /mnt/extSdCard.

How can I get this path by something like Environment.getExter

相关标签:
26条回答
  • 2020-11-22 05:52

    Yes. Different manufacturer use different SDcard name like in Samsung Tab 3 its extsd, and other samsung devices use sdcard like this different manufacturer use different names.

    I had the same requirement as you. so i have created a sample example for you from my project goto this link Android Directory chooser example which uses the androi-dirchooser library. This example detect the SDcard and list all the subfolders and it also detects if the device has morethan one SDcard.

    Part of the code looks like this For full example goto the link Android Directory Chooser

    /**
    * Returns the path to internal storage ex:- /storage/emulated/0
     *
    * @return
     */
    private String getInternalDirectoryPath() {
    return Environment.getExternalStorageDirectory().getAbsolutePath();
     }
    
    /**
     * Returns the SDcard storage path for samsung ex:- /storage/extSdCard
     *
     * @return
     */
        private String getSDcardDirectoryPath() {
        return System.getenv("SECONDARY_STORAGE");
    }
    
    
     mSdcardLayout.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            String sdCardPath;
            /***
             * Null check because user may click on already selected buton before selecting the folder
             * And mSelectedDir may contain some wrong path like when user confirm dialog and swith back again
             */
    
            if (mSelectedDir != null && !mSelectedDir.getAbsolutePath().contains(System.getenv("SECONDARY_STORAGE"))) {
                mCurrentInternalPath = mSelectedDir.getAbsolutePath();
            } else {
                mCurrentInternalPath = getInternalDirectoryPath();
            }
            if (mCurrentSDcardPath != null) {
                sdCardPath = mCurrentSDcardPath;
            } else {
                sdCardPath = getSDcardDirectoryPath();
            }
            //When there is only one SDcard
            if (sdCardPath != null) {
                if (!sdCardPath.contains(":")) {
                    updateButtonColor(STORAGE_EXTERNAL);
                    File dir = new File(sdCardPath);
                    changeDirectory(dir);
                } else if (sdCardPath.contains(":")) {
                    //Multiple Sdcards show root folder and remove the Internal storage from that.
                    updateButtonColor(STORAGE_EXTERNAL);
                    File dir = new File("/storage");
                    changeDirectory(dir);
                }
            } else {
                //In some unknown scenario at least we can list the root folder
                updateButtonColor(STORAGE_EXTERNAL);
                File dir = new File("/storage");
                changeDirectory(dir);
            }
    
    
        }
    });
    
    0 讨论(0)
  • 2020-11-22 05:53

    I have tried the solutions provided by Dmitriy Lozenko and Gnathonic on my Samsung Galaxy Tab S2 (Model: T819Y) but none helped me retrieve path to an external SD Card directory. mount command execution contained the required path to external SD Card directory (i.e. /Storage/A5F9-15F4) but it did not match the regular expression hence it was not returned. I don't get the directory naming mechanism followed by Samsung. Why they deviate from standards (i.e. extsdcard) and come up with something really fishy like in my case (i.e. /Storage/A5F9-15F4). Is there anything I am missing? Anyways, following changes in regular expression of Gnathonic's solution helped me get valid sdcard directory:

    final HashSet<String> out = new HashSet<String>();
            String reg = "(?i).*(vold|media_rw).*(sdcard|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 + new String(buffer);
                }
                is.close();
            } catch (final Exception e) {
                e.printStackTrace();
            }
    
            // parse output
            final String[] 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;
    

    I am not sure if this is a valid solution and if it will give results for other Samsung tablets but it has fixed my problem for now. Following is another method to retrieve removable SD Card path in Android (v6.0). I have tested the method with android marshmallow and it works. Approach used in it is very basic and will surely work for other versions too but testing is mandatory. Some insight into it will be helpful:

    public static String getSDCardDirPathForAndroidMarshmallow() {
    
        File rootDir = null;
    
        try {
            // Getting external storage directory file
            File innerDir = Environment.getExternalStorageDirectory();
    
            // Temporarily saving retrieved external storage directory as root
            // directory
            rootDir = innerDir;
    
            // Splitting path for external storage directory to get its root
            // directory
    
            String externalStorageDirPath = innerDir.getAbsolutePath();
    
            if (externalStorageDirPath != null
                    && externalStorageDirPath.length() > 1
                    && externalStorageDirPath.startsWith("/")) {
    
                externalStorageDirPath = externalStorageDirPath.substring(1,
                        externalStorageDirPath.length());
            }
    
            if (externalStorageDirPath != null
                    && externalStorageDirPath.endsWith("/")) {
    
                externalStorageDirPath = externalStorageDirPath.substring(0,
                        externalStorageDirPath.length() - 1);
            }
    
            String[] pathElements = externalStorageDirPath.split("/");
    
            for (int i = 0; i < pathElements.length - 1; i++) {
    
                rootDir = rootDir.getParentFile();
            }
    
            File[] files = rootDir.listFiles();
    
            for (File file : files) {
                if (file.exists() && file.compareTo(innerDir) != 0) {
    
                    // Try-catch is implemented to prevent from any IO exception
                    try {
    
                        if (Environment.isExternalStorageRemovable(file)) {
                            return file.getAbsolutePath();
    
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
    
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
    

    Kindly share if you have any other approach to handle this issue. Thanks

    0 讨论(0)
提交回复
热议问题