uni-app应用更新(Android端)

news2024/9/23 13:16:38

关于app更新,uni-app官方推荐的是 uni-upgrade-center,看了下比较繁琐,因此这里自己实现检查更新并下载安装的逻辑。

1.界面效果

               

界面中的弹框和 进度条采用了uView 提供的组件

2.检查更新并下载安装

一、版本信息配置在服务端,请求服务端接口判断是否需要更新 。

二、点击下载按钮,则开始下载App安装包,并监听下载进度,实时更新下载进度条

注意:下载App如果是在浏览器测试,可能会有跨域的问题,需要后端服务允许跨域。

三、待下载完成后开始安装。

安装App采用的是 uni-installApk插件,请自行导入项目

uni-installApk - DCloud 插件市场

3.完整代码 

update.vue

<template>
	<u-modal :show="show"   :showConfirmButton="false">
		<view class="box-a4">
			<image class="img-up" mode="widthFix" 
				src="https://beilizhengxuan.oss-cn-hangzhou.aliyuncs.com/huayu/update.png"/>
			<view class="box-a5">
				<text>发现新版本V{{version}},升级后体验更顺畅</text>
			</view>
			<view class="row-b0" v-if="!startDownload">
				<view class="btn0" @click="downLoadApp" >马上更新</view>
				<view class="btn0 white" color=""  @click="cancel"
					 v-if="forceUpdata=='0'">暂不更新</view>
			</view>
			<view v-if="startDownload" class="row-b1">
				<view class="te-j0">下载进度</view>
				<u-line-progress :percentage="percent" height="24"
					activeColor="#3c9cff"></u-line-progress>
			</view>
		</view>
	</u-modal>
</template>
<script>
import {getAppNewVersion} from '@/api/system/user'
export default{
	props:{
	},
	data(){
		return{
			startDownload: false, //是否开始下载
			show: false,
			version: '',
			forceUpdata: '',//是否需要强制更新
			apkDownloadUrl: '',//
			percent: 0,
			filePath: '',
		}
	},
	created(){
		this.handleToUpgrade()
	},
	computed:{
		showUpdate(){
			console.log('this.$stroe.state.user',this.$stroe.state.user)
			return this.$stroe.state.user.showUpdate
		}
	},
	methods:{
		async handleToUpgrade() {
			const sysInfo = uni.getSystemInfoSync()
			const appVersion = sysInfo.appVersion
			
			console.log('appVersion', appVersion)
            //请求服务端检查更新接口,判断是否需要更新
			const res = await getAppNewVersion()
	
			if(res.code == 200){
				if(res.data && res.data.newVersion){
					const newVersion = res.data.newVersion
					if(appVersion == newVersion){
						this.showToast('当前已是最新版本')
                        this.cancel()
					} else{
                        this.apkDownloadUrl = res.data.apkDownloadUrl
						this.show = true
						console.log('需要更新')
						this.version = newVersion
						this.forceUpdata =  res.data.forceUpdata
					}
				}
			}
		},
		installApp(){
			uni.installApk({
				filePath : this.filePath,
				success: (res)=>{
					console.log('安装成功--', res);
				},
				fail : (res)=>{
					console.log('安装失败--', res);
				},
				complete: (res)=>{
					console.log('安装完成--', res);
				}
			})
		},
		downLoadApp(){
			this.startDownload = true
			const downloadTask = uni.downloadFile({
				url: this.apkDownloadUrl , //仅为示例,并非真实的资源
				timeout: 6000000,
				success: (res) => {
					console.log('success res', res)
					if (res.statusCode === 200) {
						this.filePath = res.tempFilePath
						console.log('下载成功');
						this.cancel()
						this.installApp()
					}
				},
				complete: (res)=> {
					console.log('complete res', res)
				},
				fail: (res)=> {
					console.log('fail res', res)
				},
			});
			downloadTask.onProgressUpdate((res) => {
				//console.log('下载进度' + res.progress);
				//console.log('已经下载的数据长度' + res.totalBytesWritten);
				//console.log('预期需要下载的数据总长度' + res.totalBytesExpectedToWrite);
				this.percent = res.progress
				if (res.progress >= 100) {
					console.log('下载进度 abort' + res.progress);
					//downloadTask.abort();
				}
			});
		},
		cancel(){
			this.$emit('cancel')
			this.show = false
		},
        showToast(message){
	       uni.showToast({
             title: message,
              icon: 'none'
            })
        }
	}
}
</script>

