package com.bczm.widgetcollections.utils; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.text.TextUtils; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.security.PublicKey; import java.security.cert.CertPath; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPublicKey; import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * */ public class PackageUtils { /** 根据packageName获取packageInfo */ public static PackageInfo getPackageInfo(String packageName) { Context context = UIUtils.getContext(); if (null == context) { return null; } if (StringUtils.isEmpty(packageName)) { packageName = context.getPackageName(); } PackageInfo info = null; PackageManager manager = context.getPackageManager(); // 根据packageName获取packageInfo try { info = manager.getPackageInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES); } catch (PackageManager.NameNotFoundException e) { LogUtils.e(e); } return info; } /** 获取本应用的VersionCode */ public static int getVersionCode() { PackageInfo info = getPackageInfo(null); if (info != null) { return info.versionCode; } else { return -1; } } /** 获取本应用的VersionName */ public static String getVersionName() { PackageInfo info = getPackageInfo(null); if (info != null) { return info.versionName; } else { return null; } } /** 判断是否是第三方软件 */ public static boolean isThirdPartyApp(String packageName) { Context context = UIUtils.getContext(); if (null == context) { return false; } PackageManager pm = context.getPackageManager(); PackageInfo packageInfo; try { packageInfo = pm.getPackageInfo(packageName, 0); return isThirdPartyApp(packageInfo); } catch (PackageManager.NameNotFoundException e) { LogUtils.e(e); return false; } } /** 判断是否是第三方软件 */ public static boolean isThirdPartyApp(PackageInfo packageInfo) { if (null == packageInfo || null == packageInfo.applicationInfo) { return false; } return ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) || ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0); } /** 读取指定路径下APK文件签名 */ @SuppressWarnings({"unchecked", "resource"}) public static String getJarSignature(String filePath) throws Exception { if (null == filePath) { return null; } String resultSign = ""; String resultKey = ""; List<ZipEntry> names = new ArrayList<ZipEntry>(); ZipFile zf = new ZipFile(filePath); Enumeration<ZipEntry> zi = (Enumeration<ZipEntry>) zf.entries(); while (zi.hasMoreElements()) { ZipEntry ze = zi.nextElement(); String name = ze.getName(); if (name.startsWith("META-INF/") && (name.endsWith(".RSA") || name.endsWith(".DSA"))) { names.add(ze); } } Collections.sort(names, new Comparator<ZipEntry>() { @Override public int compare(ZipEntry obj1, ZipEntry obj2) { if (obj1 != null && obj2 != null) { return obj1.getName().compareToIgnoreCase(obj2.getName()); } return 0; } }); for (ZipEntry ze : names) { InputStream is = zf.getInputStream(ze); try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); CertPath cp = cf.generateCertPath(is, "PKCS7"); List<?> list = cp.getCertificates(); for (Object obj : list) { if (!(obj instanceof X509Certificate)) continue; X509Certificate cert = (X509Certificate) obj; StringBuilder builder = new StringBuilder(); builder.setLength(0); byte[] key = getPKBytes(cert.getPublicKey()); for (byte aKey : key) { builder.append(String.format("%02X", aKey)); } resultKey += builder.toString(); builder.setLength(0); byte[] signature = cert.getSignature(); for (byte aSignature : signature) { builder.append(String.format("%02X", aSignature)); } resultSign += builder.toString(); } } catch (CertificateException e) { LogUtils.e(e); } is.close(); } if (!TextUtils.isEmpty(resultKey) && !TextUtils.isEmpty(resultSign)) { return hashCode(resultKey) + "," + hashCode(resultSign); } return null; } /** 根据公钥获取key */ private static byte[] getPKBytes(PublicKey pk) { if (pk instanceof RSAPublicKey) { RSAPublicKey k = (RSAPublicKey) pk; return k.getModulus().toByteArray(); } else if (pk instanceof DSAPublicKey) { DSAPublicKey k = (DSAPublicKey) pk; return k.getY().toByteArray(); } return null; } /** 计算签名时的hashcode算法 */ public static int hashCode(String str) { int hash = 0; if (str != null) { int multiplier = 1; int offset = 0; int count = str.length(); char[] value = new char[count]; str.getChars(offset, count, value, 0); for (int i = offset + count - 1; i >= offset; i--) { hash += value[i] * multiplier; int shifted = multiplier << 5; multiplier = shifted - multiplier; } } return hash; } /** 通过包名读取已安装APP数字签名 */ public static String getInstalledPackageSignature(String packageName) { Context context = UIUtils.getContext(); if (null == context) { return null; } String signature = null; try { PackageManager pm = context.getPackageManager(); ApplicationInfo appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_SIGNATURES); String apkPath = appInfo.sourceDir; signature = getJarSignature(apkPath); } catch (PackageManager.NameNotFoundException e) { LogUtils.e(e); } catch (Exception e) { LogUtils.e(e); } return signature; } /** 获取指定路径的apk的资源 */ @SuppressWarnings({"rawtypes", "unchecked"}) public static Resources getAPKResources(String apkPath) throws Exception { Context context = UIUtils.getContext(); if (null == context) { return null; } String PathAssetManager = "android.content.res.AssetManager"; Class assetMagCls = Class.forName(PathAssetManager); Constructor assetMagCt = assetMagCls.getConstructor((Class[]) null); Object assetMag = assetMagCt.newInstance((Object[]) null); Class[] typeArgs = new Class[1]; typeArgs[0] = String.class; Method assetMagAddAssetPathMtd = assetMagCls.getDeclaredMethod("addAssetPath", typeArgs); Object[] valueArgs = new Object[1]; valueArgs[0] = apkPath; assetMagAddAssetPathMtd.invoke(assetMag, valueArgs); Resources res = context.getResources(); typeArgs = new Class[3]; typeArgs[0] = assetMag.getClass(); typeArgs[1] = res.getDisplayMetrics().getClass(); typeArgs[2] = res.getConfiguration().getClass(); Constructor resCt = Resources.class.getConstructor(typeArgs); valueArgs = new Object[3]; valueArgs[0] = assetMag; valueArgs[1] = res.getDisplayMetrics(); valueArgs[2] = res.getConfiguration(); res = (Resources) resCt.newInstance(valueArgs); return res; } }