I am getting a list of ApplicationInfo
Objects with packageManager.getInstalledApplications(0) and attempting to categorize them by whether or not they are a sy
Here are different possible ways to see if the app is a system app by its package name (used some of the codes in this post)
package com.test.util;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
import java.util.regex.Pattern;
import timber.log.Timber;
public class SystemAppChecker {
private PackageManager packageManager = null;
public SystemAppChecker(Context context) {
packageManager = context.getPackageManager();
}
/**
* Check if system app by 'pm' command-line program
*
* @param packageName
* package name of application. Cannot be null.
* @return true
if package is a system app.
*/
public boolean isSystemAppByPM(String packageName) {
if (packageName == null) {
throw new IllegalArgumentException("Package name cannot be null");
}
ProcessBuilder builder = new ProcessBuilder("pm", "list", "packages", "-s");
Process process = null;
try {
process = builder.start();
} catch (IOException e) {
Timber.e(e);
return false;
}
InputStream in = process.getInputStream();
Scanner scanner = new Scanner(in);
Pattern pattern = Pattern.compile("^package:.+");
int skip = "package:".length();
Set systemApps = new HashSet();
while (scanner.hasNext(pattern)) {
String pckg = scanner.next().substring(skip);
systemApps.add(pckg);
}
scanner.close();
process.destroy();
if (systemApps.contains(packageName)) {
return true;
}
return false;
}
/**
* Check if application is preloaded.
*
* @param packageName
* package name of application. Cannot be null.
* @return true
if package is preloaded.
*/
public boolean isSystemPreloaded(String packageName) {
if (packageName == null) {
throw new IllegalArgumentException("Package name cannot be null");
}
try {
ApplicationInfo ai = packageManager.getApplicationInfo(
packageName, 0);
if (ai.sourceDir.startsWith("/system/app/") || ai.sourceDir.startsWith("/system/priv-app/")) {
return true;
}
} catch (NameNotFoundException e) {
Timber.e(e);
}
return false;
}
/**
* Check if the app is system signed or not
*
* @param packageName
* package of application. Cannot be blank.
* @return true
if application is signed by system certificate,
* otherwise false
*/
public boolean isSystemSigned(String packageName) {
if (packageName == null) {
throw new IllegalArgumentException("Package name cannot be null");
}
try {
// Get packageinfo for target application
PackageInfo targetPkgInfo = packageManager.getPackageInfo(
packageName, PackageManager.GET_SIGNATURES);
// Get packageinfo for system package
PackageInfo sys = packageManager.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) {
Timber.e(e);
}
return false;
}
/**
* Check if application is installed in the device's system image
*
* @param packageName
* package name of application. Cannot be null.
* @return true
if package is a system app.
*/
public boolean isSystemAppByFLAG(String packageName) {
if (packageName == null) {
throw new IllegalArgumentException("Package name cannot be null");
}
try {
ApplicationInfo ai = packageManager.getApplicationInfo(
packageName, 0);
// Check if FLAG_SYSTEM or FLAG_UPDATED_SYSTEM_APP are set.
if (ai != null
&& (ai.flags & (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
return true;
}
} catch (NameNotFoundException e) {
Timber.e(e);
}
return false;
}
}