<style>
	.img-up{
		width: 100%;
	}
	.box-a4{
		width: 100%;
		display: flex;
		flex-direction: column;
		justify-content: flex-start;
	}
	.box-a5{
		flex:1;
		text-align: center;
		font-size: 28rpx;
		color: #999;
		padding: 20rpx 0;
	}
	.row-b0{
		display:flex;
		flex-direction: row;
		justify-content: space-around;
		align-items: center;
		padding: 0 50rpx;
		margin-top:60rpx;
		margin-bottom:60rpx;
	}
	.row-b0 .btn0{
		width: 240rpx;
		height: 68rpx;
		border-radius: 34rpx;
		color: white;
		display: grid;
		place-content: center;
		background:#3c9cff;
	}
	.row-b0 .btn0:active{
		opacity: 0.7;
	}
	.row-b0 .btn0.white{
		background:#fff;
		color: #666;
		border:1px solid #eee;
	}
	.row-b1{
		margin: 60rpx 40rpx;
	}
	.te-j0{
		text-align: center;
		color:#999;
		font-size: 26rpx;
		margin-bottom:20rpx;
	}
</style>

 4.引入并使用

上面将检查更新的逻辑封装在了update.vue中,使用时只需引入该组件,在父页面点击检查更新按钮时,只需将 checkUpdate 属性设置为 true,则加载 update.vue组件,进入created 方法并调用检查更新的相关逻辑,有新版本则弹框,提示更新,无新版本则将 checkUpdate重置为 false

注意:当检查更新的弹框弹出时,调用页面需要禁用 android的 返回按键,在  onBackPress函数里面做相应的逻辑判断即可。

<template>
  <view >
	<UpdateApp v-if="checkUpdate" @cancel="checkUpdate=false"/>
  </view>
</template>
<script>
import UpdateApp from './update'
  export default {
		components:{
			UpdateApp
		},
    data() {
      return {
			checkUpdate: false,
      }
    },
	onBackPress(options) {
		console.log('onBackPress options', options)
		// 禁用返回
		if (options.from == 'backbutton') {
			console.log('--禁用返回')
			if(this.checkUpdate){
				return true;// 禁用返回按键
			}else {
				return false;
			}
		}
	},
    methods: {
			
    }
  }
</script>
<style lang="scss" scoped>

</style>

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

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

相关文章

【Azure Redis】Redis-CLI连接Redis 6380端口始终遇见 I/O Error

问题描述 使用Redis-cli连接Redis服务&#xff0c;因为工具无法直接支持TLS 6380端口连接&#xff0c;所以需要使用 stunnel 配置TLS/SSL服务。根据文章(Linux VM使用6380端口(SSL方式)连接Azure Redis (redis-cli & stunnel) &#xff1a; https://www.cnblogs.com/luligh…

Python使用turtle画笑脸

import turtle as t t.pensize(5) #设置画笔尺寸 t.color("red","yellow") #设置画笔颜色 t.begin_fill() #开始填充 t.circle(150) #绘制一个半径为100像素的圆 t.end_fill() #结束填充#画眼睛&#xff08;左眼…

Leetcode - 周赛413

目录 一&#xff0c;3274. 检查棋盘方格颜色是否相同 二&#xff0c;3275. 第 K 近障碍物查询 三&#xff0c;3276. 选择矩阵中单元格的最大得分 四&#xff0c;3277. 查询子数组最大异或值 一&#xff0c;3274. 检查棋盘方格颜色是否相同 本题就是找规律&#xff0c;假设白…

x11转发远程图形界面

1、 开一个有vnc的节点 2、 开放所有用户的Xserver权限 xhost 3、X11转发 ssh hlzhang192.168.3.156 -X4、打开远程窗口 paraview在227的界面打开156的图形窗口

uniapp和vue3中使用vConsole在H5中开启移动端调试

uniapp和vue3中使用vConsole在H5中开启移动端调试 1. 安装vconsole npm install vconsole --save2. 在main.js中全局引入 重新启动项目即可

【C++】手搓实现模板类

myTamplate.h #ifndef MYTAMPLATE_H #define MYTAMPLATE_H #include <iostream> using namespace std;template<typename T> class Node {T *data; //数据域int size; //指针域int len;//实际长度 public://无参构造Node():size(10),len(0){data new T[size]…

写的一致性问题之双写模式

文章目录 1、先写mysql&#xff1a;mysql会回滚&#xff0c;而redis不会回滚2、先写redis&#xff1a; 1、先写mysql&#xff1a;mysql会回滚&#xff0c;而redis不会回滚 写入msql成功&#xff0c;写入redis也成功&#xff0c;但是后续事务提交失败&#xff0c;mysql会回滚&a…

Django学习(一)

一、创建django项目 二、修改settings.py里的配置&#xff1a; 1、修改语言和时区&#xff1a; # 语言编码 LANGUAGE_CODE zh-hansTIME_ZONE UTCUSE_I18N True# 不用时区 USE_TZ False 2、配置数据库&#xff1a; DATABASES {default: {ENGINE: django.db.backends.m…

Python中的self有什么作用

