乐趣区

关于uni-app:uniapp中安卓包检查更新新版本下载下载进度条显示功能实现

需要形容

如果想要做一个 app 的话,能够有很多种抉择计划,uni-app是其中的一个性价比高一些(坑多一些)的计划。本文记录一下,uni-app 安卓包 当前,须要 查看并下载更新 ,且 显示进度条 的性能。

代码在本人公司我的项目中利用,大家可放心使用。

需要:

  • 查看版本是否是最新版
  • 若不是最新版就下载远端服务器的最新的 apk 包
  • 下载中须要显示下载了多少了,当下载到 100% 的时候,主动装置接口

思路剖析

比方咱们有一个设置页面,在设置页面中能够去进行版本更新。

1. 查看是不是最新版

当每次进入设置页面的时候,在 onShow 钩子 中向后端发申请,获取最新版本的信息,并与以后的版本信息做比照。

比方后端提供的有这样一个:获取最新版本信息 的接口

// 接口申请,返回数据如下:{
    "code": 1,
    "success": true,
    "data": {
        "id": 123456, // 存在数据库的 id
        "applyName": "拼夕夕", // 版本名称
        "applyVersion": "1.2.3", // 版本号
        "versionDescribe": "此版本新增,是兄弟就帮忙砍一刀性能", // 版本形容
        "fileSize":11566511, // 文件的总大小,计算下载进度百分比须要应用
        "filePath": "http://ashuai.work:10000/appSrc/pdd.apk", // 版本的 url 门路,失常在浏览器地址栏中输出即间接下载了
        ... // 等等
    },
    "msg": "操作胜利"
}

咱们首先拿到后端返回的这个 applyVersion 字段的值 ”1.2.3″ 去和 当下的版本值 比照。如果远端的最新版的版本号高于当下的版本号,就阐明要更新了。否则当下的就是最新版,就不必更新。

那问题又来了,如何能拿到当下的版本呢?没关系,官网提供的有api,能够间接获取的,代码如下:

plus.runtime.getProperty(plus.runtime.appid, (info) => {this.currentVersion = info.version; // 将当下版本存到 currentVersion 字段中去})

留神这个获取版本号的操作是异步的哦,异步,异步。

而后将版本号字符串 "a.b.c" 转换成 数字 进行比照即可。

形式有很多种,比方:a*100000 + b*1000 + c*1

// 当然这里须要
if(this.applyVersionVal > this.currentVersionVal){
    // 须要更新
    this.AndroidUpdate()}else {
    // 以后已是最新版本
    uni.showToast({
        title: '以后已是最新版本',
        duration: 2000,
        icon:'none'
    });
    return
}

2. 更新下载服务器远端的 apk 文件 & 进度条显示

调用安卓的办法,创立一个下载工作,能拿到某一时刻下载的文件的大小,比照总大小即可失去下载进度百分比

AndroidCheckUpdate() {
    const _this = this
    uni.showModal({
            title: "版本更新",
            content: 'APP 有新版本公布,点击 立刻更新 进行最新版本下载。',
            confirmText: '立刻更新',
            cancelText: '稍后进行',
            success: function(res) {if (res.confirm) {
                            _this.show = true // show 变量管制一个下载进度弹框(这个 UI 款式本人写即可)// 创立一个下载工作,并依据后端返回的 apk 动态资源地址 filePath 进行下载
                            var dtask = plus.downloader.createDownload(_this.filePath, {}, function(d, status) {
                                    // 下载实现  
                                    if (status == 200) {
                                            _this.show = false // 下载实现再把下载进度弹框敞开即可
                                            plus.runtime.install(plus.io.convertLocalFileSystemURL(d
                                                    .filename), {}, {}, function(error) {
                                                    uni.showToast({
                                                            title: '装置失败',
                                                            duration: 1500
                                                    });
                                            })
                                    } else {
                                            uni.showToast({
                                                    title: '更新失败',
                                                    duration: 1500
                                            });
                                    }
                            });
                            dtask.start(); // 下载工作开始下载
                            // 对于进度的获取是应用定时器一直获取曾经下载的文件的大小,再比照总大小即可
                            let timer = setInterval(() => {let percent = (dtask.downloadedSize / this.fileSize).toFixed(2) // fileSize 文件总大小,后端返回的
                                    _this.percentVal = Math.floor(percent * 100) // 转成整数展现
                                    if (percent >= 1) { // 留神百分比,及时革除定时器即可
                                            clearInterval(timer)
                                    }
                            }, 18)
                    } else if (res.cancel) {console.log('稍后更新');
                    }
            }
    });
}

进度条应用的是 u -popup 组件,如下:

<u-popup :round="10" :show="show" mode="center">
        <view class="progressBox">
                <u-loading-icon size="36"></u-loading-icon>
                <text class="words"> 下载中 请勿退出 {{percentVal}}%</text>
        </view>
</u-popup>

留神,下载这一块是要在手机模拟器上,能力看到成果哦。笔者工作中应用的是 逍遥模拟器,挺好。

因为 plus 变量在浏览器中是没有的

版本号

效果图

下载结束当前,安卓主动装置

为了不便大家去验证,笔者也提供了一个 apk 动态资源包 filePath: http://ashuai.work:10000/appSrc/pdd.apk,在地址栏输出就能够拜访了。

动态资源 apk 接口

express同级目录下,新建文件夹 app 寄存一下 apk 文件

// 先查问有没有这个 app,有的话返回这个动态 app 资源 url 地址
route.get('/findAppUrl', (req, res) => {res.header('Access-Control-Allow-Origin', '*');
  let appName = (req.query.appName ? req.query.appName : 'pdd') + '.apk'
  let files = fs.readdirSync('./app')
  if (files.includes(appName)) { // 库存有
    res.send({
      code: '00000000',
      url: "http://ashuai.work:10000/appSrc/" + appName
    })
  } else { // 库存没有
    res.send({
      code: '00000000',
      url: ""
    })
  }
})
// 当拜访 app 资源时,就把对应的资源以流的模式返回去
route.get('/appSrc/:fileName', (req, res) => {res.header('Access-Control-Allow-Origin', '*');
  let fileName = req.params.fileName // wms2month.apk

  try {
    // 存储一份 app 的门路
    let appUrl = './app/' + fileName
    let stat = fs.statSync(appUrl)

    res.writeHead(200, {
      'Content-Type': 'application/vnd.android.package-archive', // 安卓
      'Content-Length': stat.size,
    })
    // 创立可读流
    let readStream = fs.createReadStream(appUrl)
    // 将读取的后果以管道 pipe 流的形式返回
    readStream.pipe(res);
  } catch (error) {res.send('暂无此 app 文件哦')
  }

})

至于强制更新的话,就做一个判断即可,以后版本不是服务器远端的最新版本的话,就不让往下走,不让登录即可

好忘性不如烂笔头,记录一下吧 ^_^

退出移动版