开发者

How to find the amount of free storage (disk space) left on Android? [duplicate]

This question already has answers here: How to get free and total size of each StorageVolume? (3 answers) Closed 2 years ago.

I am trying to figure out the available disk space o开发者_如何学Cn the Android phone running my application. Is there a way to do this programmatically?

Thanks,


Example: Getting human readable size like 1 Gb

String memory = bytesToHuman(totalMemory())

/*************************************************************************************************
Returns size in bytes.

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 long totalMemory()
    {
        StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());   
        long   total  = (statFs.getBlockCount() * statFs.getBlockSize());
        return total;
    }

    public long freeMemory()
    {
        StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());
        long   free   = (statFs.getAvailableBlocks() * statFs.getBlockSize());
        return free;
    }

    public long busyMemory()
    {
        StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());   
        long   total  = (statFs.getBlockCount() * statFs.getBlockSize());
        long   free   = (statFs.getAvailableBlocks() * statFs.getBlockSize());
        long   busy   = total - free;
        return busy;
    }

Converting bytes to human readable format (like 1 Mb, 1 Gb)

    public static String floatForm (double d)
    {
       return new DecimalFormat("#.##").format(d);
    }


    public static String bytesToHuman (long size)
    {
        long Kb = 1  * 1024;
        long Mb = Kb * 1024;
        long Gb = Mb * 1024;
        long Tb = Gb * 1024;
        long Pb = Tb * 1024;
        long Eb = Pb * 1024;

        if (size <  Kb)                 return floatForm(        size     ) + " byte";
        if (size >= Kb && size < Mb)    return floatForm((double)size / Kb) + " Kb";
        if (size >= Mb && size < Gb)    return floatForm((double)size / Mb) + " Mb";
        if (size >= Gb && size < Tb)    return floatForm((double)size / Gb) + " Gb";
        if (size >= Tb && size < Pb)    return floatForm((double)size / Tb) + " Tb";
        if (size >= Pb && size < Eb)    return floatForm((double)size / Pb) + " Pb";
        if (size >= Eb)                 return floatForm((double)size / Eb) + " Eb";

        return "???";
    }


Try StatFs.getAvailableBlocks. You'll need to convert the block count to KB with getBlockSize.


There are some subtleties regarding paths that none of the current answers address. You must use the right path based on what kind of stats you are interested in. Based on a deep dive into DeviceStorageMonitorService.java which generates the low disk space warnings in the notification area and the sticky broadcasts for ACTION_DEVICE_STORAGE_LOW, here are some of the paths that you can use:

  1. To check free internal disk space use the data directory obtained via Environment.getDataDirectory(). This will get you the free space on the data partition. The data partition hosts all the internal storage for all apps on the device.

  2. To check free external (SDCARD) disk space use the external storage directory obtained via Environment.getExternalStorageDirectory(). This will get you the free space on the SDCARD.

  3. To check for available memory on the system partition which contains OS files, use Environment.getRootDirectory(). Since your app has no access to the system partition, this stat is probably not very useful. DeviceStorageMonitorService uses for informational purposes and enters it into a log.

  4. To check for temporary files / cache memory, use Environment.getDownloadCacheDirectory(). DeviceStorageMonitorService attempts to clean some of the temporary files when memory gets low.

Some sample code for getting the internal (/data), external (/sdcard) and OS (/system) free memory:

// Get internal (data partition) free space
// This will match what's shown in System Settings > Storage for 
// Internal Space, when you subtract Total - Used
public long getFreeInternalMemory()
{
    return getFreeMemory(Environment.getDataDirectory());
}

// Get external (SDCARD) free space
public long getFreeExternalMemory()
{
    return getFreeMemory(Environment.getExternalStorageDirectory());
}

// Get Android OS (system partition) free space
public long getFreeSystemMemory()
{
    return getFreeMemory(Environment.getRootDirectory());
}

// Get free space for provided path
// Note that this will throw IllegalArgumentException for invalid paths
public long getFreeMemory(File path)
{
    StatFs stats = new StatFs(path.getAbsolutePath());
    return stats.getAvailableBlocksLong() * stats.getBlockSizeLong();
}


Based on @XXX's answer, I've created a gist code snippet that wraps StatFs for easy and simple usage. You can find it here as a GitHub gist.


Typecast your integer values to long before doing multiplication. Multiplication between two big integers could overflow and give a negative result.

public long sd_card_free(){
    File path = Environment.getExternalStorageDirectory();
    StatFs stat = new StatFs(path.getPath());
    int availBlocks = stat.getAvailableBlocksLong();
    int blockSize = stat.getBlockSizeLong();
    long free_memory = (long)availBlocks * (long)blockSize;

    return free_memory;
}


With a little google you might had found the StatFs-class which is:

[...] a Wrapper for Unix statfs().

Examples are here and here:

import java.io.File;

import android.os.Environment;
import android.os.StatFs;

public class MemoryStatus {

    static final int ERROR = -1;

    static public boolean externalMemoryAvailable() {
        return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
    }

    static public long getAvailableInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSize();
        long availableBlocks = stat.getAvailableBlocks();
        return availableBlocks * blockSize;
    }

    static public long getTotalInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSize();
        long totalBlocks = stat.getBlockCount();
        return totalBlocks * blockSize;
    }

    static public long getAvailableExternalMemorySize() {
        if(externalMemoryAvailable()) {
            File path = Environment.getExternalStorageDirectory();
            StatFs stat = new StatFs(path.getPath());
            long blockSize = stat.getBlockSize();
            long availableBlocks = stat.getAvailableBlocks();
            return availableBlocks * blockSize;
        } else {
            return ERROR;
        }
    }

    static public long getTotalExternalMemorySize() {
        if(externalMemoryAvailable()) {
            File path = Environment.getExternalStorageDirectory();
            StatFs stat = new StatFs(path.getPath());
            long blockSize = stat.getBlockSize();
            long totalBlocks = stat.getBlockCount();
            return totalBlocks * blockSize;
        } else {
            return ERROR;
        }
    }

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

        if (size >= 1024) {
            suffix = "KiB";
            size /= 1024;
            if (size >= 1024) {
                suffix = "MiB";
                size /= 1024;
            }
        }

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

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

        if (suffix != null)
            resultBuffer.append(suffix);
        return resultBuffer.toString();
    }
}

Source for code above (Wayback Machine)


    File pathOS = Environment.getRootDirectory();//Os Storage
    StatFs statOS = new StatFs(pathOS.getPath());

    File pathInternal = Environment.getDataDirectory();// Internal Storage
  StatFs statInternal = new StatFs(pathInternal.getPath());

    File pathSdcard = Environment.getExternalStorageDirectory();//External(SD CARD) Storage
    StatFs statSdcard = new StatFs(pathSdcard.getPath());

    if((android.os.Build.VERSION.SDK_INT < 18)) {
        // Get Android OS (system partition) free space API 18 & Below
        int totalBlocksOS = statOS.getBlockCount();
        int blockSizeOS = statOS.getBlockSize();
        int availBlocksOS = statOS.getAvailableBlocks();
        long total_OS_memory = (long) totalBlocksOS * (long) blockSizeOS;
        long free_OS_memory = (long) availBlocksOS * (long) blockSizeOS;
        long Used_OS_memory = total_OS_memory - free_OS_memory;
        TotalOsMemory       =   total_OS_memory ;
        FreeOsMemory        =   free_OS_memory;
        UsedOsMemory        =   Used_OS_memory;

        // Get internal (data partition) free space API 18 & Below
        int totalBlocksInternal = statInternal.getBlockCount();
        int blockSizeInternal = statOS.getBlockSize();
        int availBlocksInternal = statInternal.getAvailableBlocks();
        long total_Internal_memory = (long) totalBlocksInternal * (long) blockSizeInternal;
        long free_Internal_memory = (long) availBlocksInternal * (long) blockSizeInternal;
        long Used_Intenal_memory = total_Internal_memory - free_Internal_memory;
        TotalInternalMemory =   total_Internal_memory;
        FreeInternalMemory  =   free_Internal_memory ;
        UsedInternalMemory  =   Used_Intenal_memory ;

        // Get external (SDCARD) free space for API 18 & Below
        int totalBlocksSdcard = statSdcard.getBlockCount();
        int blockSizeSdcard = statOS.getBlockSize();
        int availBlocksSdcard = statSdcard.getAvailableBlocks();
        long total_Sdcard_memory = (long) totalBlocksSdcard * (long) blockSizeSdcard;
        long free_Sdcard_memory = (long) availBlocksSdcard * (long) blockSizeSdcard;
        long Used_Sdcard_memory = total_Sdcard_memory - free_Sdcard_memory;
        TotalSdcardMemory   =   total_Sdcard_memory;
        FreeSdcardMemory    =   free_Sdcard_memory;
        UsedSdcardMemory    =   Used_Sdcard_memory;
    }
    else {
        // Get Android OS (system partition) free space for API 18 & Above
        long   total_OS_memory          = (statOS.       getBlockCountLong()      * statOS.getBlockSizeLong());
        long   free_OS_memory           = (statOS.       getAvailableBlocksLong() * statOS.getBlockSizeLong());
        long Used_OS_memory = total_OS_memory - free_OS_memory;
        TotalOsMemory       =   total_OS_memory ;
        FreeOsMemory        =   free_OS_memory;
        UsedOsMemory        =   Used_OS_memory;

        // Get internal (data partition) free space for API 18 & Above
        long   total_Internal_memory    = (statInternal. getBlockCountLong()      * statInternal.getBlockSizeLong());
        long   free_Internal_memory     = (statInternal. getAvailableBlocksLong() * statInternal.getBlockSizeLong());
        long Used_Intenal_memory = total_Internal_memory - free_Internal_memory;
        TotalInternalMemory =   total_Internal_memory;
        FreeInternalMemory  =   free_Internal_memory ;
        UsedInternalMemory  =   Used_Intenal_memory ;

        // Get external (SDCARD) free space for API 18 & Above
        long   total_Sdcard_memory      = (statSdcard.   getBlockCountLong()      * statSdcard.getBlockSizeLong());
        long   free_Sdcard_memory       = (statSdcard.   getAvailableBlocksLong() * statSdcard.getBlockSizeLong());
        long Used_Sdcard_memory = tota*emphasized text*l_Sdcard_memory - free_Sdcard_memory;
        TotalSdcardMemory   =   total_Sdcard_memory;
        FreeSdcardMemory    =   free_Sdcard_memory;
        UsedSdcardMemory    =   Used_Sdcard_memory;
    }
}


/**
 * Returns the amount of free memory.
 * @return {@code long} - Free space.
 */
