How do I check if an app is a non-system app in Android? How do I check if an app is a non-system app in Android? android android

How do I check if an app is a non-system app in Android?


PackageManager pm = mcontext.getPackageManager();List<PackageInfo> list = pm.getInstalledPackages(0);for(PackageInfo pi : list) {    ApplicationInfo ai = pm.getApplicationInfo(pi.packageName, 0);    System.out.println(">>>>>>packages is<<<<<<<<" + ai.publicSourceDir);    if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {        System.out.println(">>>>>>packages is system package"+pi.packageName);              }}


I was under the impression that all apps in the system image are system apps (and normally installed in /system/app).

If FLAG_SYSTEM is only set to system applications, this will work even for apps in external storage:

boolean isUserApp(ApplicationInfo ai) {    int mask = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;    return (ai.flags & mask) == 0;}

An alternative is to use the pm command-line program in your phone.

Syntax:

pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]pm list packages: prints all packages, optionally only  those whose package name contains the text in FILTER.  Options:    -f: see their associated file.    -d: filter to only show disbled packages.    -e: filter to only show enabled packages.    -s: filter to only show system packages.    -3: filter to only show third party packages.    -i: see the installer for the packages.    -u: also include uninstalled packages.

Code:

ProcessBuilder builder = new ProcessBuilder("pm", "list", "packages", "-s");Process process = builder.start();InputStream in = process.getInputStream();Scanner scanner = new Scanner(in);Pattern pattern = Pattern.compile("^package:.+");int skip = "package:".length();Set<String> systemApps = new HashSet<String>();while (scanner.hasNext(pattern)) {    String pckg = scanner.next().substring(skip);    systemApps.add(pckg);}scanner.close();process.destroy();

Then:

boolean isUserApp(String pckg) {    return !mSystemApps.contains(pckg);}


You can check the signature of application which it signed with system. Like below

/** * Match signature of application to identify that if it is signed by system * or not. *  * @param packageName *            package of application. Can not be blank. * @return <code>true</code> if application is signed by system certificate, *         otherwise <code>false</code> */public boolean isSystemApp(String packageName) {    try {        // Get packageinfo for target application        PackageInfo targetPkgInfo = mPackageManager.getPackageInfo(                packageName, PackageManager.GET_SIGNATURES);        // Get packageinfo for system package        PackageInfo sys = mPackageManager.getPackageInfo(                "android", PackageManager.GET_SIGNATURES);        // Match both packageinfo for there signatures        return (targetPkgInfo != null && targetPkgInfo.signatures != null && sys.signatures[0]                .equals(targetPkgInfo.signatures[0]));    } catch (PackageManager.NameNotFoundException e) {        return false;    }}

You can get more code on my blog How to check if application is system app or not (By signed signature)