android --静默安装

【此篇文章为转载文章】

最近需要实现Android应用的静默安装,在网上看了不少帖子,最后在root权限下实现对应用的静默安装和卸载,现在就整个实现的过程做一个总结。

一.第一种方案
第一种方案参考了源码中/packages/apps/PackageInstaller的实现方式,实现的主要代码如下:

importjava.io.File;
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.content.pm.PackageInfo;
importandroid.content.pm.PackageManager;
importandroid.content.pm.IPackageInstallObserver;
importandroid.content.pm.PackageManager.NameNotFoundException;
importandroid.content.pm.PackageParser;
importandroid.net.Uri;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.util.DisplayMetrics;
importandroid.util.Log;
importandroid.os.FileUtils;

publicclass MyPackageInstaller {
privatestatic final String PACKAGE_NAME = "test.installservice";
privatefinal int INSTALL_COMPLETE = 1;
privateContext context;
Uri mPackageURI;
privatePackageParser.Package mPkgInfo;

privateHandler mHandler = newHandler() {
publicvoid handleMessage(Message msg) {
switch(msg.what) {
caseINSTALL_COMPLETE:
// finish the activity posting result
//setResultAndFinish(msg.arg1);
break;
default:
break;
}
}
};

voidsetResultAndFinish(intretCode) {
// Intent data = new Intent();
// setResult(retCode);
// finish();
}

publicMyPackageInstaller(Context c) {
this.context = c;
}

publicvoid installPackage() {
intinstallFlags = 0;
PackageManager pm = context.getPackageManager();
try{
PackageInfo pi = pm.getPackageInfo(
mPkgInfo.applicationInfo.packageName,
PackageManager.GET_UNINSTALLED_PACKAGES);
if(pi != null) {
// installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
installFlags |= 2;
}
}catch(NameNotFoundException e) {
}

String array[] = null;
try{
Runtime.getRuntime().exec("chmod 777 /data/data/" + PACKAGE_NAME);
Runtime.getRuntime().exec(
"chmod 777 /data/data/" + PACKAGE_NAME + "/files");
array = this.mPackageURI.toString().split("/");
System.out.println("array[last]->"+ array[array.length - 1]);
Runtime.getRuntime().exec(
"chmod 777 /data/data/" + PACKAGE_NAME + "/files/"
+ array[array.length - 1]);
}catch(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

PackageInstallObserver observer = newPackageInstallObserver();
pm.installPackage(mPackageURI, observer, installFlags, null);
// context.deleteFile(array[array.length-1]);
}

classPackageInstallObserver extendsIPackageInstallObserver.Stub {
publicvoid packageInstalled(String packageName, intreturnCode) {
Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);
msg.arg1 = returnCode;
mHandler.sendMessage(msg);
}
}

privateFile createTempPackageFile(String filePath) {
File tmpPackageFile;
inti = filePath.lastIndexOf("/");
String tmpFileName;
if(i != -1) {
tmpFileName = filePath.substring(i + 1);
}else{
tmpFileName = filePath;
}
FileOutputStream fos;
try{
// MODE_WORLD_READABLE=1
fos = context.openFileOutput(tmpFileName, 1);
}catch(FileNotFoundException e1) {
Log.e("Installer","Error opening file " + tmpFileName);
returnnull;
}
try{
fos.close();
}catch(IOException e) {
Log.e("Installer","Error opening file " + tmpFileName);
returnnull;
}
tmpPackageFile = context.getFileStreamPath(tmpFileName);
File srcPackageFile = newFile(filePath);
if(!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) {
returnnull;
}
returntmpPackageFile;
}

publicvoid makeTempCopyAndInstall(Uri mPackageURI) {
mPkgInfo = getPackageInfo(mPackageURI);
System.out.println("package="+ mPkgInfo.applicationInfo.packageName);
System.out.println("copy file=" + mPackageURI.getPath());
File mTmpFile = createTempPackageFile(mPackageURI.getPath());
if(mTmpFile == null) {
// display a dialog
Log.e("Installer",
"Error copying file locally. Failed Installation");
// showDialogInner(DLG_OUT_OF_SPACE);
return;
}
this.mPackageURI = Uri.parse("file://"+ mTmpFile.getPath());
}

publicPackageParser.Package getPackageInfo(Uri packageURI) {
finalString archiveFilePath = packageURI.getPath();
PackageParser packageParser = newPackageParser(archiveFilePath);
File sourceFile = newFile(archiveFilePath);
DisplayMetrics metrics = newDisplayMetrics();
metrics.setToDefaults();
returnpackageParser.parsePackage(sourceFile, archiveFilePath, metrics,
0);
}
}

在程序中的调用方式:this为Context,path为安装包的绝对路径

 

MyPackageInstaller mpi = newMyPackageInstaller(this);
mpi.makeTempCopyAndInstall(Uri.parse(path));
mpi.installPackage();

这种方式需要在源码下面编译apk,并将apk放入/system/app目录下面。

二.通过shell命令实现
首先,在java中实现安装和卸载apk的命令

publicclass PackageInstaller {

publicvoid unInstallApp(String packageName){
try{
Runtime.getRuntime().exec("pm uninstall "+packageName);
}catch(IOException e) {
e.printStackTrace();
}
}

publicvoid installApp(String appPath){
try{
Runtime.getRuntime().exec("pm install "+appPath);
}catch(IOException e) {
e.printStackTrace();
}
}

publicvoid reInstallApp(String appPath){
try{
Runtime.getRuntime().exec("pm install -r "+appPath);
}catch(IOException e) {
e.printStackTrace();
}
}

}
 

