获取用户可访问的应用程序?

Get user accessible apps?

我正在尝试从用户设备获取所有应用程序。 并且有很多示例如何做到这一点。 但是 - 我只想显示在启动器等中显示的应用程序。所以安装的应用程序和系统应用程序(如 com.android.calendar)。但是,我很难过滤像 "com.android.certinstaller" 这样的东西。通常 OS 使用的应用程序,但一般用户找不到图标。

我有两个实现。一个只显示用户安装的应用程序(因此没有系统应用程序,如日历或拨号器)

    PackageManager pm = getActivity().getPackageManager();
    List<ApplicationInfo> apps = pm.getInstalledApplications(0);

    List<ApplicationInfo> installedApps = new ArrayList<ApplicationInfo>();

    for(ApplicationInfo app : apps) {
        //checks for flags; if flagged, check if updated system app
        if((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1) {
            installedApps.add(app);
            //it's a system app, not interested
        } else if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
            //Discard this one
            //in this case, it should be a user-installed app
            continue;
        } else {
            installedApps.add(app);
        }
    }

和其他收集所有应用程序的应用程序:

    ArrayList<ApplicationItem> res = new ArrayList<ApplicationItem>();
    List<PackageInfo> packs = getActivity().getPackageManager().getInstalledPackages(0);
    for(int i=0;i<packs.size();i++) {
        PackageInfo p = packs.get(i);
        if ((!getSysPackages) && (p.versionName == null)) {
            continue ;
        }
        ApplicationItem newInfo = new ApplicationItem();
        newInfo.appname = p.applicationInfo.loadLabel(getActivity().getPackageManager()).toString();
        newInfo.pname = p.packageName;
        newInfo.versionName = p.versionName;
        newInfo.versionCode = p.versionCode;
        newInfo.icon = p.applicationInfo.loadIcon(getActivity().getPackageManager());
        res.add(newInfo);
    }
    return res;

所以。任何想法如何做到这一点?

顺便说一句,您可以通过 intent 获得它,只需添加 category_launcher 即可确定该应用是否 activity 可以启动

final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List<ResolveInfo> pkgAppsList = context.getPackageManager().queryIntentActivities( mainIntent, 0);

没有重复将使用 HashSet

    //using hashset so that there will be no duplicate packages, 
    //if no duplicate packages then there will be no duplicate apps
    HashSet<String> packageNames = new HashSet<String>(0);
    List<ApplicationInfo> appInfos = new ArrayList<ApplicationInfo>(0);

    //getting package names and adding them to the hashset
    for(ResolveInfo resolveInfo : pkgAppsList) {
        packageNames.add(resolveInfo.activityInfo.packageName);
    }

    //now we have unique packages in the hashset, so get their application infos
    //and add them to the arraylist
    for(String packageName : packageNames) {
        try {
            appInfos.add(packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA));
        } catch (NameNotFoundException e) {
            //Do Nothing
        }
    }

    //to sort the list of apps by their names
    Collections.sort(appInfos, new ApplicationInfo.DisplayNameComparator(packageManager));ApplicationInfo.DisplayNameComparator(packageManager));