最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to get the total internal storage size including system usage in Android (Kotlin)? - Stack Overflow

programmeradmin3浏览0评论

I'm developing a file manager app in Kotlin and I need to retrieve the total size of the internal storage, including the space occupied by the system.

I've tried using the StatFs class:

val stat = StatFs(path) // path = "/storage/emulated/0"
val totalBytes = stat.totalBytes

This method works correctly for retrieving the total size of the SD card. However, when used for the internal storage, it doesn't include the space used by the system and returns a lower value than the actual size:

Log.d("totalBytes", totalBytes.toString()) // Returns 109799354368

Adding the system-occupied space to the returned value gives the correct total internal storage size.

I've also researched potential solutions and found two main approaches:

  1. Using the df command in Linux (which Android is based on). However, I understand that this method has limitations, risks, and it's generally better to use official Android APIs.
  2. Using StorageStatsManager. This method requires the PACKAGE_USAGE_STATS permission, which is a sensitive permission. It's not requested through standard system permission dialogs (یا runtime permission prompts یا typical system permission dialogs) and the user needs to be directed to the settings to grant it. Also, the "Files by Google" app seems to be able to get the total internal storage size without requesting this permission.

I've searched online extensively but haven't found a suitable method. How can I retrieve the total internal storage size without requiring sensitive permissions, or at least with only external storage permissions (READ_EXTERNAL_STORAGE or MANAGE_EXTERNAL_STORAGE)?

I'm developing a file manager app in Kotlin and I need to retrieve the total size of the internal storage, including the space occupied by the system.

I've tried using the StatFs class:

val stat = StatFs(path) // path = "/storage/emulated/0"
val totalBytes = stat.totalBytes

This method works correctly for retrieving the total size of the SD card. However, when used for the internal storage, it doesn't include the space used by the system and returns a lower value than the actual size:

Log.d("totalBytes", totalBytes.toString()) // Returns 109799354368

Adding the system-occupied space to the returned value gives the correct total internal storage size.

I've also researched potential solutions and found two main approaches:

  1. Using the df command in Linux (which Android is based on). However, I understand that this method has limitations, risks, and it's generally better to use official Android APIs.
  2. Using StorageStatsManager. This method requires the PACKAGE_USAGE_STATS permission, which is a sensitive permission. It's not requested through standard system permission dialogs (یا runtime permission prompts یا typical system permission dialogs) and the user needs to be directed to the settings to grant it. Also, the "Files by Google" app seems to be able to get the total internal storage size without requesting this permission.

I've searched online extensively but haven't found a suitable method. How can I retrieve the total internal storage size without requiring sensitive permissions, or at least with only external storage permissions (READ_EXTERNAL_STORAGE or MANAGE_EXTERNAL_STORAGE)?

Share Improve this question edited Mar 10 at 13:46 Martin Zeitler 77.2k20 gold badges166 silver badges238 bronze badges asked Mar 10 at 10:39 MohammadMohammad 114 bronze badges 2
  • The app "Files by Google" is AFAIR a system app, thus it doesn't have to care about permissions. – Robert Commented Mar 10 at 10:51
  • @Robert "Files by Google" was not pre-installed on my device, I installed it myself. Furthermore, it does request the MANAGE_EXTERNAL_STORAGE permission. – Mohammad Commented Mar 10 at 11:30
Add a comment  | 

1 Answer 1

Reset to default 0

The size of the internal storage (eMMC) seemingly can only be obtained from the underlying Linux. For example, file /sys/class/mmc_host/mmc0/mmc0:0001/block/mmcblk0/size returns the number of total blocks, to be multiplied by block size. The name of the volume and therefore the path might vary and should better be traversed instead of hardcoded ...it really depends, because it might be named and anized differently, from device to device. Usually it's mmcblk0, eMMC block device at index 0. The outcome may have limited portability, unless throughly testing it with all kind of storage configurations, which would all have to be considered.


While one doesn't even have to run any shell automation, but StatFs (which wraps the statvfs command) would provide the desired information per mount-point, alike /mnt/emmc or whereever it may be mounted, which needs to be determined by file-system traversal.

/** Obtain the size of a partition by its mount-point. */
private fun getTotalSize(mountPoint: String): Long {
    val stat = StatFs(mountPoint)
    return stat.blockCountLong * stat.blockSizeLong
}

Please note, that the logical mount-point is not the actual physical block device. Usually the partition size should suffice, unless needing to know how large the eMMC really is. That's alike when formatting a HDD, which then also does not have the exact size of the physical drive. Internal and external storage might even be two partition on the very same eMMC, when there is no SD slot present. While from within Android, it is very difficult to determine, by which devices the storage API is really backed - and mmcblk0 might also hold an "external" storage partition.

发布评论

评论列表(0)

  1. 暂无评论