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

Android中PackageStats返回值始终为0,低版本如何计算应用目录大小?

解决Android Oreo以下计算应用存储大小的问题

嘿,我完全懂你的困扰!针对你提到的两个核心问题——Oreo以下设备如何计算/Android/data/myapplicationpackage目录大小,以及PackageStats返回0的正确用法,我来一步步给你梳理清楚:

一、PackageStats返回0?你大概率踩了这两个坑

PackageStats本身是靠谱的API,但很多开发者会在权限声明和异步调用逻辑上出错,导致返回0,具体要注意:

1. 必须在清单中声明权限

在AndroidManifest.xml里添加这个正常权限(无需动态申请,但必须声明):

<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />

2. 必须用异步回调获取结果

PackageManager的getPackageSizeInfo是异步方法,不能同步直接拿值,必须通过IPackageStatsObserver回调接收结果。以下是完整可运行的示例:

import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.os.RemoteException;

// 调用这个方法获取应用存储大小
public void fetchAppTotalStorage(String packageName) {
    PackageManager pm = getPackageManager();
    try {
        pm.getPackageSizeInfo(packageName, new IPackageStatsObserver.Stub() {
            @Override
            public void onGetStatsCompleted(PackageStats stats, boolean succeeded) throws RemoteException {
                if (succeeded) {
                    // 计算总占用:内部数据+外部数据+缓存+外部缓存
                    long totalBytes = stats.dataSize + stats.externalDataSize + stats.cacheSize + stats.externalCacheSize;
                    // 注意:更新UI要切回主线程
                    runOnUiThread(() -> {
                        long totalMB = totalBytes / (1024 * 1024);
                        // 这里可以把结果展示给用户
                    });
                } else {
                    // 处理获取失败的情况
                }
            }
        });
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

如果之前返回0,大概率是没使用异步回调,或者漏加了权限。

二、直接遍历/Android/data/你的包名目录计算大小

如果你只需要特定目录的大小,直接遍历目录累加是更灵活的方案,不受系统版本限制:

1. 权限准备

  • Android 6.0(API 23)及以上:需要动态申请READ_EXTERNAL_STORAGE权限(因为该目录属于外部存储)
  • Android 5.1及以下:仅需在清单中声明READ_EXTERNAL_STORAGE即可

2. 递归计算目录大小的代码

import java.io.File;

// 递归计算目录总大小
public long calculateDirSize(File targetDir) {
    if (!targetDir.exists() || !targetDir.isDirectory()) {
        return 0;
    }
    long totalSize = 0;
    File[] files = targetDir.listFiles();
    if (files != null) {
        for (File file : files) {
            if (file.isDirectory()) {
                totalSize += calculateDirSize(file);
            } else {
                totalSize += file.length();
            }
        }
    }
    return totalSize;
}

// 使用示例
File appExternalDataDir = new File(Environment.getExternalStorageDirectory(), "Android/data/" + getPackageName());
// 注意:大目录计算耗时,要放在子线程执行
new Thread(() -> {
    long dirSize = calculateDirSize(appExternalDataDir);
    long dirSizeMB = dirSize / (1024 * 1024);
    // 切回主线程更新UI
    runOnUiThread(() -> {
        // 展示计算结果
    });
}).start();

两种方案对比

  • PackageStats:适合获取应用的全量存储占用(内部数据、缓存、外部数据等),但依赖系统API,需处理异步逻辑。
  • 直接遍历目录:适合只需要特定目录的大小,逻辑简单兼容性强,但要注意权限和线程阻塞问题。

内容的提问来源于stack exchange,提问作者sam_k

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:28:06