当前位置: 首页 > news >正文

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();},

五、运行结果

 

相关文章:

  • “数字驱动·智建未来——2025河北省建筑电气与智能化技术交流大会”
  • C++实时统计数据均值、方差和标准差
  • python如何用递归函数求1+2+3+4+5的值
  • 【linux】一文掌握 Tmux 的各种指令(Tmux备忘清单)
  • 开源CMS系统的SEO优化功能主要依赖哪些插件?
  • Android Studio 2024版,前进返回按钮丢失解决
  • mysql模糊多次OR查询某一个字段,针对这个字段进行查询分组
  • 软件评测:从多维度看其界面、功能、性能稳定性如何?
  • ubantu18.04(Hadoop3.1.3)之Flink安装与编程实践(Flink1.9.1)
  • AWS虚拟专用网络全解析:从基础到高级实践
  • 【前端】从零开始的搭建顺序指南(技术栈:Node.js + Express + MongoDB + React)book-management
  • Spring项目使用JWT进行后端鉴权
  • 让数据优雅落地:用 serde::Deserialize 玩转结构体实体
  • Prompt
  • Go 1.24 is released(翻译)
  • 【leetcode】最长公共子路径问题
  • TypeScript概述
  • 2025年特种设备作业人员考试题库及答案(流动式起重机Q2)
  • 2.2.2goweb内置的 HTTP 处理程序2
  • gem5教程 第七章 如何在 gem 5 中运行我自己的程序
  • “上报集团文化助力区域高质量发展赋能平台”揭牌
  • 上海市市管干部任职前公示:赵亮拟为地区区长人选
  • 民航局答澎湃:督促各单位进一步完善航班大面积延误和大面积备降应急处置预案
  • 出国留学、来华留学呈现双增新趋势,“00后留学生个性鲜明”
  • 博物馆有一项活动40岁以上不能参加?馆方回应
  • 交通枢纽、产业升级,上海松江新城有这些发展密码