uni-app开发-App版本检测与下载

914 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情

为了用户体验到最新的功能和体验,移动应用一般都会内置自动检测版本和更新功能,本篇我们以uni-app开发的安卓App为例,使用应用版本号来实现App的检测与在线升级升级。

uni-app开发的App可以在manifest.json中配置版本名称和版本号用于升级检测,一般来说,应用版本名称是用于展现给用户看的版本信息。如:1.1.1,而应用版本号时内部开发使用的,用于本地app和服务端的提供的app版本进行对比检测,如:500。在uni-app中,可以使用plus.runtime.version和plus.runtime.versionCode来获取,一般来说,升级时需要版本名称和版本号都需要递增。

image-20220810141458786

开发版本检测接口

首先,我们在后端创建一个版本检测的接口,接口的用途是当App初次运行时,请求该接口,返回当前服务端的版本名称。本例中,版本名称存放在一个txt文档中("D:\releasedapp\appversion.txt),每次都更新前手动修改版本名称。为了用户体验,亦可开发一个后台版本名称管理功能,将版本号存入数据库,方便管理。

image-20220810144149647

后端接口代码:

 package com.draft.admin.controller;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 ​
 @RestController
 @RequestMapping("/system/app")
 public class AppVersionController {
     @GetMapping("/version")
     public String appVersion()throws IOException {
         File f = new File("D:\releasedapp\appversion.txt");
         FileReader fr = new FileReader(f);
         BufferedReader br = new BufferedReader(fr);
         String a = "";
         String data ="";
         while((data=br.readLine())!=null){
             a += data;
         }
         br.close();
         fr.close();
         return a;
     }
 }

apk安装包地址

App启动时,会请求接口,判断服务端App的版本名称号不等于App自身的版本号时,执行一个plus.downloader.createDownload方法,传入下载apk安装包网址,来下载服务端的apk。

那么,apk安装包网址需要这里我们在服务器上使用nginx或其他web服务器启动一个http服务,将最新版本的apk放到下载目录即可,构成该apk安装包地址,即:http://100.32.44.55/released.apk

创建检测与下载的方法

我们在项目目录下,创建一个util的文件夹,然后在util文件夹下,创建一个version.js用于存放检测与下载方法,其逻辑为:

  1. 通过uni.request()请求接口,拿到服务器版本名称,即txt存放的字符串。
  2. 获取到服务器版本名称后,通过plus.runtime.getProperty回调方法,获取当前App中manifest.json配置的版本名称,并对二者比较(这里严谨一些,可转为number类型,进行数字比较大小)
  3. 服务端和本地版本不一致的话,提示是否升级。同意升级后,传入apk安装包地址参数,执行plus.downloader.createDownload方法,进行下载,并使用plus.nativeUI.showWaiting的方法,实时显示下载进度。
  4. 下载完毕后,根据机型不同,需手动点击安装或自动转入到安卓安装界面。

具体代码如下:

 // version.js
 function checkReleasedAppVersion() {
     var _this = this;
     uni.request({
         url: this.apiUrl + 'system/app/version', //请求接口
         success: result => {
             console.log('服务器版本:' + result.data);
             // #ifdef APP-PLUS
             plus.runtime.getProperty(plus.runtime.appid, function(inf) {
                 console.log(`服务器版本:${result.data},当前版本:${inf.version}`);
                 _this.appVersion = inf.version;
                 if (inf.version != result.data) {
                     var doit = false
                     uni.showModal({
                         title: "发现新版本",
                         content: "发现新版本" + result.data + ' 请点击确定立即更新',
                         showCancel: false,
                         success: (res) => {
                             if (res.confirm == true) { //当用户确定更新,执行更新
                                 let dtask = plus.downloader.createDownload(
                                     'http://100.32.44.55/released.apk', {},
                                     (d, status) => {
                                         // console.log(d, status)
                                         // 下载完成
                                         if (status == 200) {
                                             plus.runtime.install(plus.io
                                                 .convertLocalFileSystemURL(
                                                     d.filename
                                                 ), {}, {}, (
                                                     error) => {
                                                     uni.showToast({
                                                         title: '安装失败',
                                                         mask: false,
                                                         duration: 1500
                                                     });
                                                 })
                                         } else {
                                             uni.showToast({
                                                 title: '更新失败',
                                                 mask: false,
                                                 duration: 1500
                                             });
                                         }
                                     });
                                 try {
                                     dtask.start(); // 开启下载的任务
                                     var prg = 0;
                                     var showLoading = plus.nativeUI
                                         .showWaiting(
                                             "正在下载"); //创建一个showWaiting对象 
                                     dtask.addEventListener('statechanged',
                                         function(
                                             task,
                                             status
                                         ) {
                                             // 给下载任务设置一个监听 并根据状态  做操作
                                             switch (task.state) {
                                                 case 1:
                                                     showLoading.setTitle(
                                                         "正在下载");
                                                     break;
                                                 case 2:
                                                     showLoading.setTitle(
                                                         "已连接到服务器");
                                                     break;
                                                 case 3:
                                                     prg = parseInt(
                                                         (parseFloat(
                                                                 task
                                                                 .downloadedSize
                                                             ) /
                                                             parseFloat(
                                                                 task
                                                                 .totalSize
                                                             )) *
                                                         100
                                                     );
                                                     showLoading.setTitle(
                                                         "  正在下载" +
                                                         prg + "%  ");
                                                     break;
                                                 case 4:
                                                     plus.nativeUI
                                                         .closeWaiting();
                                                     plus.runtime.quit();
                                                     //下载完成
                                                     break;
                                             }
                                         });
                                 } catch (err) {
                                     plus.nativeUI.closeWaiting();
                                     uni.showToast({
                                         title: '更新失败-03',
                                         mask: false,
                                         duration: 1500
                                     });
                                 }
 ​
                             } else {
                                 plus.runtime.quit();
                             }
                         }
                     })
                 }
             });
             // #endif
         },
     })
 }
 export {
     checkReleasedAppVersion
 }
 ​

然后,我们将此方法挂载到main.js中。

 import {
     checkReleasedAppVersion
 } from "./util/version.js"
 Vue.prototype.$checkReleasedAppVersion = checkReleasedAppVersion

最后,在App.vue中onLaunch生命周期函数中,调用此方法即可。

 <script>
     export default {
         onLaunch: function() {
             this.$checkReleasedAppVersion()
         },
         onShow: function() {
             // console.log('App Show')
         },
         onHide: function() {
             // console.log('App Hide')
         },
     }
 </script>

\