静默顾名思义就是静静的默默地,静默安装和静默卸载的意思也就是说在后台默默地安装和卸载。
最近的一个app应用分发的项目中app下载的模块,下载完成之后,用户可以通过这个app进行安装,为了提高用户的体验,我就加入了静默安装和卸载功能,然后还加入了使用am命令启动某个Activity。
这个项目中静默的方式实现代码如下:
首先判断是否有root权限,如果有利用静默方式,否则利用意图实现app安装和卸载操作。
1 package com.example.test;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.PrintWriter;
6
7 import android.content.Context;
8 import android.content.Intent;
9 import android.net.Uri;
10
11 /**
12 * 描述: app安装操作
13 * @author 吴传龙
14 * Email:andywuchuanlong@sina.cn
15 * QQ: 3026862225
16 * @version 创建时间: 2015年3月6日 下午3:51:14
17 * @version 最后修改时间:2015年3月6日 下午3:51:14 修改人:吴传龙
18 */
19 public class ApkController {
20 /**
21 * 描述: 安装
22 * 修改人: 吴传龙
23 * 最后修改时间:2015年3月8日 下午9:07:50
24 */
25 public static boolean install(String apkPath,Context context){
26 // 先判断手机是否有root权限
27 if(hasRootPerssion()){
28 // 有root权限,利用静默安装实现
29 return clientInstall(apkPath);
30 }else{
31 // 没有root权限,利用意图进行安装
32 File file = new File(apkPath);
33 if(!file.exists())
34 return false;
35 Intent intent = new Intent();
36 intent.setAction("android.intent.action.VIEW");
37 intent.addCategory("android.intent.category.DEFAULT");
38 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
39 intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
40 context.startActivity(intent);
41 return true;
42 }
43 }
44
45 /**
46 * 描述: 卸载
47 * 修改人: 吴传龙
48 * 最后修改时间:2015年3月8日 下午9:07:50
49 */
50 public static boolean uninstall(String packageName,Context context){
51 if(hasRootPerssion()){
52 // 有root权限,利用静默卸载实现
53 return clientUninstall(packageName);
54 }else{
55 Uri packageURI = Uri.parse("package:" + packageName);
56 Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,packageURI);
57 uninstallIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
58 context.startActivity(uninstallIntent);
59 return true;
60 }
61 }
62
63 /**
64 * 判断手机是否有root权限
65 */
66 private static boolean hasRootPerssion(){
67 PrintWriter PrintWriter = null;
68 Process process = null;
69 try {
70 process = Runtime.getRuntime().exec("su");
71 PrintWriter = new PrintWriter(process.getOutputStream());
72 PrintWriter.flush();
73 PrintWriter.close();
74 int value = process.waitFor();
75 return returnResult(value);
76 } catch (Exception e) {
77 e.printStackTrace();
78 }finally{
79 if(process!=null){
80 process.destroy();
81 }
82 }
83 return false;
84 }
85
86 /**
87 * 静默安装
88 */
89 private static boolean clientInstall(String apkPath){
90 PrintWriter PrintWriter = null;
91 Process process = null;
92 try {
93 process = Runtime.getRuntime().exec("su");
94 PrintWriter = new PrintWriter(process.getOutputStream());
95 PrintWriter.println("chmod 777 "+apkPath);
96 PrintWriter.println("export LD_LIBRARY_PATH=/vendor/lib:/system/lib");
97 PrintWriter.println("pm install -r "+apkPath);
98 // PrintWriter.println("exit");
99 PrintWriter.flush();
100 PrintWriter.close();
101 int value = process.waitFor();
102 return returnResult(value);
103 } catch (Exception e) {
104 e.printStackTrace();
105 }finally{
106 if(process!=null){
107 process.destroy();
108 }
109 }
110 return false;
111 }
112
113 /**
114 * 静默卸载
115 */
116 private static boolean clientUninstall(String packageName){
117 PrintWriter PrintWriter = null;
118 Process process = null;
119 try {
120 process = Runtime.getRuntime().exec("su");
121 PrintWriter = new PrintWriter(process.getOutputStream());
122 PrintWriter.println("LD_LIBRARY_PATH=/vendor/lib:/system/lib ");
123 PrintWriter.println("pm uninstall "+packageName);
124 PrintWriter.flush();
125 PrintWriter.close();
126 int value = process.waitFor();
127 return returnResult(value);
128 } catch (Exception e) {
129 e.printStackTrace();
130 }finally{
131 if(process!=null){
132 process.destroy();
133 }
134 }
135 return false;
136 }
137
138 /**
139 * 启动app
140 * com.exmaple.client/.MainActivity
141 * com.exmaple.client/com.exmaple.client.MainActivity
142 */
143 public static boolean startApp(String packageName,String activityName){
144 boolean isSuccess = false;
145 String cmd = "am start -n " + packageName + "/" + activityName + " \n";
146 Process process = null;
147 try {
148 process = Runtime.getRuntime().exec(cmd);
149 int value = process.waitFor();
150 return returnResult(value);
151 } catch (Exception e) {
152 e.printStackTrace();
153 } finally{
154 if(process!=null){
155 process.destroy();
156 }
157 }
158 return isSuccess;
159 }
160
161
162 private static boolean returnResult(int value){
163 // 代表成功
164 if (value == 0) {
165 return true;
166 } else if (value == 1) { // 失败
167 return false;
168 } else { // 未知情况
169 return false;
170 }
171 }
172 }
1 package com.example.test;
2
3 import java.io.File;
4
5 import android.support.v4.app.Fragment;
6 import android.app.Activity;
7 import android.os.Bundle;
8 import android.os.Environment;
9 import android.view.LayoutInflater;
10 import android.view.Menu;
11 import android.view.MenuItem;
12 import android.view.View;
13 import android.view.ViewGroup;
14 import android.widget.Toast;
15 import android.os.Build;
16 /**
17 * 描述: MainActivity
18 * @author 吴传龙
19 * Email:andywuchuanlong@sina.cn
20 * QQ: 3026862225
21 * @version 创建时间: 2015年3月9日 上午8:19:19
22 * @version 最后修改时间:2015年3月9日 上午8:19:19 修改人:吴传龙
23 */
24 public class MainActivity extends Activity {
25
26 @Override
27 protected void onCreate(Bundle savedInstanceState) {
28 super.onCreate(savedInstanceState);
29 setContentView(R.layout.activity_main);
30 }
31
32 /**
33 * 描述: 安装
34 * @param
35 * 修改人: 吴传龙
36 * 最后修改时间:2015年3月9日 上午8:19:30
37 */
38 public void click1(View view){
39 new Thread(){
40 public void run() {
41 String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/jniTest.apk";
42 if (ApkController.install(path, getApplicationContext())){
43 toast("安裝成功");
44 }else{
45 toast("安裝失败");
46 }
47 };
48 }.start();
49 }
50
51 /**
52 * 描述: 卸载
53 * @param
54 * 修改人: 吴传龙
55 * 最后修改时间:2015年3月9日 上午8:19:30
56 */
57 public void click2(View view){
58 new Thread(){
59 public void run() {
60 if (ApkController.uninstall("com.example.jnitest", getApplicationContext())){
61 toast("卸載成功");
62 }else{
63 toast("卸載失败");
64 }
65 };
66 }.start();
67 }
68
69 /**
70 * 描述: 启动
71 * @param
72 * 修改人: 吴传龙
73 * 最后修改时间:2015年3月9日 上午8:19:30
74 */
75 public void click3(View view){
76 if (ApkController.startApp("com.example.jnitest","com.example.jnitest.MainActivity")) {
77 toast("啟動成功");
78 }
79 }
80
81
82 public void toast(final String text){
83 runOnUiThread(new Runnable() {
84 @Override
85 public void run() {
86 Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();;
87 }
88 });
89 }
90
91 }
要用其他的方式实现静默方式,可以通过伪装成系统应用,这就要给app打上系统应用的签名,但是这些签名在小米等手机上是没用的,所以这里不做介绍。还有就是通过把应用放在system/app的目录下也可以实现。