public long getFreeInternalMemory() {
    return getFreeMemory(Environment.getDataDirectory());
}

/**
 * Returns the free amount in SDCARD.
 * @return {@code long} - Free space.
 */
public long getFreeExternalMemory() {
    return getFreeMemory(Environment.getExternalStorageDirectory());
}

/**
 * Returns the free amount in OS.
 * @return {@code long} - Free space.
 */
public long getFreeSystemMemory() {
    return getFreeMemory(Environment.getRootDirectory());
}

/**
 * Returns the free amount in mounted path
 * @param path {@link File} - Mounted path.
 * @return {@code long} - Free space.
 */
public long getFreeMemory(File path) {
    if ((null != path) && (path.exists()) && (path.isDirectory())) {
        StatFs stats = new StatFs(path.getAbsolutePath());
        return stats.getAvailableBlocksLong() * stats.getBlockSizeLong();
    }
    return -1;
}

/**
 * Convert bytes to human format.
 * @param totalBytes {@code long} - Total of bytes.
 * @return {@link String} - Converted size.
 */
public String bytesToHuman(long totalBytes) {
    String[] simbols = new String[] {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"};
    long scale = 1L;
    for (String simbol : simbols) {
        if (totalBytes < (scale * 1024L)) {
            return String.format("%s %s", new DecimalFormat("#.##").format((double)totalBytes / scale), simbol);
        }
        scale *= 1024L;
    }
    return "-1 B";
}


Since blocksize and getAvailableBlocks

are deprecated

this code can be use

note based above answer by user802467

public long sd_card_free(){
    File path = Environment.getExternalStorageDirectory();
    StatFs stat = new StatFs(path.getPath());
    long availBlocks = stat.getAvailableBlocksLong();
    long blockSize = stat.getBlockSizeLong();
    long free_memory = availBlocks * blockSize;

    return free_memory;
}

we can use getAvailableBlocksLong and getBlockSizeLong


Memory Locations:

File[] roots = context.getExternalFilesDirs(null);
String path = roots[0].getAbsolutePath(); // PhoneMemory
String path = roots[1].getAbsolutePath(); // SCCard (if available)
String path = roots[2].getAbsolutePath(); // USB (if available)

usage

long totalMemory = StatUtils.totalMemory(path);
long freeMemory = StatUtils.freeMemory(path);

final String totalSpace = StatUtils.humanize(totalMemory, true);
final String usableSpace = StatUtils.humanize(freeMemory, true);

You can use this

public final class StatUtils {

    public static long totalMemory(String path) {
        StatFs statFs = new StatFs(path);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            //noinspection deprecation
            return (statFs.getBlockCount() * statFs.getBlockSize());
        } else {
            return (statFs.getBlockCountLong() * statFs.getBlockSizeLong());
        }
    }

    public static long freeMemory(String path) {
        StatFs statFs = new StatFs(path);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            //noinspection deprecation
            return (statFs.getAvailableBlocks() * statFs.getBlockSize());
        } else {
            return (statFs.getAvailableBlocksLong() * statFs.getBlockSizeLong());
        }
    }

    public static long usedMemory(String path) {
        long total = totalMemory(path);
        long free = freeMemory(path);
        return total - free;
    }

    public static String humanize(long bytes, boolean si) {
        int unit = si ? 1000 : 1024;
        if (bytes < unit) return bytes + " B";
        int exp = (int) (Math.log(bytes) / Math.log(unit));
        String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
        return String.format(Locale.ENGLISH, "%.1f %sB", bytes / Math.pow(unit, exp), pre);
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