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 的時(shí)候,需要修改應(yīng)用版本號(往大了修改),同時(shí)版本號.json 文件中
newVersionCode對應(yīng)的值,也要和新的應(yīng)用版本號相同(方便檢測更新) newVersionName 中保存的是當(dāng)前PDA的版本名稱
versionDesc 中可以添加修改的內(nèi)容 appName 需要添加新發(fā)布的apk 名稱(用于下載對應(yīng)的文件)第三、將對應(yīng)的文件夾發(fā)布在iis中,同時(shí)要修改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è)置窗口。
選擇“新建”來添加一個(gè)新的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í)時(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) {
//自動(dòng)安裝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: "手動(dòng)入庫",
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-12
Vue.set() this.$set()引發(fā)的視圖更新思考及注意事項(xiàng)
this.$set()和Vue.set()本質(zhì)方法一樣,前者可以用在methods中使用。這篇文章主要介紹了Vue.set() this.$set()引發(fā)的視圖更新思考及注意事項(xiàng),需要的朋友可以參考下2018-08-08
elementUI?checkBox報(bào)錯(cuò)Cannot read property &ap
這篇文章主要為大家介紹了elementUI?checkBox報(bào)錯(cuò)Cannot read property 'length' of undefined的解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
詳解Vue用自定義指令完成一個(gè)下拉菜單(select組件)
本篇文章主要介紹了詳解Vue用自定義指令完成一個(gè)下拉菜單(select組件),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
vue等待數(shù)據(jù)渲染完成后執(zhí)行下一個(gè)方法問題
這篇文章主要介紹了vue等待數(shù)據(jù)渲染完成后執(zhí)行下一個(gè)方法問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
Vue+Echarts實(shí)現(xiàn)繪制多設(shè)備狀態(tài)甘特圖
這篇文章主要為大家詳細(xì)介紹了Vue如何結(jié)合Echarts實(shí)現(xiàn)繪制多設(shè)備狀態(tài)甘特圖,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03

