携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
为了用户体验到最新的功能和体验,移动应用一般都会内置自动检测版本和更新功能,本篇我们以uni-app开发的安卓App为例,使用应用版本号来实现App的检测与在线升级升级。
uni-app开发的App可以在manifest.json中配置版本名称和版本号用于升级检测,一般来说,应用版本名称是用于展现给用户看的版本信息。如:1.1.1,而应用版本号时内部开发使用的,用于本地app和服务端的提供的app版本进行对比检测,如:500。在uni-app中,可以使用plus.runtime.version和plus.runtime.versionCode来获取,一般来说,升级时需要版本名称和版本号都需要递增。
开发版本检测接口
首先,我们在后端创建一个版本检测的接口,接口的用途是当App初次运行时,请求该接口,返回当前服务端的版本名称。本例中,版本名称存放在一个txt文档中("D:\releasedapp\appversion.txt),每次都更新前手动修改版本名称。为了用户体验,亦可开发一个后台版本名称管理功能,将版本号存入数据库,方便管理。
后端接口代码:
package com.draft.admin.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
@RestController
@RequestMapping("/system/app")
public class AppVersionController {
@GetMapping("/version")
public String appVersion()throws IOException {
File f = new File("D:\releasedapp\appversion.txt");
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
String a = "";
String data ="";
while((data=br.readLine())!=null){
a += data;
}
br.close();
fr.close();
return a;
}
}
apk安装包地址
App启动时,会请求接口,判断服务端App的版本名称号不等于App自身的版本号时,执行一个plus.downloader.createDownload方法,传入下载apk安装包网址,来下载服务端的apk。
那么,apk安装包网址需要这里我们在服务器上使用nginx或其他web服务器启动一个http服务,将最新版本的apk放到下载目录即可,构成该apk安装包地址,即:http://100.32.44.55/released.apk。
创建检测与下载的方法
我们在项目目录下,创建一个util的文件夹,然后在util文件夹下,创建一个version.js用于存放检测与下载方法,其逻辑为:
- 通过uni.request()请求接口,拿到服务器版本名称,即txt存放的字符串。
- 获取到服务器版本名称后,通过plus.runtime.getProperty回调方法,获取当前App中manifest.json配置的版本名称,并对二者比较(这里严谨一些,可转为number类型,进行数字比较大小)
- 服务端和本地版本不一致的话,提示是否升级。同意升级后,传入apk安装包地址参数,执行plus.downloader.createDownload方法,进行下载,并使用plus.nativeUI.showWaiting的方法,实时显示下载进度。
- 下载完毕后,根据机型不同,需手动点击安装或自动转入到安卓安装界面。
具体代码如下:
// version.js
function checkReleasedAppVersion() {
var _this = this;
uni.request({
url: this.apiUrl + 'system/app/version', //请求接口
success: result => {
console.log('服务器版本:' + result.data);
// #ifdef APP-PLUS
plus.runtime.getProperty(plus.runtime.appid, function(inf) {
console.log(`服务器版本:${result.data},当前版本:${inf.version}`);
_this.appVersion = inf.version;
if (inf.version != result.data) {
var doit = false
uni.showModal({
title: "发现新版本",
content: "发现新版本" + result.data + ' 请点击确定立即更新',
showCancel: false,
success: (res) => {
if (res.confirm == true) { //当用户确定更新,执行更新
let dtask = plus.downloader.createDownload(
'http://100.32.44.55/released.apk', {},
(d, status) => {
// console.log(d, status)
// 下载完成
if (status == 200) {
plus.runtime.install(plus.io
.convertLocalFileSystemURL(
d.filename
), {}, {}, (
error) => {
uni.showToast({
title: '安装失败',
mask: false,
duration: 1500
});
})
} else {
uni.showToast({
title: '更新失败',
mask: false,
duration: 1500
});
}
});
try {
dtask.start(); // 开启下载的任务
var prg = 0;
var showLoading = plus.nativeUI
.showWaiting(
"正在下载"); //创建一个showWaiting对象
dtask.addEventListener('statechanged',
function(
task,
status
) {
// 给下载任务设置一个监听 并根据状态 做操作
switch (task.state) {
case 1:
showLoading.setTitle(
"正在下载");
break;
case 2:
showLoading.setTitle(
"已连接到服务器");
break;
case 3:
prg = parseInt(
(parseFloat(
task
.downloadedSize
) /
parseFloat(
task
.totalSize
)) *
100
);
showLoading.setTitle(
" 正在下载" +
prg + "% ");
break;
case 4:
plus.nativeUI
.closeWaiting();
plus.runtime.quit();
//下载完成
break;
}
});
} catch (err) {
plus.nativeUI.closeWaiting();
uni.showToast({
title: '更新失败-03',
mask: false,
duration: 1500
});
}
} else {
plus.runtime.quit();
}
}
})
}
});
// #endif
},
})
}
export {
checkReleasedAppVersion
}
然后,我们将此方法挂载到main.js中。
import {
checkReleasedAppVersion
} from "./util/version.js"
Vue.prototype.$checkReleasedAppVersion = checkReleasedAppVersion
最后,在App.vue中onLaunch生命周期函数中,调用此方法即可。
<script>
export default {
onLaunch: function() {
this.$checkReleasedAppVersion()
},
onShow: function() {
// console.log('App Show')
},
onHide: function() {
// console.log('App Hide')
},
}
</script>
\