欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 根据包名获取应用的ROM占用大小,应用安装大小、缓存大小、数据大小等等

程序员文章站 2022-05-23 15:22:29
...

获取第三方应用rom大小,主要是通过系统接口IPackageStatsObserver和PackageStats来获取的,而这两个文件我们是直接访问不到的。这边是通过ADIL的方式来调用的。

1、创建两个AIDL文件IPackageStatsObserver和PackageStats,要求包名和sdk中本身文件的包名必须一致。

包名为:android.content.pm

Android 根据包名获取应用的ROM占用大小,应用安装大小、缓存大小、数据大小等等

创建目录为上图,IPackageStatsObserver文件内容为:



package android.content.pm;

import  android.content.pm.PackageStats;
/**
 * API for package data change related callbacks from the Package Manager.
 * Some usage scenarios include deletion of cache directory, generate
 * statistics related to code, data, cache usage(TODO)
 * {@hide}
 */
oneway interface IPackageStatsObserver {
    
    void onGetStatsCompleted(in PackageStats pStats, boolean succeeded);
}

PackageStats文件内容为:


package  android.content.pm;

parcelable PackageStats;

然后build一下就可以了。

我当时是自己建的这两个文件不过一直报错,后来直接在网上下载了这两个文件,拷贝过来没错了。

这两个文件下载路径:https://download.csdn.net/download/shaoenxiao/10603646

当然也可以直接下载这个demo,里面也有这两个文件,demo下载路径在文档末尾。

2、添加权限

此功能必须要添加以下权限,否则会报错的

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

3、写java代码

主要是通过反射的方式获取到系统隐藏的方法,具体代码如下,因为我们写了IPackageStatsObserver和PackageStats这两个aidl,所以这边可以直接使用了。很简单就一个反射,大家自己看下吧。然后调用的话直接调用这方法就可以了。

    /**
     * 获得App应用的大小
     *
     * @param context
     * @param pkgName
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static void getPkgSize(final Context context, String pkgName) throws NoSuchMethodException,
            InvocationTargetException, IllegalAccessException {
        Log.d( "111", "5555555" );

        Method method = PackageManager.class.getMethod("getPackageSizeInfo",
                new Class[] { String.class, IPackageStatsObserver.class });
        // 调用 getPackageSizeInfo 方法,需要两个参数:1、需要检测的应用包名;2、回调
        method.invoke(context.getPackageManager(), new Object[] {
                pkgName,
                new IPackageStatsObserver.Stub() {
                    @Override
                    public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {
                        // 子线程中默认无法处理消息循环,自然也就不能显示Toast,所以需要手动Looper一下
                        Looper.prepare();
                        // 从pStats中提取各个所需数据
                        Toast.makeText(context,
                                "缓存大小=" + Formatter.formatFileSize(context, pStats.cacheSize) +
                                        "\n数据大小=" + Formatter.formatFileSize(context, pStats.dataSize) +
                                        "\n程序大小=" + Formatter.formatFileSize(context, pStats.codeSize),
                                Toast.LENGTH_LONG).show();
                        // 遍历一次消息队列,弹出Toast
                        Looper.loop();
                    }
                }
        });
    }

测试结果经本人验证,和手机设置里面-显示的大小是完全一致的。

demo下载路径:https://download.csdn.net/download/shaoenxiao/10603705