分类: Android 2013-02-14 14:13 1762人阅读 评论(10) 收藏 举报

最近在android 4.0.4系统下实现apk的静默安装和启动的功能,这里和大家分享一下,希望能有所帮助。

源码如下:

  1. import java.io.DataOutputStream;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.io.OutputStream;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. import android.content.Context;
  8. import android.content.Intent;
  9. import android.content.pm.ActivityInfo;
  10. import android.content.pm.PackageInfo;
  11. import android.content.pm.PackageManager;
  12. import android.content.pm.ResolveInfo;
  13. public class InstallApkUtils {
  14. public static void installAndStartApk(final Context context, final String apkPath) {
  15. if ((apkPath==null) || (context==null)) {
  16. return;
  17. }
  18. File file = new File(apkPath);
  19. if (file.exists() == false) {
  20. return;
  21. }
  22. new Thread() {
  23. public void run() {
  24. String packageName = getUninstallApkPackageName(context, apkPath);
  25. if (silentInstall(apkPath)) {
  26. List<ResolveInfo> matches = findActivitiesForPackage(context, packageName);
  27. if ((matches!=null) && (matches.size()>0)) {
  28. ResolveInfo resolveInfo = matches.get(0);
  29. ActivityInfo activityInfo = resolveInfo.activityInfo;
  30. startApk(activityInfo.packageName, activityInfo.name);
  31. }
  32. }
  33. };
  34. }.start();
  35. }
  36. public static String getUninstallApkPackageName(Context context, String apkPath) {
  37. String packageName = null;
  38. if (apkPath == null) {
  39. return packageName;
  40. }
  41. PackageManager pm = context.getPackageManager();
  42. PackageInfo info = pm.getPackageArchiveInfo(apkPath,
  43. PackageManager.GET_ACTIVITIES);
  44. if (info == null) {
  45. return packageName;
  46. }
  47. packageName = info.packageName;
  48. return packageName;
  49. }
  50. public static List<ResolveInfo> findActivitiesForPackage(Context context, String packageName) {
  51. final PackageManager pm = context.getPackageManager();
  52. final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
  53. mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
  54. mainIntent.setPackage(packageName);
  55. final List<ResolveInfo> apps = pm.queryIntentActivities(mainIntent, 0);
  56. return apps != null ? apps : new ArrayList<ResolveInfo>();
  57. }
  58. public static boolean silentInstall(String apkPath) {
  59. String cmd1 = "chmod 777 " + apkPath + " \n";
  60. String cmd2 = "LD_LIBRARY_PATH=/vendor/lib:/system/lib pm install -r " + apkPath + " \n";
  61. return execWithSID(cmd1, cmd2);
  62. }
  63. private static boolean execWithSID(String... args) {
  64. boolean isSuccess = false;
  65. Process process = null;
  66. OutputStream out = null;
  67. try {
  68. process = Runtime.getRuntime().exec("su");
  69. out = process.getOutputStream();
  70. DataOutputStream dataOutputStream = new DataOutputStream(out);
  71. for (String tmp : args) {
  72. dataOutputStream.writeBytes(tmp);
  73. }
  74. dataOutputStream.flush(); // 提交命令
  75. dataOutputStream.close(); // 关闭流操作
  76. out.close();
  77. isSuccess = waitForProcess(process);
  78. } catch (IOException e) {
  79. e.printStackTrace();
  80. }
  81. return isSuccess;
  82. }
  83. public static boolean startApk(String packageName, String activityName) {
  84. boolean isSuccess = false;
  85. String cmd = "am start -n " + packageName + "/" + activityName + " \n";
  86. try {
  87. Process process = Runtime.getRuntime().exec(cmd);
  88. isSuccess = waitForProcess(process);
  89. } catch (IOException e) {
  90. NLog.i(TAG, e.getMessage());
  91. e.printStackTrace();
  92. }
  93. return isSuccess;
  94. }
  95. private static boolean waitForProcess(Process p) {
  96. boolean isSuccess = false;
  97. int returnCode;
  98. try {
  99. returnCode = p.waitFor();
  100. switch (returnCode) {
  101. case 0:
  102. isSuccess = true;
  103. break;
  104. case 1:
  105. break;
  106. default:
  107. break;
  108. }
  109. } catch (InterruptedException e) {
  110. e.printStackTrace();
  111. }
  112. return isSuccess;
  113. }
  114. }

如果要使用,还需以下步骤:

1、在AndroidManifest.xml文件里添加如下权限:

<uses-permission android:name="android.permission.INSTALL_PACKAGES" />

2、进行系统签名。命令如下:

java -jar signapk.jar platform.x509.pem platform.pk8    XXX.apk    Signed_XXX.apk

备注:一般可在源码的目录\out\host\linux-x86\framework\下找到signapk.jar,在\build\target\product\security下找到签名文件platform.x509.pem和platform.pk8。

好了,现在大功告成!!!

