13

我的应用程序具有系统权限。它将在固件内部,现在它位于 /system/app

我可以通过这篇文章静默安装应用程序

以编程方式安装/卸载 APK(PackageManager 与 Intents)

有效的示例应用程序

http://paulononaka.wordpress.com/2011/07/02/how-to-install-a-application-in-background-on-android/

但我仍然无法以同样的方式卸载应用程序。我尝试像安装示例一样使用反射。

public ApplicationManager(Context context) throws SecurityException, NoSuchMethodException {

    observer = new PackageInstallObserver();
    pm = context.getPackageManager();

    Class<?>[] types = new Class[] {Uri.class, IPackageInstallObserver.class, int.class, String.class};
    Class<?>[] uninstalltypes = new Class[] {String.class, IPackageInstallObserver.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, observer, 0});
    }
    public void installPackage(Uri apkFile) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        method.invoke(pm, new Object[] {apkFile, observer, INSTALL_REPLACE_EXISTING, null});
    }

我添加了 uninstallPackage 方法并编辑了 ApplicationManager 方法。仍然无法正常工作。

当我运行它时,我找不到方法(在调用“deletePackage”行上)。

这不是我的更改的工作项目: https ://dl.dropbox.com/u/1928109/InstallInBackgroundSample.zip

这是函数的描述:http ://www.androidjavadoc.com/1.0_r1_src/android/content/pm/PackageManager.html#deletePackage(java.lang.String, android.content.pm.IPackageDeleteObserver, int)

参数没问题。似乎我应该指定 DeletePackageObserver 类而不是 InstallPackageObserver。但我不知道该怎么做(我没有这样的课程)。

谢谢

4

4 回答 4

18

这是我的做法:

ApplicationManager.java(更改部分):

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(在 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;
}

也不要忘记为清单添加权限

<uses-permission android:name="android.permission.DELETE_PACKAGES"/>

工作示例项目(apk 需要放在设备上的“/system/app”路径中) http ://www.mediafire.com/file/no4buw54ed6vuzo/DeleteInBackgroundSample.zip

于 2012-06-10T09:58:47.303 回答
7

这是该方法的定义方式:

   public abstract void deletePackage(
             String packageName, IPackageDeleteObserver observer, int flags);

要使用反射调用它,您需要以下内容:

Class<?>[] uninstalltypes = new Class[] {String.class, 
         IPackageDeleteObserver.class, int.class};
uninstallmethod = pm.getClass().getMethod("deletePackage", uninstalltypes);

注意观察者的类型。

于 2012-06-08T01:04:04.990 回答
4

如果您将应用程序内置到系统映像中,并且您正在使用内部 API,那么您最好停止假装自己是第三方应用程序并链接到 SDK。针对完整平台 .jar 构建并直接使用这些 API。无论如何,您都想这样做,因为这些是私有 API,因此它们可以并且确实会改变。您想根据实际声明它们的内容进行构建,因此如果它们确实发生了变化,您将在构建过程中发现这一点。

于 2012-06-09T02:10:10.297 回答
1

在 android 2.3.x 中,接口 IPackageDeleteObserver 在方法 packageDeleted 中有所不同。

于 2012-11-09T07:47:09.080 回答