如何获取设备实际总存储大小?64GB设备返回54GB问题求解
解决Android存储容量统计偏差的问题
这个问题我之前做存储相关功能时也碰到过,其实核心原因是你当前获取的是用户可操作分区的总大小,而非设备物理存储的总容量,咱们来拆解原因和对应的解决办法:
为什么会有偏差?
- 系统与厂商预留空间:厂商宣传的64GB是存储芯片的物理总容量,但Android系统本身、预装软件、恢复分区、boot分区等都会占用一部分空间,这部分不会被
StatFs统计到——因为StatFs只能读取到用户可读写的数据分区大小。 - 存储分区拆分:现在绝大多数设备的“外部存储”其实是内部存储的一个子分区(而非独立SD卡),
Environment.getExternalStorageDirectory()指向的只是这个用户数据分区,而非整个存储设备。
解决办法
方法1:用StorageManager获取物理容量(API 29+推荐)
从Android 10(API 29)开始,系统提供了StorageManager类,可以获取更全面的存储设备信息,包括物理总容量:
import android.content.Context; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import android.os.storage.StorageStats; import android.text.format.Formatter; // 在Activity或Service中调用 StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE); List<StorageVolume> storageVolumes = storageManager.getStorageVolumes(); for (StorageVolume volume : storageVolumes) { // 筛选主存储设备 if (volume.isPrimary()) { try { StorageStats stats = storageManager.queryStatsForVolume(volume.getUuid()); long totalPhysicalBytes = stats.getTotalBytes(); // 格式化后输出,比如会显示接近64GB的数值 String formattedSize = Formatter.formatFileSize(this, totalPhysicalBytes); Log.d("StorageInfo", "物理总容量: " + formattedSize); } catch (Exception e) { e.printStackTrace(); } break; } }
注意:需要申请
READ_EXTERNAL_STORAGE权限,Android 10+还需适配分区存储规则,如果是针对Android 13+,可能需要更细粒度的权限。
方法2:读取系统分区文件(兼容旧版本,但不推荐)
如果你的App需要兼容API 29以下的设备,可以尝试读取/proc/partitions文件解析物理容量,但这属于hack方式,兼容性较差(不同厂商设备的存储设备命名可能不同):
import android.text.format.Formatter; import java.io.BufferedReader; import java.io.FileReader; try { BufferedReader reader = new BufferedReader(new FileReader("/proc/partitions")); String line; while ((line = reader.readLine()) != null) { String[] parts = line.trim().split("\\s+"); // 通常主存储设备名为mmcblk0(EMMC)或nvme0n1(UFS),需根据设备调整 if (parts.length >= 4 && (parts[3].equals("mmcblk0") || parts[3].equals("nvme0n1"))) { long totalSectors = Long.parseLong(parts[2]); long sectorSize = 512; // 多数设备扇区大小为512字节 long totalBytes = totalSectors * sectorSize; String formattedSize = Formatter.formatFileSize(this, totalBytes); Log.d("StorageInfo", "物理总容量: " + formattedSize); break; } } reader.close(); } catch (Exception e) { e.printStackTrace(); }
额外说明
其实你之前得到的54GB是用户实际可使用的总空间,这个数值是准确的——因为系统和预装软件已经占用了近10GB的空间。如果你的需求是展示用户能用来存储文件的空间,那原来的代码完全没问题;只有当你需要展示厂商宣传的物理容量时,才需要用上面的方法。
内容的提问来源于stack exchange,提问作者user3964537
相关产品推荐
相关产品推荐

