Prevents clearing user data when running:
$ adb shell pm clear mypackage
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | import java.lang.reflect.Method; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class PreventClearApp implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) { XposedHelpers.findAndHookMethod( "com.android.server.pm.PackageManagerService", lpparam.classLoader, "clearApplicationUserData", String.class, "android.content.pm.IPackageDataObserver", int.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { String packageName = (String) param.args[0]; XposedBridge.log("clearApplicationUserData: " + packageName); if (packageName.equals("mypackage")) { param.setResult(null); //we do not have direct access to IPackageDataObserver, so we have to dance Object observer = param.args[1]; if(observer != null) { Class<?> iPackageDataObserverClass = Class.forName("android.content.pm.IPackageDataObserver"); Class<?>[] paramTypes = {String.class, boolean.class}; Method onRemoveCompletedMethod = iPackageDataObserverClass.getMethod("onRemoveCompleted", paramTypes); Object[] params = {packageName, true}; try { onRemoveCompletedMethod.invoke(observer, params); //observer.onRemoveCompleted(packageName, true); } catch (Exception e) { XposedBridge.log("Observer no longer exists."); } } //end dance } } } ); } } |