@写在前面的话     Android 要想静默安装app,必须是系统应用或者具有Root权限,否则根本不可能实现静默安装 转载自@苍痕

1.系统API 。不是静默安装

  1. Intent intent = new Intent(Intent.ACTION_VIEW);
  2. intent.setDataAndType(Uri.parse("file://" + apkFilePath), "application/vnd.android.package-archive");
  3. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  4. mContext.startActivity(intent);
2. 静默安装:利用ProcessBuilder
  1. /**
  2. * install slient
  3. *
  4. * @param filePath
  5. * @return 0 means normal, 1 means file not exist, 2 means other exception error
  6. */
  7. public static int installSilent(String filePath) {
  8. File file = new File(filePath);
  9. if (filePath == null || filePath.length() == 0 || file == null || file.length() <= 0 || !file.exists() || !file.isFile()) {
  10. return 1;
  11. }
  12. String[] args = { "pm", "install", "-r", filePath };
  13. ProcessBuilder processBuilder = new ProcessBuilder(args);
  14. Process process = null;
  15. BufferedReader successResult = null;
  16. BufferedReader errorResult = null;
  17. StringBuilder successMsg = new StringBuilder();
  18. StringBuilder errorMsg = new StringBuilder();
  19. int result;
  20. try {
  21. process = processBuilder.start();
  22. successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
  23. errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  24. String s;
  25. while ((s = successResult.readLine()) != null) {
  26. successMsg.append(s);
  27. }
  28. while ((s = errorResult.readLine()) != null) {
  29. errorMsg.append(s);
  30. }
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. } finally {
  36. try {
  37. if (successResult != null) {
  38. successResult.close();
  39. }
  40. if (errorResult != null) {
  41. errorResult.close();
  42. }
  43. } catch (IOException e) {
  44. e.printStackTrace();
  45. }
  46. if (process != null) {
  47. process.destroy();
  48. }
  49. }
  50. // TODO should add memory is not enough here
  51. if (successMsg.toString().contains("Success") || successMsg.toString().contains("success")) {
  52. result = 0;
  53. } else {
  54. result = 2;
  55. }
  56. Log.d("test-test", "successMsg:" + successMsg + ", ErrorMsg:" + errorMsg);
  57. return result;
  58. }

3. 静默安装:利用Runtime.getRuntime().exec()

[java] view plaincopy
  1. private static final String TAG = "test-test";
  2. private static final int TIME_OUT = 60 * 1000;
  3. private static String[] SH_PATH = {
  4. "/system/bin/sh",
  5. "/system/xbin/sh",
  6. "/system/sbin/sh"
  7. };
  8. public static boolean executeInstallCommand(String filePath) {
  9. String command = “pm install -r ” + filePath;
  10. Process process = null;
  11. DataOutputStream os = null;
  12. StringBuilder successMsg = new StringBuilder();
  13. StringBuilder errorMsg = new StringBuilder();
  14. BufferedReader successResult = null;
  15. BufferedReader errorResult = null;
  16. try {
  17. process = runWithEnv(getSuPath(), null);
  18. if (process == null) {
  19. return false;
  20. }
  21. successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
  22. errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  23. os = new DataOutputStream(process.getOutputStream());
  24. os.writeBytes(command + "\n");
  25. os.writeBytes("echo \"rc:\" $?\n");
  26. os.writeBytes("exit\n");
  27. os.flush();
  28. String s;
  29. while ((s = successResult.readLine()) != null) {
  30. successMsg.append(s);
  31. }
  32. while ((s = errorResult.readLine()) != null) {
  33. errorMsg.append(s);
  34. }
  35. // Handle a requested timeout, or just use waitFor() otherwise.
  36. if (TIME_OUT > 0) {
  37. long finish = System.currentTimeMillis() + TIME_OUT;
  38. while (true) {
  39. Thread.sleep(300);
  40. if (!isProcessAlive(process)) {
  41. break;
  42. }
  43. if (System.currentTimeMillis() > finish) {
  44. Log.w(TAG, "Process doesn't seem to stop on it's own, assuming it's hanging");
  45. // Note: 'finally' will call destroy(), but you might still see zombies.
  46. return true;
  47. }
  48. }
  49. } else {
  50. process.waitFor();
  51. }
  52. // In order to consider this a success, we require to things: a) a proper exit value, and ...
  53. if (process.exitValue() != 0) {
  54. return false;
  55. }
  56. return true;
  57. } catch (FileNotFoundException e) {
  58. Log.w(TAG, "Failed to run command, " + e.getMessage());
  59. return false;
  60. } catch (IOException e) {
  61. Log.w(TAG, "Failed to run command, " + e.getMessage());
  62. return false;
  63. } catch (InterruptedException e) {
  64. Log.w(TAG, "Failed to run command, " + e.getMessage());
  65. return false;
  66. } finally {
  67. if (os != null) {
  68. try {
  69. os.close();
  70. } catch (IOException e) {
  71. throw new RuntimeException(e);
  72. }
  73. }
  74. try {
  75. if (successResult != null) {
  76. successResult.close();
  77. }
  78. if (errorResult != null) {
  79. errorResult.close();
  80. }
  81. } catch (IOException e) {
  82. e.printStackTrace();
  83. }
  84. if (process != null) {
  85. try {
  86. // Yes, this really is the way to check if the process is still running.
  87. process.exitValue();
  88. } catch (IllegalThreadStateException e) {
  89. process.destroy();
  90. }
  91. }
  92. }
  93. }
  94. private static Process runWithEnv(String command, String[] customEnv) throws IOException {
  95. List<String> envList = new ArrayList<String>();
  96. Map<String, String> environment = System.getenv();
  97. if (environment != null) {
  98. for (Map.Entry<String, String> entry : environment.entrySet()) {
  99. envList.add(entry.getKey() + "=" + entry.getValue());
  100. }
  101. }
  102. if (customEnv != null) {
  103. for (String value : customEnv) {
  104. envList.add(value);
  105. }
  106. }
  107. String[] arrayEnv = null;
  108. if (envList.size() > 0) {
  109. arrayEnv = new String[envList.size()];
  110. for (int i = 0; i < envList.size(); i++) {
  111. arrayEnv[i] = envList.get(i);
  112. }
  113. }
  114. Process process = Runtime.getRuntime().exec(command, arrayEnv);
  115. return process;
  116. }
  117. /**
  118. * Check whether a process is still alive. We use this as a naive way to implement timeouts.
  119. */
  120. private static boolean isProcessAlive(Process p) {
  121. try {
  122. p.exitValue();
  123. return false;
  124. } catch (IllegalThreadStateException e) {
  125. return true;
  126. }
  127. }
  128. /** Get the SU file path if it exist */
  129. private static String getSuPath() {
  130. for (String p : SH_PATH) {
  131. File sh = new File(p);
  132. if (sh.exists()) {
  133. return p;
  134. }
  135. }
  136. return "su";
  137. }

