安卓获取内部存储信息

目录


前言

原生系统设置里的存储容量到底是怎么计算的,跟踪源码,涉及到VolumeInfo、StorageManagerVolumeProvider、PrivateStorageInfo、StorageStatsManager......等等,java上层没有办法使用简单的api获取到吗?搞了半天,总算获取到了,话不多说,直接上代码。

获取存储容量

java 复制代码
    /**
     * 内部总存储空间
     */
    public static long getStorageTotal(Context context) {
        StorageStatsManager storageStatsManager = (StorageStatsManager) context.getSystemService(STORAGE_STATS_SERVICE);
        try {
            return storageStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 内部可用空间
     */
    public static long getStorageFree(Context context) {
        StorageStatsManager storageStatsManager = (StorageStatsManager) context.getSystemService(STORAGE_STATS_SERVICE);
        try {
            return storageStatsManager.getFreeBytes(StorageManager.UUID_DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }


    /**
     * SD卡总空间
     */
    public static long getSdCardTotal(Context context) {
        // 获取所有可用的存储卷
        File[] externalFiles = context.getExternalFilesDirs(null);
        for (File file : externalFiles) {
            if (Environment.isExternalStorageRemovable(file) && !file.getAbsolutePath().contains("emulated")) {
                StatFs stat = new StatFs(file.getPath());
                long blockSize = stat.getBlockSizeLong();
                long totalBlocks = stat.getBlockCountLong();
                return totalBlocks * blockSize;
            }
        }
        return 0;
    }


    /**
     * SD卡可用空间
     */
    public static long getSdCardFree(Context context) {
        // 获取所有可用的存储卷
        File[] externalFiles = context.getExternalFilesDirs(null);
        for (File file : externalFiles) {
            if (Environment.isExternalStorageRemovable(file) && !file.getAbsolutePath().contains("emulated")) {
                StatFs stat = new StatFs(file.getPath());
                long blockSize = stat.getBlockSizeLong();
                long availableBlocks = stat.getAvailableBlocksLong();
                return availableBlocks * blockSize;
            }
        }
        return 0;
    }


    // 格式化文件大小为人类可读的格式
    private static String formatFileSize(long size) {
        String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
        int unitIndex = 0;
        double fileSize = size;
        while (fileSize > 1000 && unitIndex < units.length - 1) {
            fileSize = fileSize / 1000;
            unitIndex++;
        }
        return String.format("%.2f %s", fileSize, units[unitIndex]);
    }

打印下log看一下:


细心的小伙伴肯定发现单位换算是1000而不是1024了,为什么呢?

其实跟我们电脑上的硬盘存储一样,我们买硬盘的时候会发现1T的容量实际只有930G左右,厂商会解释说那是因为电脑系统采用的1024进制造成容量识别误差,因为厂商们生产的时候都是按照1T=1000G...1KB=1000B的进制的,现在手机厂商也学了这一套,标出64G,128G的容量也是按照1000进制的。 奸商啊,要是1024岂不是能放更多东西,哼,

UUID是什么?

UUID_DEFAULT 是一个常量,表示默认存储的 UUID。在这里,它代表默认存储卷的 UUID,通常指的是内部存储或者主要的外部存储(比如 SD 卡)。

在 Android 设备上,不同的存储卷可以具有不同的标识符(UUID),用于唯一标识每个存储卷。StorageManager.UUID_DEFAULT 是指向默认存储卷的 UUID,因此在获取存储信息时,使用这个 UUID 可以获得默认存储卷的存储空间信息。

更进一步的了解,参考谷歌官方:
UUID

StatFs

另外一点就是StatFs,StatFs 类是 Android 提供的用于获取文件系统信息的类,通常使用 StatFs 类来获取存储卷(如内部存储、外部 SD 卡)的文件系统信息,在应用程序中对存储空间进行监测和管理。通过 StatFs 可以获取存储卷的总大小、可用大小、文件块的大小等信息,我们这里就是使用不同文件系统的块数*每块的字节数进而获取总大小的。

相关推荐
移动开发者1号1 小时前
使用 Android App Bundle 极致压缩应用体积
android·kotlin
移动开发者1号2 小时前
构建高可用线上性能监控体系:从原理到实战
android·kotlin
ii_best6 小时前
按键精灵支持安卓14、15系统,兼容64位环境开发辅助工具
android
美狐美颜sdk7 小时前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
恋猫de小郭11 小时前
Meta 宣布加入 Kotlin 基金会,将为 Kotlin 和 Android 生态提供全新支持
android·开发语言·ios·kotlin
aqi0012 小时前
FFmpeg开发笔记(七十七)Android的开源音视频剪辑框架RxFFmpeg
android·ffmpeg·音视频·流媒体
androidwork14 小时前
深入解析内存抖动:定位与修复实战(Kotlin版)
android·kotlin
梦天201514 小时前
android核心技术摘要
android
szhangbiao16 小时前
“开发板”类APP如果做屏幕适配
android
高林雨露17 小时前
RecyclerView中跳转到最后一条item并确保它在可视区域内显示
android