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メソッドを編集しました。まだこれを機能させることはできません。

それを実行すると、メソッドが見つかりません(invoke "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)

パラメータは大丈夫です。InstallPackageObserverの代わりにDeletePackageObserverクラスを指定する必要があるようです。しかし、私はそれを行う方法がわかりません(私はそのようなクラスを持っていません)。

ありがとう

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 に答える