uniapp校验app版本并更新

最近用uniapp写了一个安卓壳子做app,遇到一个需求,校验app版本并更新

通过对比线上版本号和已安装的app版本号的差异,唤起更新弹窗

相关代码

App.vue

<script>

	export default {
		onLaunch: function() {
			this.checkVersion()
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		},
		methods: {
			checkVersion() {
//https://www.xxxx.com.cn/api/App/GetAppVersion   用来获取app信息的接口
				uni.request({
					url: 'https://www.xxxx.com.cn/api/App/GetAppVersion',
					method: 'get',
					data: {},
					header: {
						'Content-Type': 'application/json', // 设置请求头
					},
					success: (res) => {
						console.log('success', res)
						if (res.data.Flag == 1) {
							let {
								Data
							} = res.data
							if (Data.VersionCode) {
								plus.runtime.getProperty(plus.runtime.appid, function(wgtinfo) {
									const newVersionCode = Data.VersionCode; //线上最新版本号
									const selfVersionCode = wgtinfo.versionCode //当前APP应用版本
									console.log('newVersionCode:',newVersionCode)
									console.log('selfVersionCode:',selfVersionCode)
									//线上版本号和当前不一样,进行在线升级
									if (selfVersionCode != newVersionCode) {
										let platform = uni.getSystemInfoSync().platform //手机平台
										//安卓手机弹窗升级
										if (platform === 'android') {
											uni.navigateTo({
												url: '/pages/upgrade/index'
											})
										}
									}
								});
							}
						}
					},
					fail: (err) => {
						console.log('err', err)
					},
				});
			}
		}
	}
</script>

<style>
	/*每个页面公共css */
</style>

pages下的upgrade    index.vue

<template>
  <view class="upgrade-popup">
<!--    <image class="header-bg" src="../../static/upgrade_bg.png" mode="widthFix"></image>-->
    <view class="upgrade-main">
      <view class="version">发现新版本</view>
      <view class="upgrade-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: (290 * this.currentPercent / 100) + 'px' //510:按钮进度条宽度
      }
    },
    //百分比文字
    percentText() {
      let percent = this.currentPercent;
      if (typeof percent !== 'number' || isNaN(percent)) return '下载中...'
      if (percent < 100) return `下载中${percent}%`
      return '立即安装'

    }
  },
  onLoad() {
    this.init()
  },
  onBackPress(options) {
    // 禁用返回
    if (options.from == 'backbutton') {
      return true;
    }

  },
  methods: {
    //初始化获取最新APP版本信息
    init() {
	  uni.request({
	  	url: 'https://www.xxxx.com.cn/api/App/GetAppVersion',
	  	method: 'get',
	  	data: {},
	  	header: {
	  		'Content-Type': 'application/json', // 设置请求头
	  	},
	  	success: (res) => {
	  		console.log('success', res)
	  		if (res.data.Flag == 1) {
	  			let {
	  				Data
	  			} = res.data
	  			if (Data.VersionCode) {
					this.versionName = Data.VersionCode; //版本名称
					this.versionDesc = Data.Describe; //更新说明
					this.downloadUrl = Data.Url; //下载链接
					this.isForceUpdate = false; //是否强制更新
	  			}
	  		}
	  	},
	  	fail: (err) => {
	  		console.log('err', err)
	  	},
	  });
	  
    },
    //更新
    handleUpgrade() {
      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()
	  // uni.navigateTo({
	  //   url: '/pages/login/index'
	  // })
    },
  }
}
</script>

<style>
page {
  background: rgba(0, 0, 0, 0.5);/**设置窗口背景半透明*/
}
</style>
<style lang="scss" scoped>
.upgrade-popup {
  width: 290px;
  height: auto;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #fff;
  border-radius: 10px;
  box-sizing: border-box;
  border: 1px solid #eee;
}

.header-bg {
  width: 100%;
  margin-top: -112rpx;
}

.upgrade-main {
  padding: 5px 15px 15px;
  box-sizing: border-box;
  .version {
    font-size: 18px;
    color: #026DF7;
    font-weight: 700;
    width: 100%;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    letter-spacing: 1px;
  }

  .upgrade-content {
    margin-top: 30px;

    .title {
      font-size: 14px;
      font-weight: 700;
      color: #000000;
    }

    .desc {
      box-sizing: border-box;
      margin-top: 10px;
      font-size: 14px;
      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: 50px;

    .btn {
      width: 123px;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      z-index: 999;
      height: 48px;
      box-sizing: border-box;
      font-size: 16px;
      border-radius: 5px;
      letter-spacing: 1px;

      &.force {
        width: 250px;
      }

      &.close {
        border: 1px solid #E0E0E0;
        margin-right: 12px;
        color: #000;
      }

      &.upgrade {
        background-color: #026DF7;
        color: white;
      }
    }

    .progress-view {
      width: 255px;
      height: 24px;
      display: flex;
      position: relative;
      align-items: center;
      border-radius: 3px;
      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: 5px;
        border-bottom-left-radius: 5px;

      }

      .txt {
        font-size: 14px;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: #fff;
      }
    }
  }
}
</style>

pages下的upgrade    upgrade.js

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); //注册广播

}

pages.json 

{
	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/index/index",
			"style": {
				"navigationStyle": "custom"
			}
		},
		{
			"path": "pages/upgrade/index", //升级窗口页面
			"style": {
				"navigationBarTitleText": "",
				"navigationStyle": "custom",
				"app-plus": {
					"bounce": "none",
					"animationType":"none", //取消窗口动画
					"background": "transparent" // 设置背景透明
				}
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		// "navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	},
	"uniIdRouter": {}
}

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值