如何找到Android上剩余的可用存储空间(磁盘空间)?

Ash*_*win 29 storage android diskspace disk

我试图找出运行我的应用程序的Android手机上的可用磁盘空间.有没有办法以编程方式执行此操作?

谢谢,

XXX*_*XXX 48

示例:获得人类可读的大小,如1 Gb

字符串内存= 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;
    }
Run Code Online (Sandbox Code Playgroud)

将字节转换为人类可读格式(如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 "???";
    }
Run Code Online (Sandbox Code Playgroud)

  • `getAvailableBlocks()`和`getBlockSize()`已被弃用,分别用`getAvailableBlocksLong()`和`statFs.getBlockSizeLong()`替换. (6认同)

Fem*_*emi 14

试试StatFs.getAvailableBlocks.您需要使用getBlockSize将块计数转换为KB.

  • 对于 API 级别 &gt;= 18 - StatFs.getAvailableBytes () 返回文件系统上可用且可供应用程序使用的字节数。 (3认同)
  • getAvailableBlocks 在 API 级别 18 中已弃用,新方法是 getAvailableBlocksLong (2认同)

The*_*heo 7

关于路径的一些细微之处,目前的答案都没有解决.您必须根据您感兴趣的统计数据使用正确的路径.基于深入了解通知区域中生成低磁盘空间警告的DeviceStorageMonitorService.java和ACTION_DEVICE_STORAGE_LOW的粘性广播,以下是一些路径你可以使用:

  1. 要检查可用的内部磁盘空间,请使用通过Environment.getDataDirectory()获取的数据目录.这将为您提供数据分区上的可用空间.数据分区托管设备上所有应用程序的所有内部存储.

  2. 要检查空闲外部(SDCARD)磁盘空间,请使用通过Environment.getExternalStorageDirectory()获取的外部存储目录.这将为您提供SDCARD上的可用空间.

  3. 要检查包含OS文件的系统分区上的可用内存,请使用Environment.getRootDirectory().由于您的应用无权访问系统分区,因此该统计信息可能不太有用.DeviceStorageMonitorService用于提供信息,并将其输入日志.

  4. 要检查临时文件/缓存内存,请使用Environment.getDownloadCacheDirectory().当内存不足时,DeviceStorageMonitorService会尝试清除某些临时文件.

获取内部(/ data),外部(/ sdcard)和OS(/系统)可用内存的示例代码:

// 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();
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*sel 6

基于@XX的答案,我创建了一个包含StatF的gist代码片段,以方便和简单地使用.你可以在这里找到它作为GitHub的要点.


Luk*_*uth 5

通过一点谷歌,你可能会发现 -classStatFs

[...] Unix statfs() 的包装器。

示例在这里和这里:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

上述代码的来源(Wayback Machine)


use*_*467 5

在进行乘法运算之前,将整数值类型转换为很长的时间。两个大整数之间的相乘可能会溢出并产生负数结果。

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;
}
Run Code Online (Sandbox Code Playgroud)

  • +1 大概这就是为什么`getAvailableBlocks()` 和`getBlockSize()` 已被弃用并被`getAvailableBlocksLong()` 和`statFs.getBlockSizeLong()` 取代的原因。 (2认同)