Home » Android » android – How to get SD_Card path in android6.0 programmatically

android – How to get SD_Card path in android6.0 programmatically

Posted by: admin June 15, 2020 Leave a comment

Questions:

I am trying to check whether device having external storage or not by using external storage path like this given below

 if (new File("/ext_card/").exists()) {
        specialPath = "/ext_card/";
    } else if (new File("/mnt/sdcard/external_sd/").exists()) {
        specialPath = "/mnt/sdcard/external_sd/";
    } else if (new File("/storage/extSdCard/").exists()) {
        specialPath = "/storage/extSdCard/";
    } else if (new File("/mnt/extSdCard/").exists()) {
        specialPath = "/mnt/extSdCard/";
    } else if (new File("/mnt/sdcard/external_sd/").exists()) {
        specialPath = "/mnt/sdcard/external_sd/";
    } else if (new File("storage/sdcard1/").exists()) {
        specialPath = "storage/sdcard1/";
    }

But in marshmallow I con’t find this path and while checking using ES FILEMANAGER, they give like storage/3263-3131 in Moto G 3rd generation. While check in other marshmallow devices that numbers getting differ. Please help me to check that marshmallow device have external storage or not? and if storage found means how to get the path of that external storage?

Note:- I gave permission for storage in my application and also enabled storage permission in settings for my app.

Thanks in advance and did you find any mistake in my question please crt it. thank you again.

How to&Answers:

Here’s my solution, which is guaranteed to work till Android 7.0 Nougat:

/* returns external storage paths (directory of external memory card) as array of Strings */
public String[] getExternalStorageDirectories() {

        List<String> results = new ArrayList<>();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //Method 1 for KitKat & above
        File[] externalDirs = getExternalFilesDirs(null);
        String internalRoot = Environment.getExternalStorageDirectory().getAbsolutePath().toLowerCase();

        for (File file : externalDirs) {
            if(file==null) //solved NPE on some Lollipop devices
               continue;
            String path = file.getPath().split("/Android")[0];

            if(path.toLowerCase().startsWith(internalRoot))
               continue;

            boolean addPath = false;

            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                addPath = Environment.isExternalStorageRemovable(file);
            }
            else{
                addPath = Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(file));
            }

            if(addPath){
                results.add(path);
            }
        }
    }

        if(results.isEmpty()) { //Method 2 for all versions
            // better variation of: http://stackoverflow.com/a/40123073/5002496
            String output = "";
            try {
                final Process process = new ProcessBuilder().command("mount | grep /dev/block/vold")
                .redirectErrorStream(true).start();
                process.waitFor();
                final InputStream is = process.getInputStream();
                final byte[] buffer = new byte[1024];
                while (is.read(buffer) != -1) {
                    output = output + new String(buffer);
                }
                is.close();
            } catch (final Exception e) {
                e.printStackTrace();
            }
            if(!output.trim().isEmpty()) {
                String devicePoints[] = output.split("\n");
                for(String voldPoint: devicePoints) {
                    results.add(voldPoint.split(" ")[2]);
                }
            }
        }

        //Below few lines is to remove paths which may not be external memory card, like OTG (feel free to comment them out)
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            for (int i = 0; i < results.size(); i++) {
                if (!results.get(i).toLowerCase().matches(".*[0-9a-f]{4}[-][0-9a-f]{4}")) {
                    Log.d(LOG_TAG, results.get(i) + " might not be extSDcard");
                    results.remove(i--);
                }
            }
        } else {
            for (int i = 0; i < results.size(); i++) {
                if (!results.get(i).toLowerCase().contains("ext") && !results.get(i).toLowerCase().contains("sdcard")) {
                    Log.d(LOG_TAG, results.get(i)+" might not be extSDcard");
                    results.remove(i--);
                }
            }
        }

        String[] storageDirectories = new String[results.size()];
        for(int i=0; i<results.size(); ++i) storageDirectories[i] = results.get(i);

        return storageDirectories;
    }

Answer:

I found the solution for this over here https://stackoverflow.com/a/13648873/842607

The code is –

public static 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 + 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;
}

The other one is the hack which I found from the same page –

private static final 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)
 */
