碼字辛苦!轉(zhuǎn)載請(qǐng)注明出處!
· 錯(cuò)誤的方法:
public static List<PackageInfo> getAllApplication(Context context, boolean needActivities) {
PackageManager packageManager = context.getPackageManager();
return packageManager.getInstalledPackages(needActivities ? PackageManager.GET_ACTIVITIES : 0);
}
這是目前網(wǎng)上最流行,也是看上去語義最貼合實(shí)際的方法,然而,經(jīng)過博主項(xiàng)目的大量測試,發(fā)現(xiàn)此方法存在三個(gè)致命問題:
1、獲取了很多系統(tǒng)服務(wù):這些服務(wù)是沒有Activity、并且無法通過去掉系統(tǒng)APP被篩除的
2、獲取不到完整的APP列表:在博主的測試中,經(jīng)常發(fā)現(xiàn)掃描不到某QQ、某視頻等APP的BUG
3、獲取不到APP的啟動(dòng)Activity:這種方式只能獲取到APP所有的Activity,至于LauncherActivity是哪個(gè),無從得知。盡管多數(shù)APP的Manifest文件首項(xiàng)就是LauncherActivity,但仍有很多反其道而行的應(yīng)用,如:某QQ
綜上所述,樓主極不推薦使用packageManager.getInstalledPackages方式獲取應(yīng)用列表!
· 推薦的方法:
//獲取用戶安裝的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;
}
//判斷是否系統(tǒng)應(yīng)用
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;
}
· 一些常見數(shù)據(jù)的獲?。?/p>
//包名
resolveInfo.activityInfo.packageName
//啟動(dòng)Activity
resolveInfo.activityInfo.name
//APP名
resolveInfo.activityInfo.applicationInfo.loadLabel(getPackageManager())
//Icon
resolveInfo.activityInfo.applicationInfo.loadIcon(getPackageManager())
//APK安裝包路徑
resolveInfo.activityInfo.applicationInfo.sourceDir