前不久遇到一个需求,说是要实现app的静默安装并且安装完了之后要能够自启动。

我上网查了很多资料,方法基本都差不多,但是基本上每种方法我都试过了,能够实现静默安装,但是自启动的时候就遇到了问题。很多类似的博客下面几乎都有人提问说为啥不能够自启动。我当时在操作的时候也发现自启动失败,后来我反复推敲尝试实现了这个功能,大多数博客介绍的方法是没有问题的,问题在于博主没有把过程讲述得很清楚,从而给读者造成了误解,特此发文一篇希望帮助广大受阻的读者。

静默更新这个需求是有一定的前提的,一般这类的需求只会出现在一些厂商定制的pad或特定设备上面,系统要给足了root权限,手机上有一类做法可以在不需要root权限的前提下实现更新,但模式算不得静默更新,当然这不是我们今天要讨论的问题,我也就不在这里多说了。

一、安装包下载
安装包下载相关的文章数不胜收,主要是代码涉及静默安装,我这里就把我的代码拿出来做个参考吧。

public class DownLoadUtils {public static void download(final String apkUrl) {Thread thread;thread = new Thread(new Runnable() {@Overridepublic void run() {downloadFile(apkUrl);}});thread.start();}//下载apkpublic static File downloadFile(String apkUrl) {final String fileName = "update.apk";File tmpFile = new File("/sdcard/update");if (!tmpFile.exists()) {tmpFile.mkdir();}final File file = new File("/sdcard/update/" + fileName);try {URL url = new URL(apkUrl);HttpURLConnection conn = (HttpURLConnection) url.openConnection();InputStream is = conn.getInputStream();FileOutputStream fos = new FileOutputStream(file);byte[] buf = new byte[1024];conn.connect();double count = 0;if (conn.getResponseCode() >= 400) {//连接超时} else {while (count <= 100) {Log.e("install", "download" + count + "");if (is != null) {int numRead = is.read(buf);if (numRead <= 0) {break;} else {fos.write(buf, 0, numRead);}} else {break;}}}conn.disconnect();fos.close();is.close();InstallApkUtils.excuteSuCMD(InstallApkUtils.sdPath);//执行静默安装} catch (Exception e) {e.printStackTrace();}return file;}
}

上面的代码中,当安装包下载完成之后,开始执行静默安装方法。二、静默安装
强调一点,文章中提到的静默安装是在系统开发了root权限的前提之下,如果没有获取root权限,还是采用系统的安装流程吧!

public class InstallApkUtils {public static Context mContext = null;public static String sdPath = "/sdcard/update/update.apk";//下载sd路径//判断是否update目录下有文件public static boolean isHasFile() {try {File f = new File(sdPath);if (!f.exists()) {return false;}} catch (Exception e) {return false;}return true;}public static void excuteSuCMD(String currenttempfilepath) {if (isHasFile()) {Process process = null;OutputStream out = null;InputStream in = null;try {//请求rootprocess = Runtime.getRuntime().exec("su");out = process.getOutputStream();//调用安装out.write(("pm install -r " + currenttempfilepath + "\n").getBytes());in = process.getInputStream();int len = 0;byte[] bs = new byte[256];while (-1 != (len = in.read(bs))) {String state = new String(bs, 0, len);if (state.equals("success\n")) {//安装成功后的操作//静态注册自启动广播Intent intent = new Intent();//与清单文件的receiver的anction对应intent.setAction("android.intent.action.PACKAGE_REPLACED");//发送广播mContext.sendBroadcast(intent);}}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {try {if (out != null) {out.flush();out.close();}if (in != null) {in.close();}} catch (IOException e) {e.printStackTrace();}}} else {Log.e("install", "apk is not exist");}}
}

安装完成之后我们会发送一条广播
//静态注册自启动广播

 Intent intent = new Intent();//与清单文件的receiver的anction对应intent.setAction("android.intent.action.PACKAGE_REPLACED");//发送广播mContext.sendBroadcast(intent);

注意:这个广播需要系统权限,否则发送广播失败。

三、注册并接收广播
上面的安装中提到了安装结束会发送一个广播,这条广播的作用就是如果发生了安装包的替换就重新启动应用。
1
注意:很多人说安装完成之后,应用并没有自己启动,问题在于更新后的安装包没有注册并接收上一个版本发出的广播,下面所提到的源代码一定要在新安装的apk包中实现。

public class UpdateReceiver extends BroadcastReceiver {public static final String UPDATE_ACTION = "android.intent.action.PACKAGE_REPLACED";@Overridepublic void onReceive(Context context, Intent intent) {if (intent.getAction().equals(UPDATE_ACTION)) {Intent intent2 = new Intent(context, TestActivity.class);intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent2);}//接收安装广播if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {String packageName = intent.getDataString();
//            System.out.println("安装了:" + packageName + "包名的程序");        }//接收卸载广播if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {String packageName = intent.getDataString();
//            Log.e("install","卸载了:" + packageName + "包名的程序");}}
}

然后在AndroidManifest.xml文件中注册UpdateReceiver,当然你也可以选择在源代码中动态注册。
<!--静默更新、自启动-->

<receiver android:name=".utils.UpdateReceiver"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><intent-filter><action android:name="android.intent.action.PACKAGE_REPLACED" /><action android:name="android.intent.action.PACKAGE_ADDED" /><action android:name="android.intent.action.PACKAGE_REMOVED" /><data android:scheme="package" /></intent-filter></receiver>

