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