Question

I am developing an application, in which i want to get the list of all non system apps. Here is my code part:

TextView tv = new TextView(this);
        this.setContentView(tv);

        ActivityManager actvityManager = (ActivityManager)
        this.getSystemService( ACTIVITY_SERVICE );
        PackageManager pm = this.getPackageManager();
        List<PackageInfo> list =pm.getInstalledPackages(0);

        for(int i=0;i<list.size();i++)
        {
            System.out.println("list"+i+"   "+list.get(i));
        }

        for(PackageInfo pi : list) 
        {
            try
            {
                ApplicationInfo ai=pm.getApplicationInfo(pi.packageName, 0);

                if (ai.sourceDir.startsWith("/data/app/"))
                {
                    tv.setText(ai.className);// non system apps
                }
                else 
                {
                     System.out.println("system apps");// system apps
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();

            }
        }

but it showing, all the app as system apps

Was it helpful?

Solution

If an Application is a non-system application it must have a launch Intent by which it can be launched. If the launch intent is null then its a system App.

Example of System Apps: "com.android.browser.provider", "com.google.android.voicesearch".

For the above apps you will get NULL when you query for launch Intent.

PackageManager pm = getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for(ApplicationInfo packageInfo:packages){
    if( pm.getLaunchIntentForPackage(packageInfo.packageName) != null ){
                String currAppName = pm.getApplicationLabel(packageInfo).toString();
               //This app is a non-system app
    }
    else{
        //System App
    }
}

OTHER TIPS

Solution

PackageManager provides a direct way to find system apps(but not non-system apps) using PackageManager.MATCH_SYSTEM_ONLY flag.

List<ApplicationInfo> systemPackages = pm.getInstalledApplications(PackageManager.MATCH_SYSTEM_ONLY);

But there's a workaround. According to documentation, such apps have the FLAG_SYSTEM flag. We use this flag to find non-system apps:

List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo : packages) {
    if ((packageInfo.flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM) {
        //system app
    }
    else {
        //non system app
    }
}

App count obtained from both methods tallies correctly.

Criteria of having launch intent only, may not be reliable. it lists some system apps as non-system apps and vice versa. following code gives all the non-system apps which are launchable, and it works perfectly fine.

    PackageManager pm = getPackageManager();
    List<ApplicationInfo> packages = m.getInstalledApplications(PackageManager.GET_META_DATA);
    for(ApplicationInfo appInfo:packages)
    {
        String currAppName = pm.getApplicationLabel(appInfo).toString();
        String srcDir = appInfo.sourceDir;
        //Log.d(TAG, currAppName+": "+srcDir);
        if(srcDir.startsWith("/data/app/") && pm.getLaunchIntentForPackage(appInfo.packageName) != null)
        {
            Log.d(TAG, "NON-SYSTEM APP:"+srcDir);
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top