2

I'd like to get the amount on internal and external space in a device and after going to through a couple of posts on StackOverflow, I found that this is easy. I can get the amount of internal space using this:

StatFs sfsInternal = new StatFs(Environment.getRootDirectory().getAbsolutePath());
return Long.valueOf(sfsInternal.getBlockCount()) * Long.valueOf(sfsInternal.getBlockSize());

...and I can get the amount of external space using this:

StatFs sfsExternal = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
return Long.valueOf(sfsExternal.getBlockCount()) * Long.valueOf(sfsExternal.getBlockSize());

When I read about "internal" storage, I assumed that it would be the non-removable onboard storage on the device and "external" would the removable flash card storage but this hasn't been case entirely.

I found that Samsung devices e.e. Galaxy Note 2, show a large chunk of the internal storage as external. Here's an answer that discusses the same thing. https://stackoverflow.com/a/12087556/304151

How can I get the amount of internal storage (on-board and non-removable) and the amount of external storage (flash and removable) while factoring in the edge cases of Samsung's Galaxy devices. I'm yet to find an answer on StackOverflow that provides a complete working solution for this scenario. My code is for API level 17.

Thanks.

Community
  • 1
  • 1
Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382
  • what about phones that have no sdcard slot? The _internal_ memory is partitioned so that is has some _external_ space even when no sdcard is available. – jlordo Jul 01 '13 at 11:05
  • If the phone doesn't have a sd-card slot, the external storage should be reported as 0. For the internal stroage, I'd like to only report the non-removable internal space and exclude the system partition. When I go to the Settings >> Storage section on my device, all this information is represented perfectly but I haven't been able to dig out this code from the AOSP repositories. – Mridang Agarwalla Jul 01 '13 at 11:12

4 Answers4

0

Here is the code to get available free space on different devices i have tested that code on samsung GALAXY Tab7 2.2 Froyo and Nexus 7 4.2.2 Jelly Beans

    // calculate frespace on external storage
    public static int getExternalStorageFreeSpace(String storagePath)
        {
            try
                {
                    File file = new File(storagePath);
                    StatFs stat = new StatFs(file.getPath());
                    double sdAvailSize = (double) stat.getAvailableBlocks() * (double) stat.getBlockSize();
                    int valueinmb = (int) (sdAvailSize / 1024) / 1024;
                    return valueinmb;
                }
            catch (Exception e)
                {
                    System.out.println("Message//////" + e.getMessage() + "Cause555555555555" + e.getCause());
                }
            return 0;
        }

to diffrentiate between internal and external storages i have used this class and some logic

public class GetRemoveableDevices
{
    private final static String TAG = "GetRemoveableDevice";

    public GetRemoveableDevices()
        {
        }

    public static String[] getDirectories()
        {
            Log.d(TAG, "getStorageDirectories");
            File tempFile;
            String[] directories = null;
            String[] splits;
            ArrayList<String> arrayList = new ArrayList<String>();
            BufferedReader bufferedReader = null;
            String lineRead;

            try
                {
                    arrayList.clear(); // redundant, but what the hey
                    bufferedReader = new BufferedReader(new FileReader("/proc/mounts"));

                    while ((lineRead = bufferedReader.readLine()) != null)
                        {
                            Log.d(TAG, "lineRead: " + lineRead);
                            splits = lineRead.split(" ");

                            // System external storage
                            if (splits[1].equals(Environment.getExternalStorageDirectory().getPath()))
                                {
                                    arrayList.add(splits[1]);
                                    Log.d(TAG, "gesd split 1: " + splits[1]);
                                    continue;
                                }

                            // skip if not external storage device
                            if (!splits[0].contains("/dev/block/"))
                                {
                                    continue;
                                }

                            // skip if mtdblock device

                            if (splits[0].contains("/dev/block/mtdblock"))
                                {
                                    continue;
                                }

                            // skip if not in /mnt node

                            if (!splits[1].contains("/mnt"))
                                {
                                    continue;
                                }

                            // skip these names

                            if (splits[1].contains("/secure"))
                                {
                                    continue;
                                }

                            if (splits[1].contains("/mnt/asec"))
                                {
                                    continue;
                                }

                            // Eliminate if not a directory or fully accessible
                            tempFile = new File(splits[1]);
                            if (!tempFile.exists())
                                {
                                    continue;
                                }
                            if (!tempFile.isDirectory())
                                {
                                    continue;
                                }
                            if (!tempFile.canRead())
                                {
                                    continue;
                                }
                            if (!tempFile.canWrite())
                                {
                                    continue;
                                }

                            // Met all the criteria, assume sdcard
                            arrayList.add(splits[1]);
                        }

                }
            catch (FileNotFoundException e)
                {
                }
            catch (IOException e)
                {
                }
            finally
                {
                    if (bufferedReader != null)
                        {
                            try
                                {
                                    bufferedReader.close();
                                }
                            catch (IOException e)
                                {
                                }
                        }
                }

            // Send list back to caller

            if (arrayList.size() == 0)
                {
                    arrayList.add("sdcard not found");
                }
            directories = new String[arrayList.size()];
            for (int i = 0; i < arrayList.size(); i++)
                {
                    directories[i] = arrayList.get(i);
                }
            return directories;
        }

}

now i am showing you my logic

String[] dirs = GetRemoveableDevices.getDirectories();
            ArrayList<String> directories=new ArrayList<String>();
            for(String directory:dirs)
                {
                    if(!directory.contains("."))
                    directories.add(directory);
                }
            String externalStorage = "";
            String internalStorage = "";
            if (directories.size()>= 2)
                {
                    internalStorage = directories.get(0).toString();
                    externalStorage = directories.get(1).toString();
                }
            else if (directories.size() < 2)
                {
                    internalStorage = directories.get(0).toString();
                    externalStorage = null;
                }

