a_dzik
a_dzik

Reputation: 977

Get user accessible apps?

I'm trying to get all apps from the user device. And there are lots of examples how to do it. However - I want to show only apps, that are shown in Launcher and souch. So both installed apps and system apps (like com.android.calendar). However, I'm having a hard time to filter stuff like "com.android.certinstaller". Generally apps that are used by the OS, but there are no icons to be found by the typical user.

I have two implementations. One shows me only user-installed apps (so no system apps like calendar or dialer)

    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);
        }
    }

and other that gathers all of the apps:

    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;

So. Any ideas how to do this?

Upvotes: 0

Views: 180

Answers (1)

Randyka Yudhistira
Randyka Yudhistira

Reputation: 3652

You can get it with intent btw, just add category_launcher to determine if that app have activity to be launched or not

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

No duplicate will use 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));

Upvotes: 1

Related Questions