在应用中, 为了提高用户体验, 会提供更新版本号的功能. 那么怎样实现呢?

我写了一个简单的Demo, 说明一下, 须要注意几个细节. 使用了Retrofit和Rx处理网络请求.

Github下载地址

1. 逻辑

訪问server, 依据是否包括新版本号, 推断是否须要更新. 

下载Apk, 下载完毕后, 自己主动安装, 高版本号会覆盖低版本号.

逻辑:

<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-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MainActivity</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AppCompatActivity</span> {</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;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String APP_NAME = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ped_android"</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;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String VERSION = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"1.0.0"</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;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String INFO_NAME = <span class="hljs-string" style="color: rgb(0, 136, 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;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String STORE_APK = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"chunyu_apk"</span>; <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Bind</span>(R.id.main_b_install_apk) Button mBInstallApk; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> UpdateAppUtils.UpdateCallback mUpdateCallback; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 更新回调</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;">protected</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;">onCreate</span>(Bundle savedInstanceState) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>); mUpdateCallback = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> UpdateAppUtils.UpdateCallback() {
<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;">onSuccess</span>(UpdateInfo updateInfo) {
Toast.makeText(MainActivity.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"有更新"</span>, Toast.LENGTH_SHORT).show();
UpdateAppUtils.downloadApk(MainActivity.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, updateInfo, INFO_NAME, STORE_APK);
} <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;">onError</span>() {
Toast.makeText(MainActivity.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无更新"</span>, Toast.LENGTH_SHORT).show();
}
}; mBInstallApk.setOnClickListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> View.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) {
UpdateAppUtils.checkUpdate(APP_NAME, VERSION, mUpdateCallback);
}
});
}
}</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><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul>

UpdateAppUtils是核心下载类. 输入App的代号, 版本号号, 异步回调, 发送到server, 推断是否须要更新. 假设存在新版本号, 则下载Apk, 并自己主动安装更新.

2. 网络请求

更新请求, 參数是App代号和当前版本.

<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;">/**
* 更新服务
* <p>
* Created by wangchenlong on 16/1/4.
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">UpdateService</span> {</span>
String ENDPOINT = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://www.chunyuyisheng.com"</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取个人信息</span>
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@GET</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/cmsapi/app/update"</span>)
Observable<UpdateInfo> getUpdateInfo(
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Query</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"appName"</span>) String appName,
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Query</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"version"</span>) String version);
}</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></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;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 创建Retrofit服务
* <p>
* Created by wangchenlong on 16/1/4.
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ServiceFactory</span> {</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;">static</span> <T> T <span class="hljs-title" style="box-sizing: border-box;">createServiceFrom</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Class<T> serviceClass, String endpoint) {
Retrofit adapter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Retrofit.Builder()
.baseUrl(endpoint)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 加入Rx适配器</span>
.addConverterFactory(GsonConverterFactory.create()) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 加入Gson转换器</span>
.build();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> adapter.create(serviceClass);
}
}</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></ul>

更新信息的Json类.

<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;">/**
* 更新信息(JSON)
* <p>
* Created by wangchenlong on 16/1/4.
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">UpdateInfo</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Data data; <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;">public</span> Integer error_code; <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;">public</span> String error_msg; <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;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Data</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String curVersion; <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;">public</span> String appURL; <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;">public</span> String description; <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;">public</span> String minVersion; <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;">public</span> String appName; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 应用名称</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> String <span class="hljs-title" style="box-sizing: border-box;">toString</span>() {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"当前版本号: "</span> + data.curVersion + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">", 下载地址: "</span> + data.appURL + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">", 描写叙述信息: "</span> + data.description
+ <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">", 最低版本号: "</span> + data.minVersion + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">", 应用代称: "</span> + data.appName
+ <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">", 错误代码: "</span> + error_code + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">", 错误信息: "</span> + error_msg;
}
}</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>

3. 请求和下载

更新库的主类, 包括检查更新(checkUpdate)下载Apk(downloadApk)两个重要方法.

