Java 如何检查安卓设备上的可用空间?在 SD 卡上?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3394765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 22:53:49  来源:igfitidea点击:

How to Check available space on android device ? on SD card?

javaandroid

提问by Zeus

How do I check to see how much MB or GB is left on the android device ? I am using JAVA and android SDK 2.0.1.

如何查看 Android 设备上还剩多少 MB 或 GB?我正在使用 JAVA 和 android SDK 2.0.1。

Is there any system service that would expose something like this ?

是否有任何系统服务会公开这样的内容?

采纳答案by Yaroslav Boichuk

Try this code:

试试这个代码

StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());

long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount();
long megAvailable   = bytesAvailable / 1048576;

System.out.println("Megs :"+megAvailable);

Update:

更新:

getBlockCount()- return size of SD card;

getBlockCount()- 返回SD卡的大小;

getAvailableBlocks()- return the number of blocks that are still accessible to normal programs (thanks Joe)

getAvailableBlocks()- 返回正常程序仍可访问的块数(感谢 Joe)

回答by Yaroslav Boichuk

Yaroslav's answer will give the size of the SD card, not the available space. StatFs's getAvailableBlocks()will return the number of blocks that are still accessible to normal programs. Here is the function I am using:

Yaroslav 的回答将给出 SD 卡的大小,而不是可用空间。StatFsgetAvailableBlocks()将返回正常程序仍可访问的块数。这是我正在使用的功能:

public static float megabytesAvailable(File f) {
    StatFs stat = new StatFs(f.getPath());
    long bytesAvailable = (long)stat.getBlockSize() * (long)stat.getAvailableBlocks();
    return bytesAvailable / (1024.f * 1024.f);
}

The above code has reference to some deprecated functions as of August 13, 2014. I below reproduce an updated version:

上面的代码引用了一些截至 2014 年 8 月 13 日已弃用的函数。我在下面复制了一个更新版本:

public static float megabytesAvailable(File f) {
    StatFs stat = new StatFs(f.getPath());
    long bytesAvailable = 0;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
        bytesAvailable = (long) stat.getBlockSizeLong() * (long) stat.getAvailableBlocksLong();
    else
        bytesAvailable = (long) stat.getBlockSize() * (long) stat.getAvailableBlocks();
    return bytesAvailable / (1024.f * 1024.f);
}

回答by android developer

also , if you want to check available space on internal memory , use:

另外,如果您想检查内部存储器上的可用空间,请使用:

File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());

...

...

回答by Muhammad Nabeel Arif

I have designed some ready to use functions to get available space in different units. You can use these methods by simply copying any one of them into your project.

我设计了一些随时可用的函数来获得不同单位的可用空间。您可以通过简单地将其中任何一种方法复制到您的项目中来使用这些方法。

/**
 * @return Number of bytes available on External storage
 */
public static long getAvailableSpaceInBytes() {
    long availableSpace = -1L;
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();

    return availableSpace;
}


/**
 * @return Number of kilo bytes available on External storage
 */
public static long getAvailableSpaceInKB(){
    final long SIZE_KB = 1024L;
    long availableSpace = -1L;
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
    return availableSpace/SIZE_KB;
}
/**
 * @return Number of Mega bytes available on External storage
 */
public static long getAvailableSpaceInMB(){
    final long SIZE_KB = 1024L;
    final long SIZE_MB = SIZE_KB * SIZE_KB;
    long availableSpace = -1L;
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
    return availableSpace/SIZE_MB;
}

/**
 * @return Number of gega bytes available on External storage
 */
public static long getAvailableSpaceInGB(){
    final long SIZE_KB = 1024L;
    final long SIZE_GB = SIZE_KB * SIZE_KB * SIZE_KB;
    long availableSpace = -1L;
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
    return availableSpace/SIZE_GB;
}

回答by Deepak Kumar Sharma

I Hope this code can help others. Tested working fine. Thanks to above member to clarify it.

我希望这段代码可以帮助其他人。经测试工作正常。感谢上述成员澄清它。

/**
 * Get the free disk available space in boolean to download requested file 
 * 
 * @return boolean value according to size availability
 */

protected static boolean isMemorySizeAvailableAndroid(long download_bytes, boolean isExternalMemory) {
    boolean isMemoryAvailable = false;
    long freeSpace = 0;

    // if isExternalMemory get true to calculate external SD card available size
    if(isExternalMemory){
        try {
            StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
            freeSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
            if(freeSpace > download_bytes){
                isMemoryAvailable = true;
            }else{
                isMemoryAvailable = false;
            }
        } catch (Exception e) {e.printStackTrace(); isMemoryAvailable = false;}
    }else{
        // find phone available size
        try {
            StatFs stat = new StatFs(Environment.getDataDirectory().getPath());
            freeSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
            if(freeSpace > download_bytes){
                isMemoryAvailable = true;
            }else{
                isMemoryAvailable = false;
            }
        } catch (Exception e) {e.printStackTrace(); isMemoryAvailable = false;}
    }

    return isMemoryAvailable;
}

回答by Vinayak Patil

public String TotalExtMemory()
{
    StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());   
    int Total = (statFs.getBlockCount() * statFs.getBlockSize()) / 1048576;

    String strI = Integer.toString(Total);
    return strI;
}

