关于app更新,uni-app官方推荐的是 uni-upgrade-center,看了下比较繁琐,因此这里自己实现检查更新并下载安装的逻辑。
1.界面效果
界面中的弹框和 进度条采用了uView 提供的组件
2.检查更新并下载安装
一、版本信息配置在服务端,请求服务端接口判断是否需要更新 。
二、点击下载按钮,则开始下载App安装包,并监听下载进度,实时更新下载进度条
注意:下载App如果是在浏览器测试,可能会有跨域的问题,需要后端服务允许跨域。
三、待下载完成后开始安装。
安装App采用的是 uni-installApk插件,请自行导入项目
uni-installApk - DCloud 插件市场
3.完整代码
update.vue
<template>
<u-modal :show="show" :showConfirmButton="false">
<view class="box-a4">
<image class="img-up" mode="widthFix"
src="https://beilizhengxuan.oss-cn-hangzhou.aliyuncs.com/huayu/update.png"/>
<view class="box-a5">
<text>发现新版本V{{version}},升级后体验更顺畅</text>
</view>
<view class="row-b0" v-if="!startDownload">
<view class="btn0" @click="downLoadApp" >马上更新</view>
<view class="btn0 white" color="" @click="cancel"
v-if="forceUpdata=='0'">暂不更新</view>
</view>
<view v-if="startDownload" class="row-b1">
<view class="te-j0">下载进度</view>
<u-line-progress :percentage="percent" height="24"
activeColor="#3c9cff"></u-line-progress>
</view>
</view>
</u-modal>
</template>
<script>
import {getAppNewVersion} from '@/api/system/user'
export default{
props:{
},
data(){
return{
startDownload: false, //是否开始下载
show: false,
version: '',
forceUpdata: '',//是否需要强制更新
apkDownloadUrl: '',//
percent: 0,
filePath: '',
}
},
created(){
this.handleToUpgrade()
},
computed:{
showUpdate(){
console.log('this.$stroe.state.user',this.$stroe.state.user)
return this.$stroe.state.user.showUpdate
}
},
methods:{
async handleToUpgrade() {
const sysInfo = uni.getSystemInfoSync()
const appVersion = sysInfo.appVersion
console.log('appVersion', appVersion)
//请求服务端检查更新接口,判断是否需要更新
const res = await getAppNewVersion()
if(res.code == 200){
if(res.data && res.data.newVersion){
const newVersion = res.data.newVersion
if(appVersion == newVersion){
this.showToast('当前已是最新版本')
this.cancel()
} else{
this.apkDownloadUrl = res.data.apkDownloadUrl
this.show = true
console.log('需要更新')
this.version = newVersion
this.forceUpdata = res.data.forceUpdata
}
}
}
},
installApp(){
uni.installApk({
filePath : this.filePath,
success: (res)=>{
console.log('安装成功--', res);
},
fail : (res)=>{
console.log('安装失败--', res);
},
complete: (res)=>{
console.log('安装完成--', res);
}
})
},
downLoadApp(){
this.startDownload = true
const downloadTask = uni.downloadFile({
url: this.apkDownloadUrl , //仅为示例,并非真实的资源
timeout: 6000000,
success: (res) => {
console.log('success res', res)
if (res.statusCode === 200) {
this.filePath = res.tempFilePath
console.log('下载成功');
this.cancel()
this.installApp()
}
},
complete: (res)=> {
console.log('complete res', res)
},
fail: (res)=> {
console.log('fail res', res)
},
});
downloadTask.onProgressUpdate((res) => {
//console.log('下载进度' + res.progress);
//console.log('已经下载的数据长度' + res.totalBytesWritten);
//console.log('预期需要下载的数据总长度' + res.totalBytesExpectedToWrite);
this.percent = res.progress
if (res.progress >= 100) {
console.log('下载进度 abort' + res.progress);
//downloadTask.abort();
}
});
},
cancel(){
this.$emit('cancel')
this.show = false
},
showToast(message){
uni.showToast({
title: message,
icon: 'none'
})
}
}
}
</script>
<style>
.img-up{
width: 100%;
}
.box-a4{
width: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.box-a5{
flex:1;
text-align: center;
font-size: 28rpx;
color: #999;
padding: 20rpx 0;
}
.row-b0{
display:flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
padding: 0 50rpx;
margin-top:60rpx;
margin-bottom:60rpx;
}
.row-b0 .btn0{
width: 240rpx;
height: 68rpx;
border-radius: 34rpx;
color: white;
display: grid;
place-content: center;
background:#3c9cff;
}
.row-b0 .btn0:active{
opacity: 0.7;
}
.row-b0 .btn0.white{
background:#fff;
color: #666;
border:1px solid #eee;
}
.row-b1{
margin: 60rpx 40rpx;
}
.te-j0{
text-align: center;
color:#999;
font-size: 26rpx;
margin-bottom:20rpx;
}
</style>
4.引入并使用
上面将检查更新的逻辑封装在了update.vue中,使用时只需引入该组件,在父页面点击检查更新按钮时,只需将 checkUpdate 属性设置为 true,则加载 update.vue组件,进入created 方法并调用检查更新的相关逻辑,有新版本则弹框,提示更新,无新版本则将 checkUpdate重置为 false
注意:当检查更新的弹框弹出时,调用页面需要禁用 android的 返回按键,在 onBackPress函数里面做相应的逻辑判断即可。
<template>
<view >
<UpdateApp v-if="checkUpdate" @cancel="checkUpdate=false"/>
</view>
</template>
<script>
import UpdateApp from './update'
export default {
components:{
UpdateApp
},
data() {
return {
checkUpdate: false,
}
},
onBackPress(options) {
console.log('onBackPress options', options)
// 禁用返回
if (options.from == 'backbutton') {
console.log('--禁用返回')
if(this.checkUpdate){
return true;// 禁用返回按键
}else {
return false;
}
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
</style>