uniapp android online update

1. Create an app-update.vue file in pages and register it

<template>
<view class="page-height">
<view class="page-content">
<view class="wrap" v-if="popup_show">
<view class="popup-bg">
<view class="popup-content" :class="{'popup-content-show' : popup_show}">
<view class="update-wrap">
<image src="../../static/images/img.png" class="top-img"></image>
<view class="content">
<text class="title">Discovered new version V{<!-- -->{update_info.versionNo}}</text>
<!-- Upgrade description -->
<view class="title-sub" v-html="update_info.updateContent"></view>
<!-- Upgrade button -->
<button class="btn" v-if="downstatus < 1" @click="onUpdate()">Upgrade now</button>
<!-- Download progress -->
<view class="sche-wrap" v-else>
<!--Update package downloading -->
<view class="sche-bg">
<view class="sche-bg-jindu" :style="lengthWidth"></view>
</view>
<text
class="down-text">Download progress:{<!-- -->{(downSize/1024/1024 ).toFixed(2)}}M/{<!-- -->{(fileSize/1024/ 1024).toFixed(2)}}M</text>
</view>
</view>
</view>
<image src="../../static/images/close.png" class="close-ioc" @click="closeUpdate()"
v-if="downstatus < 1 & amp; & amp; update_info.force == 0"></image>
</view>
</view>
</view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
popup_show: true,
update_info: null, //upgrade parameters passed from the previous page
note: [], //Upgrade description array format
fileSize: 0, //File size
downSize: 0, //downloaded size
downing: false, //Is downloading in progress?
downstatus: 0, //0 Not downloaded 1 Started 2 Connected to the resource 3 Data received 4 Download completed
}
},
onLoad(option) {
if (option.updata_info) {
this.update_info = JSON.parse(option.updata_info)
this.note = this.update_info.updateContent.split("\
"); //Version Notes
} else {
plus.nativeUI.toast("Parameter error");
setTimeout(() => {
uni.navigateBack()
}, 500)
}

},
onBackPress(e) {
if (e.from == "backbutton") return true; //APP Android physical return key logic
},
computed: {
// Download progress calculation
lengthWidth: function() {
let w = this.downSize / this.fileSize * 100;
if (!w) {
w = 0
} else {
w = w.toFixed(2)
}
return {
width: w + "%" //return width half ratio
}
},
getHeight: function() {
let bottom = 0;
if (this.tabbar) {
bottom = 50;
}
return {
"bottom": bottom + 'px',
"height": "auto"
}
}
},
methods: {
//When update is clicked
onUpdate() {
//Determine whether it is a WIFI network and it is a non-forced update
if (this.update_info.net_check == 1 & amp; & amp; this.update_info.force == 0) {
//Determine whether it is wifi mode
uni.getNetworkType({
success: (res) => {
if (res.networkType == "wifi") {
this.startUpdate(); //Start updating
} else {
uni.showModal({
title: 'Tips',
content: 'The current network is not WIFI, continuing to update may generate traffic, are you sure you want to update? ',
success: (modal_res) => {
if (modal_res.confirm) {
this.startUpdate(); //Start updating
}
}
});
}
}
});
} else {
this.startUpdate(); //Start updating
}
},
\t\t\t//Start Update
startUpdate() {
if (this.downing) return false; //Stop if downloading is in progress
this.downing = true; //Status change is downloading
if (/\.apk$/.test(this.update_info.url)) {
// If it is an apk address
this.download_wgt() // Installation package/upgrade package update
} else if (/\.wgt$/.test(this.update_info.url)) {
// If it is an update package
this.download_wgt() // Installation package/upgrade package update
} else {
plus.runtime.openURL(this.update_info.url, function() { //Calling an external browser to open the update address
plus.nativeUI.toast("Open error");
});
}
},
// Download the upgrade resource package
download_wgt() {
plus.nativeUI.showWaiting("Download update file..."); //Download update file...
let options = {
method: "get"
};
let dtask = plus.downloader.createDownload(this.update_info.url, options);
dtask.addEventListener("statechanged", (task, status) => {
if (status === null) {} else if (status == 200) {
//Print here will be executed continuously. Please note that when it is officially online, remember not to print anything here!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!
this.downstatus = task.state;
switch (task.state) {
case 3: //Data has been received
plus.nativeUI.closeWaiting();
this.downSize = task.downloadedSize;
if (task.totalSize) {
this.fileSize = task.totalSize; //The server must return the correct content-length to have the length
}
break;
case 4:
this.installWgt(task.filename); // Install
break;
}
} else {
plus.nativeUI.closeWaiting();
plus.nativeUI.toast("Download error");
this.downing = false;
this.downstatus = 0;
}
});
dtask.start();
},
//Installation files
installWgt(path) {
plus.nativeUI.showWaiting("Install update files..."); //Install update files...
plus.runtime.install(path, {}, function() {
plus.nativeUI.closeWaiting();
// Application resource download completed!
plus.nativeUI.alert("Update completed, please restart the APP!", function() {
plus.runtime.restart(); //Restart APP
});
}, function(e) {
plus.nativeUI.closeWaiting();
//Failed to install update files
plus.nativeUI.alert("Failed to install update file [" + e.code + "]: " + e.message);
});
},
// Cancel update
closeUpdate() {
uni.setStorageSync("update_ignore", this.update_info.version);
uni.navigateBack()
},
}
}
</script>

