Android(Kotlin)如何获取包含系统占用的内部存储总大小?
解决方案:无需敏感权限获取含系统占用的内部存储总大小
你遇到的核心问题是:StatFs 传入 /storage/emulated/0 只能获取用户分区的总大小,而这个分区只是内部存储的一部分,不包含系统占用的空间。下面提供两种官方API方案,无需敏感权限即可获取完整的内部存储总容量:
方案一:Android Q(API 29)及以上:直接用 StorageVolume
从Android Q开始,StorageVolume 提供了直接获取存储设备总容量的接口,不需要敏感权限,仅需基础存储权限(如READ_EXTERNAL_STORAGE,部分场景甚至无需权限)。
import android.content.Context import android.os.Build import android.os.storage.StorageManager fun getTotalInternalStorageSize(context: Context): Long { val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager val storageVolumes = storageManager.storageVolumes for (volume in storageVolumes) { // 筛选出主内部存储(isPrimary为true,且已挂载) if (volume.isPrimary && volume.isMounted) { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { volume.totalBytes // 直接返回整个存储设备的总大小(含系统占用) } else { getLegacyTotalInternalSize() } } } return 0L }
方案二:Android Pie(API 28)及以下:读取根分区信息
低版本中没有StorageVolume.totalBytes,可以通过读取内部存储的根分区路径来获取完整总大小,同样不需要敏感权限:
import android.os.Environment import android.os.StatFs fun getLegacyTotalInternalSize(): Long { // /data 对应内部存储的核心分区,其设备包含系统+用户所有空间 val rootPath = Environment.getDataDirectory().absolutePath val statFs = StatFs(rootPath) return statFs.totalBytes }
关键说明
为什么
/storage/emulated/0不行?
这个路径是用户数据分区的挂载点,仅包含用户可读写的空间,系统占用的/system、/vendor等分区不在此范围内,所以StatFs返回的是用户分区的总大小,而非整个内部存储的容量。权限要求
- Android 10+:无需特殊权限,系统允许应用获取存储设备的基础容量信息。
- Android 9及以下:仅需
READ_EXTERNAL_STORAGE权限(在Manifest中声明并动态申请即可)。
对比其他方案
df命令:依赖系统输出格式,不同厂商设备可能存在差异,稳定性差,不推荐。StorageStatsManager:需要PACKAGE_USAGE_STATS敏感权限,需引导用户手动授权,体验差,完全没必要用。
谷歌文件应用(Files by Google)正是通过StorageManager的方案获取完整存储容量,无需敏感权限即可展示准确的总大小。
内容的提问来源于stack exchange,提问作者Mohammad
相关产品推荐
相关产品推荐

