uniapp更新版本,apk包进度条,wgt包热更新

upgrade.js

/**
 * @description H5+下载App
 * @param downloadUrl:App下载链接
 * @param progressCallBack:下载进度回调
 */
export const downloadApp = (downloadUrl, progressCallBack = () => {}, ) => {
	return new Promise((resolve, reject) => {
		//创建下载任务
		const downloadTask = plus.downloader.createDownload(downloadUrl, {
			method: "GET"
		}, (task, status) => {
			console.log(status,'status')
			if (status == 200) { //下载成功
				resolve(task.filename)
 
			} else {
				reject('fail')
				uni.showToast({
					title: '下载失败',
					duration: 1500,
					icon: "none"
				});
			}
		})
		//监听下载过程
		downloadTask.addEventListener("statechanged", (task, status) => {
			switch (task.state) {
				case 1: // 开始  
					break;
				case 2: //已连接到服务器  
					break;
				case 3: // 已接收到数据  
					let hasProgress = task.totalSize && task.totalSize > 0 //是否能获取到App大小
					if (hasProgress) {
						let current = parseInt(100 * task.downloadedSize / task.totalSize); //获取下载进度百分比
						progressCallBack(current)
					}
					break;
				case 4: // 下载完成       
					break;
			}
		});
		//开始执行下载
		downloadTask.start();
	})
 
 
}
/**
 * @description H5+安装APP
 * @param fileName:app文件名
 * @param callBack:安装成功回调
 */
export const installApp = (fileName, callBack = () => {}) => {
	//注册广播监听app安装情况
	onInstallListening(callBack);
	//开始安装
	plus.runtime.install(plus.io.convertLocalFileSystemURL(fileName), {}, () => {
		//成功跳转到安装界面
	}, function(error) {
		uni.showToast({
			title: '安装失败',
			duration: 1500,
			icon: "none"
		});
	})
 
}
/**
 * @description 注册广播监听APP是否安装成功
 * @param callBack:安装成功回调函数
 */
const onInstallListening = (callBack = () => {}) => {
 
	let mainActivity = plus.android.runtimeMainActivity(); //获取activity
	//生成广播接收器
	let receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {
		onReceive: (context, intent) => { //接收广播回调  
			plus.android.importClass(intent);
			mainActivity.unregisterReceiver(receiver); //取消监听
			callBack()
		}
	});
	let IntentFilter = plus.android.importClass('android.content.IntentFilter');
	let Intent = plus.android.importClass('android.content.Intent');
	let filter = new IntentFilter();
	filter.addAction(Intent.ACTION_PACKAGE_ADDED); //监听APP安装     
	filter.addDataScheme("package");
	mainActivity.registerReceiver(receiver, filter); //注册广播
 
}

update_mask.vue

<template>
    <view>
        <view class="update-mask" v-if="show || showPrgress">
            <view class="update-wrap" v-if="show">
                <view class="update-title">发现新版本</view>
                <view class="update-version">v{{ dataInfo.appVersion }}</view>
                <view class="update-conent">
                    <!-- <view class="update-con-title">更新内容:</view> -->
                    <view class="update-con-p">
                        <view class="update-p">尊敬的用户:</view>
                        <view class="update-p">您当前版本V{{ systemVersion }},为了提供更好的用户体验和功能改进,我们应用需要进行强制更新,请尽快更新至最新版本以获得最新功能和改进。感谢您的理解与支持!</view>
                    </view>
                </view>
                <button class="update-btn" v-if="!btnDisable" @click="gotoUpdate">
                    立即更新
                </button>
                <view class="progress-view" @click="handleInstallApp" v-else-if="btnDisable">
					<view v-if="showPrgress" style="height: 100%;">
						<view class="txt">{{percentText}}</view>
						<view class="progress"  :style="{
                            width: `${progress}%`
                        }"></view>
					</view>
                    <button class="update-finish" v-else>
                        {{ isDownloadFinish  ? '立即安装' :'下载中...'}}
                    </button>
				</view>
            </view>
        </view>
    </view>