4. 静默安装:利用反射调用API-PackageManager.installPackage()

[java] view plaincopy
  1. public static void installSilentWithReflection(Context context, String filePath) {
  2. try {
  3. PackageManager packageManager = context.getPackageManager();
  4. Method method = packageManager.getClass().getDeclaredMethod("installPackage",
  5. new Class[] {Uri.class, IPackageInstallObserver.class, int.class, String.class} );
  6. method.setAccessible(true);
  7. File apkFile = new File(filePath);
  8. Uri apkUri = Uri.fromFile(apkFile);
  9. method.invoke(packageManager, new Object[] {apkUri, new IPackageInstallObserver.Stub() {
  10. @Override
  11. public void packageInstalled(String pkgName, int resultCode) throws RemoteException {
  12. Log.d(TAG, "packageInstalled = " + pkgName + "; resultCode = " + resultCode) ;
  13. }
  14. }, Integer.valueOf(2), "com.ali.babasecurity.yunos"});
  15. //PackageManager.INSTALL_REPLACE_EXISTING = 2;
  16. } catch (NoSuchMethodException e) {
  17. e.printStackTrace();
  18. } catch (Exception e) {
  19. e.printStackTrace();
  20. }
  21. }

上面用到了反射调用,IPackageInstallObserver.class这个类在android sdk里面是没有的,您需要下载android_dependency.jar放到你工程的libs目录,这个jar提供了与PackageManager反射调用相关的类的定义。

注意:静默安装还需要在你的AndroidManifest.xml中添加权限声明。该权限默认赋予系统应用,第三方应用即使声明了,也拿不到该权限!
[html] view plaincopy
  1. <!-- 静默安装 -->
  2. <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
/**
 * 执行具体的静默安装逻辑,需要手机ROOT。
 * @param apkPath
 *          要安装的apk文件的路径
 * @return 安装成功返回true,安装失败返回false。
 */
public boolean install(String apkPath) {boolean result = false;
    DataOutputStream dataOutputStream = null;
    BufferedReader errorStream = null;
    try {// 申请su权限
        Process process = Runtime.getRuntime().exec("su");
        dataOutputStream = new DataOutputStream(process.getOutputStream());
        // 执行pm install命令
        String command = "pm install -r " + apkPath + "\n";
        dataOutputStream.write(command.getBytes(Charset.forName("utf-8")));
        dataOutputStream.flush();
        dataOutputStream.writeBytes("exit\n");
        dataOutputStream.flush();
        process.waitFor();
        errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        String msg = "";
        String line;
        // 读取命令的执行结果
        while ((line = errorStream.readLine()) != null) {msg += line;
        }Log.d("TAG", "install msg is " + msg);
        // 如果执行结果中包含Failure字样就认为是安装失败,否则就认为安装成功
        if (!msg.contains("Failure")) {result = true;
        }} catch (Exception e) {Log.e("TAG", e.getMessage(), e);
    } finally {try {if (dataOutputStream != null) {dataOutputStream.close();
            }if (errorStream != null) {errorStream.close();
            }} catch (IOException e) {Log.e("TAG", e.getMessage(), e);
        }}return result;
}

