1,安装方法有:
1),Intent 方式:
private void install(File f){ Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(android.content.Intent.ACTION_VIEW); String type = getMIMEType(f); intent.setDataAndType(Uri.fromFile(f), type); context.startActivity(intent); } /** * 获取文件类型 * @Title: getMIMEType * @Description: * @param @param f * @param @return * @return String * @throws * @date 2013-8-23 下午5:13:06 */ private static String getMIMEType(File f){ String type = ""; String fName = f.getName(); String end = fName.substring(fName.lastIndexOf(".")+1, fName.length()).toLowerCase(); if(end.equals("m4a")||end.equals("mp4")||end.equals("mid")||end.equals("xmf")||end.equals("ogg")||end.equals("wav")){ type = "audio"; }else if(end.equals("3gp")||end.equals("mp4")){ type = "video"; }else if(end.equals("jpg")||end.equals("gif")||end.equals("png")||end.equals("jpeg")||end.equals("bmp")){ type = "image"; }else if(end.equals("apk")){ type = "application/vnd.android.package-archive"; }else{ type = "/*"; } return type; }
这种方式需要考虑一个问题:如果设置中是否安装应用商店外的选项,用户选择了否,那系统安装程序会引导用户是否设置,如果设置完了,不会回到安装界面,如果取消也就取消了。所以,应该判断设置中该选项的值,如有必要引导用户设置,用户设置完成后,如果允许安装,则回到安装界面。
改进后:
private void install1(File f) { int result = Settings.Secure.getInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 0); if (0 == result) { Toast.makeText(context, "请设置安装...", 1).show(); Intent it = new Intent(); it.setAction(Settings.ACTION_APPLICATION_SETTINGS); startActivityForResult(it, 1); return; } Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(android.content.Intent.ACTION_VIEW); String type = getMIMEType(f); intent.setDataAndType(Uri.fromFile(f), type); context.startActivity(intent); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1) { int result = Settings.Secure.getInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 0); if (result == 1) { install1(f); } else { Toast.makeText(context, "无法安装,bye-bye", 1).show(); } } }
2),这种方式需要申请权限:android.permission.INSTALL_PACKAGES,
sdk 已经屏蔽PackageInstallObserver 类,系统应用(安装在/system/app下面)可以采用该方式,第三方应用无法申请安装卸载权限。
Uri mPackageURI = Uri.fromFile(new File(Environment.getExternalStorageDirectory() + apkName)); int installFlags = 0; PackageManager pm = getPackageManager(); try{ PackageInfo pi = pm.getPackageInfo(packageName,PackageManager.GET_UNINSTALLED_PACKAGES); if(pi != null) { installFlags |= PackageManager.REPLACE_EXISTING_PACKAGE; } }catch (NameNotFoundException e){ } PackageInstallObserver observer = new PackageInstallObserver(); pm.installPackage(mPackageURI, observer, installFlags);
adb install xxx.apk
4,静默安装
参考:http://www.eoeandroid.com/thread-238338-1-1.html?_dsign=b0edbb6a
参考:http://blog.csdn.net/sodino/article/details/6238818
http://lhc180.blog.51cto.com/316940/757331
最近需要实现Android应用的静默安装,在网上看了不少帖子,最后在root权限下实现对应用的静默安装和卸载,现在就整个实现的过程做一个总结。
一.第一种方案
第一种方案参考了源码中/packages/apps/PackageInstaller的实现方式,实现的主要代码如下:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
import
java.io.File;
import
java.io.FileNotFoundException;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
android.content.Context;
import
android.content.Intent;
import
android.content.pm.PackageInfo;
import
android.content.pm.PackageManager;
import
android.content.pm.IPackageInstallObserver;
import
android.content.pm.PackageManager.NameNotFoundException;
import
android.content.pm.PackageParser;
import
android.net.Uri;
import
android.os.Handler;
import
android.os.Message;
import
android.util.DisplayMetrics;
import
android.util.Log;
import
android.os.FileUtils;
public
class
MyPackageInstaller {
private
static
final
String PACKAGE_NAME =
"test.installservice"
;
private
final
int
INSTALL_COMPLETE =
1
;
private
Context context;
Uri mPackageURI;
private
PackageParser.Package mPkgInfo;
private
Handler mHandler =
new
Handler() {
public
void
handleMessage(Message msg) {
switch
(msg.what) {
case
INSTALL_COMPLETE:
// finish the activity posting result
//setResultAndFinish(msg.arg1);
break
;
default
:
break
;
}
}
};
void
setResultAndFinish(
int
retCode) {
// Intent data = new Intent();
// setResult(retCode);
// finish();
}
public
MyPackageInstaller(Context c) {
this
.context = c;
}
public
void
installPackage() {
int
installFlags =
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 =
new
PackageInstallObserver();
pm.installPackage(mPackageURI, observer, installFlags,
null
);
// context.deleteFile(array[array.length-1]);
}
class
PackageInstallObserver
extends
IPackageInstallObserver.Stub {
public
void
packageInstalled(String packageName,
int
returnCode) {
Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);
msg.arg1 = returnCode;
mHandler.sendMessage(msg);
}
}
private
File createTempPackageFile(String filePath) {
File tmpPackageFile;
int
i = 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);
return
null
;
}
try
{
fos.close();
}
catch
(IOException e) {
Log.e(
"Installer"
,
"Error opening file "
+ tmpFileName);
return
null
;
}
tmpPackageFile = context.getFileStreamPath(tmpFileName);
File srcPackageFile =
new
File(filePath);
if
(!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) {
return
null
;
}
return
tmpPackageFile;
}
public
void
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());
}
public
PackageParser.Package getPackageInfo(Uri packageURI) {
final
String archiveFilePath = packageURI.getPath();
PackageParser packageParser =
new
PackageParser(archiveFilePath);
File sourceFile =
new
File(archiveFilePath);
DisplayMetrics metrics =
new
DisplayMetrics();
metrics.setToDefaults();
return
packageParser.parsePackage(sourceFile, archiveFilePath, metrics,
0
);
}
}
|
01
02
03
|
MyPackageInstaller mpi =
new
MyPackageInstaller(
this
);
mpi.makeTempCopyAndInstall(Uri.parse(path));
mpi.installPackage();
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public
class
PackageInstaller {
public
void
unInstallApp(String packageName){
try
{
Runtime.getRuntime().exec(
"pm uninstall "
+packageName);
}
catch
(IOException e) {
e.printStackTrace();
}
}
public
void
installApp(String appPath){
try
{
Runtime.getRuntime().exec(
"pm install "
+appPath);
}
catch
(IOException e) {
e.printStackTrace();
}
}
public
void
reInstallApp(String appPath){
try
{
Runtime.getRuntime().exec(
"pm install -r "
+appPath);
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
public
class
StartMain {
private
static
final
String INSTALL_ACTION_LABEL =
"install"
;
private
static
final
String REINSTALL_ACTION_LABEL =
"reinstall"
;
private
static
final
String UNINSTALL_ACTION_LABEL =
"uninstall"
;
public
static
void
main(String args[]){
if
(args==
null
||args.length<
2
)
return
;
PackageInstaller pi=
new
PackageInstaller();
if
(args[
0
].equals(INSTALL_ACTION_LABEL)){
pi.installApp(args[
1
]);
}
if
(args[
0
].equals(REINSTALL_ACTION_LABEL)){
pi.reInstallApp(args[
1
]);
}
else
if
(args[
0
].equals(UNINSTALL_ACTION_LABEL)){
pi.unInstallApp(args[
1
]);
}
}
}
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
try
{
AssetManager assetManager = context.getResources().getAssets();
InputStream in = assetManager.open(JAR_NAME);
if
(in ==
null
) {
return
;
}
int
length = in.available();
byte
fileByte[] =
new
byte
[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();
}
|
01
02
|
String exportClassPath =
"export CLASSPATH=/data/data/"
+ context.getPackageName() +
"/files/installpackagejar.jar"
;
|
01
|
String INSTALL_ACTION_CMD =
" exec app_process /system/bin packageName.StartMain install "
;
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public
boolean
installApp(String path) {
File temp =
new
File(path);
if
(!temp.exists())
return
false
;
String cmd[] = { exportClassPath, INSTALL_ACTION_CMD + path };
try
{
consoleExec(cmd);
}
catch
(IOException e) {
e.printStackTrace();
return
false
;
}
return
true
;
}
|
01
02
03
04
05
06
07
08
09
10
|
private
void
consoleExec(String[] cmd)
throws
IOException {
Process process = Runtime.getRuntime().exec(
"su"
);
DataOutputStream os =
new
DataOutputStream(process.getOutputStream());
for
(
int
i =
0
; i < cmd.length; i++) {
os.writeBytes(cmd<i> +
"\n"
);
}
os.writeBytes(
"exit\n"
);
os.flush();
os.close();
}</i>
|
卸载:
private void uninstall_1(String pkgName) {
Uri packageURI = Uri.parse("package:" + pkgName);
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
startActivity(uninstallIntent);
}