12

To my knowledge, on Android, there is:

  • Internal memory for apps and cache
  • Internal SD Card on some phones (not removable)
  • External SD Card for music and photos (removable)

How do I get the total and available for each with a check that they exist (some phones do not have an internal SD Card)

Thanks

zsniperx
  • 2,732
  • 6
  • 25
  • 32

5 Answers5

33

Here is how you get internal storage sizes:

 StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());        
 long blockSize = statFs.getBlockSize();
 long totalSize = statFs.getBlockCount()*blockSize;
 long availableSize = statFs.getAvailableBlocks()*blockSize;
 long freeSize = statFs.getFreeBlocks()*blockSize;

Here is how you get external storage sizes (SD card size):

 StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());        
 long blockSize = statFs.getBlockSize();
 long totalSize = statFs.getBlockCount()*blockSize;
 long availableSize = statFs.getAvailableBlocks()*blockSize;
 long freeSize = statFs.getFreeBlocks()*blockSize;

Short note

Free blocks:

The total number of blocks that are free on the file system, including reserved blocks (that are not available to normal applications).

Available blocks:

The number of blocks that are free on the file system and available to applications.


Here is how to detect whether SD card is mounted:

 String state = Environment.getExternalStorageState();
 if (Environment.MEDIA_MOUNTED.equals(state)) 
 {
   // We can read and write the media    
 } 
 else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) 
 {
    // We can only read the media     
 } 
 else 
 {
    // No external media
 }
inazaruk
  • 74,247
  • 24
  • 188
  • 156
  • great response! any way to get the size of internal SD Card, not onboard flash memory? and what is the difference between freeSize and availableSize? – zsniperx Jan 26 '11 at 00:48
  • I've edited my answer to include the information you asked for. – inazaruk Jan 26 '11 at 01:07
  • Thanks! will check it out once I have time. Great answer – zsniperx Jan 30 '11 at 01:58
  • On an emulator statFs.getAvailableBlocks() is returning 0 but it is working fine on a normal device. I set the internal memory to 400MB on emulator. Is there anything I might be missing when i use this to test on emulator? – achie Nov 05 '13 at 20:02
  • @achie: make sure the AVD has a "SD card" configured. – sfera Nov 20 '13 at 12:59
  • 1
    a note: on devices with a lot of external storage, you might get negative values when using the StatFs methods which return an int value. This is (IIRC) because of long values being cast to int, resulting in an int overflow (int: 32 bit, long: 64 bit).In such cases you _might_ assume that there is "a lot" of available space on the device even if you don't know exactly how much that is – sfera Nov 20 '13 at 13:08
  • I compute memory grand total (internal + external) using this method and get 15 GB instead of 16GB (as displayed in standard Android app) Why is that? – Pascal Dec 02 '16 at 10:52
3

For internal memory Environment.getRootDirectory().getAbsolutePath() is not right approach.

Also on most of devices

Environment.getDataDirectory() works but again not consistent.

For external directory approach is right. To differentiate between internal mnt/sdcard use

Environment.isExternalStorageRemovable().

But i am still wondering about how to get exact internal memory. As with open source inconsistency and lots of versions.

swap mahan
  • 81
  • 3
3
/*************************************************************************************************
Returns size in MegaBytes.

If you need calculate external memory, change this: 
    StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());
to this: 
    StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());        
**************************************************************************************************/
    public int TotalMemory()
    {
        StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());   
        int Total = (statFs.getBlockCount() * statFs.getBlockSize()) / 1048576;
        return Total;
    }

    public int FreeMemory()
    {
        StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());
        int Free  = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1048576;
        return Free;
    }

    public int BusyMemory()
    {
        StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());   
        int Total = (statFs.getBlockCount() * statFs.getBlockSize()) / 1048576;
        int Free  = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1048576;
        int Busy  = Total - Free;
        return Busy;
    }
XXX
  • 8,996
  • 7
  • 44
  • 53
  • Using "TotalMemory" returns me -1166 ... Even if I change the variable types to long, it returns me 3071504384 , which is not what I have (~3GB compared to ~32GB) . – android developer Nov 05 '16 at 19:24
0

On most phones the total blocks are the number of blocks available to the user (i.e. less system storage etc.). I am yet to find a method that will yield the total amount of storage on the phone.

user330844
  • 872
  • 1
  • 12
  • 12
0

StatFs - Retrieve overall information about the space on a filesystem. This is a wrapper for Unix statvfs().

From API level 18 use

long getTotalBytes - The total number of bytes supported by the file system. 

For older API use

int getBlockCount ()
int getBlockSize ()

StatFs stat = new StatFs(**path**);
long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount();

Here we need provide correct string value for path variable. You need use string values of path like this: "/mnt/external_sd/" "/mnt/extSdCard/"

You can retreive list of all /mnt/ devices and use one of this values.

File mntDir = new File("/mnt/");
if(mntDir.isDirectory()){ 
String[] dirList = mntDir.list();...}

or something like

var file=new Java.IO.File("storage/");
var listOfStorages=file.ListFiles();

or

String[] externals = System.getenv("SECONDARY_STORAGE").split(":");
Mark Martin
  • 372
  • 3
  • 8