android 4.0.4系统下实现apk的静默安装和启动的更多相关文章

  1. aix系统下的websphere的静默安装

     一:环境 aix5.3,websphere6(ND版本,WebSphereV6.1_for_AIX_64-bit_Support.tar),注意:aix和websphere的版本问题 二:安装 ...

  2. Linux 系统下用源码包安装软件

    Linux系统下用源码包安装软件 by:授客 QQ:1033553122 下载源码安装包,解压或者直接双击打开(如果有安装zip或rar等压缩/解压缩软件的话),查找相关的安装说明文件,一般是READ ...

  3. Linux下如何查看tomcat是否安装、启动、文件路径、进程ID

    Linux下如何查看tomcat是否安装.启动.文件路径.进程ID 在Linux系统下,Tomcat使用命令的操作! 检测是否有安装了Tomcat: rpm -qa|grep tomcat 查看Tom ...

  4. Android 7.0 调取系统相机崩溃解决android.os.FileUriExposedException

    一.写在前面 最近由于廖子尧忙于自己公司的事情和OkGo(一款专注于让网络请求更简单的网络框架) ,故让LZ 接替维护ImagePicker(一款支持单.多选.旋转和裁剪的图片选择器),也是处理了诸多 ...

  5. 【适配整理】Android 7.0 调取系统相机崩溃解决android.os.FileUriExposedException

    一.写在前面 最近由于廖子尧忙于自己公司的事情和 OkGo (一款专注于让网络请求更简单的网络框架) ,故让LZ 接替维护 ImagePicker(一款支持单.多选.旋转和裁剪的图片选择器),也是处理 ...

  6. 【转】android 5.0 64bit系统加载库文件失败问题浅析

    原文网址:http://blog.csdn.net/andrewblog/article/details/43601303 最近公司的一个项目使用android 5.0 64 bit平台,相对以前版本 ...

  7. Android 5.0以下系统支持TLS 1.1/1.2协议版本

    一.背景 项目中,客户端与服务端之间普遍使用Https协议通信,突然接到测试同事反馈Android5.0以下手机上,App测试服使用出现问题,出现SSL handshake aborted错误信息,但 ...

  8. 关于 Android 5.0 原生系统网络图标上的感叹号问题解决方法

    解决方案 adb shell settings put global captive_portal_server g.cn 参考 关于 android 5.0 网络图标上的感叹号及其解决办法

  9. Linux系统下Apache2.4.17的安装过程

    Linux系统下安装Apache Server2.4.17.还是先声明一下,Linux命令我不进行讲解,因为我不是讲Linux命令的.有需要注意的地方,我会上图,没什么值得的注意的地方,我就不上图了. ...

随机推荐

  1. Re-install Flyme or Native Google Android on Meizu MX4 Ubuntu (by quqi99)

    作者:张华 发表于:2017-06-23 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) ## ...

  2. node.js之npm库

    npm库安装可分为本地安装和全局安装,本地安装如下: npm install <Module name> 但是好像会出问题,官方貌似推荐全局安装,so 全局安装官方所给命令如下: npm ...

  3. linux 下看所有用户 及所有组

    俺的centos vps上面不知道添加了多少个账户,今天想清理一下,但是以前还未查看过linux用户列表,google了一下,找到方便的放:一般情况下是 cat /etc/passwd 可以查看所有用 ...

  4. 如何加快MyEclipse的启动速度

    学习java开发的朋友对Myeclipse应该不陌生,MyEclipse企业级工作平台(MyEclipseEnterprise Workbench ,简称MyEclipse)是对EclipseIDE的 ...

  5. mysql8之与标准sql的区别

    一  mysql8概述 在研究mysql8新特性的时候,越来越感觉mysql8朝sql server看齐.看来对于中小型企业级应用也挺有兴趣,但是没有企业级的应用套件,有知道的麻烦告知.本文不探讨my ...

  6. vue 相邻自定义组件渲染错误正确的打开方式

    话不多说看问题: 当封装自定义组件时例如(自定义下拉列表)两个相同的组件在多次v-if变化时偶尔会发生渲染错误,明明赋值正确但是组建中的ajax方法可能返回的数据乱掉,或者其他神逻辑错误. 经过查询发 ...

  7. JVM知识整理和学习(转载并修改)

    JVM是虚拟机,也是一种规范,他遵循着冯·诺依曼体系结构的设计原理. 冯·诺依曼体系结构中,指出计算机处理的数据和指令都是二进制数,采用存储程序方式不加区分的存储在同一个存储器里,并且顺序执行,指令由 ...

  8. VS2010环境下MFC使用DataGrid绑定数据源

    如果MFC的软件中 使用DataGrid控件后,在别的电脑上不能运行行,需要拷贝一个 MSDATGRD.ocx 和msstdfmt.dll  文件在软件的目录中,并写一个批处理文件 reg.dat 文 ...

  9. java工具类mht转html格式文件 及简单的HTML解析

    package com.szy.project.utils; import java.io.BufferedInputStream; import java.io.BufferedOutputStre ...

  10. java代码逆序输出数字

    总结:请告诉我更好的方法~~~总觉得不好. package com.badu; import java.util.Scanner; //逆序输出数字: // class fa { public sta ...