Подтвердить что ты не робот

Удалите приложение с помощью системных привилегий

Мое приложение имеет системные привилегии. Он будет внутри прошивки, теперь он находится в /system/app

Мне удалось установить приложения молча с этим сообщением

программно установить/удалить APK (PackageManager vs 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. Но я не знаю, как это сделать (у меня нет такого класса).

Спасибо

4b9b3361

Ответ 1

Вот как я это сделал:

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

Ответ 2

Так определяется метод:

   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);

Обратите внимание на тип наблюдателя.

Ответ 3

Если у вас есть приложение, встроенное в образ системы, и вы используете внутренние API-интерфейсы, вы можете также прекратить делать вид, будто вы стороннее приложение и связываетесь с SDK. Создайте против полной платформы .jar и используйте эти API напрямую. Вы все равно хотите это сделать, потому что это частные API-интерфейсы, и поэтому они могут и могут измениться. Вы хотите построить против того, что на самом деле объявляет их, поэтому, если они будут меняться, вы поймете это во время своих сборок.

Ответ 4

в android 2.3.x, интерфейс IPackageDeleteObserver отличается в методе packageDeleted.