public static String[] getStorageDirectories()
{
    // Final set of paths
    final Set<String> rv = new HashSet<String>();
    // Primary physical SD-CARD (not emulated)
    final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
    // All Secondary SD-CARDs (all exclude primary) separated by ":"
    final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
    // Primary emulated SD-CARD
    final String 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.
        final String rawUserId;
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
        {
            rawUserId = "";
        }
        else
        {
            final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
            final String[] folders = DIR_SEPORATOR.split(path);
            final String 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 storages
    if(!TextUtils.isEmpty(rawSecondaryStoragesStr))
    {
        // All Secondary SD-CARDs splited into array
        final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
        Collections.addAll(rv, rawSecondaryStorages);
    }
    return rv.toArray(new String[rv.size()]);
}

Answer:

This library solve my problem.

https://github.com/hendrawd/StorageUtil

What i did is:

private File directory;
String[] allPath;

allPath = StorageUtil.getStorageDirectories(this);
for (String path: allPath){
    directory = new File(path);
    Methods.update_Directory_Files(directory);
}

Methods.update_Directory_Files()

// Retrieving files from memory

public static void  update_Directory_Files(File directory) {

    //Get all file in storage
    File[] fileList = directory.listFiles();
    //check storage is empty or not
    if(fileList != null && fileList.length > 0)
    {
        for (int i=0; i<fileList.length; i++)
        {
            boolean restricted_directory = false;
            //check file is directory or other file
            if(fileList[i].isDirectory())
            {
                for (String path : Constant.removePath){
                    if (path.equals(fileList[i].getPath())) {
                        restricted_directory = true;
                        break;
                    }
                }
                if (!restricted_directory)
                    update_Directory_Files(fileList[i]);
            }
            else
            {
                String name = fileList[i].getName().toLowerCase();
                for (String ext : Constant.videoExtensions){
                    //Check the type of file
                    if(name.endsWith(ext))
                    {
                        //first getVideoDuration
                        String videoDuration = Methods.getVideoDuration(fileList[i]);
                        long playbackPosition;
                        long percentage = C.TIME_UNSET;
                        FilesInfo.fileState state;

                        /*First check video already played or not. If not then state is NEW
                         * else load playback position and calculate percentage of it and assign it*/

                        //check it if already exist or not if yes then start from there else start from start position
                        int existIndex = -1;
                        for (int j = 0; j < Constant.filesPlaybackHistory.size(); j++) {
                            String fListName = fileList[i].getName();
                            String fPlaybackHisName = Constant.filesPlaybackHistory.get(j).getFileName();
                            if (fListName.equals(fPlaybackHisName)) {
                                existIndex = j;
                                break;
                            }
                        }

                        try {
                            if (existIndex != -1) {
                                //if true that means file is not new
                                state = FilesInfo.fileState.NOT_NEW;
                                //set playbackPercentage not playbackPosition
                                MediaMetadataRetriever retriever = new MediaMetadataRetriever();
                                retriever.setDataSource(fileList[i].getPath());
                                String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                                retriever.release();

                                int duration = Integer.parseInt(time);
                                playbackPosition = Constant.filesPlaybackHistory.get(existIndex).getPlaybackPosition();

                                if (duration > 0)
                                    percentage = 1000L * playbackPosition / duration;
                                else
                                    percentage = C.TIME_UNSET;

                            }
                            else
                                state = FilesInfo.fileState.NEW;

                            //playbackPosition have value in percentage
                            Constant.allMemoryVideoList.add(new FilesInfo(fileList[i],
                                    directory,videoDuration, state, percentage));

                            //directory portion
                            currentDirectory = directory.getPath();
                            unique_directory = true;

                            for(int j=0; j<directoryList.size(); j++)
                            {
                                if((directoryList.get(j).toString()).equals(currentDirectory)){
                                    unique_directory = false;
                                }
                            }

                            if(unique_directory){
                                directoryList.add(directory);
                            }

                            //When we found extension from videoExtension array we will break it.
                            break;

                        }catch (Exception e){
                            e.printStackTrace();
                            Constant.allMemoryVideoList.add(new FilesInfo(fileList[i],
                                    directory,videoDuration, FilesInfo.fileState.NOT_NEW, C.TIME_UNSET));
                        }

                    }
                }
            }
        }
    }
    Constant.directoryList = directoryList;
}

Answer:

in this i have redmi note prime 2.and i have no memory card.so when i found path and File[] externalDirs = getExternalFilesDirs(null); give null second postion value of file[].
}