Android应用的静默安装
来源:互联网 发布:visio2016 数据库建模 编辑:程序博客网 时间:2024/05/17 17:14
最近需要实现Android应用的静默安装,在网上看了不少帖子,最后在root权限下实现对应用的静默安装和卸载,现在就整个实现的过程做一个总结。
一.第一种方案
第一种方案参考了源码中/packages/apps/PackageInstaller的实现方式,实现的主要代码如下:
在程序中的调用方式:this为Context,path为安装包的绝对路径
这种方式需要在源码下面编译apk,并将apk放入/system/app目录下面。
二.通过shell命令实现
首先,在java中实现安装和卸载apk的命令
然后再源码环境下将该java程序编译为jar包
2.将编译好的jar包放入程序的assets目录下面,通过以下代码在程序中将该jar文件拷贝到/data/data/package/files/目录下面
在有root权限的情况下,可以在shell中执行该jar包来进行安装和卸载:
一.第一种方案
第一种方案参考了源码中/packages/apps/PackageInstaller的实现方式,实现的主要代码如下:
001
import
java.io.File;
002
import
java.io.FileNotFoundException;
003
import
java.io.FileOutputStream;
004
import
java.io.IOException;
005
import
android.content.Context;
006
import
android.content.Intent;
007
import
android.content.pm.PackageInfo;
008
import
android.content.pm.PackageManager;
009
import
android.content.pm.IPackageInstallObserver;
010
import
android.content.pm.PackageManager.NameNotFoundException;
011
import
android.content.pm.PackageParser;
012
import
android.net.Uri;
013
import
android.os.Handler;
014
import
android.os.Message;
015
import
android.util.DisplayMetrics;
016
import
android.util.Log;
017
import
android.os.FileUtils;
018
019
public
class
MyPackageInstaller {
020
private
static
final
String PACKAGE_NAME =
"test.installservice"
;
021
private
final
int
INSTALL_COMPLETE =
1
;
022
private
Context context;
023
Uri mPackageURI;
024
private
PackageParser.Package mPkgInfo;
025
026
private
Handler mHandler =
new
Handler() {
027
public
void
handleMessage(Message msg) {
028
switch
(msg.what) {
029
case
INSTALL_COMPLETE:
030
// finish the activity posting result
031
//setResultAndFinish(msg.arg1);
032
break
;
033
default
:
034
break
;
035
}
036
}
037
};
038
039
void
setResultAndFinish(
int
retCode) {
040
// Intent data = new Intent();
041
// setResult(retCode);
042
// finish();
043
}
044
045
public
MyPackageInstaller(Context c) {
046
this
.context = c;
047
}
048
049
public
void
installPackage() {
050
int
installFlags =
0
;
051
PackageManager pm = context.getPackageManager();
052
try
{
053
PackageInfo pi = pm.getPackageInfo(
054
mPkgInfo.applicationInfo.packageName,
055
PackageManager.GET_UNINSTALLED_PACKAGES);
056
if
(pi !=
null
) {
057
// installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
058
installFlags |=
2
;
059
}
060
}
catch
(NameNotFoundException e) {
061
}
062
063
String array[] =
null
;
064
try
{
065
Runtime.getRuntime().exec(
"chmod 777 /data/data/"
+ PACKAGE_NAME);
066
Runtime.getRuntime().exec(
067
"chmod 777 /data/data/"
+ PACKAGE_NAME +
"/files"
);
068
array =
this
.mPackageURI.toString().split(
"/"
);
069
System.out.println(
"array[last]->"
+ array[array.length -
1
]);
070
Runtime.getRuntime().exec(
071
"chmod 777 /data/data/"
+ PACKAGE_NAME +
"/files/"
072
+ array[array.length -
1
]);
073
}
catch
(IOException e) {
074
// TODO Auto-generated catch block
075
e.printStackTrace();
076
}
077
078
PackageInstallObserver observer =
new
PackageInstallObserver();
079
pm.installPackage(mPackageURI, observer, installFlags,
null
);
080
// context.deleteFile(array[array.length-1]);
081
}
082
083
class
PackageInstallObserver
extends
IPackageInstallObserver.Stub {
084
public
void
packageInstalled(String packageName,
int
returnCode) {
085
Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);
086
msg.arg1 = returnCode;
087
mHandler.sendMessage(msg);
088
}
089
}
090
091
private
File createTempPackageFile(String filePath) {
092
File tmpPackageFile;
093
int
i = filePath.lastIndexOf(
"/"
);
094
String tmpFileName;
095
if
(i != -
1
) {
096
tmpFileName = filePath.substring(i +
1
);
097
}
else
{
098
tmpFileName = filePath;
099
}
100
FileOutputStream fos;
101
try
{
102
// MODE_WORLD_READABLE=1
103
fos = context.openFileOutput(tmpFileName,
1
);
104
}
catch
(FileNotFoundException e1) {
105
Log.e(
"Installer"
,
"Error opening file "
+ tmpFileName);
106
return
null
;
107
}
108
try
{
109
fos.close();
110
}
catch
(IOException e) {
111
Log.e(
"Installer"
,
"Error opening file "
+ tmpFileName);
112
return
null
;
113
}
114
tmpPackageFile = context.getFileStreamPath(tmpFileName);
115
File srcPackageFile =
new
File(filePath);
116
if
(!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) {
117
return
null
;
118
}
119
return
tmpPackageFile;
120
}
121
122
public
void
makeTempCopyAndInstall(Uri mPackageURI) {
123
mPkgInfo = getPackageInfo(mPackageURI);
124
System.out.println(
"package="
+ mPkgInfo.applicationInfo.packageName);
125
System.out.println(
"copy file="
+ mPackageURI.getPath());
126
File mTmpFile = createTempPackageFile(mPackageURI.getPath());
127
if
(mTmpFile ==
null
) {
128
// display a dialog
129
Log.e(
"Installer"
,
130
"Error copying file locally. Failed Installation"
);
131
// showDialogInner(DLG_OUT_OF_SPACE);
132
return
;
133
}
134
this
.mPackageURI = Uri.parse(
"file://"
+ mTmpFile.getPath());
135
}
136
137
public
PackageParser.Package getPackageInfo(Uri packageURI) {
138
final
String archiveFilePath = packageURI.getPath();
139
PackageParser packageParser =
new
PackageParser(archiveFilePath);
140
File sourceFile =
new
File(archiveFilePath);
141
DisplayMetrics metrics =
new
DisplayMetrics();
142
metrics.setToDefaults();
143
return
packageParser.parsePackage(sourceFile, archiveFilePath, metrics,
144
0
);
145
}
146
}
在程序中的调用方式:this为Context,path为安装包的绝对路径
1
MyPackageInstaller mpi =
new
MyPackageInstaller(
this
);
2
mpi.makeTempCopyAndInstall(Uri.parse(path));
3
mpi.installPackage();
这种方式需要在源码下面编译apk,并将apk放入/system/app目录下面。
二.通过shell命令实现
首先,在java中实现安装和卸载apk的命令
01
public
class
PackageInstaller {
02
03
public
void
unInstallApp(String packageName){
04
try
{
05
Runtime.getRuntime().exec(
"pm uninstall "
+packageName);
06
}
catch
(IOException e) {
07
e.printStackTrace();
08
}
09
}
10
11
public
void
installApp(String appPath){
12
try
{
13
Runtime.getRuntime().exec(
"pm install "
+appPath);
14
}
catch
(IOException e) {
15
e.printStackTrace();
16
}
17
}
18
19
public
void
reInstallApp(String appPath){
20
try
{
21
Runtime.getRuntime().exec(
"pm install -r "
+appPath);
22
}
catch
(IOException e) {
23
e.printStackTrace();
24
}
25
}
26
27
}
01
public
class
StartMain {
02
03
private
static
final
String INSTALL_ACTION_LABEL =
"install"
;
04
private
static
final
String REINSTALL_ACTION_LABEL =
"reinstall"
;
05
private
static
final
String UNINSTALL_ACTION_LABEL =
"uninstall"
;
06
07
public
static
void
main(String args[]){
08
if
(args==
null
||args.length<
2
)
return
;
09
PackageInstaller pi=
new
PackageInstaller();
10
if
(args[
0
].equals(INSTALL_ACTION_LABEL)){
11
pi.installApp(args[
1
]);
12
}
13
if
(args[
0
].equals(REINSTALL_ACTION_LABEL)){
14
pi.reInstallApp(args[
1
]);
15
}
16
else
if
(args[
0
].equals(UNINSTALL_ACTION_LABEL)){
17
pi.unInstallApp(args[
1
]);
18
}
19
}
20
21
}
然后再源码环境下将该java程序编译为jar包
2.将编译好的jar包放入程序的assets目录下面,通过以下代码在程序中将该jar文件拷贝到/data/data/package/files/目录下面
01
try
{
02
AssetManager assetManager = context.getResources().getAssets();
03
InputStream in = assetManager.open(JAR_NAME);
04
if
(in ==
null
) {
05
return
;
06
}
07
int
length = in.available();
08
byte
fileByte[] =
new
byte
[length];
09
in.read(fileByte,
0
, fileByte.length);
10
in.close();
11
OutputStream out = context.openFileOutput(JAR_NAME,
12
Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
13
out.write(fileByte);
14
out.close();
15
}
catch
(Exception e) {
16
e.printStackTrace();
17
}
在有root权限的情况下,可以在shell中执行该jar包来进行安装和卸载:
1
String exportClassPath =
"export CLASSPATH=/data/data/"
2
+ context.getPackageName() +
"/files/installpackagejar.jar"
;
1
String INSTALL_ACTION_CMD =
" exec app_process /system/bin packageName.StartMain install "
;
01
public
boolean
installApp(String path) {
02
File temp =
new
File(path);
03
if
(!temp.exists())
04
return
false
;
05
String cmd[] = { exportClassPath, INSTALL_ACTION_CMD + path };
06
try
{
07
consoleExec(cmd);
08
}
catch
(IOException e) {
09
e.printStackTrace();
10
return
false
;
11
}
12
return
true
;
13
}
01
private
void
consoleExec(String[] cmd)
throws
IOException {
02
Process process = Runtime.getRuntime().exec(
"su"
);
03
DataOutputStream os =
new
DataOutputStream(process.getOutputStream());
04
for
(
int
i =
0
; i < cmd.length; i++) {
05
os.writeBytes(cmd<i> +
"\n"
);
06
}
07
os.writeBytes(
"exit\n"
);
08
os.flush();
09
os.close();
10
}
0 0
- Android应用的静默安装
- android应用的安装之静默安装
- Android静默安装应用
- Android静默安装应用
- Android静默安装应用
- Android--应用静默安装
- 如何实现Android应用的静默安装
- 如何实现android应用的静默安装
- 如何实现Android应用的静默安装
- 如何实现Android应用的静默安装
- 如何实现Android应用的静默安装
- Android中实现应用的静默安装
- android应用静默安装方法
- android的静默安装
- Android的静默安装
- android应用后台安装,静默安装的代码实现方法
- android应用后台安装,静默安装的代码实现方法
- android应用后台安装,静默安装的代码实现方法
- 通过ODBC与MySQL进行数据交互
- 考研一周总结汇报
- htmlt你要注意的几点
- Android应用启动另一个应用
- 基于“好莱坞原则”的分布式文件存储系统
- Android应用的静默安装
- JAVA堆栈(转载)
- ulimit -c unlimited
- (5)QlikView中的RowNo()函数
- siwft初学(一)
- PHP----JS相互调用
- 永勤科技 熙睿平台介绍
- 发布端口
- sqlserver备份DB的windows permission问题