UNIapp實(shí)現(xiàn)局域網(wǎng)內(nèi)在線升級的操作方法
首先是UNIapp 生成apk
用Hbuilder 進(jìn)行打包
可以從網(wǎng)站https://www.yunedit.com/reg?goto=cert 使用自有證書,目測比直接使用云證書要快一些。
發(fā)布apk 網(wǎng)站
用IIS發(fā)布即可
注意事項(xiàng)中記錄如下內(nèi)容
第一、需要在 iis 的MiMe 中添加apk 的格式,否則無法下載apk 文件到手持機(jī)中。 添加方式 打開MIME 點(diǎn)擊添加
分別輸入 apk application/vnd.android.package-archive 點(diǎn)擊保存即可第二、發(fā)布新的apk 的時候,需要修改應(yīng)用版本號(往大了修改),同時版本號.json 文件中
newVersionCode對應(yīng)的值,也要和新的應(yīng)用版本號相同(方便檢測更新) newVersionName 中保存的是當(dāng)前PDA的版本名稱
versionDesc 中可以添加修改的內(nèi)容 appName 需要添加新發(fā)布的apk 名稱(用于下載對應(yīng)的文件)第三、將對應(yīng)的文件夾發(fā)布在iis中,同時要修改uniapp 中的http.js文件
uni.setStorageSync(‘loadVersion’, ‘http://127.0.0.1:8032/’); 修改內(nèi)部的url
要在IIS中添加.apk文件的MIME類型,可以按照以下步驟操作:
打開IIS管理器,找到服務(wù)器,右鍵選擇“屬性”。
在打開的屬性窗口中,選擇“MIME類型”選項(xiàng)卡。
點(diǎn)擊“MIME類型”按鈕,打開MIME類型設(shè)置窗口。
選擇“新建”來添加一個新的MIME類型。
在“擴(kuò)展名”中填寫“.apk”,在“MIME類型”中填寫“.apk”的MIME類型“application/vnd.android.package-archive”。
點(diǎn)擊“確定”保存設(shè)置。
重啟IIS服務(wù),以使更改生效。
完成以上步驟后,IIS就能夠正確識別和處理.apk文件了
版本號.json中的內(nèi)容為
{"newVersionCode":223,"newVersionName":"V1.2.0","versionDesc":"升級了部分功能","appName":"android_debug.apk"}
uniapp相關(guān)代碼
upgrade.vue中存在
<template> <view class="upgrade-popup"> <view class="main"> <view class="version">發(fā)現(xiàn)新版本{{versionName}}</view> <view class="content"> <text class="title">更新內(nèi)容</text> <view class="desc" v-html="versionDesc"></view> </view> <!--下載狀態(tài)-進(jìn)度條顯示 --> <view class="footer" v-if="isStartDownload"> <view class="progress-view" :class="{'active':!hasProgress}" @click="handleInstallApp"> <!-- 進(jìn)度條 --> <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> <!-- 強(qiáng)制更新 --> <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, //是否強(qiáng)制更新 versionName: '', //版本名稱 versionDesc: '', //更新說明 downloadUrl: '', //APP下載鏈接 isDownloadFinish: false, //是否下載完成 hasProgress: false, //是否能顯示進(jìn)度條 currentPercent: 0, //當(dāng)前下載百分比 isStartDownload: false, //是否開始下載 fileName: '', //下載后app本地路徑名稱 } }, computed: { //設(shè)置進(jìn)度條樣式,實(shí)時更新進(jìn)度位置 setProStyle() { return { width: (510 * this.currentPercent / 100) + 'rpx' //510:按鈕進(jìn)度條寬度 } }, //百分比文字 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(); //模擬接口獲取最新版本號,版本號固定為整數(shù) const baseurl = uni.getStorageSync('loadVersion')+options.appName+'?V='+randomNum;; console.log('結(jié)果為') console.log((baseurl)) //模擬接口獲取 setTimeout(() => { //演示數(shù)據(jù)請根據(jù)實(shí)際修改 this.versionName = options.versionName; //版本名稱 this.versionDesc = options.versionDesc; //更新說明 this.downloadUrl = baseurl; //下載鏈接 this.isForceUpdate = false; //是否強(qiáng)制更新 }, 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 => { //下載進(jìn)度監(jiān)聽 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() { //下載完成才能安裝,防止下載過程中點(diǎn)擊 if (this.isDownloadFinish && this.fileName) { installApp(this.fileName, () => { //安裝成功,關(guān)閉升級彈窗 uni.navigateBack() }) } }, //關(guān)閉返回 handleClose() { uni.navigateBack() }, } } </script> <style> page { background: rgba(0, 0, 0, 0.5);/**設(shè)置窗口背景半透明*/ } </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:下載進(jìn)度回調(diào) */ export const downloadApp = (downloadUrl, progressCallBack = () => {}, ) => { return new Promise((resolve, reject) => { //創(chuàng)建下載任務(wù) 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" }); } }) //監(jiān)聽下載過程 downloadTask.addEventListener("statechanged", (task, status) => { switch (task.state) { case 1: // 開始 break; case 2: //已連接到服務(wù)器 break; case 3: // 已接收到數(shù)據(jù) let hasProgress = task.totalSize && task.totalSize > 0 //是否能獲取到App大小 if (hasProgress) { let current = parseInt(100 * task.downloadedSize / task.totalSize); //獲取下載進(jìn)度百分比 progressCallBack(current) } break; case 4: // 下載完成 break; } }); //開始執(zhí)行下載 downloadTask.start(); }) } /** * @description H5+安裝APP * @param fileName:app文件名 * @param callBack:安裝成功回調(diào) */ export const installApp = (fileName, callBack = () => {}) => { //注冊廣播監(jiān)聽app安裝情況 onInstallListening(callBack); //開始安裝 plus.runtime.install(plus.io.convertLocalFileSystemURL(fileName), {}, () => { //成功跳轉(zhuǎn)到安裝界面 }, function(error) { uni.showToast({ title: '安裝失敗', duration: 1500, icon: "none" }); }) } /** * @description 注冊廣播監(jiān)聽APP是否安裝成功 * @param callBack:安裝成功回調(diào)函數(shù) */ const onInstallListening = (callBack = () => {}) => { let mainActivity = plus.android.runtimeMainActivity(); //獲取activity //生成廣播接收器 let receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', { onReceive: (context, intent) => { //接收廣播回調(diào) plus.android.importClass(intent); mainActivity.unregisterReceiver(receiver); //取消監(jiān)聽 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); //監(jiān)聽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手持機(jī)系統(tǒng)</view> <view class="card-container"> <view class="fn-title">基礎(chǔ)功能</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: "有單據(jù)組盤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: "無單據(jù)組盤", icon: 'edit-pen-fill', color: '#8B8989', path: "/pages/createbyus/HaveOrderGroup/HaveOrderGroup", subPage: true //二級頁面 }, { name: "入庫計(jì)劃", icon: '/static/fc.png', path: "/pages/basics/T_In_ReceiptNotice/T_In_ReceiptNotice", color: '#EE0000', subPage: true //二級頁面 }, { name: "確認(rèn)出庫", 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: "盤點(diǎn)處理", icon: '/static/fc.png', path: "/pages/strategy/T_InventoryCheckDetail/T_InventoryCheckDetail", color: '#EE0000', subPage: true //二級頁面 }, { name: "出庫計(jì)劃", 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: "地圖導(dǎo)航", // icon: '/static/fc.png', // color:'#EE0000', // path: "/pages/map/map", // subPage: true //二級頁面 // }, // //待開發(fā)功能 // { // 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; // 獲取手機(jī)狀態(tài)欄高度 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(); //模擬接口獲取最新版本號,版本號固定為整數(shù) const baseurl = uni.getStorageSync('loadVersion')+'版本號.json?V='+randomNum; console.log(baseurl) var requestTask = uni.request({ url: baseurl, //僅為示例,并非真實(shí)接口地址。 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) //當(dāng)前App版本號 console.log(index+'../index/upgrade?versionName='+newVersionName+'&versionDesc='+res.data.versionDesc) console.log(selfVersionCode) console.log(newVersionCode) //線上版本號高于當(dāng)前,進(jìn)行在線升級 if (selfVersionCode < newVersionCode) { let platform = uni.getSystemInfoSync().platform //手機(jī)平臺 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('開發(fā)中') return; } //注意下面的跳轉(zhuǎn)方式,一級頁面指pages.json中tabBar配置path //具體見uni頁面跳轉(zhuǎn)文檔 if (item.subPage) { //二級頁面用navigateTo跳轉(zhuǎn) 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>
到此這篇關(guān)于UNIapp實(shí)現(xiàn)局域網(wǎng)內(nèi)在線升級的文章就介紹到這了,更多相關(guān)UNIapp在線升級內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue 使用class創(chuàng)建和清除水印的示例代碼
這篇文章主要介紹了vue 使用class創(chuàng)建和清除水印的示例代碼,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12Vue.set() this.$set()引發(fā)的視圖更新思考及注意事項(xiàng)
this.$set()和Vue.set()本質(zhì)方法一樣,前者可以用在methods中使用。這篇文章主要介紹了Vue.set() this.$set()引發(fā)的視圖更新思考及注意事項(xiàng),需要的朋友可以參考下2018-08-08elementUI?checkBox報錯Cannot read property &ap
這篇文章主要為大家介紹了elementUI?checkBox報錯Cannot read property 'length' of undefined的解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06vue等待數(shù)據(jù)渲染完成后執(zhí)行下一個方法問題
這篇文章主要介紹了vue等待數(shù)據(jù)渲染完成后執(zhí)行下一個方法問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12Vue+Echarts實(shí)現(xiàn)繪制多設(shè)備狀態(tài)甘特圖
這篇文章主要為大家詳細(xì)介紹了Vue如何結(jié)合Echarts實(shí)現(xiàn)繪制多設(shè)備狀態(tài)甘特圖,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03