uniapp自动更新
本文只讲述Android的更新。静默更新,市场更新,静默下载等都可参照思路发挥。
配置更新页面路由
pages.json 配置更新弹出层,注意它不能在第一个,path为你自己的路径
"pages":[
//其他页面
{
"path": "pages/upgrade/index",
"style": {
"disableScroll": true,
"app-plus": {
"backgroundColorTop": "transparent",
"background": "transparent",
"titleNView": false,
"scrollIndicator": false,
"popGesture": "none",
"animationType": "fade-in",
"animationDuration": 200
}
}
}
]
配置更新的js
store,request,引入。API和uni.request的封装自行封装。不喜欢封装也可以直接替换request.getAppUpdate()
import Store from '@/store/index.js'
import request from '@/requset/api.js'
/**
* 检查版本是否存在更新
*/
const update = () => {
request.getAppUpdate().then(res => {
// #ifdef APP-PLUS
plus.runtime.getProperty(plus.runtime.appid, (info) => {
if(info.versionCode < res.data.version_code){
Store.commit('setAppUploadInfo', res.data)
uni.navigateTo({
url: `/pages/upgrade/index`,
fail: (err) => {
console.error('更新弹框跳转失败', err)
}
})
}
})
// #endif
}).catch(err => {
})
}
export default {
update
}
更新页面和交互
<template>
<view class="mask">
<view class="mask-content">
<view class="top">
<image src="/static/bg_top.png" mode="widthFix"></image>
<view class="text">版本更新</view>
</view>
<view class="mask-body">
<view class="content">
<view class="title">{{title}}</view>
<view class="desc" v-if="$store.state.appUploadInfo && $store.state.appUploadInfo.explain">{{$store.state.appUploadInfo.explain}}</view>
</view>
<view class="mask-foor">
<template v-if="!downloadSuccess">
<view class="btn" v-if="!downloading" @click="updateApp">立即下载更新</view>
<view class="progress-box flex-column" v-if="downloading">
<progress class="progress" border-radius="6" :percent="downLoadPercent"
activeColor="#3DA7FF" show-info stroke-width="6" />
<view style="width:100%;font-size: 28rpx;display: flex;justify-content: space-around;">
<text>{{downLoadingText}}</text>
<text>({{downloadedSize}}/{{packageFileSize}}M)</text>
</view>
</view>
</template>
<template v-else>
<view class="btn" v-if="installed" @click="restart">安装完毕,点击重启</view>
<button class="btn" style="border: none;color: #fff;" plain :loading="installing" :disabled="installing" @click="installPackage" v-else>{{installing ? '正在安装……' : '下载完成,立即安装'}}</button>
</template>
</view>
</view>
<image class="close-img" src="/static/app_update_close.png" @click.stop="closeUpdate" mode="aspectFit"></image>
</view>
</view>
</template>
<script>
let downloadTask = null;
export default {
data() {
return {
title:"发现新版本!", //标题
content:'更新了',//更新说明
downloading:false, //是否处于下载中
downLoadPercent:20, //进度条比例
downLoadingText: '安装包下载中,请稍后', //提示语
packageFileSize:50, //下载包的大小
downloadedSize:20, //下载大小
downloadSuccess:false,//是否下载完成
installing:false,//是否处于安装中
tempFilePath: '', // 要安装的本地包地址
}
},
onBackPress() {
// 强制更新不允许返回
if (this.$store.state.appUploadInfo && this.$store.state.appUploadInfo.is_force) {
return true
}
downloadTask && downloadTask.abort()
},
methods: {
/**
* 检测是否存在安装包
*/
checkLocalStoragePackage(){
},
/**
* 点击下载安装包
*/
updateApp(){
this.downloadPackage()
},
/**
* 下载安装包
*/
downloadPackage(){
const _this = this;
//设置下载状态
_this.downloading = true;
//下载包
downloadTask = uni.downloadFile({
url:_this.$store.state.appUploadInfo.package_url,
success:(res) => {
if (res.statusCode == 200) {
this.downloadSuccess = true;
this.tempFilePath = res.tempFilePath
// 强制更新,直接安装
if (this.$store.state.appUploadInfo.is_force) {
this.installPackage();
}
}
},
complete: () => {
this.downloading = false;
this.downLoadPercent = 0
this.downloadedSize = 0
this.packageFileSize = 0
downloadTask = null;
}
})
downloadTask.onProgressUpdate(res => {
this.downLoadPercent = res.progress;
this.downloadedSize = (res.totalBytesWritten / Math.pow(1024, 2)).toFixed(2);
this.packageFileSize = (res.totalBytesExpectedToWrite / Math.pow(1024, 2)).toFixed(2);
});
},
/**
* 安装app
*/
installPackage(){
const _this = this;
this.installing = true;
// #ifdef APP-PLUS
plus.runtime.install(this.tempFilePath, {
force: false
}, async res => {
this.installing = false;
this.installed = true;
if (this.$store.state.appUploadInfo.is_force) {
uni.showLoading({
icon: 'none',
title: '安装成功,正在重启……'
})
setTimeout(() => {
uni.hideLoading()
this.restart();
}, 1000)
}
}, async err => {
// 如果是安装之前的包,安装失败后删除之前的包
if (this.installForBeforeFilePath) {
await this.deleteSavedFile(this.installForBeforeFilePath)
this.installForBeforeFilePath = '';
}
// 安装失败需要重新下载安装包
this.installing = false;
this.installed = false;
uni.showModal({
title: '更新失败,请重新下载',
content: err.message,
showCancel: false
});
});
// #endif
},
async closeUpdate() {
if (this.downloading) {
if (this.$store.state.appUploadInfo.is_force) {
return uni.showToast({
title: '下载中,请稍后……',
icon: 'none',
duration: 500
})
}
uni.showModal({
title: '是否取消下载?',
cancelText: '否',
confirmText: '是',
success: res => {
if (res.confirm) {
downloadTask && downloadTask.abort()
uni.navigateBack()
}
}
});
return;
}
if (this.downloadSuccess && this.tempFilePath) {
// 包已经下载完毕,稍后安装,将包保存在本地
await this.saveFile(this.tempFilePath, this.version)
uni.navigateBack()
return;
}
uni.navigateBack()
},
/**
* 删除安装包
*/
deleteSavedFile(filePath) {
// uni.removeStorageSync(localFilePathKey)
return uni.removeSavedFile({
filePath
})
},
/**
* 重启
*/
restart() {
this.installed = false;
// #ifdef APP-PLUS
//更新完重启app
plus.runtime.restart();
// #endif
},
}
}
</script>
<style lang="scss">
page{
background: transparent;
}
.mask {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .65);
display: flex;
justify-content: center;
align-items: center;
.mask-content{
position: relative;
top: 0;
width: 600rpx;
.top{
position: absolute;
top: -195rpx;
left: 0;
width: 600rpx;
height: 270rpx;
.text {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
line-height: 160px;
text-align: center;
font-size: 45rpx;
font-weight: bold;
color: #F8F8FA;
position: absolute;
top: 0;
left: 50rpx;
z-index: 1;
}
image{
width: 100%;
display: block;
}
}
.mask-body{
background-color: #fff;
box-sizing: border-box;
min-height: 30vh;
padding: 100rpx 50rpx 30rpx;
box-sizing: border-box;
font-family: Source Han Sans CN;
border-bottom-right-radius: 30rpx;
border-bottom-left-radius: 30rpx;
display: flex;
flex-direction: column;
.content{
flex:1;
.title{
font-size: 30rpx;
font-weight: 600;
color:#1785ff;
}
.desc{
padding-top: 20rpx;
font-size: 24rpx;
color:#1a1a1a;
}
}
.uni-progress{
border-radius: 50%;
}
.mask-foor{
.btn{
text-align: center;
font-size: 30rpx;
font-weight: 400;
color: #FFFFFF;
border-radius: 40rpx;
margin: 0 18rpx;
height: 80rpx;
line-height: 80rpx;
background: linear-gradient(to right, #1785ff, #3DA7FF);
}
}
}
.close-img{
width: 70rpx;
height: 70rpx;
display: block;
margin: 60rpx auto 0;
}
}
}
</style>
app_update_close.png
bg_top.png
网友评论