uniapp打包apk如何实现版本更新
我们做的比较简单,在后端设置版本号,并在uniapp的config.js中定义版本号,每次跟后端的进行对比,不一致的话就更新。
一、下载apk
主要代码(下载安装包,并进行安装,一般得手动同意安装)
const uploadTask = uni.downloadFile({ // 下载apk/资源包url: 'xxx',//下载apk的地址success: (downloadResult) => {console.log(downloadResult);if (downloadResult.statusCode === 200) {// uni.clearStorage()plus.runtime.install(downloadResult.tempFilePath, {force: true},function() {plus.runtime.restart(); // 重启APP },function(e) {_this.show = falseuni.showToast({title: e.message,icon: 'none'})});} else {_this.show = falseif (_this.updateType === 1) {uni.showToast({title: '资源包下载失败',duration: 2000,icon: 'error'})} else {uni.showToast({title: 'APK下载失败',duration: 2000,icon: 'error'})}}}});
二、监听下载进度
//监听下载进度 uploadTask.onProgressUpdate((res) => {_this.updateProgress = res.progress //下载进度 0-100if (_this.updateType === 1) {if (res.progress > 95) {// _this.restartFlag = true}}});
三、全部代码
dialog.vue
<template><view class="uploadCon" v-if="show"><view class="uploadBox"><!-- 版本信息弹窗 --><view class="dialogBox"><view class="circle"><image src="@/static/images/icons/upload.png" mode="widthFix"></image></view><view class="needLoad" v-if="versionsFlag === 1"><view class="title">{{updateType === 1?'最新资源包':'发现新版本'}} V{{getVersion}}</view><view class="tips"><view>电子秤检测到新版本,请更新后使用!</view></view><view class="buttonCon"><!-- <view class="button button2" @click="show = false">暂不更新</view> --><view class="button button1" @click="updateNow">立即更新</view></view></view><view class="loadingBox" v-if="versionsFlag === 3"><view class="title">正在下载,请稍后 </view><view><progress :percent="updateProgress" show-info stroke-width="20" /></view></view></view></view></view>
</template><script>import {appInfo,} from "@/config.js"import {uploadSys} from "@/api/system/user.js"import {getToken} from "@/api/login.js"export default {data() {return {// 版本更新相关version: '', //版本名称versionCode: '', //版本号 当前getVersion:'',//最新版本apkUpdateContent: '', //更新内容说明updateType: '', //1资源包更新2版本更新versionsFlag: 1, //1需要更新弹窗2已是最新版本弹窗3正在下载latestVersionInfo: '', //已是最新版本弹窗内容updateAPKPath: '', //下载文件路径updateProgress: 0, //下载进度restartFlag: false,show: false}},mounted() {this.update();},methods: {update() {let _this = thislet platform = uni.getSystemInfoSync().platformlet server = '***********************'let signServer = '***********************'// 当前版本信息this.versionCode = appInfo.version; //版本号uploadSys({}).then(response => {this.getVersion = response.rows[0].dictValue;if (this.versionCode == this.getVersion) {//已经是最新版本} else {this.show = true//要更新this.versionsFlag = 1;}})},//弹窗点击确认更新以后updateNow() {let _this = this_this.versionsFlag = 3const uploadTask = uni.downloadFile({ // 下载apk/资源包url: 'xxx',//apk下载地址,更换成你自己的success: (downloadResult) => {console.log(downloadResult);if (downloadResult.statusCode === 200) {// uni.clearStorage()plus.runtime.install(downloadResult.tempFilePath, {force: true},function() {plus.runtime.restart(); // 重启APP },function(e) {_this.show = falseuni.showToast({title: e.message,icon: 'none'})});} else {_this.show = falseif (_this.updateType === 1) {uni.showToast({title: '资源包下载失败',duration: 2000,icon: 'error'})} else {uni.showToast({title: 'APK下载失败',duration: 2000,icon: 'error'})}}}});//监听下载进度 uploadTask.onProgressUpdate((res) => {_this.updateProgress = res.progressif (_this.updateType === 1) {if (res.progress > 95) {// _this.restartFlag = true}}});},}}
</script><style scoped lang="scss">@import "@/static/scss/dialog.scss";</style>
dialog.scss
.uploadCon{position: fixed;top: 0;left: 0;right: 0;bottom: 0;z-index: 100;background-color: rgba(0,0,0,0.6);.uploadBox{position: fixed;width: 24%;height: 40%;top: 30%;left: 38%;z-index: 1000;background-image: -webkit-linear-gradient(top, #fff,#f4f8ff, #e4ecfb, #c7d9fc);border: 1px solid #fff;border-radius: 15rpx;box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);.dialogBox{display: flex;flex-direction: column;padding: 10% 15% 0%;height: 67%;position: relative;.needLoad{height: 100%;display: flex;flex-direction: column;justify-content: space-between;}.loadingBox{height: 100%;display: flex;flex-direction: column;justify-content: space-around;}.circle{position: absolute;left: 0;right: 0;width: 14vh;height: 14vh;margin: 0 auto;top: -7vh;background-color: #fff;border-radius: 100%;display: flex;justify-content: center;align-items: center;image{width: 8vh;}}.title{margin-top: 30rpx;text-align: center;// line-height: 90rpx;font-size: 50rpx;font-weight: bold;}.buttonCon{display: flex;justify-content: space-between;.button{line-height: 90rpx;border-radius: 10rpx;text-align: center;width: 100%;font-size: 34rpx;}.button1{background-color: #336edf;color: #fff;}.button2{background-color: #fff;color: #7d7d7d;}.tips{font-size: 34rpx;line-height: 60rpx;}}}}
}
四、下载到安卓指定位置
uni.downloadFile设置下载文件的路径,但不能指定下载到设备的某个路径下,用plus.downloader.createDownload可以实现,代码还提供了替换功能。
代码如下:
//下载人脸文件updateNow() {this.saveFileWithCN('https://xxx/statics/datFile/Users.dat', 'Users.dat')},saveFileWithCN(fileUrl, customFileName) { // 文件下载地址, 自定义文件名const defaultPathPrefix = "/sdcard/Documents"; //下载到内存Documents文件下const fullPath = `${defaultPathPrefix}/${customFileName}`;console.log(fullPath)// 3. 检查并删除已存在的文件(实现替换功能)const File = plus.android.importClass('java.io.File');const targetFile = new File(fullPath);// uni.showLoading({// title: '核心文件下载中...',// mask: true// });this.tips = '核心文件下载中...';if (targetFile.exists()) {targetFile.delete(); // 删除旧文件console.log("已删除旧文件:", fullPath);}const dtask = plus.downloader.createDownload(fileUrl, {filename: fullPath}, (d, status) => {if (status === 200) {console.log("保存路径:", d.filename);this.tips = '核心文件下载完成!';uni.setStorageSync('update',true);this.initFaceModule();setTimeout(() => {this.tips = ''}, 1000)} else {this.tips = '核心文件下载失败!';setTimeout(() => {this.tips = ''}, 1000)}});dtask.start();},
五、运行结果