</template>
<script>
import { getAppVersion } from '@/api/api.js'
import {
    downloadApp,
    installApp
} from './upgrade.js'
export default {
    components: {},
    data() {
        return {
            show: false,
            info: "",
            dataInfo: "",
            showPrgress: false,
            progress: 0,
            percentText: '下载中',
            isDownloadFinish: false,
            btnDisable: false,
            systemVersion:"",
            testData:"",
            fileName: "",//文件名称
        }
    },
    watch: {},
    async mounted() {
        // 大版本更新
        this.getUplate(); 
    },
    methods: {
        getUplate(){
            uni.hideLoading();
            let that = this;
            const info = uni.getSystemInfoSync()
            const systemVersion = plus.runtime.version
            that.systemVersion = systemVersion;
            let updateStatus = ""
            getAppVersion().then(res => {
                let status = res.status;
                let data = res.data;
                if (status === 200 && data) {
                    if (data.androidAddress) {
                        if (data.androidAddress.indexOf('.apk') > -1) {
                            const nowVersion = systemVersion.split('.').join('')
                            let appVersion = data.appVersion.split('.').join('')
                            console.log("当前版本",nowVersion)
                            console.log("线上版本",appVersion)
							console.log("是否更新",nowVersion < appVersion)
                            if (nowVersion < appVersion) {
                                uni.hideTabBar();
                                updateStatus = 'apk';
                                that.updateMet(updateStatus,info,data);
                            }
                        } 
                    }
                }
            })
           
        },
        updateMet(updateStatus,info,data){
            if(updateStatus == 'apk' || updateStatus == 'wgt'){
                this.show = true;
                this.info = info;
                this.dataInfo = data;
                this.updateStatus = updateStatus;
            }
        },
        // 开始更新
        gotoUpdate(){
            this.btnDisable = true;
            if(this.updateStatus == 'apk'){
                this.apkUpdate(this.info, this.dataInfo);
            }
        },
        //安装app
        handleInstallApp() {
           //下载完成才能安装,防止下载过程中点击
            if (this.isDownloadFinish && this.fileName) {
                installApp(this.fileName, () => {
                    //安装成功,关闭升级弹窗
                    // uni.navigateBack()
                })
            }
        },
        apkUpdate(info, data){
            let that = this;
            downloadApp(data.androidAddress, current => {
                that.showPrgress = true;
                that.progress = current;
                that.percentText = `下载中${current}%`
            }).then(fileName => {
                //下载完成
                that.isDownloadFinish = true;
                that.percentText = `下载完成`
                that.showPrgress = false;
                that.fileName = fileName
                if (fileName) {
                    //自动安装App
                    that.handleInstallApp()
                }
            }).catch(e => {
                console.log(e, 'e')
            })
        },
    },
}
</script>
<style lang="scss" scoped>
$btn-height: 80rpx;
.update-mask{
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1000;
    background: rgba(0,0,0,0.3);
    z-index: 99999;
    .update-wrap{
        background: #fff;
        color: #000;
        position: absolute;
        width: 80%;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
        padding: 40rpx;
        border-radius: 20rpx;
        letter-spacing: 2rpx;
    }
    .update-title{
        font-size: 38rpx;
        margin-bottom: 6rpx;
    }
    .update-version{
        font-size: 28rpx;
        margin-bottom: 60rpx;
        margin-top: 6rpx;
    }
    .update-conent{
        font-size: 24rpx;
    }
    .update-con-p{
        margin: 30rpx 0;
    }
    .update-p{
        line-height: 40rpx;
    }
    .update-btn{
        background: #43CF7C;
        text-align: center;
        color: #fff;
        height: $btn-height;
        line-height: $btn-height;
        border-radius: 6rpx;
        position: relative;
        font-size: 32rpx;
    }
}
.progress-view {
    width: 100%;
    height: $btn-height;
    display: flex;
    position: relative;
    align-items: center;
    border-radius: 6rpx;
    background-color: rgba(255,255,255,0.4);
    display: flex;
    justify-content: flex-start;
    overflow: hidden;
    border: 1px solid #43CF7C;
    .progress {
        height: 100%;
        background-color: rgba(67,207,124,0.3);
        padding: 0px;
        box-sizing: border-box;
        width: 20%;
        position: absolute;
        top: 0;
        left: 0;
    }

    .txt {
        font-size: 28rpx;
        position: absolute;
        top: 50%;
        left: 50%;
        z-index: 10;
        transform: translate(-50%, -50%);
        color: #43CF7C;
    }
    .update-finish{
        position: absolute;
        width: 100%;
        height: 100%;
        text-align: center;
        line-height: $btn-height;
        color: #43CF7C;
        font-size: 28rpx;
    }
}
</style>

wgt更新

wgtUpdate.js

