我想以编程方式获取设备内部/外部存储空闲内存的大小。我正在使用这段代码:
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
。如何修复此代码,以便获得免费大小?
答案 0 :(得分:166)
以下是您的目的代码:
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;
答案 1 :(得分:35)
这就是我这样做的方式:
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);
答案 2 :(得分:24)
从API 9开始,您可以:
long freeBytesInternal = new File(ctx.getFilesDir().getAbsoluteFile().toString()).getFreeSpace();
long freeBytesExternal = new File(getExternalFilesDir(null).toString()).getFreeSpace();
答案 3 :(得分:21)
要获取所有可用的存储文件夹(包括SD卡),首先要获取存储文件:
File internalStorageFile=getFilesDir();
File[] externalStorageFiles=ContextCompat.getExternalFilesDirs(this,null);
然后你可以得到每个的可用大小。
有三种方法可以做到:
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);
请注意,我认为内部存储可能与第一个外部存储相同,因为第一个是模拟的存储。
答案 4 :(得分:9)
@Android-Droid - 你错了Environment.getExternalStorageDirectory()
指向外部存储器,它不一定是SD卡,也可以是内部存储器的挂载。参见:
答案 5 :(得分:6)
如果您获得内部存储路径和外部存储路径,则很容易找到可用的存储空间。手机的外部存储路径也非常容易找到
Environment.getExternalStorageDirectory()的getPath();
所以我只专注于如何找到外部可移动存储的路径,如可移动SD卡,USB OTP(未测试USB OTG,因为我没有USB OTG)。
下面的方法将列出所有可能的外部可移动存储路径。
type
答案 6 :(得分:6)
试试这个简单的代码段
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];
}
答案 7 :(得分:3)
快速添加到外部存储器主题
不要对Dinesh Prajapati的答案中的方法名externalMemoryAvailable()
感到困惑。
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
为您提供内存的当前状态,如果介质存在并以其读/写访问权限挂载在其挂载点。
即使在没有SD卡的设备上,你也会获得true
,例如Nexus 5.但在使用存储操作之前,它仍然是一种“必备”方法。
要检查设备上是否有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卡,所以如果你需要所有这些 - 请调整上面的代码。
答案 8 :(得分:1)
@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
答案 9 :(得分:0)
关于外部理论,还有另一种方式:
File external = Environment.getExternalStorageDirectory();
free:external.getFreeSpace();
total:external.getTotalSpace();
答案 10 :(得分:0)
这就是我做到的方式。
内部总内存
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";
答案 11 :(得分:0)
我自己检查了不同的解决方案后,编写了完整的代码来查找
''''
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)
}
}
}}
答案 12 :(得分:0)
此处提到的解决方案均不能用于外部存储器。这是我的代码(用于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.getBlockCount();
}
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上运行。希望对您有帮助。