Android 静默安装的几种方式相关推荐

  1. android开启gps功能,android 打开GPS的几种方式

    1.在讨论打开gps的之前先看下如何检测gps的开关情况: 方式一: boolean gpsEnabled = locationManager.isProviderEnabled(LocationMa ...

  2. android ui 最新教程,Android更新UI的五种方式,androidui五种

    Android更新UI的五种方式,androidui五种handler.post activity.runOnUiThread view.post handler+Thread AsyncTask 例 ...

  3. 【Linux入门到精通系列讲解】Centos 7软件安装的三种方式

    centos 软件安装的三种方式 Linux下面安装软件的常见方法: 一.yum 替你下载软件 替你安装 替你解决依赖关系 点外卖 缺少的东西 外卖解决 1.方便 简单 2.没有办法深入修改 yum ...

  4. Eclipse插件安装的三种方式

    Eclipse插件安装总结通过个人的学习体会,将目前Eclipse插件安装的三种方式,总结如下: 第一种方法很简单,在Eclipse的主目录(%ECLIPSE_HOME%)下有一个plugins目录和 ...

  5. android实现后台静默安装,Android 静默安装实现方法

    Android静默安装的方法,静默安装就是绕过安装程序时的提示窗口,直接在后台安装. 注意:静默安装的前提是设备有ROOT权限. 代码如下: /** * 静默安装 * @param file * @r ...

  6. android注册广播两种方式,Android 注册广播的两种方式对比

    Android 注册广播的两种方式对比 1.常驻型广播 常驻型广播,当你的应用程序关闭了,如果有广播信息来,你写的广播接收器同样的能接受到, 他的注册方式就是在你的应用程序中的AndroidManif ...

  7. 【转】Linux下软件安装的几种方式

    转自Linux下软件安装的几种方式 Linux 系统的/usr目录 Linux 软件安装到哪里合适,目录详解 Linux 的软件安装目录是也是有讲究的,理解这一点,在对系统管理是有益的 /usr:系统 ...

  8. mysql安装方法_MySQL安装的三种方式

    MySQL安装的三种方式 Mysql安装方式对比 安装方式 安装简易度 使用简易度 定制化程度 适合范围 rpm包安装 简单 简单 低 仅适合redhat/centos系列linux 二进制安装 安装 ...

  9. android 图片方法,分享实现Android图片选择的两种方式

    Android选择图片的两种方式: 第一种:单张选取 通过隐式启动activity,跳转到相册选择一张返回结果 关键代码如下: 发送请求: private static final int PICTU ...

  10. android使用其他应用打开方式,Android 启动activity的4种方式及打开其他应用的activity的坑...

    Android启动的四种方式分别为standard,singleTop,singleTask,singleInstence. standard是最常见的activity启动方式,也是默认的启动的方式. ...

最新文章

  1. 使用Repeater的Template
  2. 真是祸从GPT-2口出,和AI聊会天,把别人隐私都给套出来了
  3. python包管理器修改镜像地址
  4. 程序员面对下列技术问题,如何做决策
  5. Android 抓包的一些命令 及 adb使用的一些注意事项
  6. 超级usb万能启动盘
  7. 使用webpack、babel、react、antdesign配置单页面应用开发环境
  8. android gdb 远程调试工具,gdb输入/输出错误远程调试到Android
  9. [转]Win XP常遇网络故障分析:局域网问题
  10. Ubuntu16.04+ ROS kinetic 使用kinect2 ORK功能包 linemod算法实现可乐罐识别
  11. 设施规划选址——重心法
  12. 安师大计算机专业排名多少,安师大的计算机专业怎么样
  13. 讯飞智能语音鼠标G50:AI语音、转写翻译、记录截图一键搞定!
  14. 麒麟系统开发笔记(一):国产麒麟系统搭建开发环境之虚拟机安装
  15. 《数据访问 - 第01章 文件 - 文件和流的概念》
  16. STC51单片机20——DS1302可调电子时钟1602显示proteus仿真
  17. 弹性力学第五版pdf_弹性力学5-圣维南原理.pdf
  18. sat求解器解哈密顿回路
  19. 重磅 l 全国首例微信三级分销被认定为传销,三级分销“身世”揭秘(下)
  20. 《Android源码设计模式解析与实战》读书笔记(十三)

热门文章

  1. 浅析new一个对象的过程
  2. 从社区报告看未来20年美国AI研究战略
  3. Zemax自学--2(Zemax软件总览)
  4. IT资源专业搜索-www.easysoo.cn
  5. ZEMAX | 如何使用渐晕系数
  6. 前端与移动开发----微信小程序----小程序(一)
  7. 哈夫模型-arcgis
  8. java正则表达式中的斜杠,java正则表达式匹配斜杠[Java编程]
  9. 新能源车提车、上牌流程
  10. 弱监督学习总结(1)