你是否曾经好奇过,为什么Python类中的方法总是有一个神秘的self参数?为什么有时它似乎可有可无,有时却又不可或缺?今天,让我们一起深入探讨Python中self的奥秘,揭开面向对象编程的神秘面纱! 目录 引言:self的重要性self的本质:实例的引用为什么需要self?self的工作原理self的…

极米科技:走出舒适圈,推动数据架构现代化升级 | OceanBase 《DB大咖说》

《DB 大咖说》第 13 期&#xff0c;邀请到了极米科技软件与创新产品线高级架构师施刘凡来进行分享。 在小红书平台上&#xff0c;“是否应将家里的电视升级为投影仪&#xff1f;”这一话题激发了上百万篇笔记的分享与推荐&#xff0c;反映出年轻群体对投影仪的偏好。随着手机、…

Java MVC

1. MVC模式 1.1. JavaBean JavaBean&#xff1a;符合特定规范的Java类&#xff0c;是一种可重用的组件 特定规范&#xff1a; public, class, 提供无参数构造方法属性private提供public的getter和setter方法 功能分类&#xff1a; 封装数据&#xff1a;数据Bean&#xff0c…

【gtokentool】什么是数字货币?怎么使用?

一、什么是数字货币 数字货币是一种基于密码学原理&#xff0c;独立于传统银行体系运行的电子货币形式。数字货币具有以下特点&#xff1a; 去中心化&#xff1a;数字货币采用去中心化的交易验证方式&#xff0c;不依赖于任何中央机构或政府。安全性高&#xff1a;通过加密算法…

STM32G474之DAC

STM32G474分别使用CORDIC硬件和“math.h”的正弦值&#xff0c;从DAC1和DAC2输出。 1、DAC特点 PA4的附加功能为DAC1_OUT1&#xff0c;无需映射&#xff0c;直接将它配置为模拟功能&#xff0c;就可以使用了。 PA6的附加功能为DAC2_OUT1&#xff0c;无需映射&#xff0c;直接将…

数据结构-栈、队列-详解

数据结构-栈、队列-详解 1.前言2.栈2.1是什么2.2函数实现struct StackStackInitStackDestroyStackPushStackSizeStackEmptyStackTopStackPop 2.3小结 3.队列3.1是什么3.2函数实现struct QueueQueueInitQueueDestroyQueueEmptyQueuePushQueuePopQueueFrontQueueBackQueueSize 3.…

Verilog基础,原码,反码与补码的概念

Verilog模块初认识 1、Verilog模块(Module) Verilog中的module可以看成一个具有输入输出端口的黑盒子&#xff0c;该黑盒子有输入和输出接口(信号)&#xff0c;通过把输入在盒子中执行某些操作来实现某项功能。(类似于C语言中的函数) 图1 模块示意图 1.1 模块描述 图1 所示的…

【408DS算法题】035进阶-17年真题_二叉树转中缀表达式

Index 真题题目分析实现总结 真题题目 请设计一个算法&#xff0c;将给定的表达式树&#xff08;二叉树&#xff09;转换为等价的中缀表达式&#xff08;通过括号反映操作符的计算次序&#xff09;并输出。 例如&#xff0c; 当下列两棵表达式树作为算法的输入时&#xff0c; …

vivado 定义约束设置和文件

步骤2&#xff1a;定义约束集和文件 首先创建一个新的约束集&#xff0c;并向其中添加一个空的XDC约束文件 示例设计已经包含两个约束集&#xff0c;但您没有在本实验室中使用它们。 1.在“流导航器”中&#xff0c;单击“项目管理器”部分中的“添加源”。 2.从“添加源”对话…

【自考zt】【软件工程】【21.10】

关键字&#xff1a; 软件需求基本性质、软件系统需求挑战、耦合&#xff08;高内容&#xff0c;低无直接&#xff09;、内聚&#xff08;初始化时间&#xff09;、uml包、rup边界类、测试首要目标、单元测试最后工作、性能需求 软件开发本质、软件需求规约三种风格、提炼、用…

windows C++ 并行编程-并发和UWP(二)

下面例程用于演示在UWP中进行并发编程。 示例: 创建 C Windows 运行时组件并从 C# 中使用它 假设有一个使用 XAML 和 C# 的应用&#xff0c;可用它来定义 UI 和 C Windows 运行时组件以执行计算密集型操作。 在此示例中&#xff0c;C 组件会计算给定范围中的哪些数字是质数。…

Sqoop 数据迁移

Sqoop 数据迁移 一、Sqoop 概述二、Sqoop 优势三、Sqoop 的架构与工作机制四、Sqoop Import 流程五、Sqoop Export 流程六、Sqoop 安装部署6.1 下载解压6.2 修改 Sqoop 配置文件6.3 配置 Sqoop 环境变量6.4 添加 MySQL 驱动包6.5 测试运行 Sqoop6.5.1 查看Sqoop命令语法6.5.2 测…