如何獲取其他app的資源

weixin_34050427發表於2016-09-18

簡介

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除了<code> Context.CONTEXT_IGNORE_SECURITY </code>,還有
<code>Context.CONTEXT_INCLUDE_CODE </code>與<code>Context.CONTEXT_RESTRICTED </code>。

其中<code>Context.CONTEXT_RESTRICTED </code>將會返回一個有限制的context,它可能會禁用某些特定屬性。比如:一個與有限制的context想關聯的view可能會忽略特定的xml屬性。

而<code>Context.CONTEXT_INCLUDE_CODE </code>則會返回一個包含app程式碼的context。這意味可以載入程式碼到呼叫方的程式中去,從而使之可以通過getClassLoader()方法來初始化app的類。設定這個標誌位會強制應用安全限制到你訪問的app上去。如果被請求的app不能安全地載入到你的程式中去,則會丟擲java.lang.SecurityException。如果不設定這個標誌位,這個app可以被沒有任何限制地載入,但是在呼叫getClassLoader時始終只返回系統預設的classloader。(疑問:class loader都包含什麼?如何獲取呀)

<code>Context.CONTEXT_IGNORE_SECURITY </code>則會在請求context時忽略任何安全限制,始終允許它被載入。相較於使用<code>Context.CONTEXT_INCLUDE_CODE </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的應用場景和區別分別是什麼?

相關文章