【问题标题】:Android get free size of internal/external memoryAndroid 获得内部/外部内存的可用大小
【发布时间】:2011-12-29 07:47:15
【问题描述】:

我想以编程方式获取设备内部/外部存储的可用内存大小。我正在使用这段代码:

StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount();
long megAvailable = bytesAvailable / 1048576;
Log.e("","Available MB : "+megAvailable);

File path = Environment.getDataDirectory();
StatFs stat2 = new StatFs(path.getPath());
long blockSize = stat2.getBlockSize();
long availableBlocks = stat2.getAvailableBlocks();
String format =  Formatter.formatFileSize(this, availableBlocks * blockSize);
Log.e("","Format : "+format);

我得到的结果是:

11-15 10:27:18.844: E/(25822): Available MB : 7572
11-15 10:27:18.844: E/(25822): Format : 869MB

问题是我现在想获得 SdCard 的空闲内存 1,96GB。如何修复此代码以便获得免费尺寸?

【问题讨论】:

  • 从 API 级别 18 开始,他们已将方法重命名为以 Long 结尾。可能你需要在它之前添加一个 API 级别的检查
  • 所有解决方案我试过没有人工作,当我格式化为内部存储时......你能取悦我吗,如何做到这一点?
  • 以重复形式关闭 - 较新的帖子可以回答 Android R

标签: android android-sdcard diskspace


【解决方案1】:

