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#
770 0
|
2月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
2月前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
45 1
|
3天前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
7天前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
1月前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
70 19
|
2月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
1月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
74 14
|
1月前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
1月前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
41 5

热门文章

最新文章