Android获得免费的内部/外部内存大小

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

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 

问题是我想获得现在1,96GB的SdCard的空闲内存。 我怎样才能解决这个代码,所以我可以得到免费的大小?

以下是您的目的代码:

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

获取RAM大小

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

这是我做的方式:

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

由于API 9你可以做到:

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

要获取所有可用的存储文件夹(包括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,你可以使用:

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

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

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

find一个外部SD卡位置

如果您获得内部和外部存储path,则很容易find可用的存储空间。 另外手机的外部存储path确实很容易find使用

Environment.getExternalStorageDirectory()的getPath();

所以我只专注于如何找出可移动的SD卡,USB OTP(未经testing的USB OTG,因为我没有USB OTG)等外部可移动存储的path。

下面的方法将列出所有可能的外部可移动存储path。

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

试试这个简单的片段

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

快速添加到外部内存主题

不要被Dinesh Prajapati的答案中的方法名externalMemoryAvailable()所困惑。

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

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

它不显示瞬态设备,如USB闪存驱动器。

另外请注意,Android 4.3及更低版本的ContextCompat.getExternalFilesDirs() 总是只返回1个条目(SD卡,如果可用的话,否则内部)。 你可以在这里阅读更多。

  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设备可能有两个SD卡,所以如果你需要所有这些,请调整上面的代码。

关于外在的东西,还有另一种方式:
File external = Environment.getExternalStorageDirectory(); free:external.getFreeSpace(); total:external.getTotalSpace();