function wgtUpdate(data){
    uni.downloadFile({
        url: data.androidAddress,
        success: downloadResult => {
            if (downloadResult.statusCode === 200) {
                plus.runtime.install(
                    downloadResult.tempFilePath,
                    {
                        force: false
                    },
                    function () {
                        console.log('install success...')
                        plus.runtime.restart()
                    },
                    function (error) {
                        uni.showModal({
                            title: '更新失败',
                            content: error.message,
                            confirmText: '我知道了',
                            showCancel: false
                        })
                        console.error('install fail...')
                    }
                )
            }
        }
    })
}
export default wgtUpdate

app.vue

<script>
	import wgtUpdate from "@/utils/update/wgtUpdate";
	import { getAppVersion } from '@/api/api.js';
	export default {
		globalData: {},
		onLaunch: function(option) {
			getAppVersion().then(res => {
				let status = res.status;
				let data = res.data;
				if (status === 200 && data) {
					if(data.androidAddress.indexOf('.wgt') > -1) {
						plus.runtime.getProperty(plus.runtime.appid, function (widgetInfo) {
							if (widgetInfo.version < data.appVersion) {
								wgtUpdate(data)
							}
						})
					}
				}
			
			})
		},
		onShow() {	
		},
		methods: {

		},
	}
</script>
<style lang="scss">
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BGP(Border Gateway Protocol)路由收集器

全球 BGP&#xff08;边界网关协议&#xff09;路由收集器的分布情况以及相关数据。以下是主要的信息解读&#xff1a; 地图标记&#xff1a; 每个绿色点代表一个路由收集器的位置。路由收集器分布在全球不同的地区&#xff0c;覆盖了五大区域&#xff1a; ARIN&#xff08;美…

【Rust自学】10.5. 生命周期 Pt.1:生命周期的定义与意义、借用检查器与泛型生命周期

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 10.5.1. 什么是生命周期 Rust的每个引用都有自己的生命周期&#xff0c;生命周期的作用是让引用保持有效&#xff0c;也可以说它是保持引…

Vue2: table加载树形数据的踩坑记录

table中需要加载树形数据,如图: 官网给了两个例子,且每个例子中的tree-props都是这么写的: :tree-props="{children: children, hasChildren: hasChildren}" 给我一种错觉,以为数据结构中要同时指定children和hasChildren字段,然而,在非懒加载模式下,数据结…

深入了解 SSL/TLS 协议及其工作原理

深入了解 SSL/TLS 协议及其工作原理 一. 什么是 SSL/TLS?二. SSL/TLS 握手过程三. SSL/TLS 数据加密与传输四. 总结 点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有惊喜。 作者&#xff1a;神的孩子都在歌唱 一. 什么是 SSL/TLS? 安全套接层&am…

sqlserver sql转HTMM邮件发送

通过sql的形式&#xff0c;把表内数据通过邮件的形式发送出去 declare title varchar(100) DECLARE stat_date CHAR(10),create_time datetime SET stat_dateCONVERT(char(10),GETDATE(),120) SET create_timeDATEADD(MINUTE,-20,GETDATE()) DECLARE xml NVARCHAR (max) DECLAR…

用QT实现 端口扫描工具1

安装在线QT&#xff0c;尽量是完整地自己进行安装&#xff0c;不然会少包 参考【保姆级图文教程】QT下载、安装、入门、配置VS Qt环境-CSDN博客 临时存储空间不够。 Windows系统通常会使用C盘来存储临时文件。 修改临时文件存储位置 打开系统属性&#xff1a; 右键点击“此电…

Selenium 自动化,如何下载正确的 ChromeDriver

在 Python 的 Selenium 自动化操作中&#xff0c;chromedriver 是不可或缺的驱动程序。没有正确安装对应版本的驱动&#xff0c;运行代码时常常会遇到报错问题&#xff0c;比如 “session not created: This version of ChromeDriver only supports Chrome version XX”。 今天…

泊松融合 实例2025

目录 例子1: 实现代码: 原作者代码: 本博客直接给出来最好的效果和源代码 参数说明: 效果不好,不推荐的参数:MONOCHROME_TRANSFER,NORMAL_CLONE 例子1: 目标图: 原图: 效果图: 实现代码: 坐标是要目标图上中心点坐标: import cv2if __na

前端如何从入门进阶到高级

在前端学习的道路上&#xff0c;我们将其划分为三个阶段&#xff1a;入门、实战和进阶。以下是各阶段的学习指南 一、入门阶段 在入门阶段&#xff0c;我们的目标是掌握前端的基本语法和知识&#xff0c;以便能够独立解决一些基础问题。这一阶段&#xff0c;我们建议通过视频…

