uninstall app silently with system privileges
Solution 1:
Here is how I did it:
ApplicationManager.java (changed part):
private PackageInstallObserver observer;
private PackageDeleteObserver observerdelete;
private PackageManager pm;
private Method method;
private Method uninstallmethod;
class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
public void packageDeleted(String packageName, int returnCode) throws RemoteException {
/*if (onInstalledPackaged != null) {
onInstalledPackaged.packageInstalled(packageName, returnCode);
}*/
}
}
public ApplicationManager(Context context) throws SecurityException, NoSuchMethodException {
observer = new PackageInstallObserver();
observerdelete = new PackageDeleteObserver();
pm = context.getPackageManager();
Class<?>[] types = new Class[] {Uri.class, IPackageInstallObserver.class, int.class, String.class};
Class<?>[] uninstalltypes = new Class[] {String.class, IPackageDeleteObserver.class, int.class};
method = pm.getClass().getMethod("installPackage", types);
uninstallmethod = pm.getClass().getMethod("deletePackage", uninstalltypes);
}
public void uninstallPackage(String packagename) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
uninstallmethod.invoke(pm, new Object[] {packagename, observerdelete, 0});
}
PackageDeleteObserver.java (in android.content.pm):
package android.content.pm;
public interface IPackageDeleteObserver extends android.os.IInterface {
public abstract static class Stub extends android.os.Binder implements android.content.pm.IPackageDeleteObserver {
public Stub() {
throw new RuntimeException("Stub!");
}
public static android.content.pm.IPackageDeleteObserver asInterface(android.os.IBinder obj) {
throw new RuntimeException("Stub!");
}
public android.os.IBinder asBinder() {
throw new RuntimeException("Stub!");
}
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
throws android.os.RemoteException {
throw new RuntimeException("Stub!");
}
}
public abstract void packageDeleted(java.lang.String packageName, int returnCode)
throws android.os.RemoteException;
}
Also dont forget to add permission to manifest:
<uses-permission android:name="android.permission.DELETE_PACKAGES"/>
Working sample project (apk need to be placed in "/system/app" path on device): http://www.mediafire.com/file/no4buw54ed6vuzo/DeleteInBackgroundSample.zip
Solution 2:
This is how the method is defined:
public abstract void deletePackage(
String packageName, IPackageDeleteObserver observer, int flags);
To call it using reflection, you would need something like:
Class<?>[] uninstalltypes = new Class[] {String.class,
IPackageDeleteObserver.class, int.class};
uninstallmethod = pm.getClass().getMethod("deletePackage", uninstalltypes);
Note the type of the observer.
Solution 3:
If you are having your app built into the system image, and you are using internal APIs, you might as well stop pretending like you are a third party app and linking against the SDK. Build against the full platform .jar and use those APIs directly. You want to do that anyway, because these are private APIs, and so they can and do change. You want to build against what is actually declaring them, so if they do change, you will catch this during your builds.
Solution 4:
in android 2.3.x, the interface IPackageDeleteObserver is different in method packageDeleted.