APP自动更新功能的快速集成和实现方法讲解

来源:互联网 发布:起名源码 编辑:程序博客网 时间:2024/05/08 15:38

android的开发有时候让人很蛋疼,比如说app的更新,像ios的更新都被app store包办了方便快捷,但是国内的安卓市场却五花八门,途径各种各样。不要太期望像苹果那样把更新全权交个某夹或者某0,app内都要自己继承一个自动更新的功能。那我们就要自己实现一个。

效果图如下:

这里写图片描述 这里写图片描述

更新分成2种,一种是普通更新(如上图1)用户可以选择不更新,一种是强制更新(如上图2),新版本已经不再向下兼容,更新时会锁定屏幕,用户要么更新要么退出。

这里我把代码分享一下,更新功能都集成到了一个library中方便调用,下面先说下使用方法:

使用方法:

首先下载更新功能库library-version,导入工程后关联到自己项目: 
library-version下载链接

然后在自己项目中需要检查更新的地方添加如下代码:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    UpdateHelper updateHelper = new UpdateHelper<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Builder</span>(this)        <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.checkUrl</span>(url)        <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isAutoInstall</span>(false) //设置为false需在下载完手动点击安装,默认值为true,下载后自动安装。        <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.build</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>    updateHelper<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.check</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

如果你有复杂的需求,需要在更新过程中加入自己的处理逻辑,那么可以使用下面的接口:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    UpdateHelper updateHelper = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> UpdateHelper.Builder(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>)        .checkUrl(url)        .isAutoInstall(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置为false需在下载完手动点击安装,默认值为true,下载后自动安装。</span>        .build();    updateHelper.check(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> OnUpdateListener() {            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onStartCheck</span>() {            }            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onFinishCheck</span>(UpdateInfo info) {            }            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onStartDownload</span>() {            }            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onInstallApk</span>() {            }            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onFinshDownload</span>() {            }            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDownloading</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> progress) {            }        });</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul>

有几点需要注意: 
第一点:其中isAutoInstall(false)只适用于普通更新,强制更新一律自动安装。 
第二点:其中url是你的apk的下载接口,你需要提供一个如下的接口:

