获取用户已安装的APP列表及APK安装包

码字辛苦!转载请注明出处!

· 错误的方法:

public static List<PackageInfo> getAllApplication(Context context, boolean needActivities) {
        PackageManager packageManager = context.getPackageManager();
        return packageManager.getInstalledPackages(needActivities ? PackageManager.GET_ACTIVITIES : 0);
    }

这是目前网上最流行,也是看上去语义最贴合实际的方法,然而,经过博主项目的大量测试,发现此方法存在三个致命问题:

1、获取了很多系统服务:这些服务是没有Activity、并且无法通过去掉系统APP被筛除的

2、获取不到完整的APP列表:在博主的测试中,经常发现扫描不到某QQ、某视频等APP的BUG

3、获取不到APP的启动Activity:这种方式只能获取到APP所有的Activity,至于LauncherActivity是哪个,无从得知。尽管多数APP的Manifest文件首项就是LauncherActivity,但仍有很多反其道而行的应用,如:某QQ

综上所述,楼主极不推荐使用packageManager.getInstalledPackages方式获取应用列表!

· 推荐的方法:

//获取用户安装的APP
    public static List<ResolveInfo> getInstalledApplication(Context context, boolean needSysAPP) {
        PackageManager packageManager = context.getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0);
        if (!needSysAPP) {
            List<ResolveInfo> resolveInfosWithoutSystem = new ArrayList<>();
            for (int i = 0; i < resolveInfos.size(); i++) {
                ResolveInfo resolveInfo = resolveInfos.get(i);
                try {
                    if (!isSysApp(context, resolveInfo.activityInfo.packageName)) {
                        resolveInfosWithoutSystem.add(resolveInfo);
                    }
                } catch (PackageManager.NameNotFoundException e) {
                    e.printStackTrace();
                }
            }
            return resolveInfosWithoutSystem;
        }
        return resolveInfos;
    }

    //判断是否系统应用
    public static boolean isSysApp(Context context, String packageName) throws PackageManager.NameNotFoundException {
        PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
        return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1;
    }

· 一些常见数据的获取:

//包名
resolveInfo.activityInfo.packageName

//启动Activity
resolveInfo.activityInfo.name 

//APP名
resolveInfo.activityInfo.applicationInfo.loadLabel(getPackageManager())

//Icon
resolveInfo.activityInfo.applicationInfo.loadIcon(getPackageManager())

//APK安装包路径
resolveInfo.activityInfo.applicationInfo.sourceDir

最后,宇宙惯例:如果博主的帮助让你感激涕零,不如就给博主一个小红包呗~

猜你喜欢

转载自blog.csdn.net/u014653815/article/details/85773304