在获取apk资源时候最重要的一个类就是PackageManager,我们可以通过这个类得到各种想要的东西,首先是得到已经安装的apk的基本信息,包括label,和图标等资源:
PackageManager pm = getPackageManager(); List<PackageInfo> apkInfos = pm.getInstalledPackages(0); ArrayList<String> infos_name = new ArrayList<String>() ;//用来存放label ArrayList<Drawable> infos_icon = newArrayList<Drawable>();//用来存储apk启动图标资源 String name = ""; Drawable icon; PackageInfo apk; for (int i = 0; i < apkInfos.size(); ) { apk = apkInfos.get(i); i++; name = (String) pm.getApplicationLabel(apk.applicationInfo); icon = pm.getApplicationIcon(apk.applicationInfo); infos_icon.add(icon); infos_name.add(name); }接下来我们利用PackageManager获得已安装apk中的activity,和service等
List<PackageInfo>packagesInfo = pm.getInstalledPackages(0); for (PackageInfo packageInfo : packagesInfo) { Log.d("TAG","packageInfo NAME IS :"+packageInfo.packageName); } PackageManager pm = getPackageManager(); try { //获得com.example.pertest包中的activity,service和broadcastreceiver PackageInfo packageInfo = pm.getPackageInfo("com.example.pertest", PackageManager.GET_PERMISSIONS | PackageManager.GET_SERVICES | PackageManager.GET_RECEIVERS); ActivityInfo[] activities = packageInfo.activities; if (activities != null) { for (ActivityInfo activityInfo : activities) { Log.d("TAG", "the activity " + activityInfo.toString() + "==" + packageInfo.versionCode + "===" + packageInfo.versionName); } } else { Log.d("TAG", "the activity is null"); } ServiceInfo[] serviceInfos = packageInfo.services; for (ServiceInfo serviceInfo : serviceInfos) { Log.d("TAG", "service name is :" + serviceInfo.name); } activities = packageInfo.receivers; for (ActivityInfo activity : activities) { Log.d("TAG", "receiver is :" + activity.name); } } catch (NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }
得到未安装apk的图标:
public static Drawable getAppIcon(Context context, String apkFilepath) { PackageManager pm = context.getPackageManager(); PackageInfo pkgInfo = getPackageInfo(context, apkFilepath); if (pkgInfo == null) { return null; } ApplicationInfo appInfo = pkgInfo.applicationInfo; if (Build.VERSION.SDK_INT >= 8) { appInfo.sourceDir = apkFilepath; appInfo.publicSourceDir = apkFilepath; } return pm.getApplicationIcon(appInfo); }得到未安装apk的名称:
public static CharSequence getAppLabel(Context context, String apkFilepath) { PackageManager pm = context.getPackageManager(); PackageInfo pkgInfo = getPackageInfo(context, apkFilepath); if (pkgInfo == null) { return null; } ApplicationInfo appInfo = pkgInfo.applicationInfo; if (Build.VERSION.SDK_INT >= 8) { appInfo.sourceDir = apkFilepath; appInfo.publicSourceDir = apkFilepath; } return pm.getApplicationLabel(appInfo); }如果还觉得不够的话,我们可以得到:PackageInfo对象,通过该对象,我们就可以获得该未安装apk的activity,service,broadcastreceiver等,方法同"获得已安装apk中的activity,和service" ,代码如下:
//得到PackageInfo对象,其中包含了该apk包含的activity和service public static PackageInfo getPackageInfo(Context context, String apkFilepath) { PackageManager pm = context.getPackageManager(); PackageInfo pkgInfo = null; try { pkgInfo = pm.getPackageArchiveInfo(apkFilepath, PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES); } catch (Exception e) { // should be something wrong with parse e.printStackTrace(); } return pkgInfo; }
String mNativeLibDir = mContext.getDir("pluginlib", Context.MODE_PRIVATE).getAbsolutePath(); private DexClassLoader createDexClassLoader(String dexPath) { File dexOutputDir = mContext.getDir("dex", Context.MODE_PRIVATE); dexOutputPath = dexOutputDir.getAbsolutePath(); DexClassLoader loader = new DexClassLoader(dexPath, dexOutputPath, mNativeLibDir, mContext.getClassLoader()); return loader; }第一个参数dexPath就是我们apk的存放路径。
第二个参数dexOutPath就是该apk文件对应的dex文件的存放路径,不可以为null。
第三个参数是目标类中使用的C/C++库的列表,每个目录用File.pathSeparator间隔开
;
可以为 null。
第四个参数是该类装载器的父装载器,一般用当前执行类的装载器。
在获得了该DexClassLoader对象以后,我们就可以实现动态加载该apk中的方法了,详细的方法,请看我的另一篇文章:android动态加载
对于加载未安装的apk中的资源,由于使用的是不同的context,所以,这里先这样做:
private AssetManager createAssetManager(String dexPath) { try { AssetManager assetManager = AssetManager.class.newInstance(); Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class); addAssetPath.invoke(assetManager, dexPath); return assetManager; } catch (Exception e) { e.printStackTrace(); return null; } } private Resources createResources(AssetManager assetManager) { Resources superRes = mContext.getResources(); Resources resources = new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration()); return resources; }此时的assetManager和resources就可以和平时一样来用了。
原文地址:http://blog.csdn.net/mockingbirds/article/details/44903155