Python爬虫基础——认识网页结构(各种标签的使用)

1、添加<div>标签的代码定义了两个区块的宽度和高度均为100px&#xff0c;边框的格式也相同&#xff0c;只是区块中显示的内容不同&#xff1b; 2、添加<ul>和<ol>标签分别用于定义无序列表和有序列表。<il>标签位于<ul>标签或<ol>标签之…

基于W2605C语音识别合成芯片的智能语音交互闹钟方案-AI对话享受智能生活

随着科技的飞速发展&#xff0c;智能家居产品正逐步渗透到我们的日常生活中&#xff0c;其中智能闹钟作为时间管理的得力助手&#xff0c;也在不断进化。基于W2605C语音识别与语音合成芯片的智能语音交互闹钟&#xff0c;凭借其强大的联网能力、自动校时功能、实时天气获取、以…

Python提取目标Json键值:包含子嵌套列表和字典

目标&#xff1a;取json中所有的Name、Age字典 思路&#xff1a;递归处理字典中直接包含子字典的情况&#xff0c; import jsondef find_targ_dicts(data,key1,key2):result {}if isinstance(data, dict):if key1 in data and key2 in data: # 第一层字典中包含key1和key2re…

你已经分清JAVA中JVM、JDK与JRE的作用和关系了吗?

你已经分清JAVA中JVM、JDK与JRE的作用和关系了吗&#xff1f; 一. JVM、JDK与JRE的关系二. JVM、JDK与JRE的作用2.1 什么是JVM&#xff1f;2.2 什么是JDK&#xff1f;2.3 什么是JRE&#xff1f; 前言 点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有…

深度学习blog-RAG构建高效生成式AI的优选路径

RAG&#xff08;Retrieval-Augmented Generation&#xff09; 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;模型的性能和应用场景也不断扩展。其中&#xff0c;检索增强生成&#xff08;RAG, Retrieval-Augmented Generation&#xff09;模型作为一种新…

数据中台与数据治理服务方案[50页PPT]

本文概述了数据中台与数据治理服务方案的核心要点。数据中台作为政务服务数据化的核心&#xff0c;通过整合各部门业务系统数据&#xff0c;进行建模与加工&#xff0c;以新数据驱动政府管理效率提升与政务服务能力增强。数据治理则聚焦于解决整体架构问题&#xff0c;确保数据…

AI生成PPT,效率与创意的双重升级

AI生成PPT&#xff0c;效率与创意的双重升级&#xff01;在信息化高速发展的今天&#xff0c;我们的工作节奏被无限压缩&#xff0c;效率成为了衡量工作能力的重要指标。而制作PPT这种事&#xff0c;总是让人又爱又恨——既想做得出彩&#xff0c;又不想花费大量时间。现在有了…

【HF设计模式】05-单例模式

声明&#xff1a;仅为个人学习总结&#xff0c;还请批判性查看&#xff0c;如有不同观点&#xff0c;欢迎交流。 摘要 《Head First设计模式》第5章笔记&#xff1a;结合示例应用和代码&#xff0c;介绍单例模式&#xff0c;包括遇到的问题、采用的解决方案、以及达到的效果。…

嵌入式linux系统中QT信号与槽实现

第一:Qt中信号与槽简介 信号与槽是Qt编程的基础。因为有了信号与槽的编程机制,在Qt中处理界面各个组件的交互操作时变得更加直观和简单。 槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。 案例操作与实现: #ifndef …

php有两个数组map比较 通过id关联,number可能数量变化 比较他们之间增加修改删除

在PHP中&#xff0c;比较两个通过ID关联的数组&#xff0c;并确定它们之间的增加、修改和删除操作&#xff0c;你可以使用以下步骤&#xff1a; 创建两个数组&#xff1a;假设你有两个数组&#xff0c;分别表示“旧数据”和“新数据”。使用ID作为键&#xff1a;为了方便比较&a…

C++和OpenGL实现3D游戏编程【连载19】——着色器光照初步(平行光和光照贴图)(附源码)

1、本节要实现的内容 我们在前期的教程中,讨论了在即时渲染模式下的光照内容。但在我们后期使用着色器的核心模式下,会经常在着色器中使光照,我们这里就讨论一下着色器光照效果,以及光照贴图效果,同时这里知识会为后期的更多光照效果做一些铺垫。本节我们首先讨论冯氏光照…