Android APK管理器代码,主要就是两个列表,一个显示SD卡上面的APK文件的list,一个显示已经安装的app的list。
1:获取SD卡上的APK安装文件后,要用代码读出APK里面的信息,如icon等,的主要代码如下:
private void getUninatllApkInfo(Context context, String apkPath) { String PATH_PackageParser = "android.content.pm.PackageParser"; String PATH_AssetManager = "android.content.res.AssetManager"; 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); Log.d("ANDROID_LAB", "pkgParser:" + pkgParser.toString()); // 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况 DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); 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] = 0; Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs); // 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开 // ApplicationInfo info = mPkgInfo.applicationInfo; Field appInfoFld = pkgParserPkg.getClass().getDeclaredField( "applicationInfo"); ApplicationInfo info = (ApplicationInfo) appInfoFld .get(pkgParserPkg); // uid 输出为"-1",原因是未安装,系统未分配其Uid。 Log .d("ANDROID_LAB", "pkg:" + info.packageName + " uid=" + info.uid); Class assetMagCls = Class.forName(PATH_AssetManager); Constructor assetMagCt = assetMagCls.getConstructor((Class[]) null); Object assetMag = assetMagCt.newInstance((Object[]) null); typeArgs = new Class[1]; typeArgs[0] = String.class; Method assetMag_addAssetPathMtd = assetMagCls.getDeclaredMethod( "addAssetPath", typeArgs); valueArgs = new Object[1]; valueArgs[0] = apkPath; assetMag_addAssetPathMtd.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); CharSequence label = null; if (info.labelRes != 0) { label = res.getText(info.labelRes); } Log.d("ANDROID_LAB", "label=" + label); // 这里就是读取一个apk程序的图标 if (info.icon != 0) { this.icon = res.getDrawable(info.icon); appName = label.toString(); packageName = info.packageName; } } catch (Exception e) { e.printStackTrace(); } }
icon就是这个APK的图标,appName就是这个apk的名称,packageName就是这个apk的包名。
2:下面是如何获取所有的已经安装的非系统app的代码:
其中的
if((p.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0){ continue; }
作用是过滤掉system app。