静默顾名思义就是静静的默默地,静默安装和静默卸载的意思也就是说在后台默默地安装和卸载。
最近的一个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的目录下也可以实现。