以下是您的目的代码:

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

    public static String getAvailableInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSizeLong();
        long availableBlocks = stat.getAvailableBlocksLong();
        return formatSize(availableBlocks * blockSize);
    }

    public static String getTotalInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSizeLong();
        long totalBlocks = stat.getBlockCountLong();
        return formatSize(totalBlocks * blockSize);
    }

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

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

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

        if (size >= 1024) {
            suffix = "KB";
            size /= 1024;
            if (size >= 1024) {
                suffix = "MB";
                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();
    }

获取内存大小

ActivityManager actManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
MemoryInfo memInfo = new ActivityManager.MemoryInfo();
actManager.getMemoryInfo(memInfo);
long totalMemory = memInfo.totalMem;

【讨论】:

  • getBlockSize()getBlockCount 已弃用。
  • @DineshPrajapati 感谢您的回答,我有疑问,如果我使用 Environment.getRootDirectory() 而不是 Environment.getDataDirectory 来计算内部存储,我会得到一些输出..这是指内部存储器其他记忆..
  • @DineshPrajapati .. 在 MOTO G2 上测试 为外部存储获取错误数据
  • 可能会发生一些 API 被弃用的情况,请在 developers.android.com 上查看
  • 对更新的 API 级别最后使用 Long (>18)
【解决方案2】:

我就是这样做的:

StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable;
if (android.os.Build.VERSION.SDK_INT >= 
    android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
    bytesAvailable = stat.getBlockSizeLong() * stat.getAvailableBlocksLong();
}
else {
    bytesAvailable = (long)stat.getBlockSize() * (long)stat.getAvailableBlocks();
}
long megAvailable = bytesAvailable / (1024 * 1024);
Log.e("","Available MB : "+megAvailable);

【讨论】:

  • 但这已被弃用:(
  • @ArMo372,你们找到替换代码了吗?
  • 只需将getBlockSizegetAvailableBlocks 替换为getBlockSizeLonggetAvailableBlocksLong
  • 这没有得到正确的可用空间。这是 1141 而不是 1678 @smg
  • 当我格式化为内部存储时解决方案不工作......你能请我吗,如何做到这一点
【解决方案3】:

从 API 9 开始,您可以这样做:

long freeBytesInternal = new File(ctx.getFilesDir().getAbsoluteFile().toString()).getFreeSpace();
long freeBytesExternal = new File(getExternalFilesDir(null).toString()).getFreeSpace();

【讨论】:

  • File.getUsableSpace() 可能更好,因为您可能没有以 root 身份运行。
  • File.getUsableSpace() 看起来比使用StatFs 更容易使用。我为什么要使用StatFs@MarkCarter?
  • @DiscoS2 如果您的 minSdkVersion 小于 9,您将使用 StatFs。
  • 您还如何监控存储变化?
【解决方案4】:

要获取所有可用的存储文件夹(包括 SD 卡),首先要获取存储文件:

File internalStorageFile=getFilesDir();
File[] externalStorageFiles=ContextCompat.getExternalFilesDirs(this,null);

然后你可以得到每一个的可用大小。

有3种方法可以做到:

API 8 及以下:

StatFs stat=new StatFs(file.getPath());
long availableSizeInBytes=stat.getBlockSize()*stat.getAvailableBlocks();

API 9 及更高版本:

long availableSizeInBytes=file.getFreeSpace();

API 18 及以上(如果前一个没问题,则不需要):

long availableSizeInBytes=new StatFs(file.getPath()).getAvailableBytes(); 

要获得一个漂亮的格式化字符串,您可以使用:

String formattedResult=android.text.format.Formatter.formatShortFileSize(this,availableSizeInBytes);

或者你可以使用它以防你希望看到确切的字节数但很好:

NumberFormat.getInstance().format(availableSizeInBytes);

请注意,我认为内部存储可能与第一个外部存储相同,因为第一个是模拟的。


编辑:在 Android Q 及更高版本上使用 StorageVolume,我认为可以使用以下方法获得每个的可用空间:

fun getStorageVolumesAccessState(context: Context) {
    val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
    val storageVolumes = storageManager.storageVolumes
    val storageStatsManager = context.getSystemService(Context.STORAGE_STATS_SERVICE) as StorageStatsManager
    for (storageVolume in storageVolumes) {
        var freeSpace: Long = 0L
        var totalSpace: Long = 0L
        val path = getPath(context, storageVolume)
        if (storageVolume.isPrimary) {
            totalSpace = storageStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT)
            freeSpace = storageStatsManager.getFreeBytes(StorageManager.UUID_DEFAULT)
        } else if (path != null) {
            val file = File(path)
            freeSpace = file.freeSpace
            totalSpace = file.totalSpace
        }
        val usedSpace = totalSpace - freeSpace
        val freeSpaceStr = Formatter.formatFileSize(context, freeSpace)
        val totalSpaceStr = Formatter.formatFileSize(context, totalSpace)
        val usedSpaceStr = Formatter.formatFileSize(context, usedSpace)
        Log.d("AppLog", "${storageVolume.getDescription(context)} - path:$path total:$totalSpaceStr used:$usedSpaceStr free:$freeSpaceStr")
    }
}

fun getPath(context: Context, storageVolume: StorageVolume): String? {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
        storageVolume.directory?.absolutePath?.let { return it }
    try {
        return storageVolume.javaClass.getMethod("getPath").invoke(storageVolume) as String
    } catch (e: Exception) {
    }
    try {
        return (storageVolume.javaClass.getMethod("getPathFile").invoke(storageVolume) as File).absolutePath
    } catch (e: Exception) {
    }
    val extDirs = context.getExternalFilesDirs(null)
    for (extDir in extDirs) {
        val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
        val fileStorageVolume: StorageVolume = storageManager.getStorageVolume(extDir)
                ?: continue
        if (fileStorageVolume == storageVolume) {
            var file = extDir
            while (true) {
                val parent = file.parentFile ?: return file.absolutePath
                val parentStorageVolume = storageManager.getStorageVolume(parent)
                        ?: return file.absolutePath
                if (parentStorageVolume != storageVolume)
                    return file.absolutePath
                file = parent
            }
        }
    }
    try {
        val parcel = Parcel.obtain()
        storageVolume.writeToParcel(parcel, 0)
        parcel.setDataPosition(0)
        parcel.readString()
        return parcel.readString()
    } catch (e: Exception) {
    }
    return null
}

希望这会有所帮助。

【讨论】:

  • 如何在具有 API 23 的设备上获取可移动 SD 卡(或 USB OTG 闪存驱动器)上的可用空间? new StatFs(file.getPath()).getAvailableBytes() 或 file.getUsableSpace() 提供 972546048 字节,无论 Nexus 5(Marshmallow 6.0.1)上的实际存储大小如何。
  • @isabsent Nexus 5 没有 SD 卡插槽。你是怎么检查的?
  • 我用 USB OTG 闪存盘检查过。
  • @isabsent 我从未使用过它。对不起。它在 API 22 及更低版本上运行良好吗?
  • @Smeet 您可以在 Android 6 或更高版本上试用吗?如果是这样,可能是这样的问题:code.google.com/p/android/issues/detail?id=200326
【解决方案5】:

@Android-Droid - 你错了Environment.getExternalStorageDirectory()指向的外部存储不一定是SD卡,也可以是内部存储器的挂载。见:

Find an external SD card location

【讨论】:

    【解决方案6】:

    试试这个简单的 sn-p

        public static String readableFileSize() {
        long availableSpace = -1L;
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
            availableSpace = (long) stat.getBlockSizeLong() * (long) stat.getAvailableBlocksLong();
        else
            availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
    
        if(availableSpace <= 0) return "0";
        final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" };
        int digitGroups = (int) (Math.log10(availableSpace)/Math.log10(1024));
        return new DecimalFormat("#,##0.#").format(availableSpace/Math.pow(1024, digitGroups)) + " " + units[digitGroups];
    }
    

    【讨论】:

    • 谢谢,但我有java.lang.ArrayIndexOutOfBoundsException: length=5; index=-2147483648 错误,似乎digitGroups 结果是-2147483648。
    • 当我格式化为内部存储时解决方案不工作......你能请我吗,如何做到这一点
    【解决方案7】:

    如果您获得内部和外部存储路径,则很容易找到可用的存储空间。手机的外部存储路径也很容易找到

    Environment.getExternalStorageDirectory().getPath();

    所以我只专注于如何找出外部可移动存储的路径,如可移动 sdcard、USB OTG(未测试 USB OTG,因为我没有 USB OTG)。

    以下方法将列出所有可能的外部可移动存储路径。

     /**
         * This method returns the list of removable storage and sdcard paths.
         * I have no USB OTG so can not test it. Is anybody can test it, please let me know
         * if working or not. Assume 0th index will be removable sdcard path if size is
         * greater than 0.
         * @return the list of removable storage paths.
         */
        public static HashSet<String> getExternalPaths()
        {
        final HashSet<String> out = new HashSet<String>();
        String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
        String s = "";
        try
        {
            final Process process = new ProcessBuilder().command("mount").redirectErrorStream(true).start();
            process.waitFor();
            final InputStream is = process.getInputStream();
            final byte[] buffer = new byte[1024];
            while (is.read(buffer) != -1)
            {
                s = s + new String(buffer);
            }
            is.close();
        }
        catch (final Exception e)
        {
            e.printStackTrace();
        }
    
        // parse output
        final String[] lines = s.split("\n");
        for (String line : lines)
        {
            if (!line.toLowerCase(Locale.US).contains("asec"))
            {
                if (line.matches(reg))
                {
                    String[] parts = line.split(" ");
                    for (String part : parts)
                    {
                        if (part.startsWith("/"))
                        {
                            if (!part.toLowerCase(Locale.US).contains("vold"))
                            {
                                out.add(part.replace("/media_rw","").replace("mnt", "storage"));
                            }
                        }
                    }
                }
            }
        }
        //Phone's external storage path (Not removal SDCard path)
        String phoneExternalPath = Environment.getExternalStorageDirectory().getPath();
    
        //Remove it if already exist to filter all the paths of external removable storage devices
        //like removable sdcard, USB OTG etc..
        //When I tested it in ICE Tab(4.4.2), Swipe Tab(4.0.1) with removable sdcard, this method includes
        //phone's external storage path, but when i test it in Moto X Play (6.0) with removable sdcard,
        //this method does not include phone's external storage path. So I am going to remvoe the phone's
        //external storage path to make behavior consistent in all the phone. Ans we already know and it easy
        // to find out the phone's external storage path.
        out.remove(phoneExternalPath);
    
        return out;
    }
    

    【讨论】:

    • 我记得,在某些设备上使用常量名称处理路径可能不起作用,因为有些设备可能有自己的路径。我希望不是这样。 +1 的努力。
    • @androiddeveloper 谢谢亲爱的投票。我需要所有人的支持才能在您的设备中测试此代码,因为我没有所有设备,但在 4 个不同的设备上进行了测试并且工作正常。请在此处评论不适用于任何机构的手机。
    • 当我格式化为内部存储时解决方案不工作......你能请我吗,如何做到这一点
    【解决方案8】:

    快速添加到外部存储器主题

    不要被 Dinesh Prajapati 回答中的方法名称 externalMemoryAvailable() 所迷惑。

    Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) 为您提供内存的当前状态,前提是媒体存在并安装在其安装点并具有读/写访问权限。 即使在没有 SD 卡的设备(如 Nexus 5)上,您也会收到true。但在任何存储操作之前,它仍然是“必备”方法。

    要检查您的设备上是否有 SD 卡,您可以使用方法 ContextCompat.getExternalFilesDirs()

    它不显示临时设备,例如 USB 闪存驱动器。

    另外请注意,Android 4.3 及更低版本上的ContextCompat.getExternalFilesDirs()始终仅返回 1 个条目(SD 卡如果可用,否则为内部)。你可以阅读更多关于它的信息here

      public static boolean isSdCardOnDevice(Context context) {
        File[] storages = ContextCompat.getExternalFilesDirs(context, null);
        if (storages.length > 1 && storages[0] != null && storages[1] != null)
            return true;
        else
            return false;
    }
    

    就我而言,这已经足够了,但不要忘记某些 Android 设备可能有 2 个 SD 卡,所以如果您需要所有这些 - 调整上面的代码。

    【讨论】:

      【解决方案9】:

      我就是这样做的..

      内部总内存

      double totalSize = new File(getApplicationContext().getFilesDir().getAbsoluteFile().toString()).getTotalSpace();
      double totMb = totalSize / (1024 * 1024);
      

      内部空闲尺寸

       double availableSize = new File(getApplicationContext().getFilesDir().getAbsoluteFile().toString()).getFreeSpace();
          double freeMb = availableSize/ (1024 * 1024);
      

      外部可用内存和总内存

       long freeBytesExternal =  new File(getExternalFilesDir(null).toString()).getFreeSpace();
             int free = (int) (freeBytesExternal/ (1024 * 1024));
              long totalSize =  new File(getExternalFilesDir(null).toString()).getTotalSpace();
              int total= (int) (totalSize/ (1024 * 1024));
             String availableMb = free+"Mb out of "+total+"MB";
      

      【讨论】:

      • 您的方法显示我总共有 50 GB 的空闲空间中的 29 GB。但是,我的标准文件应用程序(华为 P20 Lite)和来自 Google 的文件应用程序显示总共 64 GB 中的 32 GB 是免费的。我是否遗漏了某些内容,或者您​​的方法是否从存储中排除了某些内容?
      【解决方案10】:

      这里提到的解决方案都不能用于外部存储器。这是我的代码(用于 RAM、ROM、系统存储和外部存储)。您可以使用(总存储空间 - 已用存储空间)计算免费存储空间。此外,不得将Environment.getExternalStorageDirectory() 用于外部存储。它不一定指向外部 SD 卡。此外,此解决方案适用于所有 Android 版本(在真实设备和模拟器上针对 API 16-30 进行了测试)。

          // Divide by (1024*1024*1024) to get in GB, by (1024*1024) to get in MB, by 1024 to get in KB..
      
          // RAM
          ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
          ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
          manager.getMemoryInfo(memoryInfo);
          long totalRAM=memoryInfo.totalMem;
          long availRAM=memoryInfo.availMem;  // remember to convert in GB,MB or KB.
          long usedRAM=totalRAM-availRAM;
      
          // ROM
          getTotalStorageInfo(Environment.getDataDirectory().getPath());
          getUsedStorageInfo(Environment.getDataDirectory().getPath());
      
          // System Storage
          getTotalStorageInfo(Environment.getRootDirectory().getPath());
          getUsedStorageInfo(Environment.getRootDirectory().getPath());
      
          // External Storage (SD Card)
          File[] files = ContextCompat.getExternalFilesDirs(context, null);
          if(Build.VERSION.SDK_INT<=Build.VERSION_CODES.JELLY_BEAN_MR2){
              if (files.length == 1) {
                  Log.d("External Storage Memory","is present");
                  getTotalStorageInfo(files[0].getPath());
                  getUsedStorageInfo(files[0].getPath());
              }
          } else {
              if (files.length > 1 && files[0] != null && files[1] != null) {
                  Log.d("External Storage Memory","is present");
                  long t=getTotalStorageInfo(files[1].getPath());
                  long u=getUsedStorageInfo(files[1].getPath());
                  System.out.println("Total External Mem: "+t+" Used External Mem: "+u+" Storage path: "+files[1].getPath());
              }
          }
      }
      
      public long getTotalStorageInfo(String path) {
          StatFs statFs = new StatFs(path);
          long t;
          if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
              t = statFs.getTotalBytes();
          } else {
              t = statFs.getBlockCount() * statFs.getBlockSize();
          }
          return t;    // remember to convert in GB,MB or KB.
      }
      
      public long getUsedStorageInfo(String path) {
          StatFs statFs = new StatFs(path);
          long u;
          if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
              u = statFs.getTotalBytes() - statFs.getAvailableBytes();
          } else {
              u = statFs.getBlockCount() * statFs.getBlockSize() - statFs.getAvailableBlocks() * statFs.getBlockSize();
          }
          return u;  // remember to convert in GB,MB or KB.
      }
      

      现在对于 ROM,我使用路径作为“/data”,系统存储路径是“/system”。对于外部存储,我使用了ContextCompat.getExternalFilesDirs(context, null);,因此它也可以在 Android Q 和 Android R 上运行。希望对您有所帮助。

      【讨论】:

      • 在getTotalStorageInfo方法中,否则条件应该是t = statFs.getBlockCount() * statFs.getBlockSize();
      • @praveenb 感谢您指出这一点。我现在已经更正了。
      【解决方案11】:
      @RequiresApi(api = Build.VERSION_CODES.O)
      private void showStorageVolumes() {
          StorageStatsManager storageStatsManager = (StorageStatsManager) getSystemService(Context.STORAGE_STATS_SERVICE);
          StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
          if (storageManager == null || storageStatsManager == null) {
              return;
          }
          List<StorageVolume> storageVolumes = storageManager.getStorageVolumes();
          for (StorageVolume storageVolume : storageVolumes) {
              final String uuidStr = storageVolume.getUuid();
              final UUID uuid = uuidStr == null ? StorageManager.UUID_DEFAULT : UUID.fromString(uuidStr);
              try {
                  Log.d("AppLog", "storage:" + uuid + " : " + storageVolume.getDescription(this) + " : " + storageVolume.getState());
                  Log.d("AppLog", "getFreeBytes:" + Formatter.formatShortFileSize(this, storageStatsManager.getFreeBytes(uuid)));
                  Log.d("AppLog", "getTotalBytes:" + Formatter.formatShortFileSize(this, storageStatsManager.getTotalBytes(uuid)));
              } catch (Exception e) {
                  // IGNORED
              }
          }
      }
      

      StorageStatsManager 类引入了 Android O 及更高版本,它可以为您提供外部/内部存储中的免费和总字节。有关源代码的详细信息,您可以阅读我的以下文章。你可以在低于 Android O 的情况下使用反射

      https://medium.com/cashify-engineering/how-to-get-storage-stats-in-android-o-api-26-4b92eca6805b

      【讨论】:

      • 是的!这有效,并显示了我的内部存储(华为 P20 Lite)上的总空间和可用空间的确切数量。感谢您为我省去了很多麻烦!
      【解决方案12】:

      关于外部记忆,还有一个办法:
      File external = Environment.getExternalStorageDirectory(); free:external.getFreeSpace(); total:external.getTotalSpace();

      【讨论】:

        【解决方案13】:

        在检查不同的解决方案后自己编写代码,这是查找的完整代码

        • 外部存储器总数
        • 可用外部存储器
        • 使用的外部存储器
        • 内存总量
        • 使用的内存
        • 空闲内存

        ''''

        object DeviceMemoryUtil {
        private const val error: String = "Something went wrog"
        private const val noExternalMemoryDetected = "No external Storage detected"
        private var totalExternalMemory: Long = 0
        private var freeExternalMemory: Long = 0
        private var totalInternalStorage: Long = 0
        private var freeInternalStorage: Long = 0
        
        /**
         * Checks weather external memory is available or not
         */
        private fun externalMemoryAvailable(): Boolean {
            return Environment.getExternalStorageState() ==
                    Environment.MEDIA_MOUNTED
        }
        
        /**
         *Gives total external memory
         * @return String Size of external memory
         * @return Boolean True if memory size is returned
         */
        fun getTotalExternalMemorySize(): Pair<String?, Boolean> {
            val dirs: Array<File> = ContextCompat.getExternalFilesDirs(CanonApplication.getCanonAppInstance(), null)
            return if (externalMemoryAvailable()) {
                if (dirs.size > 1) {
                    val stat = StatFs(dirs[1].path)
                    val blockSize = stat.blockSizeLong
                    val totalBlocks = stat.blockCountLong
                    var totalExternalSize = totalBlocks * blockSize
                    totalExternalMemory = totalExternalSize
                    Pair(formatSize(totalExternalSize), true)
                } else {
                    Pair(error, false)
                }
            } else {
                Pair(noExternalMemoryDetected, false)
            }
        }
        
        /**
         * Gives free external memory size
         * @return String Size of free external memory
         * @return Boolean True if memory size is returned
         */
        fun getAvailableExternalMemorySize(): Pair<String?, Boolean> {
            val dirs: Array<File> = ContextCompat.getExternalFilesDirs(CanonApplication.getCanonAppInstance(), null)
            if (externalMemoryAvailable()) {
                return if (dirs.size > 1) {
                    val stat = StatFs(dirs[1].path)
                    val blockSize = stat.blockSizeLong
                    val availableBlocks = stat.availableBlocksLong
                    var freeExternalSize = blockSize * availableBlocks
                    freeExternalMemory = freeExternalSize
                    Pair(formatSize(freeExternalSize), true)
                } else {
                    Pair(error, false)
                }
            } else {
                return Pair(noExternalMemoryDetected, false)
            }
        }
        
        /**
         * Gives used external memory size
         *  @return String Size of used external memory
         * @return Boolean True if memory size is returned
         */
        fun getUsedExternalMemorySize(): Pair<String?, Boolean> {
            return if (externalMemoryAvailable()) {
                val totalExternalSize = getTotalExternalMemorySize()
                val freeExternalSize = getAvailableExternalMemorySize()
                if (totalExternalSize.second && freeExternalSize.second) {
                    var usedExternalVolume = totalExternalMemory - freeExternalMemory
                    Pair(formatSize(usedExternalVolume), true)
                } else {
                    Pair(error, false)
                }
            } else {
                Pair(noExternalMemoryDetected, false)
            }
        }
        
        /**
         *Formats the long to size of memory in gb,mb etc.
         * @param size Size of memory
         */
        fun formatSize(size: Long): String? {
            return android.text.format.Formatter.formatFileSize(CanonApplication.getCanonAppInstance(), size)
        }
        
        /**
         * Gives total internal memory size
         *  @return String Size of total internal memory
         * @return Boolean True if memory size is returned
         */
        fun getTotalInternalStorage(): Pair<String?, Boolean> {
            if (showStorageVolumes()) {
                return Pair(formatSize(totalInternalStorage), true)
            } else {
                return Pair(error, false)
            }
        
        }
        
        /**
         * Gives free or available internal memory size
         *  @return String Size of free internal memory
         * @return Boolean True if memory size is returned
         */
        fun getFreeInternalStorageVolume(): Pair<String?, Boolean> {
            return if (showStorageVolumes()) {
                Pair(formatSize(freeInternalStorage), true)
            } else {
                Pair(error, false)
            }
        }
        
        /**
         *For calculation of internal storage
         */
        private fun showStorageVolumes(): Boolean {
            val storageManager = CanonApplication.canonApplicationInstance.applicationContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager
            val storageStatsManager = CanonApplication.canonApplicationInstance.applicationContext.getSystemService(Context.STORAGE_STATS_SERVICE) as StorageStatsManager
            if (storageManager == null || storageStatsManager == null) {
                return false
            }
            val storageVolumes: List<StorageVolume> = storageManager.storageVolumes
            for (storageVolume in storageVolumes) {
                var uuidStr: String? = null
                storageVolume.uuid?.let {
                    uuidStr = it
                }
                val uuid: UUID = if (uuidStr == null) StorageManager.UUID_DEFAULT else UUID.fromString(uuidStr)
                return try {
                    freeInternalStorage = storageStatsManager.getFreeBytes(uuid)
                    totalInternalStorage = storageStatsManager.getTotalBytes(uuid)
                    true
                } catch (e: Exception) {
                    // IGNORED
                    false
                }
            }
            return false
        }
        
        fun getTotalInternalExternalMemory(): Pair<Long?, Boolean> {
            if (externalMemoryAvailable()) {
                if (getTotalExternalMemorySize().second) {
                    if (getTotalInternalStorage().second) {
                        return Pair(totalExternalMemory + totalInternalStorage, true)
                    } else {
                        return Pair(0, false)
                    }
                }
                return Pair(0, false)
            } else {
                if (getTotalInternalStorage().second) {
                    return Pair(totalInternalStorage, true)
                } else {
                    return Pair(0, false)
                }
            }
        
        }
        
        fun getTotalFreeStorage(): Pair<Long,Boolean> {
            if (externalMemoryAvailable()){
                if(getFreeInternalStorageVolume().second){
                    getFreeInternalStorageVolume()
                    getAvailableExternalMemorySize()
                        return Pair(freeExternalMemory + freeInternalStorage,true)
                }
                else{
                    return Pair(0,false)
                }
            }
            else {
                if (getFreeInternalStorageVolume().second){
                    getFreeInternalStorageVolume()
                    return Pair(freeInternalStorage,true)
                }
              else{
                    return Pair(0,false)
                }
            }
        
        }}
        

        【讨论】:

          猜你喜欢
          • 2015-11-12
          • 1970-01-01
          • 1970-01-01
          • 2019-04-19
          • 2011-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多