在Android上安装其他Apk有两种方式
1、启动Android应用安装器进行安装
这种方式会弹出一个对话框用户选择是否安装,实现代码如下,本文不做详细介绍:
/**
* 安装apk
*
* @param path apk路径
*/
public void update(String path) {
Log.v("正确的安装路径", path);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");
startActivity(intent);
}
2、通过pm命令安装
通过这种方式可以实现Android apk的后台静默安装。
首先对pm安装做个简单的介绍,在平常使用IntelliJ IDEA的过程中可以发现在安装应用的过程中控制台会出现如下输出:
Waiting for device.
Target device: android-md_1008b-0123456789ABCDEF
Uploading file
local path: E:\1.1\1.1\App\AndroidAssist\out\production\AppInstall\AppInstall.apk
remote path: /data/local/tmp/com.example.AppInstall
Installing com.example.AppInstall
DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/com.example.AppInstall"
pkg: /data/local/tmp/com.example.AppInstall
Success
其中有一行 pm install -r "……",这就是执行的 pm 命令进行apk的安装。
那么问题来了,如何在Android执行shell命令,方式有两种,一种是通过Runtime.exec(),另一种是ProcessBuilder。详见:
http://blog.csdn.net/junjieking/article/details/7682380
终于,重点来了,Android通过pm命令实现apk的静默安装:
需要在Manifest.xml中申请安装应用,以及其他需要的权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.DELETE_PACKAGES"/>
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>
<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
应用安装的权限需要当前应用和系统Framwork有相同的签名,在打包的时候必须进行签名,否则无法实现应用的安装。
对应用签名时需要以下文件platform.pk8 platform.x509.pem signapk.jar,将需要签名的apk放置在同一目录下然后在cmd窗口执行命令:
java -jar signapk.jar platform.x509.pem platform.pk8 input.apk output.apk
以AppInstall.apk为例:
java -jar signapk.jar platform.x509.pem platform.pk8 AppInstall.apk AppInstall_signed.apk
相关文件的下载地址
http://download.csdn.net/detail/lhangtk/8274143
实现apk安装的关键代码如下:
/**
* 安装应用
* @param apkAbsolutePath 安装应用的路径
* @return 安装结果的控制台输出
*/
public String install(String apkAbsolutePath) {
//初始化pm指令
String[] args = {"pm", "install", "-r", apkAbsolutePath};
String result = "";
//进程生成器,将指令封装成独立的进程,进行调用
ProcessBuilder processBuilder = new ProcessBuilder(args);
//进程
Process process = null;
InputStream errIs = null;
InputStream inIs = null;
try {
//字节流,临时存储控制台的输出内容
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int read = -1;
//执行安装apk的pm指令
process = processBuilder.start();
//接收控制台输出的异常情况,输入流
errIs = process.getErrorStream();
while ((read = errIs.read()) != -1) {
baos.write(read);
}
baos.write("\r\n".getBytes());
//正常输出
inIs = process.getInputStream();
while ((read = inIs.read()) != -1) {
baos.write(read);
}
byte[] data = baos.toByteArray();
//将控制台输出转化为字符串返回
result = new String(data);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {//最后必须将所有输入输出流关闭
try {
if (errIs != null) {
errIs.close();
}
if (inIs != null) {
inIs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (process != null) {
process.destroy();
}
}
return result;
}
直接调用以上方法就能够实现apk后台静默安装。
demo的下载地址:
http://download.csdn.net/detail/lhangtk/8274251
说明:
部分文章说需要在Manifest.xml中添加 android:sharedUserId="android.uid.system"以保证应用uid为system_uid,事实上是不需要的,另外如果添加了该部分的说明,会在静态引用sdcard路径时出现如下错误
Static storage paths aren’t available from AID_SYSTEM
详见: