美文网首页
Android 获取 应用列表 方法记录

Android 获取 应用列表 方法记录

作者: 行走中的3卡 | 来源:发表于2022-11-09 14:56 被阅读0次

    有时,我们需要获取设备上的 应用列表,
    例如获取 所有已安装的 或者 能够显示在 桌面上的APK.
    基于这些列表,我们可以做一些管理功能, 例如权限展示等的.

    1. 获取所有已安装的应用

    简单起见, 仅返回每个应用的包名

        //{@ - 获取所有安装的APK (MATCH_UNINSTALLED_PACKAGES 表示未卸载的APK, 包括APK已被删除但是保留数据的)
        // 需要获取所有apk 添加permission <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
        private List<String> getInstalledPackages(Context context) {
            List<String> installedPackageList = new ArrayList<>();
            List<PackageInfo> installedPackageInfoList = context.getPackageManager().getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES);
    
            for (PackageInfo packageInfo: installedPackageInfoList) {
                installedPackageList.add(packageInfo.packageName);
            }
            return installedPackageList;
        }
        //@}
    

    这里需要注意, 在AndroidManifest 需要加上权限声明,否则只能获取部分应用.

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

    2. 获取所有 能够显示在 桌面上的 应用

    简单起见, 仅返回每个应用的包名

        //{@add - 获取所有带有桌面属性的APK -
        // 需要获取所有apk 添加permission <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
        private List<String> getAllLauncherIconPackages(Context context) {
            List<String> launcherIconPackageList = new ArrayList<>();
    
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
    
            //set MATCH_ALL to prevent any filtering of the results
            List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_ALL);
            for (ResolveInfo info: resolveInfos) {
                launcherIconPackageList.add(info.activityInfo.packageName);
            }
    
            return launcherIconPackageList;
        }
        //@add}
    

    这里需要注意, 在AndroidManifest 需要加上权限声明,否则只能获取部分应用.

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

    3. 测试API

    方便测试上述API, 增加了一个单独函数

        private void printPackages(List<String> packagesList, String packageTag){
             if (packagesList == null) {
                 Log.d(TAG, packageTag + " packagesList is null" );
                 return;
             }
            int packageSize = packagesList.size();
            Log.d(TAG, packageTag + " packageSize=" + packageSize);
            for (int index = 0; index < packageSize; index++) {
                Log.d(TAG, "The " + index + " package is: " + packagesList.get(index));
            }
        }
    

    则可以调用(this 是在一个Activity里传递):

            List<String> installedPackages = getInstalledPackages(this);
            printPackages(installedPackages, "installed");
    
            List<String> launcherIconPackages = getAllLauncherIconPackages(this);
            printPackages(launcherIconPackages, "launcherIcon");
    

    则会得到如下输出:

    14:40:19.096 9446 9446 AppListActivity: installed packageSize=455
    14:40:19.096 9446 9446 AppListActivity: The 0 package is: com.google.android.networkstack.tethering
    ...
    14:40:19.114 9446 9446 AppListActivity: launcherIcon packageSize=66
    14:40:19.114 9446 9446 AppListActivity: The 0 package is: com.android.gallery3d
    ...

    4. 拓展

    我们可以根据获取到的 resolveInfos , 即
    List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_ALL);

    然后 根据 resolveInfo.activityInfo 去获取每个 应用的 PackageInfo对象
    进而获取到它所声明的所有 permissions.
    例如:

    ActivityInfo ai = resolveInfo.activityInfo;
    PackageInfo pi = pm.getPackageInfo(ai.packageName, PackageManager.GET_PERMISSIONS);
    if (ai.enabled && ai.exported && pi.requestedPermissions != null) {
          // 这里可以对 应用所声明的权限 做分类, 例如哪些是 涉及 用户隐私的.
    }
    

    注意, 这里的 pi.requestedPermissions 包括应用本身 以及它 依赖的aar 包里声明的所有权限,
    即在AndroidManifest 里有这些:

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

    附录

    https://stackoverflow.com/questions/65629648/list-the-all-apps-in-android
    https://stackoverflow.com/questions/60679685/what-does-query-all-packages-permission-do/60766583#60766583
    Android中获取应用程序(包)的信息(launcher获取系统应用)

    相关文章

      网友评论

          本文标题:Android 获取 应用列表 方法记录

          本文链接:https://www.haomeiwen.com/subject/yzdntdtx.html