下面从一个未安装的android的apk文件获取apk信息
1 /** 2 * 获取未安装的apk信息 3 * 4 * @param ctx Context 5 * @param apkPath apk路径,可以放在SD卡 6 * @return 7 */ 8 public static AppInfoData getApkFileInfo(Context ctx, String apkPath) 9 { 10 System.out.println(apkPath); 11 File apkFile = new File(apkPath); 12 if (!apkFile.exists() || !apkPath.toLowerCase().endsWith(".apk")) 13 { 14 System.out.println("file path is not correct"); 15 return null; 16 } 17 18 AppInfoData appInfoData; 19 String PATH_PackageParser = "android.content.pm.PackageParser"; 20 String PATH_AssetManager = "android.content.res.AssetManager"; 21 try 22 { 23 //反射得到pkgParserCls对象并实例化,有参数 24 Class<?> pkgParserCls = Class.forName(PATH_PackageParser); 25 Class<?>[] typeArgs = {String.class}; 26 Constructor<?> pkgParserCt = pkgParserCls.getConstructor(typeArgs); 27 Object[] valueArgs = {apkPath}; 28 Object pkgParser = pkgParserCt.newInstance(valueArgs); 29 30 //从pkgParserCls类得到parsePackage方法 31 DisplayMetrics metrics = new DisplayMetrics(); 32 metrics.setToDefaults();//这个是与显示有关的, 这边使用默认 33 typeArgs = new Class<?>[]{File.class,String.class, 34 DisplayMetrics.class,int.class}; 35 Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage", typeArgs); 36 37 valueArgs=new Object[]{new File(apkPath),apkPath,metrics,0}; 38 39 //执行pkgParser_parsePackageMtd方法并返回 40 Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs); 41 42 //从返回的对象得到名为"applicationInfo"的字段对象 43 if (pkgParserPkg==null) 44 { 45 return null; 46 } 47 Field appInfoFld = pkgParserPkg.getClass().getDeclaredField("applicationInfo"); 48 49 //从对象"pkgParserPkg"得到字段"appInfoFld"的值 50 if (appInfoFld.get(pkgParserPkg)==null) 51 { 52 return null; 53 } 54 ApplicationInfo info = (ApplicationInfo) appInfoFld.get(pkgParserPkg); 55 56 //反射得到assetMagCls对象并实例化,无参 57 Class<?> assetMagCls = Class.forName(PATH_AssetManager); 58 Object assetMag = assetMagCls.newInstance(); 59 //从assetMagCls类得到addAssetPath方法 60 typeArgs = new Class[1]; 61 typeArgs[0] = String.class; 62 Method assetMag_addAssetPathMtd = assetMagCls.getDeclaredMethod("addAssetPath", typeArgs); 63 valueArgs = new Object[1]; 64 valueArgs[0] = apkPath; 65 //执行assetMag_addAssetPathMtd方法 66 assetMag_addAssetPathMtd.invoke(assetMag, valueArgs); 67 68 //得到Resources对象并实例化,有参数 69 Resources res = ctx.getResources(); 70 typeArgs = new Class[3]; 71 typeArgs[0] = assetMag.getClass(); 72 typeArgs[1] = res.getDisplayMetrics().getClass(); 73 typeArgs[2] = res.getConfiguration().getClass(); 74 Constructor<Resources> resCt = Resources.class.getConstructor(typeArgs); 75 valueArgs = new Object[3]; 76 valueArgs[0] = assetMag; 77 valueArgs[1] = res.getDisplayMetrics(); 78 valueArgs[2] = res.getConfiguration(); 79 //这个是重点 80 //得到Resource对象后可以有很多用处 81 res = (Resources) resCt.newInstance(valueArgs); 82 83 // 读取apk文件的信息 84 appInfoData = new AppInfoData(); 85 if (info!=null) 86 { 87 if (info.icon != 0) 88 { 89 // 图片存在,则读取相关信息 90 Drawable icon = res.getDrawable(info.icon);// 图标 91 appInfoData.setAppicon(icon); 92 } 93 if (info.labelRes != 0) 94 { 95 String neme = (String) res.getText(info.labelRes);// 名字 96 appInfoData.setAppname(neme); 97 }else 98 { 99 String apkName=apkFile.getName(); 100 appInfoData.setAppname(apkName.substring(0,apkName.lastIndexOf("."))); 101 } 102 String pkgName = info.packageName;// 包名 103 appInfoData.setApppackage(pkgName); 104 } 105 else 106 { 107 return null; 108 } 109 PackageManager pm = ctx.getPackageManager(); 110 PackageInfo packageInfo = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES); 111 if (packageInfo != null) 112 { 113 appInfoData.setAppversion(packageInfo.versionName);//版本号 114 appInfoData.setAppversionCode(packageInfo.versionCode+"");//版本码 115 } 116 return appInfoData; 117 } catch (Exception e) 118 { 119 e.printStackTrace(); 120 } 121 return null; 122 }