public String FreeExtMemory()
{
    StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
    int Free  = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1048576;
    String strI = Integer.toString(Free);
    return strI;
}

public String BusyExtMemory()
{
    StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());   
    int Total = (statFs.getBlockCount() * statFs.getBlockSize()) / 1048576;
    int Free  = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1048576;
    int Busy  = Total - Free;
    String strI = Integer.toString(Busy);
    return strI;
}

回答by fada21

New methods was introduced since API version 18.

自 API 版本 18 以来引入了新方法。

I used something like that for big disk cache size estimation (for Picasso OkHttp downloader cache). Helper method was like that:

我使用类似的东西来估计大磁盘缓存大小(用于 Picasso OkHttp 下载器缓存)。辅助方法是这样的:

private static final String BIG_CACHE_PATH = "my-cache-dir";
private static final float  MAX_AVAILABLE_SPACE_USE_FRACTION = 0.9f;
private static final float  MAX_TOTAL_SPACE_USE_FRACTION     = 0.25f;

static File createDefaultCacheDirExample(Context context) {
    File cache = new File(context.getApplicationContext().getCacheDir(), BIG_CACHE_PATH);
    if (!cache.exists()) {
        cache.mkdirs();
    }
    return cache;
}

/**
 * Calculates minimum of available or total fraction of disk space
 * 
 * @param dir
 * @return space in bytes
 */
@SuppressLint("NewApi")
static long calculateAvailableCacheSize(File dir) {
    long size = 0;
    try {
        StatFs statFs = new StatFs(dir.getAbsolutePath());
        int sdkInt = Build.VERSION.SDK_INT;
        long totalBytes;
        long availableBytes;
        if (sdkInt < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            int blockSize = statFs.getBlockSize();
            availableBytes = ((long) statFs.getAvailableBlocks()) * blockSize;
            totalBytes = ((long) statFs.getBlockCount()) * blockSize;
        } else {
            availableBytes = statFs.getAvailableBytes();
            totalBytes = statFs.getTotalBytes();
        }
        // Target at least 90% of available or 25% of total space
        size = (long) Math.min(availableBytes * MAX_AVAILABLE_SPACE_USE_FRACTION, totalBytes * MAX_TOTAL_SPACE_USE_FRACTION);
    } catch (IllegalArgumentException ignored) {
        // ignored
    }
    return size;
}

回答by Joop

Google has information on this on the getting started page- See Query Free Space. They say that you can either check the available space by getFreeSpace()but they state that this is inaccurate and you should expect a little less free space than this. They say:

Google 在入门页面上提供了相关信息- 请参阅查询可用空间。他们说你可以检查可用空间,getFreeSpace()但他们说这是不准确的,你应该期望比这少一点的可用空间。他们说:

If the number returned is a few MB more than the size of the data you want to save, or if the file system is less than 90% full, then it's probably safe to proceed. Otherwise, you probably shouldn't write to storage.

如果返回的数字比您要保存的数据大小多几 MB,或者文件系统未满 90%,那么继续操作可能是安全的。否则,您可能不应该写入存储。

Also they give the advice that it's often more useful not the check the free space at all and just trycatchfor an error:

他们还提出建议,通常更有用的是根本不检查可用空间,而只是检查trycatch错误:

You aren't required to check the amount of available space before you save your file. You can instead try writing the file right away, then catch an IOException if one occurs. You may need to do this if you don't know exactly how much space you need. For example, if you change the file's encoding before you save it by converting a PNG image to JPEG, you won't know the file's size beforehand.

在保存文件之前,您无需检查可用空间量。您可以尝试立即写入文件,然后在发生 IOException 时捕获该异常。如果您不确切知道需要多少空间,则可能需要执行此操作。例如,如果您在通过将 PNG 图像转换为 JPEG 来保存文件之前更改了文件的编码,则您事先不会知道文件的大小。

I would recommend that only for very large file sizes you should check the available storage beforehand so you don't lose time downloading or creating a file which if obviously too large to hold. In either cases you should always use trycatchso I think that the only argument for checking the available free space beforehand if is either the unnecessary use of resources and time is too much.

我建议仅对于非常大的文件,您应该事先检查可用存储空间,这样您就不会浪费时间下载或创建一个显然太大而无法容纳的文件。在任何一种情况下,您都应该始终使用,trycatch所以我认为事先检查可用空间的唯一理由是不必要地使用资源和时间太多。

回答by Ilya Gazman

Based on thisanswer, Added support to Android version < 18

基于答案,添加了对 Android 版本 < 18 的支持

public static float megabytesAvailable(File file) {
    StatFs stat = new StatFs(file.getPath());
    long bytesAvailable;
    if(Build.VERSION.SDK_INT >= 18){
        bytesAvailable = getAvailableBytes(stat);
    }
    else{
        //noinspection deprecation
        bytesAvailable = stat.getBlockSize() * stat.getAvailableBlocks();
    }

    return bytesAvailable / (1024.f * 1024.f);
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private static long getAvailableBytes(StatFs stat) {
    return stat.getBlockSizeLong() * stat.getAvailableBlocksLong();
}