/* Copyright (C) 2014 Vivek Panyam. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.vivekpanyam.TestApp; import java.io.File; import java.lang.reflect.Method; import android.app.Activity; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import dalvik.system.DexClassLoader; public class DynamicApp { public static Context ctx; public static ClassLoader classLoader; /** * Init the DynamicApp with an APK file * * @param a An activity in the currently running application * @param filename The path to the APK file to load */ public static void init(Activity a, String filename) { try{ //Get Application Context ctx = a.getApplicationContext(); //If there is an update, launch that File update = new File(ctx.getFilesDir(), "update_done.apk"); if (update.exists()) { update.renameTo(new File(ctx.getFilesDir(), filename)); } //Load new package; extract it from assets if necessary String file = Utils.loadDexFile(a, ctx, filename); // Check signatures Signature[] mySignatures = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNATURES).signatures; // Get package info of new package PackageInfo newInfo = Utils.getAPKInfo(file, ctx); Signature[] newSignatures = newInfo.signatures; boolean sigMatch = false; // This is fine because the arrays are going to be pretty small for (Signature signature : mySignatures) { for (Signature signature2 : newSignatures) { if (signature.equals(signature2)) { sigMatch = true; break; } } } if (!sigMatch) { return; } //Get version of new package int version = newInfo.versionCode; //Get Dispatcher of other package and init it. Class<?> evolve = Class.forName("com.vivekpanyam.evolve.Evolve", false, DynamicApp.classLoader); //Load resources Class<?>[] parameterTypes = new Class[1]; parameterTypes[0] = java.lang.String.class; Method m = evolve.getDeclaredMethod("loadResources", parameterTypes); m.setAccessible(true); Object[] parameters = new Object[1]; parameters[0] = file; m.invoke(evolve, parameters); //Init Dispatcher Class<?>[] parameterTypes2 = new Class[3]; parameterTypes2[0] = Activity.class; parameterTypes2[1] = Integer.class; parameterTypes2[2] = DexClassLoader.class; Method m2 = evolve.getDeclaredMethod("init", parameterTypes2); m2.setAccessible(true); Object[] parameters2 = new Object[3]; parameters2[0] = a; parameters2[1] = version; parameters2[2] = DynamicApp.classLoader; m2.invoke(evolve, parameters2); } catch (Exception e) { e.printStackTrace(); } } }