package org.bbs.apklauncher; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.bbs.apklauncher.api.ExportApi; import org.bbs.apklauncher.emb.auto_gen.Target_ActionBarActivity; import org.bbs.apklauncher.emb.auto_gen.Target_Activity; import org.bbs.apklauncher.emb.auto_gen.Target_ActivityGroup; import org.bbs.apklauncher.emb.auto_gen.Target_ExpandableListActivity; import org.bbs.apklauncher.emb.auto_gen.Target_FragmentActivity; import org.bbs.apklauncher.emb.auto_gen.Target_ListActivity; import org.bbs.apklauncher.emb.auto_gen.Target_PreferenceActivity; import org.bbs.apklauncher.emb.auto_gen.Target_Service; import org.bbs.apklauncher.emb.auto_gen.Target_TabActivity; import org.bbs.apkparser.PackageInfoX.ActivityInfoX; import android.app.Activity; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; import android.inputmethodservice.InputMethodService; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.view.WindowManager; @ExportApi public class ApkUtil { private static final String TAG = ApkUtil.class.getSimpleName(); static HashMap<String, String> sActivityClassMap = new HashMap<String, String>(); static HashMap<String, String> sPreDefinedActivityClassMap = new HashMap<String, String>(); static HashMap<String, String> sSuperClassNameMap = new HashMap<String, String>(); public static void updateTitle(Activity activity, ActivityInfo info, Resources res) { CharSequence title = ""; if (info.labelRes > 0) { title = res.getString(info.labelRes); } if (TextUtils.isEmpty(title)) { title = info.nonLocalizedLabel; } if (!TextUtils.isEmpty(title)) { activity.setTitle(title); } } public static void updateTitle(Activity activity){ ApkPackageManager apk = ApkPackageManager.getInstance(); ActivityInfoX info = apk.getActivityInfo(activity.getClass()); ApkUtil.updateTitle(activity, info, activity.getResources()); } public static Resources loadApkResource(String apkFilePath, Context context) { // not support file:// schema ??? if (apkFilePath.startsWith("file://")) { apkFilePath = apkFilePath.substring("file://".length()); } AssetManager assets = null; try { assets = AssetManager.class.getConstructor(null).newInstance(null); Method method = assets.getClass().getMethod("addAssetPath", new Class[]{String.class}); Object r = method.invoke(assets, apkFilePath); DisplayMetrics metrics = new DisplayMetrics(); ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metrics); // TODO add config & metrics Configuration config = context.getResources().getConfiguration(); // metrics = context.getResources().getDisplayMetrics(); Resources res = new Resources(assets, metrics, config); res.updateConfiguration(config, metrics); return res; } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } static String getHostActivityClassName(ClassLoader classloader, String targetActivityClassName){ String cName = null; if (sPreDefinedActivityClassMap.containsKey(targetActivityClassName)){ cName = sPreDefinedActivityClassMap.get(targetActivityClassName); } if (TextUtils.isEmpty(cName)) { } return cName; } public static String getSuperClassName(ClassLoader classloader, String className) { String cName = null; List<String> superClassNames = new ArrayList<String>(); if (sSuperClassNameMap.containsKey(className)) { cName = sSuperClassNameMap.get(className); try { Class<?> clazz; clazz = classloader.loadClass(className); superClassNames = getClassType(clazz); dumpClassType(superClassNames); } catch (ClassNotFoundException e) { e.printStackTrace(); } return cName; } if (TextUtils.isEmpty(cName)) { try { Class<?> clazz = classloader.loadClass(className); superClassNames = getClassType(clazz); // activity if (superClassNames.contains(Target_ActionBarActivity.class.getName())) { cName = Target_ActionBarActivity.class.getName(); } else if (superClassNames.contains(Target_FragmentActivity.class.getName())) { cName = Target_FragmentActivity.class.getName(); } else if (superClassNames.contains(Target_ExpandableListActivity.class.getName())) { cName = Target_ExpandableListActivity.class.getName(); } else if (superClassNames.contains(Target_ListActivity.class.getName())) { cName = Target_ListActivity.class.getName(); } else if (superClassNames.contains(Target_PreferenceActivity.class.getName())){ cName = Target_PreferenceActivity.class.getName(); } else if (superClassNames.contains(Target_TabActivity.class.getName())){ cName = Target_TabActivity.class.getName(); } else if (superClassNames.contains(Target_ActivityGroup.class.getName())){ cName = Target_ActivityGroup.class.getName(); } else if (superClassNames.contains(Target_Activity.class.getName())) { cName = Target_Activity.class.getName(); } // service else if ( // superClassNames.contains(JobService.class.getName()) superClassNames.contains("android.app.job.JobService") // || superClassNames.contains(DreamService.class.getName()) || superClassNames.contains("android.service.dreams.DreamService") // || superClassNames.contains(InputMethodService.class.getName()) || superClassNames.contains(InputMethodService.class.getName()) ) { notImpl(); } else if (superClassNames.contains(Target_Service.class.getName())) { cName = Target_Service.class.getName(); } // broadcastreceiver } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } dumpClassType(superClassNames); if (!TextUtils.isEmpty(cName)) { sSuperClassNameMap.put(className, cName); } else { throw new RuntimeException("no usefull super class for : " + className); } //==========123456789012345678 Log.d(TAG, "superClass : " + cName + " for " + className); return cName; } // @SuppressLint("NewApi") // public static String getServiceSuperClassName(ClassLoader classloader, String serviceClassName) { // String cName = null; // if (sSuperClassNameMap.containsKey(serviceClassName)) { // cName = sSuperClassNameMap.get(serviceClassName); // } // List<String> superClassNames = new ArrayList<String>(); // if (TextUtils.isEmpty(cName)) { // try { // Class<?> clazz = classloader.loadClass(serviceClassName); // superClassNames = getClassType(clazz); // if ( //// superClassNames.contains(JobService.class.getName()) // superClassNames.contains("android.app.job.JobService") //// || superClassNames.contains(DreamService.class.getName()) // || superClassNames.contains("android.service.dreams.DreamService") //// || superClassNames.contains(InputMethodService.class.getName()) // || superClassNames.contains(InputMethodService.class.getName()) // // ) { // notImpl(); // } // if (superClassNames.contains(Target_Service.class.getName())) { // cName = Target_Service.class.getName(); // } // } catch (ClassNotFoundException e) { // e.printStackTrace(); // } // } // // if (!TextUtils.isEmpty(cName)) { // sSuperClassNameMap.put(serviceClassName, cName); // } else { // dumpClassType(superClassNames); // throw new RuntimeException("no usefull super class for service: " + serviceClassName); // } // //==========123456789012345678 // Log.d(TAG, "super class : " + cName + " for " + serviceClassName); // return cName; // } private static void notImpl() { throw new RuntimeException("not impl yet."); } public static List<String> getClassType(Class clazz) { List<String> className = new ArrayList<String>(); className.add(clazz.getName()); while (!clazz.getName().equals(Object.class.getName())) { clazz = clazz.getSuperclass(); className.add(clazz.getName()); } return className; } public static void dumpClassType(List<String> superClassName) { Log.d(TAG, "class hierarchy: "); final int N = superClassName.size(); for (int i = N - 1; i >= 0; i--) { String c = superClassName.get(i); //==========123456789012345678 Log.d(TAG, "class : " + c); } // for (String c : superClassName){ // //==========123456789012345678 // Log.d(TAG, "class : " + c); // } } public static void dumpClassType(Class<?> clazz) { dumpClassType(getClassType(clazz)); } }