【问题标题】:How to Check available space on android device ? on SD card? [duplicate]如何检查安卓设备上的可用空间?在 SD 卡上? [复制]
【发布时间】:2011-03-24 14:41:49
【问题描述】:

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

有没有系统服务会暴露这样的东西?

【问题讨论】:

    标签: java android


    【解决方案1】:

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

    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);
    }
    

    以上代码引用了一些截至 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);
    }
    

    【讨论】:

    • 是的 getBlockSize() 已弃用。我们还可以使用 Environment.getDataDirectory().getUsableSpace() 来检索可用空间。
    【解决方案2】:

    试试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);
    

    更新:

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

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

    【讨论】:

    • 正如 Joe Wreschning 所说,这可以找到 SD 卡的大小
    • 请参考 Joe 下面的回答。
    • “megAvailable”是否有 SD 卡的数据大小或 SD 卡中的可用空间?
    • getBlockSizegetBlockCount 现在已弃用。请改用stat.getBlockSizeLong() * stat.getBlockCountLong()
    • 这段代码中唯一未被弃用的部分是System.out.println
    【解决方案3】:

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

    /**
     * @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;
    }
    

    【讨论】:

    • 非常感谢您提供了如此漂亮的代码示例,它的工作原理就像一个魅力 :)
    • 发现重复太多了。代码不错,但可以做得更小。
    • @Raigex 不,他不能说你可以复制单个部分,所以你只能使用其中的一个。
    • 任何不推荐使用的方法?
    【解决方案4】:

    基于this的回答,增加了对Android版本的支持

    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();
    }
    

    【讨论】:

    • 有效! )file = Environment.getExternalStorageDirectory().getPath()
    【解决方案5】:

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

    我使用类似的东西来估计大磁盘缓存大小(用于 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;
    }
    

    【讨论】:

    • 要转换为 MB,您应该减少 1048576(MB 中的字节数)。
    【解决方案6】:

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

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

    ...

    【讨论】:

      【解决方案7】:

      Google has information on this on the getting started page - 请参阅查询可用空间。他们说您可以通过getFreeSpace() 检查可用空间,但他们说这是不准确的,您应该期望比这更少的可用空间。他们说:

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

      他们还提出建议,它通常更有用,而不是检查可用空间,而只是 try catch 错误:

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

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

      【讨论】:

        【解决方案8】:

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

        /**
         * 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;
        }
        

        【讨论】:

          【解决方案9】:
          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;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-09
            相关资源
            最近更新 更多