获取SD卡上 未安装 APK文件信息
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. }