android --静默安装

简介: 【此篇文章为转载文章】最近需要实现Android应用的静默安装,在网上看了不少帖子,最后在root权限下实现对应用的静默安装和卸载,现在就整个实现的过程做一个总结。一.第一种方案第一种方案参考了源码中/packages/apps/PackageInstaller的实现方式,实现的主要代码如下: importjava.

【此篇文章为转载文章】

最近需要实现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();
}

相关文章
|
Android开发
android 静默安装
http://www.360doc.com/content/13/0922/15/9171956_316239845.shtml#
746 0
|
17天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
12 0
|
1月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
90 0
|
2月前
|
Android开发
安卓SO层开发 -- 编译指定平台的SO文件
安卓SO层开发 -- 编译指定平台的SO文件
29 0
|
1月前
|
设计模式 人工智能 开发工具
安卓应用开发:构建未来移动体验
【2月更文挑战第17天】 随着智能手机的普及和移动互联网技术的不断进步,安卓应用开发已成为一个热门领域。本文将深入探讨安卓平台的应用开发流程、关键技术以及未来发展趋势。通过分析安卓系统的架构、开发工具和框架,本文旨在为开发者提供全面的技术指导,帮助他们构建高效、创新的移动应用,以满足不断变化的市场需求。
18 1
|
1月前
|
机器学习/深度学习 调度 Android开发
安卓应用开发:打造高效通知管理系统
【2月更文挑战第14天】 在移动操作系统中,通知管理是影响用户体验的关键因素之一。本文将探讨如何在安卓平台上构建一个高效的通知管理系统,包括服务、频道和通知的优化策略。我们将讨论最新的安卓开发工具和技术,以及如何通过这些工具提高通知的可见性和用户互动性,同时确保不会对用户造成干扰。
31 1
|
9天前
|
XML 开发工具 Android开发
构建高效的安卓应用:使用Jetpack Compose优化UI开发
【4月更文挑战第7天】 随着Android开发不断进化,开发者面临着提高应用性能与简化UI构建流程的双重挑战。本文将探讨如何使用Jetpack Compose这一现代UI工具包来优化安卓应用的开发流程,并提升用户界面的流畅性与一致性。通过介绍Jetpack Compose的核心概念、与传统方法的区别以及实际集成步骤,我们旨在提供一种高效且可靠的解决方案,以帮助开发者构建响应迅速且用户体验优良的安卓应用。
|
17天前
|
Android开发
Android开发小技巧:怎样在 textview 前面加上一个小图标。
Android开发小技巧:怎样在 textview 前面加上一个小图标。
10 0
|
18天前
|
Android开发
Android 开发 pickerview 自定义选择器
Android 开发 pickerview 自定义选择器
10 0
|
24天前
|
Java Android开发
Android开发系列全套课程
本系列课程面向有java基础,想进入企业从事android开发的计算机专业者。学习搭配实战案例,高效掌握岗位知识。
16 1