You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取设备实际总存储大小?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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:07:42