如何获取其他app的资源

简介

1.根据该app的pkgName创建context
2.根据context,资源标示符,和资源类型读取资源。

详细介绍


1.创建context
public static Context getContextFromPackageName(Context context, String packageName) {
    if (packageName == null)
        return null;
    try {
        Context slaveContext = context.createPackageContext(packageName, Context.CONTEXT_IGNORE_SECURITY);
        return slaveContext;
    } catch (Exception e) {    }
    return null;
}

使用到的flag除了 Context.CONTEXT_IGNORE_SECURITY ,还有
Context.CONTEXT_INCLUDE_CODE Context.CONTEXT_RESTRICTED

其中Context.CONTEXT_RESTRICTED 将会返回一个有限制的context,它可能会禁用某些特定属性。比如:一个与有限制的context想关联的view可能会忽略特定的xml属性。

Context.CONTEXT_INCLUDE_CODE 则会返回一个包含app代码的context。这意味可以加载代码到调用方的进程中去,从而使之可以通过getClassLoader()方法来初始化app的类。设置这个标志位会强制应用安全限制到你访问的app上去。如果被请求的app不能安全地加载到你的进程中去,则会抛出java.lang.SecurityException。如果不设置这个标志位,这个app可以被没有任何限制地加载,但是在调用getClassLoader时始终只返回系统默认的classloader。(疑问:class loader都包含什么?如何获取呀)

Context.CONTEXT_IGNORE_SECURITY 则会在请求context时忽略任何安全限制,始终允许它被加载。相较于使用Context.CONTEXT_INCLUDE_CODE ,它并不是那么安全。所以请小心使用。

2.加载res下的资源
public Drawable getResourcesFromApk(String resourceName,Context mApkContext) {
    if (mApkContext == null || resourceName == null)
      return null;
    try {
        Resources localResources = mApkContext.getPackageManager().getResourcesForApplication(mApkContext.getPackageName());
        int resourceID = localResources.getIdentifier(mApkContext.getPackageName() + ":drawable/" + resourceName, null, null);
        Drawable localDrawable = null;
        if (resourceID != 0) {
            localDrawable = localResources.getDrawable(resourceID);
            return localDrawable;
        }
      return null;
  } catch (Exception localNameNotFoundException) {
      localNameNotFoundException.printStackTrace();
  }
  return null;
}

其他资源如int,color,colorStateList,string,以此类推。

获取icon与app名称

//这里的context是对应app的context。
public static Drawable getAppIcon(Context context,String pkgName) {
  PackageManager pm = context.getPackageManager();   
  try {
      ApplicationInfo info = pm.getApplicationInfo(pkgName, 0);
      return info.loadIcon(pm);//获取app name调用loadLabel方法,但是返回结果可能为null
  } catch (PackageManager.NameNotFoundException e) {
      e.printStackTrace();
  }
  return null;
}
疑问
  • 获取到一个app的context之后,除了获取资源还可以做什么?
  • 以上三个flag的应用场景和区别分别是什么?

你可能感兴趣的:(如何获取其他app的资源)