UNIapp实现局域网内在线升级的操作方法
作者:走在路上的霍纳奇思
首先是UNIapp 生成apk
用Hbuilder 进行打包
可以从网站https://www.yunedit.com/reg?goto=cert 使用自有证书,目测比直接使用云证书要快一些。
发布apk 网站
用IIS发布即可
注意事项中记录如下内容
第一、需要在 iis 的MiMe 中添加apk 的格式,否则无法下载apk 文件到手持机中。 添加方式 打开MIME 点击添加
分别输入 apk application/vnd.android.package-archive 点击保存即可第二、发布新的apk 的时候,需要修改应用版本号(往大了修改),同时版本号.json 文件中
newVersionCode对应的值,也要和新的应用版本号相同(方便检测更新) newVersionName 中保存的是当前PDA的版本名称
versionDesc 中可以添加修改的内容 appName 需要添加新发布的apk 名称(用于下载对应的文件)第三、将对应的文件夹发布在iis中,同时要修改uniapp 中的http.js文件
uni.setStorageSync(‘loadVersion’, ‘http://127.0.0.1:8032/’); 修改内部的url
要在IIS中添加.apk文件的MIME类型,可以按照以下步骤操作:
打开IIS管理器,找到服务器,右键选择“属性”。
在打开的属性窗口中,选择“MIME类型”选项卡。
点击“MIME类型”按钮,打开MIME类型设置窗口。
选择“新建”来添加一个新的MIME类型。
在“扩展名”中填写“.apk”,在“MIME类型”中填写“.apk”的MIME类型“application/vnd.android.package-archive”。
点击“确定”保存设置。
重启IIS服务,以使更改生效。
完成以上步骤后,IIS就能够正确识别和处理.apk文件了
版本号.json中的内容为
{"newVersionCode":223,"newVersionName":"V1.2.0","versionDesc":"升级了部分功能","appName":"android_debug.apk"}
uniapp相关代码
upgrade.vue中存在
<template> <view class="upgrade-popup"> <view class="main"> <view class="version">发现新版本{{versionName}}</view> <view class="content"> <text class="title">更新内容</text> <view class="desc" v-html="versionDesc"></view> </view> <!--下载状态-进度条显示 --> <view class="footer" v-if="isStartDownload"> <view class="progress-view" :class="{'active':!hasProgress}" @click="handleInstallApp"> <!-- 进度条 --> <view v-if="hasProgress" style="height: 100%;"> <view class="txt">{{percentText}}</view> <view class="progress" :style="setProStyle"></view> </view> <view v-else> <view class="btn upgrade force">{{ isDownloadFinish ? '立即安装' :'下载中...'}}</view> </view> </view> </view> <!-- 强制更新 --> <view class="footer" v-else-if="isForceUpdate"> <view class="btn upgrade force" @click="handleUpgrade">立即更新</view> </view> <!-- 可选择更新 --> <view class="footer" v-else> <view class="btn close" @click="handleClose">以后再说</view> <view class="btn upgrade" @click="handleUpgrade">立即更新</view> </view> </view> </view> </template> <script> import { downloadApp, installApp } from './upgrade.js' export default { data() { return { isForceUpdate: false, //是否强制更新 versionName: '', //版本名称 versionDesc: '', //更新说明 downloadUrl: '', //APP下载链接 isDownloadFinish: false, //是否下载完成 hasProgress: false, //是否能显示进度条 currentPercent: 0, //当前下载百分比 isStartDownload: false, //是否开始下载 fileName: '', //下载后app本地路径名称 } }, computed: { //设置进度条样式,实时更新进度位置 setProStyle() { return { width: (510 * this.currentPercent / 100) + 'rpx' //510:按钮进度条宽度 } }, //百分比文字 percentText() { let percent = this.currentPercent; if (typeof percent !== 'number' || isNaN(percent)) return '下载中...' if (percent < 100) return `下载中${percent}%` return '立即安装' } }, onLoad(options) { this.init(options) }, onBackPress(options) { // 禁用返回 if (options.from == 'backbutton') { return true; } }, methods: { //初始化获取最新APP版本信息 init(options) { let randomNum = Math.random(); //模拟接口获取最新版本号,版本号固定为整数 const baseurl = uni.getStorageSync('loadVersion')+options.appName+'?V='+randomNum;; console.log('结果为') console.log((baseurl)) //模拟接口获取 setTimeout(() => { //演示数据请根据实际修改 this.versionName = options.versionName; //版本名称 this.versionDesc = options.versionDesc; //更新说明 this.downloadUrl = baseurl; //下载链接 this.isForceUpdate = false; //是否强制更新 }, 200) }, //更新 handleUpgrade() { console.log('Hello UniApp!-----------------------------------------------') uni.getStorage({ key: 'loadVersion', success: function (res) { console.log(res.data); } }); //requestTask.abort(); if (this.downloadUrl) { this.isStartDownload = true //开始下载App downloadApp(this.downloadUrl, current => { //下载进度监听 this.hasProgress = true this.currentPercent = current }).then(fileName => { //下载完成 this.isDownloadFinish = true this.fileName = fileName if (fileName) { //自动安装App this.handleInstallApp() } }).catch(e => { console.log(e, 'e') }) } else { uni.showToast({ title: '下载链接不存在', icon: 'none' }) } }, //安装app handleInstallApp() { //下载完成才能安装,防止下载过程中点击 if (this.isDownloadFinish && this.fileName) { installApp(this.fileName, () => { //安装成功,关闭升级弹窗 uni.navigateBack() }) } }, //关闭返回 handleClose() { uni.navigateBack() }, } } </script> <style> page { background: rgba(0, 0, 0, 0.5);/**设置窗口背景半透明*/ } </style> <style lang="scss" scoped> .upgrade-popup { width: 580rpx; height: auto; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #fff; border-radius: 20rpx; box-sizing: border-box; border: 1px solid #eee; } .header-bg { width: 100%; margin-top: -112rpx; } .main { padding: 10rpx 30rpx 30rpx; box-sizing: border-box; .version { font-size: 36rpx; color: #026DF7; font-weight: 700; width: 100%; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: 1px; } .content { margin-top: 60rpx; .title { font-size: 28rpx; font-weight: 700; color: #000000; } .desc { box-sizing: border-box; margin-top: 20rpx; font-size: 28rpx; color: #6A6A6A; max-height: 80vh; overflow-y: auto; } } .footer { width: 100%; display: flex; justify-content: center; align-items: center; position: relative; flex-shrink: 0; margin-top: 100rpx; .btn { width: 246rpx; display: flex; justify-content: center; align-items: center; position: relative; z-index: 999; height: 96rpx; box-sizing: border-box; font-size: 32rpx; border-radius: 10rpx; letter-spacing: 2rpx; &.force { width: 500rpx; } &.close { border: 1px solid #E0E0E0; margin-right: 25rpx; color: #000; } &.upgrade { background-color: #026DF7; color: white; } } .progress-view { width: 510rpx; height: 90rpx; display: flex; position: relative; align-items: center; border-radius: 6rpx; background-color: #dcdcdc; display: flex; justify-content: flex-start; padding: 0px; box-sizing: border-box; border: none; overflow: hidden; &.active { background-color: #026DF7; } .progress { height: 100%; background-color: #026DF7; padding: 0px; box-sizing: border-box; border: none; border-top-left-radius: 10rpx; border-bottom-left-radius: 10rpx; } .txt { font-size: 28rpx; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #fff; } } } } </style>
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); //注册广播 }
home.vue
<template> <view> <image style="width: 100%;" mode="widthFix" src="/static/swiper1.png"></image> <!-- <u-swiper height="360rpx" :list="swiperList" :radius="0"></u-swiper> --> <view class="home-content"> <view class="app-name">WMS手持机系统</view> <view class="card-container"> <view class="fn-title">基础功能</view> <u-grid :border="false" @click="gridClick" col="4"> <u-grid-item v-for="(item,index) in fn" :key="index"> <view :class="['grid-item-bg','grid-item-bg-'+(index+1)]"> <u-icon :name='item.icon' :color="item.color" size="28"></u-icon> </view> <view class="grid-text">{{item.name}}</view> </u-grid-item> </u-grid> </view> <view style="padding:30rpx;padding-top:0;"> <vol-alert type="primary"> </vol-alert> </view> </view> </view> </template> <script> export default { data() { return { height: 0, swiperList: [ '/static/swiper1.png', '/static/swiper2.png', '/static/swiper3.png' ], fn: [{ name: "有单据组盘1", icon: '/static/fc.png', path: "/pages/basics/T_In_ReceiptNoticeDetail/T_In_ReceiptNoticeDetail", color: '#EE0000', subPage: true //二级页面 }, { name: "手动入库", icon: '/static/fc.png', path: "", color: '#EE0000', subPage: true //二级页面 }, { name: "无单据组盘", icon: 'edit-pen-fill', color: '#8B8989', path: "/pages/createbyus/HaveOrderGroup/HaveOrderGroup", subPage: true //二级页面 }, { name: "入库计划", icon: '/static/fc.png', path: "/pages/basics/T_In_ReceiptNotice/T_In_ReceiptNotice", color: '#EE0000', subPage: true //二级页面 }, { name: "确认出库", icon: '/static/fc.png', path: "/pages/reportvshow/V_OutboundDetail/V_OutboundDetail", color: '#EE0000', subPage: true //二级页面 }, { name: "托盘处理", icon: '/static/fc.png', path: "/pages/strategy/DealTrayCURD/DealTrayCURD", color: '#EE0000', subPage: true //二级页面 }, { name: "盘点处理", icon: '/static/fc.png', path: "/pages/strategy/T_InventoryCheckDetail/T_InventoryCheckDetail", color: '#EE0000', subPage: true //二级页面 }, { name: "出库计划", icon: '/static/flow.png', color: '#EE0000', path: "/pages/basics/T_Out_DeliveryNotice/T_Out_DeliveryNotice", subPage: true //二级页面 }, { name: "审批流程", icon: '/static/flow.png', color: '#EE0000', path: "/pages/flow/flow", subPage: false //二级页面 }, { name: "表单示例", icon: '/static/form.png', color: '#EE0000', path: "/pages/form/form", subPage: true //二级页面 }, { name: "Table组件", icon: '/static/fc.png', color: '#EE0000', path: "/pages/form/form", subPage: true //二级页面 }, { name: "菜单列表", icon: '/static/table.png', color: '#EE0000', path: "/pages/menu/menu", subPage: false //二级页面 }, // { // name: "地图导航", // icon: '/static/fc.png', // color:'#EE0000', // path: "/pages/map/map", // subPage: true //二级页面 // }, // //待开发功能 // { // name: "敬请期待", // icon: '/static/fc.png', // path: "pages/basics/T_In_ReceiptNotice/T_In_ReceiptNotice", // color:'#EE0000', // subPage: true //二级页面 // }, // { // name: "敬请期待", // icon: '/static/fc.png', // color:'#EE0000', // path: "", // } ], } }, onLoad() { var _this = this; // 获取手机状态栏高度 uni.getSystemInfo({ success: function(data) { // 将其赋值给this _this.height = data.statusBarHeight; } }); _this.init(); }, onReady(){ this.checkVersion(1) }, onShow() { }, methods: { //初始化 init() { }, //检查版本更新情况 checkVersion(indexValue) { var _this = this; let index=0; setTimeout(() => { let randomNum = Math.random(); //模拟接口获取最新版本号,版本号固定为整数 const baseurl = uni.getStorageSync('loadVersion')+'版本号.json?V='+randomNum; console.log(baseurl) var requestTask = uni.request({ url: baseurl, //仅为示例,并非真实接口地址。 method:'GET', success: function(res) { index++; console.log(res.data); const newVersionName =res.data.newVersionName //线上最新版本名 const newVersionCode =res.data.newVersionCode; //线上最新版本号 const selfVersionCode = Number(uni.getSystemInfoSync().appVersionCode) //当前App版本号 console.log(index+'../index/upgrade?versionName='+newVersionName+'&versionDesc='+res.data.versionDesc) console.log(selfVersionCode) console.log(newVersionCode) //线上版本号高于当前,进行在线升级 if (selfVersionCode < newVersionCode) { let platform = uni.getSystemInfoSync().platform //手机平台 uni.navigateTo({ url: '../index/upgrade?versionName='+newVersionName+'&versionDesc='+res.data.versionDesc+'&appName='+res.data.appName }) } else { _this.clickUseInfo(indexValue); } }, fail :function(res) { console.log(res); }, complete: ()=> {} }); }, 200) }, getStyle(item) { return { paddingTop: 20 + 'rpx', background: item.color, padding: '50%', color: "#ffff", 'border-radius': '50%', left: '-24rpx' } }, gridClick(index) { this.checkVersion(index) }, clickUseInfo(index) { const item = this.fn[index]; console.log(index) if (!item.path) { this.$toast('开发中') return; } //注意下面的跳转方式,一级页面指pages.json中tabBar配置path //具体见uni页面跳转文档 if (item.subPage) { //二级页面用navigateTo跳转 uni.navigateTo({ url: this.fn[index].path }) return; } //一级页面 uni.switchTab({ url: this.fn[index].path }) }, swiperClick(index) { } } } </script> <style lang="less" scoped> .home-content { z-index: 999; position: relative; margin-top: -220rpx; } .app-name { text-align: center; color: #ffff; font-weight: bolder; font-size: 60rpx; top: -40rpx; position: relative; } .card-container { box-shadow: 1px 1px 9px #b9b6b629; margin: 30rpx 30rpx 30rpx 30rpx; border: 1px solid #f1f1f1; border-radius: 10rpx; padding: 26rpx 10rpx 14rpx 10rpx; background: #ffff; .fn-title { font-family: 黑体; font-size: 30rpx; font-weight: bold; //color: #8f9ca2; padding: 4rpx 20rpx 30rpx 20rpx; } .grid-text { padding-top: 8rpx; font-size: 26rpx; color: #626262; padding-bottom: 20rpx; } } .grid-item-bg { border-radius: 50%; width: 86rpx; height: 86rpx; display: flex; align-items: center; justify-content: center; box-shadow: 5px 3px 6px #e0ddddb0; } .grid-item-bg-1 { background-image: linear-gradient(to bottom right, #97caff, #47a1fe); } .grid-item-bg-2 { background-image: linear-gradient(to bottom right, #f8bcbc, #f07e7e); } .grid-item-bg-3 { background-image: linear-gradient(to bottom right, #afb5e6, #808cf0); } .grid-item-bg-4 { background-image: linear-gradient(to bottom right, #98e4e2, #56c3bf); } .grid-item-bg-5 { background-image: linear-gradient(to bottom right, #d1d1d1, #c878e7); } .grid-item-bg-6 { background-image: linear-gradient(to bottom right, #97caff, #47a1fe); } .grid-item-bg-7 { background-image: linear-gradient(to bottom right, #98e4e2, #56c3bf); } .grid-item-bg-8 { background-image: linear-gradient(to bottom right, #afb5e6, #808cf0); } </style>
到此这篇关于UNIapp实现局域网内在线升级的文章就介绍到这了,更多相关UNIapp在线升级内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!