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