获取用户已安装的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方式获取应用列表!

· 推荐的方法:

首先添加权限:

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

 然后拷贝代码:PackageUtils.kt

package com.example.myapplication

import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo

object PackageUtils {
    //获取用户安装的APP
    fun getInstalledApplication(context: Context, needSysAPP: Boolean): List<ResolveInfo> {
        val packageManager = context.packageManager
        val intent = Intent(Intent.ACTION_MAIN)
        intent.addCategory(Intent.CATEGORY_LAUNCHER)
        val resolveInfoList = packageManager.queryIntentActivities(intent, 0)
        if (!needSysAPP) {
            val resolveInfoListWithoutSystem: MutableList<ResolveInfo> = ArrayList()
            for (i in resolveInfoList.indices) {
                val resolveInfo = resolveInfoList[i]
                try {
                    if (!isSysApp(context, resolveInfo.activityInfo.packageName)) {
                        resolveInfoListWithoutSystem.add(resolveInfo)
                    }
                } catch (e: PackageManager.NameNotFoundException) {
                    e.printStackTrace()
                }
            }
            return resolveInfoListWithoutSystem
        }
        return resolveInfoList
    }

    //判断是否系统应用
    @Throws(PackageManager.NameNotFoundException::class)
    fun isSysApp(context: Context, packageName: String): Boolean {
        val packageInfo = context.packageManager.getPackageInfo(packageName, 0)
        return packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 1
    }
}

· 一些常见数据的获取:

//包名
resolveInfo.activityInfo.packageName

//启动Activity
resolveInfo.activityInfo.name 

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

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

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

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

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值