纯前端实现uniapp写的安卓APP跟IOS在线自动升级功能

关于Uniapp自动升级用到的阿里云要收费的问题
使用的UI框架为UVIEW2.0
用到的请求等

总结下思路 就是通过获取XML文件返回来的信息来判断要不要更新,用到的前端代码是在
链接: 升级中心 uni-upgrade-center - App.基础上修改的,后面附上修改后的代码
提取XML文件返回来的字段来对比版本号,以及获取下载地址等

创建升级前端组件

1.在项目components新建名为upgrade-center组件,新建up.js文件

2.在pages.json页面新增增加的组件页面路径

代码:

// 页面路径
{"path": "components/upgrade-center/upgrade-center","style": {"disableScroll": true,"app-plus": {"backgroundColorTop": "transparent","background": "transparent","titleNView": false,"scrollIndicator": false,"popGesture": "none","animationType": "fade-in","animationDuration": 200}}},

3.up.js代码
const PACKAGE_INFO_KEY = '__package_info__'export default function() {// #ifdef APP-PLUSlet appversion = ''plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => {console.log("A版本号", wgtinfo); //应用版本号appversion = wgtinfo.version})let xmlstr = nulluni.$u.http.get('填写为你的XML请求地址', {/* 会加在url上 */header: {},/* 会与全局header合并,如有同名属性,局部覆盖全局 */dataType: 'json',// 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)// #ifndef MP-ALIPAYresponseType: 'text',// #endif}).then(res => {let version = res.data.match(/version(\S*)version/)[1].replace(/[></]/g, '') // 版本// 整包更新 格式// let INFO_KEY_Up = {//   "message": "整包更新",//    "is_silently": false,//   "is_mandatory": true,//   "appid": "__uni__96d9bbc",//    "name": "银通车辆信息平台",//   "title": "",//  "contents": "",//   "platform": ["Android"],//  "version": "",//    "url": "",//    "stable_publish": true,//     "type": "native_app",//     "uni_platform": "android",//    "create_env": "upgrade-center",//   "create_date": 1673250560025// }// WGT更新 格式// let INFO_KEY_Up = {//  "message": "wgt更新",//   "is_silently": false,//   "is_mandatory": false,//  "appid": "__uni__96d9bbc",//    "name": "银通车辆信息平台",//   "title": "",//  "contents": "",//   "platform": ["Android"],//  "version": "",//    "min_uni_version": "",//    "url": "",//    "stable_publish": true,//     "type": "wgt",//    "uni_platform": "android",//    "create_env": "upgrade-center",//   "create_date": 1673250560025// }// WGT更新 let INFO_KEY_Up = {"message": "wgt更新","is_silently": false,"is_mandatory": false,"appid": "更改自己的APPID","name": "更改自己的软件名字","title": "","contents": "","platform": ["Android"],"version": "","min_uni_version": "","url": "","stable_publish": true,"type": "","uni_platform": "android", //安卓"create_env": "upgrade-center", "create_date": 1673856560025}let INFO_KEY = JSON.stringify(res.data).replace(/\s*/g, "") //获取XML内容console.log(INFO_KEY);INFO_KEY_Up.version = INFO_KEY.match(/version(\S*)version/)[1].replace(/[></]/g, '') // 版本INFO_KEY_Up.title = INFO_KEY.match(/title(\S*)title/)[1].replace(/[></]/g, '') // 版本INFO_KEY_Up.contents = INFO_KEY.match(/contents(\S*)contents/)[1].replace(/[></]/g, '') // WGT版本INFO_KEY_Up.url = INFO_KEY.match(/url(\S*)url/)[1].replace(/[><]/g, '')INFO_KEY_Up.url = INFO_KEY_Up.url.substr(0, INFO_KEY_Up.url.length - 1);INFO_KEY_Up.type = INFO_KEY.match(/type(\S*)type/)[1].replace(/[></]/g, '') // WGT或则整包更新if (appversion >= version) {uni.$u.toast("当前已经是最新版本")} else {let xt = uni.$u.os()console.log(xt, "当前设备类型");if (xt == 'android') {uni.$u.toast("发现新版本,请及时更新")}// IOS整包跳转到应用商城更新  //没有此需求可以注释if (xt == 'ios' && INFO_KEY_Up.type == 'native_app') {uni.$u.toast("发现新版本,正在前往APPStore更新")setTimeout(function() {let appleId = '填写你的IOS商店的ID'plus.runtime.launchApplication({action: `itms-apps://itunes.apple.com/cn/app/id${appleId}?mt=8`}, function(e) {console.log('Open system default browser failed: ' + e.message);});}, 1200);return}}if (appversion < version) {// let curPage = getCurrentPages();// let route = curPage[curPage.length - 1].route; //获取当前页面的路由console.log(INFO_KEY_Up, "当前更新版本信息");uni.setStorageSync('PACKAGE_INFO_KEY', INFO_KEY_Up)setTimeout(function() {let curPage = getCurrentPages();let route = curPage[curPage.length - 1].route; //获取当前页面的路由if (route != 'components/UPAPP/UPAPP') {let xt = uni.$u.os()console.log(xt, "当前设备类型");if (xt == 'android') {uni.reLaunch({url: `/components/upgrade-center/upgrade-center`,fail: (err) => {console.error('更新弹框跳转失败', err)}})return}if (xt == 'ios' && INFO_KEY_Up.type == 'wgt') {uni.reLaunch({url: `/components/upgrade-center/upgrade-center`,fail: (err) => {console.error('更新弹框跳转失败', err)}})return}}}, 500);} else {return}}).catch(err => {})// #endif
}
4.upgrade-center.vue代码
<template><view class="mask flex-center"><view class="content botton-radius"><view class="content-top"><text class="content-top-text">{{title}}</text><image class="content-top" style="top: 0;" width="100%" height="100%"src="../../uni_modules/uni-upgrade-center-app/images/bg_top.png"></image></view><view class="content-header"></view><view class="content-body"><view class="title"><text>{{subTitle}}</text><!-- <text style="padding-left:20rpx;font-size: 0.5em;color: #666;">v.{{version}}</text> --></view><view class="body"><scroll-view class="box-des-scroll" scroll-y="true"><text class="box-des">{{contents}}</text></scroll-view></view><view class="footer flex-center"><template><template v-if="!downloadSuccess"><view class="progress-box flex-column" v-if="downloading"><progress class="progress" border-radius="35" :percent="downLoadPercent"activeColor="#3DA7FF" show-info stroke-width="10" /><view style="width:100%;font-size: 28rpx;display: flex;justify-content: space-around;"><text>{{downLoadingText}}</text><text>({{downloadedSize}}/{{packageFileSize}}M)</text></view></view><button v-else class="content-button" style="border: none;color: #fff;" plain@click="updateApp">{{downLoadBtnText}}</button></template><button v-else-if="downloadSuccess && !installed" class="content-button"style="border: none;color: #fff;" plain :loading="installing" :disabled="installing"@click="installPackage">{{installing ? '正在安装……' : '下载完成,立即安装'}}</button><button v-if="installed && isWGT" class="content-button" style="border: none;color: #fff;" plain@click="restart">安装完毕,点击重启</button></template></view></view><!-- <image v-if="!is_mandatory" class="close-img"src="../../uni_modules/uni-upgrade-center-app/images/app_update_close.png" @click.stop="closeUpdate"></image><image v-if="is_mandatory" class="close-img"src="../../uni_modules/uni-upgrade-center-app/images/app_update_close.png" @click="closeUp"></image> --></view></view>
</template><script>const localFilePathKey = '__localFilePath__'const platform_iOS = 'iOS';let downloadTask = null;let openSchemePromise/*** 对比版本号,如需要,请自行修改判断规则* 支持比对  ("3.0.0.0.0.1.0.1", "3.0.0.0.0.1")  ("3.0.0.1", "3.0")  ("3.1.1", "3.1.1.1") 之类的* @param {Object} v1* @param {Object} v2* v1 > v2 return 1* v1 < v2 return -1* v1 == v2 return 0*/function compare(v1 = '0', v2 = '0') {v1 = String(v1).split('.')v2 = String(v2).split('.')const minVersionLens = Math.min(v1.length, v2.length);let result = 0;for (let i = 0; i < minVersionLens; i++) {const curV1 = Number(v1[i])const curV2 = Number(v2[i])if (curV1 > curV2) {result = 1break;} else if (curV1 < curV2) {result = -1break;}}if (result === 0 && (v1.length !== v2.length)) {const v1BiggerThenv2 = v1.length > v2.length;const maxLensVersion = v1BiggerThenv2 ? v1 : v2;for (let i = minVersionLens; i < maxLensVersion.length; i++) {const curVersion = Number(maxLensVersion[i])if (curVersion > 0) {v1BiggerThenv2 ? result = 1 : result = -1break;}}}return result;}export default {data() {return {// 从之前下载安装installForBeforeFilePath: '',// 安装installed: false,installing: false,// 下载downloadSuccess: false,downloading: false,downLoadPercent: 0,downloadedSize: 0,packageFileSize: 0,tempFilePath: '', // 要安装的本地包地址// 默认安装包信息title: '更新日志',contents: '',is_mandatory: false,// 可自定义属性subTitle: '发现新版本',downLoadBtnTextiOS: '立即跳转更新',downLoadBtnText: '立即下载更新',downLoadingText: '安装包下载中,请稍后'}},onLoad() {const localPackageInfo = uni.getStorageSync('PACKAGE_INFO_KEY');const requiredKey = ['version', 'url', 'type']for (let key in localPackageInfo) {if (requiredKey.indexOf(key) !== -1 && !localPackageInfo[key]) {console.error(`参数 ${key} 必填,请检查后重试`)uni.navigateBack()return;}}Object.assign(this, localPackageInfo)this.checkLocalStoragePackage()},onBackPress() {// 强制更新不允许返回if (this.is_mandatory) {return true}downloadTask && downloadTask.abort()},onHide() {openSchemePromise = null},computed: {isWGT() {return this.type === 'wgt'},// isiOS() {//  return !this.isWGT ? this.platform.includes(platform_iOS) : false;// },// isAppStore() {//  return this.isiOS || (!this.isiOS && !this.isWGT && this.url.indexOf('.apk') === -1)// }},methods: {checkLocalStoragePackage() {// 如果已经有下载好的包,则直接提示安装const localFilePathRecord = uni.getStorageSync(localFilePathKey)if (localFilePathRecord) {const {version,savedFilePath,installed} = localFilePathRecord// 比对版本if (!installed && compare(version, this.version) === 0) {this.downloadSuccess = true;this.installForBeforeFilePath = savedFilePath;this.tempFilePath = savedFilePath} else {// 如果保存的包版本小 或 已安装过,则直接删除this.deleteSavedFile(savedFilePath)}}},async closeUpdate() {if (this.downloading) {if (this.is_mandatory) {return uni.showToast({title: '下载中,请稍后……',icon: 'none',duration: 500})}uni.showModal({title: '是否取消下载?',cancelText: '否',confirmText: '是',success: res => {if (res.confirm) {downloadTask && downloadTask.abort()uni.navigateBack()}}});return;}if (this.downloadSuccess && this.tempFilePath) {// 包已经下载完毕,稍后安装,将包保存在本地await this.saveFile(this.tempFilePath, this.version)uni.navigateBack()return;}uni.navigateBack()},// closeUp() {//  if (this.downloading) {//       // if (this.is_mandatory) {//       //  return uni.showToast({//        //      title: '下载中,请稍后……',//      //      icon: 'none',//       //      duration: 500//         //  })//        // }//      uni.showModal({//           title: '是否取消下载?',//            cancelText: '否',//            confirmText: '是',//           success: res => {//                 if (res.confirm) {//                    downloadTask && downloadTask.abort()//                  let curPage = getCurrentPages();//                     let route = curPage[curPage.length - 2].route; //获取当前页面的路由//                   if (route == 'pages/login/login') {//                       console.log(8888888);//                         uni.reLaunch({//                            url: '/pages/login/login'//                       })//                    } else {//                      uni.switchTab({//                           url: '/' + route//                       }); // 返回上一页//                  }//                 }//             }//         });//       return;//   }//     let curPage = getCurrentPages();//     let route = curPage[curPage.length - 2].route; //获取当前页面的路由//   if (route == 'pages/login/login') {//       console.log(8888888);//         uni.reLaunch({//            url: '/pages/login/login'//       })//    } else {//      uni.switchTab({//           url: '/' + route//       }); // 返回上一页//  }// },updateApp() {this.downloadPackage()},// 跳转应用商店downloadPackage() {this.downloading = true;//下载包downloadTask = uni.downloadFile({url: this.url,success: res => {if (res.statusCode == 200) {this.downloadSuccess = true;this.tempFilePath = res.tempFilePath// 强制更新,直接安装if (this.is_mandatory) {this.installPackage();}}},complete: () => {this.downloading = false;this.downLoadPercent = 0this.downloadedSize = 0this.packageFileSize = 0downloadTask = null;}});downloadTask.onProgressUpdate(res => {this.downLoadPercent = res.progress;this.downloadedSize = (res.totalBytesWritten / Math.pow(1024, 2)).toFixed(2);this.packageFileSize = (res.totalBytesExpectedToWrite / Math.pow(1024, 2)).toFixed(2);});},installPackage() {// #ifdef APP-PLUS// wgt资源包安装if (this.isWGT) {this.installing = true;}plus.runtime.install(this.tempFilePath, {force: false}, async res => {this.installing = false;this.installed = true;// wgt包,安装后会提示 安装成功,是否重启if (this.isWGT) {// 强制更新安装完成重启uni.showLoading({icon: 'none',title: '安装成功,正在重启……'})setTimeout(() => {uni.hideLoading()this.restart();}, 1000)} else {const localFilePathRecord = uni.getStorageSync(localFilePathKey)uni.setStorageSync(localFilePathKey, {...localFilePathRecord,installed: true})}}, async err => {// 如果是安装之前的包,安装失败后删除之前的包if (this.installForBeforeFilePath) {await this.deleteSavedFile(this.installForBeforeFilePath)this.installForBeforeFilePath = '';}// 安装失败需要重新下载安装包this.installing = false;this.installed = false;uni.showModal({title: '更新失败,请重新下载',content: err.message,showCancel: false});});// 非wgt包,安装跳出覆盖安装,此处直接返回上一页if (!this.isWGT && !this.is_mandatory) {uni.navigateBack()}// #endif},restart() {this.installed = false;// #ifdef APP-PLUS//更新完重启appplus.runtime.restart();// #endif},saveFile(tempFilePath, version) {return new Promise((resolve, reject) => {uni.saveFile({tempFilePath,success({savedFilePath}) {uni.setStorageSync(localFilePathKey, {version,savedFilePath})},complete() {resolve()}})})},deleteSavedFile(filePath) {uni.removeStorageSync(localFilePathKey)return uni.removeSavedFile({filePath})},}}
</script><style>page {background: transparent;}.flex-center {/* #ifndef APP-NVUE */display: flex;/* #endif */justify-content: center;align-items: center;}.mask {position: fixed;left: 0;top: 0;right: 0;bottom: 0;background-color: rgba(0, 0, 0, .65);}.botton-radius {border-bottom-left-radius: 30rpx;border-bottom-right-radius: 30rpx;}.content {position: relative;top: 0;width: 600rpx;background-color: #fff;box-sizing: border-box;padding: 0 50rpx;font-family: Source Han Sans CN;}.text {/* #ifndef APP-NVUE */display: block;/* #endif */line-height: 200px;text-align: center;color: #FFFFFF;}.content-top {position: absolute;top: -195rpx;left: 0;width: 600rpx;height: 270rpx;}.content-top-text {font-size: 45rpx;font-weight: bold;color: #F8F8FA;position: absolute;top: 120rpx;left: 50rpx;z-index: 1;}.content-header {height: 70rpx;}.title {font-size: 33rpx;font-weight: bold;color: #3DA7FF;line-height: 38px;}.footer {height: 150rpx;display: flex;align-items: center;justify-content: space-around;}.box-des-scroll {box-sizing: border-box;padding: 0 40rpx;height: 200rpx;text-align: left;}.box-des {font-size: 26rpx;color: #000000;line-height: 50rpx;}.progress-box {width: 100%;}.progress {width: 90%;height: 40rpx;border-radius: 35px;}.close-img {width: 70rpx;height: 70rpx;z-index: 1000;position: absolute;bottom: -120rpx;left: calc(50% - 70rpx / 2);}.content-button {text-align: center;flex: 1;font-size: 30rpx;font-weight: 400;color: #FFFFFF;border-radius: 40rpx;margin: 0 18rpx;height: 80rpx;line-height: 80rpx;background: linear-gradient(to right, #1785ff, #3DA7FF);}.flex-column {display: flex;flex-direction: column;align-items: center;}
</style>

如何插入一段漂亮的代码片

去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
var foo = 'bar';

XML文件格式(新建一个TXT文本复制下面内容更改后缀名为XML)

更改为自己项目的信息

<update>
<package>bao.ming.com</package>
<name>APP</name>
<appid>__UNI__8888683</appid>
<title>标题1.0.99更新</title>
<version>1.0.99</version>
<contents>测试更新内容</contents>
<platform>["Android"]</platform>
<type>["native_app"]</type>
<url>http://www.APP.apk</url> //更改自己的安装包下载地址
</update>

使用方法

在APP.vue里面引入

import upgrade from '@/components/upgrade-center/up.js'

在APP.VUE的onLaunch或则onShow里面使用

onLaunch: function() {upgrade()      },

【uniapp】uniapp安卓APP在线自动升级功能相关推荐

  1. uniapp打包安卓APP实现自动更新(更新app)

    先列出需要注意的地方,避免新手朋友们出错 如果uniapp运行app报错:ReferenceError: plus is not defined ,普通浏览器里没有plus环境,只有HBuilder真 ...

  2. uni-app打包安卓app如何接入极光推送(JG-JPush)?

    最近公司在做uni-app的跨端应用,其中在打包app时需要用到消息推送功能,经过一番摸索也是终于弄通并成功集成了第三方极光推送.话不多说,直接开撸: 一.我们需要用到的一些插件以及极光平台的官网链接 ...

  3. uniapp 开发安卓App实现高德地图路线规划导航

    文章目录 技术概述 技术详述 问题与解决 我的总结 参考文献 技术概述 描述这个技术是做什么的/什么情况下会使用到这个技术,学习该技术的原因,技术的难点在哪里.控制在50-100字内. uniapp的 ...

  4. 火山安卓开发支付宝自动转账功能

    火山安卓开发支付宝自动转账功能 首先你们需要准备火山安卓的无障碍和Root开发框架 点击下载无障碍和Root开发框架 下载完成后,需要更改里面的Root模拟点击坐标的位置 更改位置后,点击编译(注意: ...

  5. uniapp+canvas实现app在线电子签名

    项目基于uniapp做的app端,需要实现在线签名功能,找了很多文档学习参考,特此记录. template中, <view class="onevalue">// 展示 ...

  6. uniApp开发安卓App调试与打包

    总结一下auniapp开发安卓app的调试方式及打包; 代码编程查看文档即可.; 1通过vue-cli方式初始化项目 参考地址: https://uniapp.dcloud.io/quickstart ...

  7. uniapp开发安卓APP测试实现微信支付(初学者都能轻松get)

    前提条件 上代码 打包运行 注意bug!! 这里我们是前后端各一个人测试,这里分享一点前端的代码知识以及我们在测试过程中遇到的bug 前提条件 首先我们要去微信开放平台申请微信开放APP的应用包名和应 ...

  8. uniapp打包安卓App流程(超详细版)

    安卓打包流程 申请证书文件 1.官方有keystore文件生成方法,大家可以点击发行-原生APP云打包中如何生成证书进行证书查看证书生成官方做法 2.小编更加推荐香蕉云编一键生成,不用安装java环境 ...

  9. uniapp - 实现安卓APP实时在线更新APP

    思路:启动APP时,需要一个接口提供是否有APP包更新,通过接口返回更新包的版本号.更新地址进等信息,通过获取app包版本号与更新包的版本号进行比较来进行更新. 一.发布蒲公英平台,进行实时APP更新 ...

最新文章

  1. 机房重构(个人版)——类图
  2. https原理:证书传递、验证和数据加密、解密过程解析 (转)
  3. node MySQL buffer_node.js中buffer方法使用说明
  4. Cityscapse 数据集使用 + 训练 STDC踩坑
  5. Hadoop 2.x 完全分布式HA集群环境搭建
  6. linux以16进制查看文件
  7. 【斗医】【11】Web应用开发20天
  8. 如何将特定提交推送到远程,而不是之前的提交?
  9. VC++:如何将程序最小化到托盘 [转]
  10. React Native Android混合开发实战教程
  11. batchplot插件用法_最好用的CAD批量打印机SmartBatchPlot使用指南
  12. 微博研发实习阶段性总结及知识点整理
  13. 【机器学习】07. 决策树模型DecisionTreeClassifier(代码注释,思路推导)
  14. LeetCode 13 罗马符号转化为数字(难度: Easy)
  15. 无线投屏没有网络也可以投屏吗?
  16. rviz_marker_绘制直线_矩形框
  17. dev-c++开发的全鼠标操作控制台战棋
  18. 使用Python创建excel文件成功后报错打不开
  19. DX11 游戏开发笔记 (二) DX11 基础框架三角形 下
  20. sudo dolphin_如何使用Dolphin在PC上玩Wii和GameCube游戏

热门文章

  1. maven替换中央仓库- 阿里云
  2. stm32F103zexx(战舰v1) 移植liteOS
  3. ES集群搭建主机规划
  4. HTTP Status 505 – HTTP Version Not Supported
  5. 格林威治时间转换成字符串
  6. 每日新老客户数统计--sql 常见面试题(二)
  7. flask template中使用Vue,遇到引入element-ui无效问题,Unknown custom element did you register the component correc
  8. 门户博客靠什么赚钱?
  9. 高德地图的定位和大头针
  10. javascript正则表达式验证手机号