当然需要用到的权限不要忘了声明

<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /><uses-permission android:name="android.permission.RESTART_PACKAGES" /><uses-permissionandroid:name="android.permission.INSTALL_PACKAGES"tools:ignore="ProtectedPermissions" />

四、总结
整个过程大概流程如下:

下载apk到指定的文件夹下(声明相关的权限);
注册广播,用来监听app的变动情况实现app的自启动,广播的注册和接收处理在所有的app版本里都要存在;
获取root权限,从文件夹获取安装包,执行安装程序;
安装完成之后,发送广播重新启动app。
我当时在实现的过程中,发现app没有重新启动,但是退出app再重新进入已经是更新过的版本,后来我反复阅读别人的文章,发现是我自己没有理解透彻整个实现的过程,我放在服务器上的安装包没有实现广播的接收流程,所以导致了app没有重新启动,后来重新上传了安装包测试通过。
————————————————

转载于:https://blog.csdn.net/zhimingshangyan/article/details/79770255

android root权限下Apk下载、静默安装并自启相关推荐

  1. Android 无需root实现apk的静默安装

    转载请注明出处:http://blog.csdn.net/yyh352091626/article/details/50533137 Android的静默安装似乎是一个很有趣很诱人的东西,但是,用普通 ...

  2. Android 4.0.4系统下实现apk的静默安装和启动

    转自http://www.linuxidc.com/Linux/2013-02/79403.htm 未亲测 最近在Android 4.0.4系统下实现apk的静默安装和启动的功能,这里和大家分享一下, ...

  3. python root_python在非root权限下的安装方法

    以前在使用Python的时候,都是使用root用户安装好的全局python,现在,因为root用户安装的Python版本太低,同时自己没有root权限去对全局Python升级,所以要在非root用户下 ...

  4. 极光推送+服务下载+静默安装

    极光推送+服务下载+静默安装 今年进入了一家新公司,项目的难点是静默更新和超大屏幕适配,屏幕适配使用约束布局来做不算什么问题,而静默更新这块就需要研究一下了,在网上有很多讲静默更新的,写得很好,不过都 ...

  5. android root权限破解分析

    破解android的root权限的本质是:在系统中加入一个任何用户都可能用于登陆的su命令.或者说替换掉系统中的su程序,因为系统中的默认su程序需要验证实际用户权限,只有root和 shell用户才 ...

  6. Linux(RedHat)下Weblogic 12C静默安装

    Java 版本确认与安装 Oracle 12需要安装JDK, Open JDK 不可以,如果已经安装的话,需要卸载重装. //查找已安装的Java rpm -qa|grep java //卸载安装的o ...

  7. windows10下postgreSQL 下载、安装、启动、关闭

    windows10下postgreSQL 下载.安装.启动.关闭 下载 安装 l设置密码和端口,一直next直到安装完成 环境变量

  8. Android基于IIS的APK下载(五)IIS的配置

    这里使用的IIS是win7_64的. 步骤一:打开IIS.控制面板->管理工具(如果没有,请把查看方式调成大图标)->Internet 信息服务(IIS)管理器. 步骤二:配置网站目录 步 ...

  9. windows怎么下载安装python-windows下numpy下载与安装图文教程

    Numpy介绍 NumPy系统是Python的一种开源的数值计算扩展.这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构 ...

最新文章

  1. oracle查找重复记录
  2. 批量kill掉linux中符合某些字段的进程
  3. HTML CSS里display:block的原理和用法
  4. wget整站抓取、网站抓取功能;下载整个网站;下载网站到本地
  5. Android 手游闪屏极简方案
  6. linux操作系统的体系结构
  7. 星光嵌入式WM8978音频模块发布
  8. 计算机培训校本研修心得,关于校本研修培训心得体会(精选10篇)
  9. BI 工具常用图表用法
  10. vue-quill-editor 富文本 自定义图片上传操作
  11. Hardhat 学习笔记
  12. 《大明王朝》掠之于商——沈一石的“盛世”悲歌
  13. 不了解喜欢的明星有什么关系?教你用Neo4j 快速构建明星关系图谱,让你比他自己还了解
  14. 父类声明子类实例化对象详解
  15. JVM参数 之 -XX:MaxGCPauseMillis 与 -XX:GCTimeRatio
  16. 关于CAN和CANFD物理层和数据链路层的对比分析
  17. H5实现RTMP流的直播小记
  18. 使用matla求取一维线性函数的系数
  19. 用js制作一个新年倒计时
  20. Python3 微信

热门文章

  1. im即时通讯开发之后台应用保活、消息推送的噩梦
  2. 网上花店java项目_Java+SSM实现网上花店售卖系统
  3. 阿里云服务器mysql开放远程连接步骤
  4. mysql binlog协议_mysql binlog协议分析--具体event
  5. 计算机主机机箱面板指示灯,电脑主机指示灯不亮了是什么原因
  6. 2019c/c++校招100题
  7. 中国各省人力资本测算就业人员受教育程度构成(2000-2021年)
  8. 视觉人工智能初识 OpenMMLab
  9. CURRENT_TIMESTAMP函数精度
  10. 1000:Calculate A + B