7

Welcome all

I have tried every question related to this in Stackoverflow and google and none of them works. I have tried something like this next link, but it returns the same as internal storage: How to get an External storage sd card size (With Mounted SD card)?

For example, if I have about 12GB internal storage and 4GB SD card storage, no matter what method I use, I always get the exact same number for the SD space as I do for internal space.

It seems that the old methods posted here in Stackoverflow only works until Android KitKat but do not work in next android versions.

Is possible to solve this?

Community
  • 1
  • 1
NullPointerException
  • 36,107
  • 79
  • 222
  • 382
  • 1
    Well wich path did you use? The code you posted has nothing to do with an sd card. – greenapps Sep 29 '16 at 18:40
  • @greenapps i tryed like 20 solutions posted in stack. Can't remember all of them. Simply tryed all of them. None of them works since 4.4 kitkat. Do you know a solution which works? – NullPointerException Sep 29 '16 at 18:47
  • I dont know what you tried. And you did not tell which path you took for the sd card. If you only told the path. – greenapps Sep 29 '16 at 19:00
  • @greenapps Environment.getExternalStorageDirectory().getAbsolutePath(), "df /mnt/sdcard", Environment.getExternalStorageDirectory(), System.getenv("SECONDARY_STORAGE"); and i'm pretty sure i tryed more options, these are simply examples – NullPointerException Sep 29 '16 at 19:06
  • Those functions do not deliver a path for a removable micro sd card. So no wonder that you did not succeed. You first should find the path for SD card. – greenapps Sep 29 '16 at 19:20
  • 1
    @greenapps do you know the real path of the SD card or you are just trolling here? of course those paths did not work, all we know it. – NullPointerException Sep 29 '16 at 19:20
  • You are not serious if you accuse me that way. – greenapps Sep 29 '16 at 19:39
  • @greenapps "real" path of the SD card could be different in each phone. Which is why knowing the full path for your phone doesn't help because it won't work on another phone. Hence the reason Google/Android recommends not to hardcode the path in the application. Knowing the path isn't going to help solve the problem – ᴛʜᴇᴘᴀᴛᴇʟ Sep 29 '16 at 21:22

2 Answers2

8

Ok, I've always wondered this and couldn't find an answer online. So here's what I do. It might not be so clean but it works for me every time.

For my case: it returns 61,055 MB. I have a 64 GB sd card inserted.

Oh and I forgot to mention: I did this on Samsung Galaxy S5 6.0 and Sony Xperia Z5 Premium 5.1.1 today to confirm. However, I also have an app that few hundred people use daily and I haven't experienced any issues yet.

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
static String getExternalSdCardSize() {
    File storage = new File("/storage");
    String external_storage_path = "";
    String size = "";

    if (storage.exists()) {
        File[] files = storage.listFiles();

        for (File file : files) {
            if (file.exists()) {
                try {
                    if (Environment.isExternalStorageRemovable(file)) {
                        // storage is removable
                        external_storage_path = file.getAbsolutePath();
                        break;
                    }
                } catch (Exception e) {
                    Log.e("TAG", e.toString());
                }
            }
        }
    }

    if (!external_storage_path.isEmpty()) {
        File external_storage = new File(external_storage_path);
        if (external_storage.exists()) {
            size = totalSize(external_storage);
        }
    }
    return size;
}

private static String totalSize(File file) {
    StatFs stat = new StatFs(file.getPath());
    long blockSize, totalBlocks;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        blockSize = stat.getBlockSizeLong();
        totalBlocks = stat.getBlockCountLong();
    } else {
        blockSize = stat.getBlockSize();
        totalBlocks = stat.getBlockCount();
    }

    return formatSize(totalBlocks * blockSize);
}

private static String formatSize(long size) {
    String suffix = null;

    if (size >= 1024) {
        suffix = "KB";
        size /= 1024;
        if (size >= 1024) {
            suffix = "MB";
            size /= 1024;
        }
    }

    StringBuilder resultBuilder = new StringBuilder(Long.toString(size));

    int commaOffset = resultBuilder.length() - 3;
    while (commaOffset > 0) {
        resultBuilder.insert(commaOffset, ',');
        commaOffset -= 3;
    }

    if (suffix != null) resultBuilder.append(suffix);
    return resultBuilder.toString();
}
ᴛʜᴇᴘᴀᴛᴇʟ
  • 4,466
  • 5
  • 39
  • 73
0

My phone has a built-in storage of 32GB and SD Card of 15GB. Doing a df on /mnt/sdcard gives a 32GB result, which is not what we are looking for. Digging further, I found this /storage directory. It has 3 files in there:

shell@E5803:/storage $ ls
8E5D-12E2
emulated
self

doing a df on each item gives the following:

shell@E5803:/storage $ df self                                                 
Filesystem               Size     Used     Free   Blksize
self                   889.4M     0.0K   889.4M   4096
shell@E5803:/storage $ df emulated                                             
Filesystem               Size     Used     Free   Blksize
emulated                22.6G    10.8G    11.8G   4096
shell@E5803:/storage $ df 8E5D-12E2/                                           
Filesystem               Size     Used     Free   Blksize
8E5D-12E2/              14.9G     2.3G    12.7G   32768

I think the magic command is "df /storage/" + mFilesArray[0] where mFilesArray[] is the result from ls /storage.

(Let's hope that Google guys don't change the SD Card mount point in the future, which I doubt.)

Hope this helps.

user1506104
  • 6,554
  • 4
  • 71
  • 89