然后再源码环境下将该java程序编译为jar包
2.将编译好的jar包放入程序的assets目录下面,通过以下代码在程序中将该jar文件拷贝到/data/data/package/files/目录下面

try{
AssetManager assetManager = context.getResources().getAssets();
InputStream in = assetManager.open(JAR_NAME);
if(in == null) {
return;
}
intlength = in.available();
bytefileByte[] = newbyte[length];
in.read(fileByte,0, fileByte.length);
in.close();
OutputStream out = context.openFileOutput(JAR_NAME,
Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
out.write(fileByte);
out.close();
}catch(Exception e) {
e.printStackTrace();
}

在有root权限的情况下,可以在shell中执行该jar包来进行安装和卸载:

String exportClassPath = "export CLASSPATH=/data/data/"
+ context.getPackageName() + "/files/installpackagejar.jar";

 

String INSTALL_ACTION_CMD = " exec app_process /system/bin packageName.StartMain install ";
publicboolean installApp(String path) {
File temp = newFile(path);
if(!temp.exists())
returnfalse;
String cmd[] = { exportClassPath, INSTALL_ACTION_CMD + path };
try{
consoleExec(cmd);
}catch(IOException e) {
e.printStackTrace();
returnfalse;
}
returntrue;
}
privatevoid consoleExec(String[] cmd) throwsIOException {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = newDataOutputStream(process.getOutputStream());
for(inti = 0; i < cmd.length; i++) {
os.writeBytes(cmd<i> + "\n");
}
os.writeBytes("exit\n");
os.flush();
os.close();
}
时间: 2024-10-22 23:03:12

android --静默安装的相关文章

android静默安装问题,求大神们进来指点。

问题描述 android静默安装问题,求大神们进来指点. 最新公司需求写一个静默安装的功能,本人在网上找了很多代码,也都在root过的手机里面实验过.但是没有用现在贴上代码Process process = Runtime.getRuntime().exec(""sh""); DataOutputStream dos = new DataOutputStream(process.getOutputStream()); cmd = String.valueOf(cmd

Android静默安装实现方案 仿360手机助手秒装和智能安装功能_Android

之前有很多朋友都问过我,在Android系统中怎样才能实现静默安装呢?所谓的静默安装,就是不用弹出系统的安装界面,在不影响用户任何操作的情况下不知不觉地将程序装好.虽说这种方式看上去不打搅用户,但是却存在着一个问题,因为Android系统会在安装界面当中把程序所声明的权限展示给用户看,用户来评估一下这些权限然后决定是否要安装该程序,但如果使用了静默安装的方式,也就没有地方让用户看权限了,相当于用户被动接受了这些权限.在Android官方看来,这显示是一种非常危险的行为,因此静默安装这一行为系统是

Android静默安装软件app代码(测试可用)

android手机在获得root权限之后,可以调用命令的方式静默安装软件,这一点体验是很不错,但是目前网络上关于android静默安装app的代码均出自一人之手,其中有一个非常sb的bug,借用代码的人居然都没有发现,导致网络上几乎所有关于android app静默安装的代码都是错误的.  代码如下 复制代码 new Thread() {      public void run() {      Process process = null;      OutputStream out = n

Android 静默安装实现方法

Android静默安装的方法,静默安装就是绕过安装程序时的提示窗口,直接在后台安装. 注意:静默安装的前提是设备有ROOT权限. 代码如下: /** * 静默安装 * @param file * @return */ public boolean slientInstall(File file) { boolean result = false; Process process = null; OutputStream out = null; try { process = Runtime.ge

android 静默安装-android 定制系统下的静默安装

问题描述 android 定制系统下的静默安装 目前的要求是在ACER-Z120手机上(该手机应该是基于android 4.1.1的定制系统)实现软件的静默安装.就是我要写一个控制软件来下载被控制软件,下载完了静默安装被控制软件.我的控制软件要执行 pm install 命令是不是要先得到该操作系统的platform..pk8 platform.x509.pem signapk.jar三个文件,用命令来对我的控制软件进行签名,在安装进入该手机?整个过程这样对吗? 解决方案 放在/system/a

android实现静默安装与卸载的方法_Android

本文实例讲述了android实现静默安装与卸载的方法.分享给大家供大家参考.具体如下: 方法1:[使用调用接口方法,由于安装卸载应用程序的部分API是隐藏的,所以必须下载Android系统源码,在源码下开发并编译之后使用MM命令编译生成APK文件] import java.io.File; import android.app.Activity; import android.os.Bundle; import android.content.Intent; import android.con

Android无需root实现apk的静默安装_Android

Android的静默安装似乎是一个很有趣很诱人的东西,但是,用普通做法,如果手机没有root权限的话,似乎很难实现静默安装,因为Android并不提供显示的Intent调用,一般是通过以下方式安装apk: Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startAct

非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名

非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名 最近自家的系统要做一个升级服务,里面有三个功能,第一个是系统升级,也就是下载OTA包推送到recovery里升级的,而第二个是MCU升级,这就涉及到我们自家系统的一些情况了,而第三个就是应用升级了,领导要求不要骚扰用户,于是我就想到了静默安装了,因为我们的系统是在wifi环境下工作的,所以不担心流量哈,而且我们系统是没有ROOT的,所以我们肯定野不能使用RunTime方

java实现静默安装apk_Android

静默安装就是偷偷的把一个应用安装到手机上,就是屏蔽确认框,通过反射 只能写个主要的代码,这个是在linux编译用到,因为静默安装需要调用系统服务,在源码下编译,我也是搞了好久 InstallActivity.java package com.smart.Installback; import java.io.File; //import com.android.packageinstaller.R; import android.app.Activity; import android.os.B