<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;">/**
* 更新管理器
* <p>
* Created by wangchenlong on 16/1/6.
*/</span>
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@SuppressWarnings</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"unused"</span>)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">UpdateAppUtils</span> {</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@SuppressWarnings</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"unused"</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;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String TAG = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DEBUG-WCL: "</span> + UpdateAppUtils.class.getSimpleName(); <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 检查更新
*/</span>
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@SuppressWarnings</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"unused"</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;">static</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;">checkUpdate</span>(String appCode, String curVersion, UpdateCallback updateCallback) {
UpdateService updateService =
ServiceFactory.createServiceFrom(UpdateService.class, UpdateService.ENDPOINT); updateService.getUpdateInfo(appCode, curVersion)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(updateInfo -> onNext(updateInfo, updateCallback),
throwable -> onError(throwable, updateCallback));
} <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;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</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;">onNext</span>(UpdateInfo updateInfo, UpdateCallback updateCallback) {
Log.e(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"返回数据: "</span> + updateInfo.toString());
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (updateInfo.error_code != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> || updateInfo.data == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ||
updateInfo.data.appURL == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
updateCallback.onError(); <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;">else</span> {
updateCallback.onSuccess(updateInfo);
}
} <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;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</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;">onError</span>(Throwable throwable, UpdateCallback updateCallback) {
updateCallback.onError();
} <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 下载Apk, 并设置Apk地址,
* 默认位置: /storage/sdcard0/Download
*
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> context 上下文
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> updateInfo 更新信息
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> infoName 通知名称
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> storeApk 存储的Apk
*/</span>
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@SuppressWarnings</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"unused"</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;">static</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;">downloadApk</span>(
Context context, UpdateInfo updateInfo,
String infoName, String storeApk
) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!isDownloadManagerAvailable()) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
} String description = updateInfo.data.description;
String appUrl = updateInfo.data.appURL; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (appUrl == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> || appUrl.isEmpty()) {
Log.e(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"请填写\"App下载地址\""</span>);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
} appUrl = appUrl.trim(); <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;">if</span> (!appUrl.startsWith(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http"</span>)) {
appUrl = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://"</span> + appUrl; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 加入Http信息</span>
} Log.e(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"appUrl: "</span> + appUrl); DownloadManager.Request request;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
request = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> DownloadManager.Request(Uri.parse(appUrl));
} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {
e.printStackTrace();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
}
request.setTitle(infoName);
request.setDescription(description);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, storeApk); Context appContext = context.getApplicationContext();
DownloadManager manager = (DownloadManager)
appContext.getSystemService(Context.DOWNLOAD_SERVICE); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 存储下载Key</span>
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(appContext);
sp.edit().putLong(PrefsConsts.DOWNLOAD_APK_ID_PREFS, manager.enqueue(request)).apply();
} <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 最小版本大于9</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;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">isDownloadManagerAvailable</span>() {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD;
} <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;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">UpdateCallback</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onSuccess(UpdateInfo updateInfo); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onError();
}
}</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><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</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;">    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 检查更新
*/</span>
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@SuppressWarnings</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"unused"</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;">static</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;">checkUpdate</span>(String appCode, String curVersion, UpdateCallback updateCallback) {
UpdateService updateService =
ServiceFactory.createServiceFrom(UpdateService.class, UpdateService.ENDPOINT); updateService.getUpdateInfo(appCode, curVersion)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(updateInfo -> onNext(updateInfo, updateCallback),
throwable -> onError(throwable, updateCallback));
}</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></ul>

下载Apk: 转换和解析Url, 设置通知信息和存储位置, 存储下载Id, 自己主动安装更新.