<style lang="scss" scoped>
.page-height {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: rgba($color: #000000, $alpha: .7);
}

.popup-bg {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 750rpx;
}

.popup-content {
display: flex;
flex-direction: column;
align-items: center;
}

.popup-content-show {
animation: mymove 300ms;
transform: scale(1);
}

@keyframes mymove {
0% {
transform: scale(0);
/*Start to original size*/
}

100% {
transform: scale(1);
}

}

.update-wrap {
width: 580rpx;
border-radius: 18rpx;
position: relative;
display: flex;
flex-direction: column;
background-color: #ffffff;
padding: 170rpx 30rpx 0;

.top-img {
position: absolute;
left: 0;
width: 100%;
height: 256rpx;
top: -128rpx;
}

.content {
display: flex;
flex-direction: column;
align-items: center;
padding-bottom: 40rpx;

.title {
font-size: 32rpx;
font-weight: bold;
color: #6526f3;
}

.title-sub {
text-align: center;
font-size: 24rpx;
color: #666666;
padding: 30rpx 0;
}

.btn {
width: 460rpx;
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
font-size: 30rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 100px;
background-color: #6526f3;
margin-top: 20rpx;
}
}
}

.close-ioc {
width: 70rpx;
height: 70rpx;
margin-top: 30rpx;
}

.sche-wrap {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
padding: 10rpx 50rpx 0;

.sche-wrap-text {
font-size: 24rpx;
color: #666;
margin-bottom: 20rpx;
}

.sche-bg {
position: relative;
background-color: #cccccc;
height: 30rpx;
border-radius: 100px;
width: 480rpx;
display: flex;
align-items: center;

.sche-bg-jindu {
position: absolute;
left: 0;
top: 0;
height: 30rpx;
min-width: 40rpx;
border-radius: 100px;
background: url(../../static/images/round.png) #5775e7 center right 4rpx no-repeat;
background-size: 26rpx 26rpx;
}
}

.down-text {
font-size: 24rpx;
color: #5674e5;
margin-top: 16rpx;
}
}
</style>

2. Create a js file on the homepage that stores the IP and version number.

let baseUrl = '';
let version = '1.0.0'
// development environment
if (process.env.NODE_ENV === 'development') {
baseUrl = '';
}
// Production Environment
if (process.env.NODE_ENV === 'production') {
baseUrl = '';
}

export default {
baseUrl,
version
};
dada(){
    return{
        showProgress: false,
progress: 0,
}

3. Check the version number event

onShow() {
// Get version check updates
this.updateVersion()
},
methods: {
updateVersion() {
var that = this
getVersion({
versionType: 1
}).then(res => {
if (res.versionNo & amp; & amp; res.versionNo > that.oldVerison) {
res.url = that.baseUrl + '/upload/apk/mnf_' + res.versionNo + '.apk';//This is the interface for backend update
//popup update
uni.navigateTo({
url: "/pages/index/app-update?updata_info=" + JSON.stringify(res),
animationType: "fade-in"
})
// that.downloadPath = that.baseUrl + '/upload/apk/mnf_cashier_' + res
// .versionNo + '.apk';
// // The background version is greater than the current version, and an update prompt box will pop up.
// uni.showModal({
// title: 'Version update',
// content: 'The current version of the APP has been discontinued, please download the latest version! ',
// confirmText: 'Update now',
// showCancel: false,
// success(res) {
// if (res.confirm) {
// if (that.isDownload == false) {
// that.downloadApp();
// }
// that.isDownload = true;
// } else {
\t\t\t
// }
// }
// });
}
})
},
exitApp: function() {
if (plus.os.name.toLowerCase() === 'android') {
plus.runtime.quit();
} else {
const threadClass = plus.ios.importClass("NSThread");
const mainThread = plus.ios.invoke(threadClass, "mainThread");
plus.ios.invoke(mainThread, "exit");
//If the above one doesn’t work, use the one below
plus.ios.import("UIApplication").sharedApplication().performSelector("exit")
}
},
downloadApp: function(url) {
var that = this;
that.showProgress = true;
that.progress = 0;
that.downloadTask = uni.downloadFile({
url: that.downloadPath,
success(res) {
if (res.statusCode === 200) {
plus.runtime.install(res.tempFilePath, null, function() {
that.exitApp();
}, function() {
uni.showModal({
title: 'Version update',
content: 'The installation of the new version failed, please install it manually or contact the administrator! ',
confirmText: 'OK',
showCancel: false,
success(res) {
that.exitApp();
}
});
});
}
},
fail(res) {
console.log(res);
},
complete(res) {
console.log(res);
that.showProgress = false;
that.progress = 0;
}
\t\t\t
});
that.downloadTask.onProgressUpdate(res => {
that.progress = res.progress;
});
},
}