hope it will be helpful

farrukh
  • 627
  • 4
  • 16
0

"Internal storage" is for privately held data. It's called internal because it's relative to the application itself. It's for sandboxing the application's data and keeping it private.

Environment.getRootDirectory() gets the phone's system folder. Which is not internal storage, but external storage.

External storage is for publicly shared data, external to the application.

Since mounting naming conventions vary greatly between phones, it can be difficult to differentiate from an SD card and normal onboard directories. But generally, the sd card is mounted to the directory /sdcard/.

frogmanx
  • 2,620
  • 1
  • 18
  • 20
  • While what you say is true, I'm wondering how Android (Cyanogenmod) does this on my Galaxy Note 2. When I go to Settings >> Storage on my device, it shows that I have 10.46 GB on my Internal storage. I don't have a sd-card on my device and so it shows that there is no external storage. This looks correct to me. When I'm using the API calls which I posted in my question, the 10.46 GB is returned when I query the size of the external storage. Any thoughts on this? – Mridang Agarwalla Jul 01 '13 at 12:02
  • Here's the code from AOSP: https://github.com/CyanogenMod/android_packages_apps_Settings/tree/cm-10.1/src/com/android/settings/deviceinfo – Mridang Agarwalla Jul 01 '13 at 12:03
0

I found some code that does this on this blog post.

package com.sapien.music.importer.util;

import java.io.File;

@SuppressLint("NewApi")
public class StorageOptions {
public static String[] labels;
public static String[] paths;
public static int count = 0;

private static Context sContext;
private static ArrayList<String> sVold = new ArrayList<String>();

public static void determineStorageOptions(Context context) {
    sContext = context.getApplicationContext();

    readVoldFile();

    testAndCleanList();

    setProperties();
}

private static void readVoldFile() {
    /*
     * Scan the /system/etc/vold.fstab file and look for lines like this:
     * dev_mount sdcard /mnt/sdcard 1
     * /devices/platform/s3c-sdhci.0/mmc_host/mmc0
     * 
     * When one is found, split it into its elements and then pull out the
     * path to the that mount point and add it to the arraylist
     * 
     * some devices are missing the vold file entirely so we add a path here
     * to make sure the list always includes the path to the first sdcard,
     * whether real or emulated.
     */

    sVold.add("/mnt/sdcard");

    try {
        Scanner scanner = new Scanner(new File("/system/etc/vold.fstab"));
        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.contains("usb"))
                    continue;

                // don't add the default vold path
                // it's already in the list.
                if (!sVold.contains(element))
                    sVold.add(element);
            }
        }
    } catch (Exception e) {
        // swallow - don't care
        e.printStackTrace();
    }
}

private static void testAndCleanList() {
    /*
     * Now that we have a cleaned list of mount paths, test each one to make
     * sure it's a valid and available path. If it is not, remove it from
     * the list.
     */

    for (int i = 0; i < sVold.size(); i++) {
        String voldPath = sVold.get(i);
        File path = new File(voldPath);
        if (!path.exists() || !path.isDirectory() || !path.canWrite())
            sVold.remove(i--);
    }
}

private static void setProperties() {
    /*
     * At this point all the paths in the list should be valid. Build the
     * public properties.
     */

    ArrayList<String> labelList = new ArrayList<String>();

    int j = 0;
    if (sVold.size() > 0) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD)
            labelList.add("Auto");
        else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            if (Environment.isExternalStorageRemovable()) {
                labelList.add(sContext
                        .getString(R.string.text_external_storage) + " 1");
                j = 1;
            } else
                labelList.add(sContext
                        .getString(R.string.text_internal_storage));
        } else {
            if (!Environment.isExternalStorageRemovable()
                    || Environment.isExternalStorageEmulated())
                labelList.add(sContext
                        .getString(R.string.text_internal_storage));
            else {
                labelList.add(sContext
                        .getString(R.string.text_external_storage) + " 1");
                j = 1;
            }
        }

        if (sVold.size() > 1) {
            for (int i = 1; i < sVold.size(); i++) {
                labelList.add(sContext
                        .getString(R.string.text_external_storage)
                        + " " + (i + j));
            }
        }
    }

    labels = new String[labelList.size()];
    labelList.toArray(labels);

    paths = new String[sVold.size()];
    sVold.toArray(paths);

    count = Math.min(labels.length, paths.length);

    /*
     * don't need these anymore, clear the lists to reduce memory use and to
     * prepare them for the next time they're needed.
     */
    sVold.clear();
}
Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382
0

try this out:

 private boolean is_sdCardSaveToUse(){

    /**default disk cache size in bytes*/
    final int DEFAULT_DISK_CACHE_SIZE = 1024 * 1024 * 10; //10 MB

    /**get sdCard state*/
    String sdCardState = Environment.getExternalStorageState();

    /**check if the sdCard is mounted*/
    /**check if we can write to sdCard*/if (Environment.MEDIA_MOUNTED.equals(sdCardState)) {
        if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(sdCardState)) {
            Log.d("sdCard", "mounted readOnly");
        } else {
            Log.d("sdCard", "mounted readWrite");

            /**get free usable space in bytes */
            long freeUsableSpace = Environment.getExternalStorageDirectory().getUsableSpace();
            int temp = Math.round(((float) freeUsableSpace / 1024) / 1024); //convert from bytes to MB.
            Log.d("usableSpace= ", Integer.toString(temp) + " MB");

            if (freeUsableSpace > DEFAULT_DISK_CACHE_SIZE){
                return  true;
            } else {
                Log.d("sdCard","not enough space");
                return  false;
            }

        }

    } else{
        Log.d("sdCard","not mounted");
        return false;
    }

   return false;
}
zibetto
  • 21
  • 2