码字辛苦!转载请注明出处!
· 错误的方法:
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
最后,宇宙惯例:如果博主的帮助让你感激涕零,不如就给博主一个小红包呗~