<code class="hljs json has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">{    "<span class="hljs-attribute" style="box-sizing: border-box;">status</span>":<span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span></span>,    "<span class="hljs-attribute" style="box-sizing: border-box;">isForce</span>":<span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span></span>,    "<span class="hljs-attribute" style="box-sizing: border-box;">apkUrl</span>":<span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://dl.m.duoku.com/game/49000/49554/20150206145821_DuoKu.apk"</span></span>,    "<span class="hljs-attribute" style="box-sizing: border-box;">versionCode</span>":<span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">14</span></span>,    "<span class="hljs-attribute" style="box-sizing: border-box;">updateTips</span>":<span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"update1.1.7.2"</span></span>,    "<span class="hljs-attribute" style="box-sizing: border-box;">versionName</span>":<span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"1.1.7.2"</span></span>,    "<span class="hljs-attribute" style="box-sizing: border-box;">changeLog</span>":<span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"1.新增了用户信息的采集<br>2.修复了路径规划节点超过1000个异常崩溃的bug"</span></span>,    "<span class="hljs-attribute" style="box-sizing: border-box;">size</span>":<span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"25M"</span></span>}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

参数说明:

参数名类型说明是否必选statusint请求是否成功(1成功其他否)是isForceint是否强制更新(1是0否)是apkUrlString下载url是versionCodeint版本号是updateTipsString更新标题否versionNameString版本名是changeLogString更新说明是sizeString包大小是

其中版本号versionCode是判断是否需要更新的关键,它被设置在你的app的AndroidManifest.xml文件中:

<code class="hljs lua has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><manifest xmlns:android=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res/android"</span>    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">package</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com.ccrv.cber"</span>    android:versionCode=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"13"</span>    android:versionName=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"1.1.7.1"</span> ></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

而版本名versionName只是用于给用户作展示用,它并不参与到逻辑中。这是android的版本管理规范。

提供了以上的接口功能集成就完成了,很方便吧。

下面解释下主要代码:不看实现原理的可以跳过了

先看下目录结构:

这里写图片描述

解释下每个包中的类是用来干嘛的:

  • UpdateHelper:更新功能的主流程,程序的入口
  • VersionDialog:复用的几种的弹出对话
  • OnUpdateListener:更新过程的回调接口,如果有回调需要则需要自己实现
  • UpdateInfo:版本信息的实体类
  • com.shelwee.update.utils包下则都是些网络相关的工具类

library的主要处理流程都集中在UpdateHelper类中,在检查更新的时候首先调用了check方法:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">check</span>(OnUpdateListener listener) {        initButtonReceiver();        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (listener != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.updateListener = listener;        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mContext == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {            Log.e(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"NullPointerException"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"The context must not be null."</span>);            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;        }        AsyncCheck asyncCheck = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> AsyncCheck();        asyncCheck.execute(checkUrl);    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

在check方法内部启动异步任务AsyncCheck去我们提供的接口获取服务器目前app信息, 
通过JSONHandler类来获取返回信息并封装成UpdateInfo实体对象:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">        @Override        protected UpdateInfo doInBackground(String... params) {                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>            updateInfo = JSONHandler.toUpdateInfo(HttpRequest.get(url));                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> updateInfo;        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

在onPostExecute回调方法中,比较服务器最新版本和本地版本号,如果不是最新,则调用showUpdateUI(updateInfo)方法:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">protected void onPostExecute(UpdateInfo updateInfo) {    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mContext != null && updateInfo != null) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (Integer.parseInt(updateInfo.getVersionCode()) > getPackageInfo().versionCode) {            showUpdateUI(updateInfo);            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {            Toast.makeText(mContext, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"当前已是最新版"</span>, Toast.LENGTH_LONG).show();            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>        }    }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

在showUpdateUI方法中判断是否是强制更新来弹出不同的窗口和处理事件,并在点击事件中判断用户当前是否使用流量,如果是则调用showNetDialog(updateInfo)提示,如果不是则启动下载异步任务asyncDownLoad.execute(updateInfo):

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**     * 弹出提示更新窗口     */</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">showUpdateUI</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> UpdateInfo updateInfo) {    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (updateInfo.getIsForce()==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//普通更新</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> VersionDialog dialog = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> VersionDialog(...,STYLE_UPDATE_NOMAL);            dialog.setOnPositiveListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> OnClickListener() {                <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(View v) {                    dialog.dismiss();                    NetWorkUtils netWorkUtils = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> NetWorkUtils(mContext);                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> type = netWorkUtils.getNetType();                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (type != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {                        showNetDialog(updateInfo);                    }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {                        AsyncDownLoad asyncDownLoad = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> AsyncDownLoad();                        asyncDownLoad.execute(updateInfo);                    }                }            });            dialog.show();        }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//强制更新</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> VersionDialog dialog = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> VersionDialog(...,STYLE_UPDATE_FORCE);            ...            dialog.show();        }    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li></ul>

下载任务中,每5%调用handler发送一次UPDATE_NOTIFICATION_PROGRESS消息来更新UI中的进度条; 
并在下载完成的回调函数onPostExecute中给handler发送COMPLETE_DOWNLOAD_APK来通知安装:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">        @Override        protected Boolean doInBackground(UpdateInfo... params) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>            FileOutputStream fos = new FileOutputStream(apkFile);            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> ((length = inputStream.read(buf)) != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>                int progress = (int) ((count / (float) total) * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>);                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (progress % <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span> == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {                    handler.obtainMessage(UPDATE_NOTIFICATION_PROGRESS,progress, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, params[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]).sendToTarget();                }                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>            }            inputStream.close();            fos.close();            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>        }        @Override        protected void onPostExecute(Boolean flag) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>            handler.obtainMessage(COMPLETE_DOWNLOAD_APK).sendToTarget();            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>

在handler的处理函数中,UPDATE_NOTIFICATION_PROGRESS消息调用showDownloadNotificationUI()来更新UI; 
COMPLETE_DOWNLOAD_APK消息中判断是否自动安装来调用installApk()自动安装:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (msg.what) {            case UPDATE_NOTIFICATION_PROGRESS:                showDownloadNotificationUI((UpdateInfo) msg.obj, msg.arg1);                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;            case COMPLETE_DOWNLOAD_APK:                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (UpdateHelper.this.isAutoInstall) {                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>                    //自动安装                    installApk(Uri.parse(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"file://"</span> + cache.get(APK_PATH)));                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {                    //点击通知栏消息进行手动安装                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>                }            }            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>        }    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul>

showDownloadNotificationUI判断是否是强制更新来决定是通知栏提示进度或者对话框提示进度:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    private void showDownloadNotificationUI(UpdateInfo updateInfo,final int progress) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mContext != null) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (updateInfo.getIsForce()==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {                // 普通更新,通知栏提示                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>                notificationManager.notify(DOWNLOAD_NOTIFICATION_ID,ntfBuilder.build());            }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {                // 强制更新,对话框提示                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>                pd.show();            }        }    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

下面是安装apk的方法:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    private void installApk(Uri data) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>        Intent i = new Intent(Intent.ACTION_VIEW);        i.setDataAndType(data, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"application/vnd.android.package-archive"</span>);        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        mContext.startActivity(i);        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>    }</code>
0 0
原创粉丝点击