文档章节

Android应用静默安装和卸载

coderminer
 coderminer
发布于 2016/11/01 09:39
字数 1164
阅读 195
收藏 0

App的静默安装和卸载

Android系统本身提供了安装卸载功能,但是api接口是@hide的,不是公开的接口,所以在应用级别
是无法实现静默安装和卸载的,要实现静默安装和卸载需要是系统应用,要有系统签名和相应的权限

简单思路如下:

  1. 通过反射获得安装接口installPackage和 卸载接口 deletePackage
  2. 在自己的包中引入两个接口IPackageInstallObserverIPackageDeleteObserver的空实现
  3. 调用安装卸载的方法,回调上面的两个接口
  4. 添加权限 <uses-permission android:name="android.permission.DELETE_PACKAGES"/> <uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
  5. 进行系统签名
  6. 将应用push到系统中,作为系统应用

PackageManager中的提供的接口如下

  1. 安装接口
// @SystemApi
public abstract void installPackage(
      Uri packageURI, IPackageInstallObserver observer, int flags,
      String installerPackageName);
  1. 卸载接口
// @SystemApi
public abstract void deletePackage(
      String packageName, IPackageDeleteObserver observer, int flags);

引入两个回掉的空实现

在自己应用的工程中新建一个包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;
}

自己定义个接口回调

  • OnPackagedObserver.java
package com.example;
public interface OnPackagedObserver {

	public void packageInstalled(String packageName, int returnCode);
	public void packageDeleted(String packageName,int returnCode);
}

实现方法

  • 反射接口
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);
  • 实现回调接口
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);
  }
}
}
  • 实现 卸载接口只需要提供要卸载的应用的包名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文件进行系统签名,由于<uses-permission android:name="android.permission.DELETE_PACKAGES"/> <uses-permission android:name="android.permission.INSTALL_PACKAGES"/> 是系统应用需要的权限,在开发应用时,如果加载AndroidManifest.xml
中会编译不过,需要先用工具 apktool 工具先把apk文件解压出来,用编辑器在AndroidManifest.xml中加入上面的两个权限,然后在用工具apktool重新打包

具体的使用方法参考 [Android实践 -- Apktool 的使用](http://www.jianshu.com/p/1896307da564)
  • 解压
apktool d test.apk
  • 修改之后,重新打包
apktool b test

签名之后的文件,需要在进行系统签名
具体的使用方法请参考 Android实践 -- 对apk进行系统签名

java -jar signapk.jar platform.x509.pem platform.pk8 test.apk test_signed.apk

将签名之后的文件 push到手机中,需要root权限

具体的代码实现

源码

附录,安装卸载错误码速查

回调中的returnCodePackageManager中的相关的定义如下:

  • 安装错误码
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;

© 著作权归作者所有

coderminer
粉丝 1
博文 50
码字总数 8996
作品 0
海淀
私信 提问
Android apk的安装、卸载、更新升级(通过Eclipse实现静默安装)

一、通过Intent消息机制发送消息,调用系统应用进行,实现apk的安装/卸载 。 (1) 调用系统的安装应用,让系统自动进行apk的安装 String fileName = "/data/data/com.zlc.ipanel.operate/F...

zhoulc
2013/04/06
22.8K
40
[RK3288][Android7.1] 调试笔记 --- APK代码中无法通过pm install自我升级

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kris_fei/article/details/90171912 Platform: RK3288 OS: Android 7.1 Kernel: v4.4.83 现象: APK中使用命令...

KrisFei
05/13
0
0
那些年Android黑科技①:只要活着,就有希望

“黑科技什么的最喜欢了! 对,我们就是要搞事。 来呀。谁怕谁。三年血赚,死刑不亏。(๑´ڡ`๑) ” -- 来自暗世界android工程师 前言: 这个世界上手机有三大系统,苹果、 安卓、 中国安卓 ...

猴亮屏
2017/10/24
44
0
即使您卸载它们,应用程序也可以追踪到您

简评:如果信息泄露了,你可能会因为这多收到一条广告、一条短信,或者出现更严重的事情。但大多科技公司对用户隐私上没有给用户多少选择。 如果你刚卸载了一个应用程序,又突然在各个地方看...

极小光
2018/11/07
0
0
2011全年腾讯移动安全实验室手机病毒行业报告

http://news.zdnet.com.cn/zdnetnews/2012/0118/2075538.shtml 本文摘要 2011年全年,腾讯移动安全实验室一共截获被植入手机病毒软件包数25404个,其中Symbian平台截获被植入病毒软件包数165...

abel_cao
01/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

64.监控平台介绍 安装zabbix 忘记admin密码

19.1 Linux监控平台介绍 19.2 zabbix监控介绍 19.3/19.4/19.6 安装zabbix 19.5 忘记Admin密码如何做 19.1 Linux监控平台介绍: 常见开源监控软件 ~1.cacti、nagios、zabbix、smokeping、ope...

oschina130111
今天
13
0
当餐饮遇上大数据,嗯真香!

之前去开了一场会,主题是「餐饮领袖新零售峰会」。认真听完了餐饮前辈和新秀们的分享,觉得获益匪浅,把脑子里的核心纪要整理了一下,今天和大家做一个简单的分享,欢迎感兴趣的小伙伴一起交...

数澜科技
今天
7
0
DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN

本文作者:PETER LAI ,是 Diode 的区块链工程师。在进入软件开发领域之前,他主要是在做工商管理相关工作。Peter Lai 也是一位活跃的开源贡献者。目前,他正在与 Diode 团队一起开发基于区块...

红薯
今天
12
0
CC攻击带来的危害我们该如何防御?

随着网络的发展带给我们很多的便利,但是同时也带给我们一些网站安全问题,网络攻击就是常见的网站安全问题。其中作为站长最常见的就是CC攻击,CC攻击是网络攻击方式的一种,是一种比较常见的...

云漫网络Ruan
今天
12
0
实验分析性专业硕士提纲撰写要点

为什么您需要研究论文的提纲? 首先当您进行研究时,您需要聚集许多信息和想法,研究论文提纲可以较好地组织你的想法, 了解您研究资料的流畅度和程度。确保你写作时不会错过任何重要资料以此...

论文辅导员
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部