【发布时间】:2011-03-24 14:41:49
【问题描述】:
如何查看 Android 设备上还剩多少 MB 或 GB?我正在使用 JAVA 和 android SDK 2.0.1。
有没有系统服务会暴露这样的东西?
【问题讨论】:
如何查看 Android 设备上还剩多少 MB 或 GB?我正在使用 JAVA 和 android SDK 2.0.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);
}
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);
}
【讨论】:
试试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)
【讨论】:
getBlockSize 和 getBlockCount 现在已弃用。请改用stat.getBlockSizeLong() * stat.getBlockCountLong()。
System.out.println
我设计了一些即用型函数来获得不同单元的可用空间。您可以通过简单地将其中任何一种方法复制到您的项目中来使用这些方法。
/**
* @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;
}
【讨论】:
基于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();
}
【讨论】:
自 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;
}
【讨论】:
另外,如果您想检查内存的可用空间,请使用:
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
...
【讨论】:
Google has information on this on the getting started page - 请参阅查询可用空间。他们说您可以通过getFreeSpace() 检查可用空间,但他们说这是不准确的,您应该期望比这更少的可用空间。他们说:
如果返回的数字比您要保存的数据大小多几 MB,或者如果文件系统未满 90%,那么继续操作可能是安全的。否则,您可能不应该写入存储。
他们还提出建议,它通常更有用,而不是检查可用空间,而只是 try catch 错误:
在保存文件之前,您无需检查可用空间量。相反,您可以尝试立即写入文件,然后在发生时捕获 IOException。如果您不确切知道需要多少空间,您可能需要这样做。例如,如果您在保存文件之前通过将 PNG 图像转换为 JPEG 来更改文件的编码,则您不会事先知道文件的大小。
我建议仅对于非常大的文件,您应该事先检查可用存储空间,这样您就不会浪费时间下载或创建明显太大而无法容纳的文件。在任何一种情况下,您都应该始终使用try catch,所以我认为事先检查可用空间的唯一论据是不必要地使用资源和时间太多。
【讨论】:
我希望这段代码可以帮助其他人。测试工作正常。感谢上面的成员澄清它。
/**
* 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;
}
【讨论】:
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;
}
【讨论】: