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

五、运行结果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/903456.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

局部和整体的关系

Prompt&#xff1a;为什么要研究局部和整体的关系呢&#xff1f;是因为很多情况下&#xff0c;局部就能表达出整体&#xff1f; 这是一个非常本质的问题&#xff0c;其实你已经接近数学和物理中“几何本质”的核心了。我们研究局部和整体的关系&#xff0c;是因为&#xff1a;…

企业办公协同平台安全一体化生态入住技术架构与接口标准分析报告

全球组织数字化与智能化背景下 企业办公协同平台安全一体化生态入住技术架构与接口标准分析报告 一、背景与市场需求 市场规模与增量 根据Statista数据&#xff0c;全球协同办公平台市场规模预计从2023年的$480亿增长至2027年的$900亿&#xff0c;年复合增长率&#xff08;CAG…

【2025最新面试八股常问知识点】HTTP1.0,HTTP1.1,HTTP2.0,HTTP3.0,HTTP的进化之路。

HTTP 超文本传输协议&#xff08;英文&#xff1a;HyperText Transfer Protocol&#xff0c;缩写&#xff1a;HTTP&#xff09;是一种用于分布式、协作式和超媒体信息系统的应用层协议。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的…

【算法练习】归并排序和归并分治

文章目录 1.归并排序1.1 递归版本1.2 非递归版本 2.归并分治2.1 计算数组的小和2.2 计算翻转对 1.归并排序 归并排序的核心步骤是&#xff1a; 拆分&#xff1a;将无序数组不断对半拆分成小块&#xff0c;直到每个小块只剩一个元素&#xff08;自然有序&#xff09;。 合并&a…

域对齐是什么

域对齐&#xff08;Domain Alignment&#xff09;是在机器学习和计算机视觉等领域中常用的技术 定义 域对齐旨在将不同域&#xff08;Domain&#xff09;的数据映射到一个共同的特征空间中&#xff0c;使得来自不同域的数据在该空间中具有相似的分布。这里的“域”可以指代不…

【linux】git安装、升级

git安装、升级 一、快捷安装版本2.18.0二、自定义版本安装&#xff08;安装、升级&#xff09;1、移除旧文件2、安装所需依赖3、选择指定版本4、解压文件、编译5、增加环境变量&#xff0c;验证是否版本 三、升级 一、快捷安装版本2.18.0 yum install git git --version二、自…

编程日志4.24

栈的链表基础表示结构 #include<iostream> #include<stdexcept> using namespace std; //模板声明&#xff0c;表明Stack类是一个通用的模板&#xff0c;可以用于存储任何类型的元素T template<typename T> //栈的声明 //Stack类的声明&#xff0c;表示一…

《冰雪传奇点卡版》:探索冰雪世界的传奇旅程!

《冰雪传奇点卡版》以“纯净打金”为核心&#xff0c;摒弃复杂付费坑&#xff0c;回归经典传奇玩法。以下从核心玩法、资源获取、职业搭配、交易变现四维度展开&#xff0c;助你高效开启冰雪传奇之旅。 一、核玩法解析&#xff1a;如何高效获取资源&#xff1f; 1. 职业定位与…

DeepClaude开源程序可以实现代码生成、创作诗句以及内容创作等功能

一、软件介绍 文末提供程序和源码下载 DeepClaude开源程序是增强的 AI&#xff0c;可以实现代码生成&#xff1a;DeepSeek r1 Claude 3.7 十四行诗 - 无与伦比的性能&#xff01;内容创作&#xff1a;DeepSeek r1 Gemini 2.5 Pro - 卓越的质量&#xff01;OpenAI 兼容。流媒…

Java常用注解通俗解释

注解就像是给Java代码贴的"便利贴"&#xff0c;它们不会改变代码本身的逻辑&#xff0c;但能给编译器、开发工具或运行时环境提供额外信息。下面我用最通俗的方式解释Java中最常用的注解&#xff1a; 一、基础篇&#xff1a;人人必知的注解 1. Override - "我…

vscode chrome调试怎么在所有浏览器都好使

chrome调试时只能在打开的浏览器里进行调试&#xff0c;其它打开的chrome浏览器就不能调试了&#xff0c;怎么解决。 右键点击 Chrome 的快捷方式图标&#xff0c;选择属性 在目标一栏&#xff0c;最后加上--remote-debugging-port9222 注意要用空格隔开 lanch.json 文件配置 …

Unity PBR基础知识

PBR原理 基于物理的渲染&#xff08;Physically Based Rendering&#xff0c;PBR&#xff09;是指使用基于物理原理和微平面理论建模的着色/光照模型&#xff0c;以及使用从现实中测量的表面参数来准确表示真实世界材质的渲染理念。 PBR基础理念 微平面理论&#xff08;Micr…

COM组件使用方法

普通COM组件&#xff08;如DLL&#xff09;仅暴露方法/属性接口&#xff0c;而ActiveX控件&#xff08;如OCX&#xff09;需要可视化交互&#xff08;如按钮、表格&#xff09;&#xff0c;需通过 ​​AxInterop​​ 包装器实现宿主环境集成。 项目中引入ActiveX控件流程如下。…

在 Spring Boot 项目中如何使用索引来优化 SQL 查询?

在 Spring Boot 项目中使用索引来优化 SQL 查询是提升数据库性能最常用的方法之一。下面是详细的步骤和实践指南&#xff1a; 核心目标&#xff1a;让数据库能够通过扫描索引&#xff08;小范围、有序的数据结构&#xff09;快速定位到所需数据行&#xff0c;而不是扫描整个表…

Vue3生产环境与Vue Devtools

在 Vue 3 的生产环境中&#xff0c;默认情况下 Vue Devtools 是无法正常使用 的&#xff0c;但开发者可以通过配置强制启用。以下是关键信息总结&#xff1a; &#x1f4cc; 核心结论 默认不可用 Vue 3 生产构建会移除 Devtools 支持以优化性能和安全性。 可强制启用 通过构建…

ARP渗透学习1

ARP协议工作原理 1. 什么是ARP ARP定义: 地址解析协议&#xff08;Address Resolution Protocol&#xff09;&#xff0c;是根据IP地址获取物理地址的一个TCP/IP协议。 2. 工作原理 ARP表: 每台计算机都需要一个ARP表&#xff0c;用来保存IP地址和MAC地址的映射关系。查询过…

甲骨文云2025深度解析:AI驱动的云原生生态与全球化突围

一、战略转型&#xff1a;从数据库巨头到AI云服务先锋 1. 技术重心向AI与云深度迁移 甲骨文在2025年加速向AI原生云架构转型&#xff0c;其核心战略围绕生成式AI与量子计算展开。通过推出Oracle 23ai自治数据库&#xff0c;深度集成AI向量搜索功能&#xff0c;并重构云基础设…

【网络原理】TCP异常处理(二):连接异常

目录 一. 由进程崩溃引起的连接断开 二. 由关机引起的连接断开 三. 由断电引起的连接断开 四. 由网线断开引起的连接断开 一. 由进程崩溃引起的连接断开 在一般情况下&#xff0c;进程无论是正常结束&#xff0c;还是异常崩溃&#xff0c;都会触发回收文件资源&#xff0c;…

想做博闻强记的自己

2025年4月29日&#xff0c;13~25℃&#xff0c;还好 待办&#xff1a; 冶金《物理》期末测试 阅卷&#xff08;冶金《物理》期末测试试卷&#xff09; 重修《物理》《物理2》电子材料归档 规则变更&#xff0c;《高等数学2》期末试卷推倒重来 遇见&#xff1a;直播画面。 感受…

IP属地是实时位置还是自己设置

刷微博、抖音时&#xff0c;评论区总能看到“IP属地”&#xff1f;这个突然冒出来的小标签&#xff0c;让不少网友摸不着头脑&#xff1a;‌IP属地是实时位置&#xff0c;还是可以自己设置&#xff1f;‌别急&#xff0c;今天咱们就来聊聊这个话题&#xff01; 1、什么是IP属地…