android静默卸载,Android实践 -- Android静默安装和卸载
App的靜默安裝和卸載
Android系統(tǒng)本身提供了安裝卸載功能,但是api接口是@hide的,不是公開的接口,所以在應(yīng)用級別
是無法實現(xiàn)靜默安裝和卸載的,要實現(xiàn)靜默安裝和卸載需要是系統(tǒng)應(yīng)用,要有系統(tǒng)簽名和相應(yīng)的權(quán)限
簡單思路如下:
通過反射獲得安裝接口installPackage和 卸載接口 deletePackage
在自己的包中引入兩個接口IPackageInstallObserver和IPackageDeleteObserver的空實現(xiàn)
調(diào)用安裝卸載的方法,回調(diào)上面的兩個接口
添加權(quán)限
進行系統(tǒng)簽名
將應(yīng)用push到系統(tǒng)中,作為系統(tǒng)應(yīng)用
在PackageManager中的提供的接口如下
安裝接口
// @SystemApi
public abstract void installPackage(
Uri packageURI, IPackageInstallObserver observer, int flags,
String installerPackageName);
卸載接口
// @SystemApi
public abstract void deletePackage(
String packageName, IPackageDeleteObserver observer, int flags);
引入兩個回掉的空實現(xiàn)
在自己應(yīng)用的工程中新建一個包android.content.pm,并添加兩個文件
IPackageDeleteObserver.java
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;
}
IPackageInstallObserver.java
package android.content.pm;
public interface IPackageInstallObserver extends android.os.IInterface {
public abstract static class Stub extends android.os.Binder implements android.content.pm.IPackageInstallObserver {
public Stub() {
throw new RuntimeException("Stub!");
}
public static android.content.pm.IPackageInstallObserver 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 packageInstalled(java.lang.String packageName, int returnCode)
throws android.os.RemoteException;
}
自己定義個接口回調(diào)
OnPackagedObserver.java
package com.example;
public interface OnPackagedObserver {
public void packageInstalled(String packageName, int returnCode);
public void packageDeleted(String packageName,int returnCode);
}
實現(xiàn)方法
反射接口
PackageManager 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 method = pm.getClass().getMethod("installPackage", types);
Method uninstallmethod = pm.getClass().getMethod("deletePackage", uninstalltypes);
實現(xiàn)回調(diào)接口
private OnPackagedObserver onInstalledPackaged;
class PackageInstallObserver extends IPackageInstallObserver.Stub {
public void packageInstalled(String packageName, int returnCode) throws RemoteException {
if (onInstalledPackaged != null) {
onInstalledPackaged.packageInstalled(packageName, returnCode);
}
}
}
class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
public void packageDeleted(String packageName, int returnCode) throws RemoteException {
if (onInstalledPackaged != null) {
onInstalledPackaged.packageDeleted(packageName, returnCode);
}
}
}
實現(xiàn)
卸載接口只需要提供要卸載的應(yīng)用的包名packagename ,安裝提供了三個接口
public void uninstallPackage(String packagename) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
uninstallmethod.invoke(pm, new Object[] {packagename, observerdelete, 0});
}
public void installPackage(String apkFile) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
installPackage(new File(apkFile));
}
public void installPackage(File apkFile) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
if (!apkFile.exists()) throw new IllegalArgumentException();
Uri packageURI = Uri.fromFile(apkFile);
installPackage(packageURI);
}
public void installPackage(Uri apkFile) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
method.invoke(pm, new Object[] {apkFile, observer, INSTALL_REPLACE_EXISTING, null});
}
簽名
生成一個apk文件,需要對這個apk文件進行系統(tǒng)簽名,由于
是系統(tǒng)應(yīng)用需要的權(quán)限,在開發(fā)應(yīng)用時,如果加載AndroidManifest.xml
中會編譯不過,需要先用工具 apktool 工具先把apk文件解壓出來,用編輯器在AndroidManifest.xml中加入上面的兩個權(quán)限,然后在用工具apktool重新打包
具體的使用方法參考 [Android實踐 -- Apktool 的使用](http://www.jianshu.com/p/1896307da564)
解壓
apktool d test.apk
修改之后,重新打包
apktool b test
簽名之后的文件,需要在進行系統(tǒng)簽名
具體的使用方法請參考 Android實踐 -- 對apk進行系統(tǒng)簽名
java -jar signapk.jar platform.x509.pem platform.pk8 test.apk test_signed.apk
將簽名之后的文件 push到手機中,需要root權(quán)限
具體的代碼實現(xiàn)
附錄,安裝卸載錯誤碼速查
回調(diào)中的returnCode在PackageManager中的相關(guān)的定義如下:
安裝錯誤碼
public static final int INSTALL_SUCCEEDED = 1;
public static final int INSTALL_FAILED_ALREADY_EXISTS = -1;
public static final int INSTALL_FAILED_INVALID_APK = -2;
public static final int INSTALL_FAILED_INVALID_URI = -3;
public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4;
public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5;
public static final int INSTALL_FAILED_NO_SHARED_USER = -6;
public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7;
public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8;
public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9;
public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10;
public static final int INSTALL_FAILED_DEXOPT = -11;
public static final int INSTALL_FAILED_OLDER_SDK = -12;
public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13;
public static final int INSTALL_FAILED_NEWER_SDK = -14;
public static final int INSTALL_FAILED_TEST_ONLY = -15;
public static final int INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16;
public static final int INSTALL_FAILED_MISSING_FEATURE = -17;
public static final int INSTALL_FAILED_CONTAINER_ERROR = -18;
public static final int INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19;
public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20;
public static final int INSTALL_FAILED_VERIFICATION_TIMEOUT = -21;
public static final int INSTALL_FAILED_VERIFICATION_FAILURE = -22;
public static final int INSTALL_FAILED_PACKAGE_CHANGED = -23;
public static final int INSTALL_FAILED_UID_CHANGED = -24;
public static final int INSTALL_FAILED_VERSION_DOWNGRADE = -25;
public static final int INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE = -26;
public static final int INSTALL_PARSE_FAILED_NOT_APK = -100;
public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101;
public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102;
public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103;
public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104;
public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105;
public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106;
public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107;
public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108;
public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;
public static final int INSTALL_FAILED_INTERNAL_ERROR = -110;
public static final int INSTALL_FAILED_USER_RESTRICTED = -111;
public static final int INSTALL_FAILED_DUPLICATE_PERMISSION = -112;
public static final int INSTALL_FAILED_NO_MATCHING_ABIS = -113;
public static final int NO_NATIVE_LIBRARIES = -114;
public static final int INSTALL_FAILED_ABORTED = -115;
卸載錯誤碼
public static final int DELETE_SUCCEEDED = 1;
public static final int DELETE_FAILED_INTERNAL_ERROR = -1;
public static final int DELETE_FAILED_DEVICE_POLICY_MANAGER = -2;
public static final int DELETE_FAILED_USER_RESTRICTED = -3;
public static final int DELETE_FAILED_OWNER_BLOCKED = -4;
public static final int DELETE_FAILED_ABORTED = -5;
總結(jié)
以上是生活随笔為你收集整理的android静默卸载,Android实践 -- Android静默安装和卸载的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 马斯克承诺星际飞船将“很快”尝试轨道发射
- 下一篇: 丰田计划推电动汽车新平台,丰田章男:电动