I am trying to figure out the available disk space on the Android phone running my application. Is there a way to do this programmatically?
Thanks,
Try StatFs.getAvailableBlocks. You'll need to convert the block count to KB with getBlockSize.
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 "???";
}
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:
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.
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.
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.
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 provided
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;
}
}
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
/**
* 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";
}
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);
}
}
来源:https://stackoverflow.com/questions/7115016/how-to-find-the-amount-of-free-storage-disk-space-left-on-android