package cm.android.applications; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.Signature; import android.util.DisplayMetrics; import java.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import cm.android.util.AndroidUtils; import cm.java.codec.HashUtil; import cm.java.util.ObjectUtil; import cm.java.util.Utils; public class AppUtil { private static final Logger logger = LoggerFactory.getLogger(AppUtil.class); public static final AppFilter THIRD_PARTY_FILTER = new AppFilter() { public void init() { } @Override public boolean filterApp(ApplicationInfo info) { if (isSystemUpdateApp(info)) { return true; } else if (!isSystemApp(info)) { return true; } return false; } }; /** * 用户应用 */ public static final int APP_USER = 0; /** * 系统应用 */ public static final int APP_SYSTEM = 1; /** * 所有应用(用户+系统) */ public static final int APP_ALL = 2; /** * 获取已安装的应用 * * @param flag {@link #APP_USER},{@link #APP_SYSTEM},{@link #APP_ALL} * @return PackageInfo列表 */ public static List<PackageInfo> getInstalledPackages(PackageManager pm, int flag) { List<PackageInfo> packages = getInstalledPackages(pm); List<PackageInfo> appList = new ArrayList<PackageInfo>(); if (flag == APP_USER) { for (int i = 0; i < packages.size(); i++) { PackageInfo packageInfo = packages.get(i); if (THIRD_PARTY_FILTER.filterApp(packageInfo.applicationInfo)) { appList.add(packageInfo); } } return appList; } else if (flag == APP_SYSTEM) { for (int i = 0; i < packages.size(); i++) { PackageInfo packageInfo = packages.get(i); if (isSystemApp(packageInfo.applicationInfo)) { appList.add(packageInfo); } } return appList; } else { return packages; } } public static List<PackageInfo> getInstalledPackages(PackageManager pm) { int retrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS; List<PackageInfo> packages = pm.getInstalledPackages(retrieveFlags); return packages; } public static List<ApplicationInfo> getInstalledApplications( PackageManager pm) { int retrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS; List<ApplicationInfo> packages = pm.getInstalledApplications(retrieveFlags); return packages; } /** * 获取已安装的应用 * * @param flag {@link #APP_USER},{@link #APP_SYSTEM},{@link #APP_ALL} * @return ApplicationInfo列表 */ public static List<ApplicationInfo> getInstalledApps(PackageManager pm, int flag) { List<ApplicationInfo> apps = getInstalledApplications(pm); List<ApplicationInfo> appList = ObjectUtil.newArrayList(); if (flag == APP_USER) { for (int i = 0; i < apps.size(); i++) { ApplicationInfo applicationInfo = apps.get(i); if (THIRD_PARTY_FILTER.filterApp(applicationInfo)) { appList.add(applicationInfo); } } return appList; } else if (flag == APP_SYSTEM) { for (int i = 0; i < apps.size(); i++) { ApplicationInfo applicationInfo = apps.get(i); if (isSystemApp(applicationInfo)) { appList.add(applicationInfo); } } return appList; } else { return apps; } } /** * 获取已安装的应用 * * @param flag {@link #APP_USER},{@link #APP_SYSTEM},{@link #APP_ALL} */ public static Map<String, ApplicationInfo> getInstalledAppsMap(PackageManager pm, int flag) { List<ApplicationInfo> apps = getInstalledApplications(pm); Map<String, ApplicationInfo> appMap = AndroidUtils.newMap(); if (flag == APP_USER) { for (int i = 0; i < apps.size(); i++) { ApplicationInfo applicationInfo = apps.get(i); if (THIRD_PARTY_FILTER.filterApp(applicationInfo)) { appMap.put(applicationInfo.packageName, applicationInfo); } } return appMap; } else if (flag == APP_SYSTEM) { for (int i = 0; i < apps.size(); i++) { ApplicationInfo applicationInfo = apps.get(i); if (isSystemApp(applicationInfo)) { appMap.put(applicationInfo.packageName, applicationInfo); } } return appMap; } else { for (ApplicationInfo applicationInfo : apps) { appMap.put(applicationInfo.packageName, applicationInfo); } return appMap; } } /** * 获取已安装的应用 * * @param flag {@link #APP_USER},{@link #APP_SYSTEM},{@link #APP_ALL} */ public static Map<String, PackageInfo> getInstalledPackagesMap(PackageManager pm, int flag) { List<PackageInfo> packages = getInstalledPackages(pm); Map<String, PackageInfo> appMap = AndroidUtils.newMap(); if (flag == APP_USER) { for (int i = 0; i < packages.size(); i++) { PackageInfo packageInfo = packages.get(i); if (THIRD_PARTY_FILTER.filterApp(packageInfo.applicationInfo)) { appMap.put(packageInfo.packageName, packageInfo); } } return appMap; } else if (flag == APP_SYSTEM) { for (int i = 0; i < packages.size(); i++) { PackageInfo packageInfo = packages.get(i); if (isSystemApp(packageInfo.applicationInfo)) { appMap.put(packageInfo.packageName, packageInfo); } } return appMap; } else { for (PackageInfo packageInfo : packages) { appMap.put(packageInfo.packageName, packageInfo); } return appMap; } } /** * 同时获取用户应用和系统应用 */ public static void getPackages(PackageManager pm, List<PackageInfo> userAppList, List<PackageInfo> sysAppList) { List<PackageInfo> packages = getInstalledPackages(pm); if (null != userAppList) { userAppList.clear(); for (int i = 0; i < packages.size(); i++) { PackageInfo packageInfo = packages.get(i); if (THIRD_PARTY_FILTER.filterApp(packageInfo.applicationInfo)) { userAppList.add(packageInfo); } } } if (null != sysAppList) { sysAppList.clear(); // APP_SYSTEM for (int i = 0; i < packages.size(); i++) { PackageInfo packageInfo = packages.get(i); if (isSystemApp(packageInfo.applicationInfo)) { sysAppList.add(packageInfo); } } } } /** * 获取未安装的APK信息 * * @param archiveFilePath APK文件的路径。如:/sdcard /download/XX.apk */ @Deprecated public static PackageInfo getArchiveInfo(PackageManager pm, String archiveFilePath) { PackageInfo info = getArchiveInfo(pm, archiveFilePath, PackageManager.GET_ACTIVITIES); return info; } public static PackageInfo getArchiveInfo(PackageManager pm, String archiveFilePath, int flags) { PackageInfo info = pm.getPackageArchiveInfo(archiveFilePath, flags); return info; } /** * 获取拥有应用入口的应用列表 */ // 获得所有启动Activity的信息,类似于Launch界面 public static List<ResolveInfo> getLunchAppInfo(PackageManager pm) { Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); // 通过查询,获得所有ResolveInfo对象. List<ResolveInfo> resolveInfos = pm.queryIntentActivities(mainIntent, 0); // 调用系统排序 , 根据name排序 // 该排序很重要,否则只能显示系统应用,而不能列出第三方应用程序 Collections.sort(resolveInfos, new ResolveInfo.DisplayNameComparator(pm)); return resolveInfos; // if (mlistAppInfo != null) { // mlistAppInfo.clear(); // for (ResolveInfo reInfo : resolveInfos) { // String activityName = reInfo.activityInfo.name; // // // 获得该应用程序的启动Activity的name // String pkgName = reInfo.activityInfo.packageName; // 获得应用程序的包名 // String appLabel = (String) reInfo.loadLabel(pm); // 获得应用程序的Label // Drawable icon = reInfo.loadIcon(pm); // 获得应用程序图标 // // 为应用程序的启动Activity 准备Intent // Intent launchIntent = new Intent(); // launchIntent.setComponent(new ComponentName(pkgName, // activityName)); // // 创建一个AppInfo对象,并赋值 // AppInfo appInfo = new AppInfo(); // appInfo.setAppLabel(appLabel); // appInfo.setPkgName(pkgName); // appInfo.setAppIcon(icon); // appInfo.setIntent(launchIntent); // mlistAppInfo.add(appInfo); // 添加至列表中 // } // } } // /** // * 获取应用PackageInfo信息 // */ // @Deprecated // public static PackageInfo getPackageInfo(PackageManager pm, String packageName) { // PackageInfo packageInfo = getPackageInfo(pm, packageName, PackageManager.GET_ACTIVITIES | // PackageManager.GET_GIDS | // PackageManager.GET_CONFIGURATIONS | // PackageManager.GET_INSTRUMENTATION | // PackageManager.GET_PERMISSIONS | // PackageManager.GET_PROVIDERS | // PackageManager.GET_RECEIVERS | // PackageManager.GET_SERVICES | // PackageManager.GET_SIGNATURES | // PackageManager.GET_UNINSTALLED_PACKAGES | // PackageManager.GET_URI_PERMISSION_PATTERNS | // PackageManager.GET_SHARED_LIBRARY_FILES); // return packageInfo; // } /** * 获取应用PackageInfo信息 */ public static PackageInfo getPackageInfo(PackageManager pm, String packageName, int flags) { try { PackageInfo packageInfo = pm.getPackageInfo(packageName, flags); return packageInfo; } catch (NameNotFoundException e) { // logger.error(e.getMessage(), e); return null; } } /** * 获取应用签名 */ public static android.content.pm.Signature[] getSignature(PackageManager pm, String packageName) { try { android.content.pm.Signature[] sigs = pm.getPackageInfo( packageName, PackageManager.GET_SIGNATURES).signatures; return sigs; } catch (NameNotFoundException e) { logger.error(e.getMessage(), e); return null; } } public static X509Certificate getCertificate(Signature signature) { if (signature == null) { return null; } try { InputStream is = new ByteArrayInputStream(signature.toByteArray()); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) certFactory.generateCertificate(is); return cert; } catch (CertificateException e) { logger.error(e.getMessage(), e); return null; } } public static byte[] getPublicKey(Signature signature) { X509Certificate cert = getCertificate(signature); if (cert != null) { byte[] pubKey = cert.getPublicKey().getEncoded(); return pubKey; } else { return null; } } /** * 获取签名hash */ public static int getSignatureHashCode(PackageManager pm, String packageName) { int sig = 0; Signature[] s = getSignature(pm, packageName); if (s != null) { sig = s[0].hashCode(); } return sig; } public static byte[] getFingerprint(Context context, String tag) { return getFingerprint(context, tag, context.getPackageName()); } public static byte[] getFingerprint(Context context, String tag, String packageName) { StringBuilder sb = new StringBuilder(); sb.append(tag); sb.append(packageName); android.content.pm.Signature[] signatures = getSignature(context.getPackageManager(), packageName); if (signatures != null) { sb.append(signatures[0].toCharsString()); } byte[] fingerprint = HashUtil.getHmac(Utils.getBytes(tag), Utils.getBytes(sb.toString())); return fingerprint; } /** * 获取未安装应用签名 */ public static String showUninstallAPKSignatures(String apkPath) { String PATH_PackageParser = "android.content.pm.PackageParser"; try { // apk包的文件路径 // 这是一个Package 解释器, 是隐藏的 // 构造函数的参数只有一个, apk文件的路径 // PackageParser packageParser = new PackageParser(apkPath); Class pkgParserCls = Class.forName(PATH_PackageParser); Class[] typeArgs = new Class[1]; typeArgs[0] = String.class; Constructor pkgParserCt = pkgParserCls.getConstructor(typeArgs); Object[] valueArgs = new Object[1]; valueArgs[0] = apkPath; Object pkgParser = pkgParserCt.newInstance(valueArgs); // 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况 DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); // PackageParser.Package mPkgInfo = packageParser.parsePackage(new // File(apkPath), apkPath, // metrics, 0); typeArgs = new Class[4]; typeArgs[0] = File.class; typeArgs[1] = String.class; typeArgs[2] = DisplayMetrics.class; typeArgs[3] = Integer.TYPE; Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod( "parsePackage", typeArgs); valueArgs = new Object[4]; valueArgs[0] = new File(apkPath); valueArgs[1] = apkPath; valueArgs[2] = metrics; valueArgs[3] = PackageManager.GET_SIGNATURES; Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs); typeArgs = new Class[2]; typeArgs[0] = pkgParserPkg.getClass(); typeArgs[1] = Integer.TYPE; Method pkgParser_collectCertificatesMtd = pkgParserCls .getDeclaredMethod("collectCertificates", typeArgs); valueArgs = new Object[2]; valueArgs[0] = pkgParserPkg; valueArgs[1] = PackageManager.GET_SIGNATURES; pkgParser_collectCertificatesMtd.invoke(pkgParser, valueArgs); // 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开 Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField( "mSignatures"); Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg); return info[0].toCharsString(); } catch (Exception e) { logger.error(e.getMessage(), e); } return null; } /** * 判断应用是否为系统应用 */ public static boolean isSystemApp(ApplicationInfo applicationInfo) { if (applicationInfo == null) { return false; } if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0) { return true; } return false; } public static boolean isSystemUpdateApp(ApplicationInfo applicationInfo) { if (applicationInfo == null) { return false; } return ((applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0); } public static boolean isSystemApp(PackageManager packageManager, String packageName) { if (Utils.isEmpty(packageName)) { return false; } try { ApplicationInfo app = packageManager.getApplicationInfo(packageName, 0); return AppUtil.isSystemApp(app); } catch (NameNotFoundException e) { logger.error("packageName = " + packageName, e); } return false; } public static boolean isAppInstalled(PackageManager pm, String packageName) { int mRetrieveFlags = 0; // Process.myUserHandle()== UserHandle. // if (myUserId() == 0) { // mRetrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES | // PackageManager.GET_DISABLED_COMPONENTS | // PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS; // } else { mRetrieveFlags = PackageManager.GET_DISABLED_COMPONENTS | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS; // } return getPackageInfo(pm, packageName, mRetrieveFlags) != null; } public static interface AppFilter { public void init(); public boolean filterApp(ApplicationInfo info); } public static class AppFilterExcludeSelf implements AppFilter { private String packageName; public AppFilterExcludeSelf(String packageName) { this.packageName = packageName; } public void init() { } @Override public boolean filterApp(ApplicationInfo info) { if (info.packageName.equals(packageName)) { return false; } if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { return true; } else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { return true; } return false; } } }