<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;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 下载Apk, 并设置Apk地址,
* 默认位置: /storage/sdcard0/Download
*
* @param context 上下文
* @param updateInfo 更新信息
* @param infoName 通知名称
* @param storeApk 存储的Apk
*/</span>
@SuppressWarnings(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"unused"</span>)
public static void downloadApk(
Context context, UpdateInfo updateInfo,
String infoName, String storeApk
) {
if (!isDownloadManagerAvailable()) {
return<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
} String description = updateInfo<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.data</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.description</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
String appUrl = updateInfo<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.data</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.appURL</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> if (appUrl == null || appUrl<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isEmpty</span>()) {
Log<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.e</span>(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"请填写\"App下载地址\""</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
return<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
} appUrl = appUrl<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.trim</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; // 去掉首尾空格</span> if (!appUrl<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.startsWith</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http"</span>)) {
appUrl = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://"</span> + appUrl<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; // 加入Http信息</span>
} Log<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.e</span>(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"appUrl: "</span> + appUrl)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> DownloadManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Request</span> request<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
try {
request = new DownloadManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Request</span>(Uri<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parse</span>(appUrl))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
} catch (Exception e) {
e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
return<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}
request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTitle</span>(infoName)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setDescription</span>(description)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
if (Build<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.VERSION</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.SDK</span>_INT >= Build<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.VERSION</span>_CODES<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.HONEYCOMB</span>) {
request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.allowScanningByMediaScanner</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setNotificationVisibility</span>(DownloadManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Request</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.VISIBILITY</span>_VISIBLE_NOTIFY_COMPLETED)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}
request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setDestinationInExternalPublicDir</span>(Environment<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.DIRECTORY</span>_DOWNLOADS, storeApk)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> Context appContext = context<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getApplicationContext</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
DownloadManager manager = (DownloadManager)
appContext<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSystemService</span>(Context<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.DOWNLOAD</span>_SERVICE)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> // 存储下载Key
SharedPreferences sp = PreferenceManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getDefaultSharedPreferences</span>(appContext)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
sp<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.edit</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.putLong</span>(PrefsConsts<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.DOWNLOAD</span>_APK_ID_PREFS, manager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.enqueue</span>(request))<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.apply</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><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><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li></ul>

使用DownloadManager下载文件是Android的推荐方式. 

存储下载Id(manager.enqueue(request))是为了在安装应用时, 找到Apk. 

默认存储地址/storage/sdcard0/Download.

4.自己主动安装

注冊广播接收器, 接收消息ACTION_DOWNLOAD_COMPLETE, 下载完毕会发送广播. 获取下载文件的Uri, 进行匹配, 发送安装消息, 自己主动安装.

<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;">/**
* 安装下载接收器
* <p>
* Created by wangchenlong on 16/1/5.
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">InstallReceiver</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">BroadcastReceiver</span> {</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;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String TAG =
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DEBUG-WCL: "</span> + InstallReceiver.class.getSimpleName(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 安装下载接收器</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;">onReceive</span>(Context context, Intent intent) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> downloadApkId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);
installApk(context, downloadApkId);
}
} <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 安装Apk</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;">installApk</span>(Context context, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> downloadApkId) {
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取存储ID</span>
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> id = sp.getLong(PrefsConsts.DOWNLOAD_APK_ID_PREFS, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>L); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (downloadApkId == id) {
DownloadManager dManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Intent install = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Intent(Intent.ACTION_VIEW);
Uri downloadFileUri = dManager.getUriForDownloadedFile(downloadApkId);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (downloadFileUri != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
install.setDataAndType(downloadFileUri, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"application/vnd.android.package-archive"</span>);
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(install);
} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
Log.e(TAG, <span class="hljs-string" style="color: rgb(0, 136, 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><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><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li></ul>

安装本应用下载的Apk, 不安装其它Apk, 存储下载Id, 与广播Id进行匹配. 

下载失败, 也会发送下载完毕(ACTION_DOWNLOAD_COMPLETE)广播, Uri可能为空, 须要推断, 否则发生崩溃.

OK, that’s all! Enjoy It!

在应用中更新App版本号的更多相关文章

  1. 在应用中更新App版本

    在应用中, 为了提高用户体验, 会提供更新版本的功能. 那么如何实现呢? 我写了一个简单的Demo, 说明一下, 需要注意几个细节. 使用了Retrofit和Rx处理网络请求. Github下载地址 ...

  2. uniapp中IOS安卓热更新和整包更新app更新

    在App.vue中 onLaunch: function() { console.log('App Launch'); // #ifdef APP-PLUS this.getVersion(); // ...

  3. IOS开发中如何实现自动检测更新APP

    自动检测更新实现逻辑: 先上github地址:https://github.com/wolfhous/HSUpdateApp 1,获取当前项目APP版本号 2,拿到AppStore项目版本号 3,对比 ...

  4. android 反纠结app开发: 在线程中更新view

    大体上想实现一个思路: 对一个view 的内容进行不停地变化, 通过按钮停止这种变化,以达到随机选择的目的. 开发过程中 使用textview 模拟,  建立线程 mythread = new Thr ...

  5. iOS 开发笔记 - 开发中如何实现自动检测更新APP

    1.获取当前项目APP版本号 2.拿到AppStore项目版本号 3.对比版本号,实现更新功能 直接上代码: #import "ViewController.h" //1一定要先配 ...

  6. iOS获取设备型号和App版本号等信息(OC+Swift)

    iOS获取设备型号和App版本号等信息(OC+Swift) 字数1687 阅读382 评论3 喜欢10 好久没有写过博客了,因为中间工作比较忙,然后有些个人事情所以耽误了.但是之前写的博客还一直有人来 ...

  7. iOS 怎样更新APP

    app更新的流程思想 得到当前版本currentVersion,将currentVersion与近期的版本latestVersion进行比較,若当前currentVersion较小.进行更新操作. 获 ...

  8. [Phonegap+Sencha Touch] 移动开发77 Cordova Hot Code Push插件实现自己主动更新App的Web内容

    原文地址:http://blog.csdn.net/lovelyelfpop/article/details/50848524 插件地址:https://github.com/nordnet/cord ...

  9. apicloud 上传/更新App版本到 ios store 流程步骤

    app更新 上传APP的地址: https://itunesconnect.apple.com/login 苹果开发者中心: https://developer.apple.com/ app正式包更新 ...

随机推荐

  1. 【收藏】Web前端开发第三方插件大全

    收集整理了一些Web前端开发比较成熟的第三方插件,分享给大家. ******************************************************************** ...

  2. PHP小技巧

    1.js获取服务器年月日 var date= '<?php echo date("Y-m-d",time())?>';//获取服务器年月

  3. [深度学习]实现一个博弈型的AI,从五子棋开始(1)

    好久没有写过博客了,多久,大概8年???最近重新把写作这事儿捡起来……最近在折腾AI,写个AI相关的给团队的小伙伴们看吧. 搞了这么多年的机器学习,从分类到聚类,从朴素贝叶斯到SVM,从神经网络到深度 ...

  4. JAVA的免费天气api接口调用示例

    step1:选择本文所示例的接口"免费天气api" url:https://www.juhe.cn/docs/api/id/39/aid/87 step2:每个接口都需要传入一个参 ...

  5. linux 内存 大于 jvm xmx

    文章来源: http://www.cnblogs.com/guozp/p/7845605.html 1.虽然你jvm参数设置了-Xms6g -Xmx6g,但操作系统不并会马上分配6G的物理内存,而是确 ...

  6. jquery.tagsinput的使用例子,包括模糊查询后端代码

    <link rel="stylesheet" type="text/css" href="~/lib/jquery.tagsinput.jurg ...

  7. [转载] Redis实现分布式锁

    转载自http://zhidao.baidu.com/link?url=m56mmWYwRgCymsaLZ2tx-GWDy5FYmUWGovEtuApjTpktHS3bhofrCS-QVGiLoWeS ...

  8. 《Linux命令行与shell脚本编程大全》第十章 使用编辑器

    主要介绍vim, nano, emacs,KWrite,Kate,GNOME 10.1 vim Unix系统最初的编辑器 10.1.1检查vim软件包 先搞明白你所用的Linux系统是哪种vim软件包 ...

  9. 深度学习之tensorflow (一)

    一.TensorFlow简介 1.TensorFlow定义: tensor  :张量,N维数组 Flow   :  流,基于数据流图的计算 TensorFlow : 张量从图像的一端流动到另一端的计算 ...

  10. pt-stalk

    1.名词解释 Collect forensic data about MySQL when problems occur 在问题发生的时候采集现场数据 pt-stalk waits for a tri ...