安卓获取内部存储信息

目录


前言

原生系统设置里的存储容量到底是怎么计算的,跟踪源码,涉及到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 可以获取存储卷的总大小、可用大小、文件块的大小等信息,我们这里就是使用不同文件系统的块数*每块的字节数进而获取总大小的。

相关推荐
selt79116 小时前
Redisson之RedissonLock源码完全解析
android·java·javascript
Yao_YongChao17 小时前
Android MVI处理副作用(Side Effect)
android·mvi·mvi副作用
非凡ghost18 小时前
JRiver Media Center(媒体管理软件)
android·学习·智能手机·媒体·软件需求
席卷全城18 小时前
Android 推箱子实现(引流文章)
android
齊家治國平天下18 小时前
Android 14 系统中 Tombstone 深度分析与解决指南
android·crash·系统服务·tombstone·android 14
maycho12320 小时前
MATLAB环境下基于双向长短时记忆网络的时间序列预测探索
android
思成不止于此21 小时前
【MySQL 零基础入门】MySQL 函数精讲(二):日期函数与流程控制函数篇
android·数据库·笔记·sql·学习·mysql
brave_zhao21 小时前
达梦数据库(DM8)支持全文索引功能,但并不直接兼容 MySQL 的 FULLTEXT 索引语法
android·adb
sheji341621 小时前
【开题答辩全过程】以 基于Android的网上订餐系统为例,包含答辩的问题和答案
android
easyboot1 天前
C#使用SqlSugar操作mysql数据库
android·sqlsugar