需求说明:使用MUI+Vue等技术并且通过HBuilderX打包开发移动app,在有版本更新时需要自动提示用户有新版本,并且可以点击下载自动安装。

思路说明:

  1. 应用打开时(使用Vue的生命周期mounted),获取自己的版本信息appinfo;

    (本身app的信息一般存放在mainfest.json中,直接获取即可)
mui.plusReady(function(){
mui.getJSON("manifest.json", null, function(manifest){
var version = data.version
var vercode_local = version.code;
var vername_local = version.name;
console.log("版本名称:"+vername_local+",版本code:"+vercode_local);
});
});
  1. 获取remote服务器上移动应用最新的版本信息(一般是存放一个json的数据信息)
mui.getJSON(【服务器的url + appInfo.version_json】, null, function(data) {
var verCode = data.verCode;
var verName = data.verName;
//服务器版本
//console.log("服务器版本名称:"+verName +",服务器版本code:"+verCode);
});
  1. 判断两个版本号是否相等,不相等则需要更新
if(vercode_local == verCode) {
mui.toast("当前已经是最新版本!");
} else {
var btnArray = ['是', '否'];
mui.confirm('当前版本是:' + vername_local + ', 最新版本是:' + verName + ', 是否立即更新?', '发现最新版本', btnArray, function(z) {
if(z.index == 0) {
console.log('确定');
installApk(BASEINFO.maxsvc + appInfo.version_apk);
} else {
console.log('不确定');
return;
}
});
}

1.在vue的mounted生命周期进行更新校验

mounted() {
mui.plusReady(function() {
//console.log("检查更新!!!!");
mui.init({statusBarBackground: '#EEEEEE'});
plus.screen.lockOrientation("landscape-primary");
if(mui.os.android) {
mui.getJSON("../../manifest.json", null, function(data) {
var version = data.version
var vercode_local = version.code;
var vername_local = version.name;
//当前版本
//console.log("版本名称:"+vername_local+",版本code:"+vercode_local);
mui.getJSON(BASEINFO.maxsvc + appInfo.version_json, null, function(data) {
var verCode = data.verCode;
//服务器版本
//console.log("服务器版本code:"+verCode);
var verName = data.verName;
if(vercode_local == verCode) {
mui.toast("当前已经是最新版本!");
} else {
var btnArray = ['是', '否'];
mui.confirm('当前版本是:' + vername_local + ', 最新版本是:' + verName + ', 是否立即更新?', '发现最新版本', btnArray, function(z) {
if(z.index == 0) {
console.log('确定');
installApk(BASEINFO.maxsvc + appInfo.version_apk);
} else {
console.log('不确定');
return;
}
});
}
});
});
}
});
}

2.其中需要用到application.js中声明的函数

3.application.js中的函数

var BASEINFO={
//接口url
maxsvc:"http://*.*.*.*:port/appUpdate",
maxbiz:"http://*.*.*.*:port/maxbiz",
download:"http://*.*.*.*:port/whatsup/releaseapk.jsp"
} function getWinWH() {
var temp = {};
var winWidth = "0";
var winHeight = "0";
if(window.innerWidth) {
winWidth = window.innerWidth;
} else if((document.body) && (document.body.clientWidth)) {
winWidth = document.body.clientWidth;
}
if(window.innerHeight) {
winHeight = window.innerHeight;
} else if((document.body) && (document.body.clientHeight)) {
winHeight = document.body.clientHeight;
}
if(document.documentElement && document.documentElement.clientHeight && document.documentElement.clientWidth) {
winHeight = document.documentElement.clientHeight;
winWidth = document.documentElement.clientWidth;
}
temp.winWidth = winWidth;
temp.winHeight = winHeight; return temp;
} function getAppInfo(appname) {
var prefix = "";
var path = "";
var name = "";
// MaxUA
if(appname == "mua") {
path = "com.maxnerva.maxua";
prefix = "";
name = path;
}
// 异常停线通知(L5)
if(appname == "men") {
path = "com.newpc.b2b.";
prefix = "asm_";
name = path + prefix + appname;
}
// E点名(L5)
if(appname == "mrc") {
path = "com.newpc.b2b.";
prefix = "asm_";
name = path + prefix + appname;
}
// 组装生产日报表(L5)
if(appname == "pdr") {
path = "com.newpc.b2b.";
prefix = "asm_";
name = path + prefix + appname;
}
// 仓库进料转仓(L6)
if(appname == "mgr") {
path = "com.foxconn.";
prefix = "";
name = path + prefix + appname;
}
// 发料单查询(L6)
if(appname == "mgi") {
path = "com.foxconn.max.activity";
prefix = "";
name = path;
}
// 仓库分批发料(L5)
if(appname == "mso") {
path = "com.newpc.b2b.";
prefix = "asm_";
name = path + prefix + appname;
}
// 上料表查询(L6)
if(appname == "mgf") {
path = "com.newpc.b2b.";
prefix = "asm_";
name = path + prefix + appname;
}
// IQC进料检验(L6)
if(appname == "mqi") {
path = "com.foxconn.iqc";
prefix = "";
name = path;
}
// 流程卡(L5)
if(appname == "wfc") {
path = "com.mts.";
prefix = "";
name = path + prefix + appname;
} // mqi_v
if(appname == "mqi_v") {
path = "com.foxconn.";
prefix = "";
name = path + prefix + appname;
} var appInfo = {};
appInfo.scheme = "open";
appInfo.host = name;
appInfo.package = name;
appInfo.version_json = "/resource/download/" + appname + ".json";
appInfo.version_apk = "/resource/download/" + appname + ".apk";
appInfo.version_desc = "/resource/download/" + appname + ".desc";
return appInfo;
} function installApk(url) {
var dtask = plus.downloader.createDownload(url, {}, function(d, status) {
if(status == 200) {
plus.nativeUI.toast("正在准备环境,请稍后!");
sleep(1000);
var path = d.filename;
console.log(d.filename);
plus.runtime.install(path);
} else {
alert('Download failed:' + status);
}
});
dtask.start();
} function sleep(numberMillis) {
var now = new Date();
var exitTime = now.getTime() + numberMillis;
while(true) {
now = new Date();
if(now.getTime() > exitTime)
return;
}
} function getAppVersion(packagename) {
var versionJson = {};
var main = plus.android.runtimeMainActivity();
var pm = main.getPackageManager();
var PackageManager = plus.android.importClass(pm);
var pi = pm.getPackageInfo(packagename, 0);
var PackageInfo = plus.android.importClass(pi);
var vercode_local = plus.android.getAttribute(pi, "versionCode");
var vername_local = plus.android.getAttribute(pi, "versionName");
versionJson.vercode_local = vercode_local;
versionJson.vername_local = vername_local;
return versionJson;
} function jumpAndroid(appname) {
var appInfo = getAppInfo(appname);
//
console.log("appInfo "+appInfo); var url = appInfo.scheme + "://" + appInfo.host +
"?BUNDLE_CAMP=" + localStorage.getItem("musercamp") +
"&BUNDLE_USERNAME=" + localStorage.getItem("musername") +
"&BUNDLE_USERPASSWRD=" + localStorage.getItem("mpassword");
//
console.log("appInfo "+appInfo); try {
if(plus.os.name == "Android") {
if(plus.runtime.isApplicationExist({
pname: appInfo.host,
action: appInfo.scheme + '://'
})) {
var versionJosn = getAppVersion(appInfo.package);
var vercode_local = versionJosn.vercode_local;
var vername_local = versionJosn.vername_local;
mui.getJSON(BASEINFO.maxsvc + appInfo.version_json, null, function(data) {
var verCode = data.verCode;
var verName = data.verName;
if(vercode_local == verCode) {
location.href = url;
} else {
var btnArray = ['是', '否'];
mui.confirm('当前版本是:' + vername_local + ', 最新版本是:' + verName + ', 是否立即更新?', '发现最新版本', btnArray, function(z) {
if(z.index == 0) {
installApk(BASEINFO.maxsvc + appInfo.version_apk);
} else {
location.href = url;
}
});
}
});
} else {
var btnArray = ['是', '否'];
mui.confirm('应用程式未安装, 是否立即安装?', '应用程式安装确认', btnArray, function(z) {
if(z.index == 0) {
installApk(BASEINFO.maxsvc + appInfo.version_apk);
} else {
return;
}
});
}
}
} catch(e) {
mui.toast("更新失败 "+e.toString());
}
} function myAjax(url, type, input, timeout, success, error) {
var xhr = new plus.net.XMLHttpRequest();
if(timeout && timeout > 0) xhr.timeout = timeout;
xhr.onreadystatechange = function() {
switch(xhr.readyState) {
case 0:
console.log("xhr请求已初始化");
break;
case 1:
console.log("xhr请求已打开");
break;
case 2:
console.log("xhr请求已发送");
break;
case 3:
console.log("xhr请求已响应");
break;
case 4:
if(xhr.status == 200) {
success(eval('('+xhr.responseText + ')'));
} else {
error(xhr.readyState, xhr);
}
break;
default:
break;
}
}
if(input) {
if(type == 'post' || type == 'get') {
xhr.open(type || "GET", url);
xhr.send(JSON.stringify(input));
} else {
throw new Error("type is undefined !")
}
} else {
if(type != 'post' && type != 'get') {
throw new Error("type is undefined !")
}
xhr.open(type || "GET", url);
xhr.send();
}
} function isSysAdmin(groups) {
var result = false;
for(var i = 0; i < groups.length; i++) {
var group = groups[i];
if(group.groupcode.toUpperCase() == "SYSADMIN") {
result = true;
break;
}
}
return result;
} function isReadonly() {
var result = false;
var muserStr=localStorage.getItem("muser");
var muserObj=eval('(' + muserStr + ')');
var groups=muserObj.group;
if(groups && groups.length>0 && groups[0].groupcode.toUpperCase().indexOf("_READ")>0) result = true;
return result;
} function getLongUsername(){
var muserStr=localStorage.getItem("muser");
var muserObj=eval('(' + muserStr + ')');
var muser=muserObj.user;
return muser.username+"("+muser.lastname+")";
} //其他方法检查版本
function svn(t) {
var xhr_svn = new plus.net.XMLHttpRequest();
xhr_svn.onreadystatechange = function() {
if (xhr_svn.readyState == 4) {
if (xhr_svn.status == 200) {
var res = JSON.parse(xhr_svn.responseText);
if (res.state == 'yes') {
if (res.mark != t) {
var upr;
plus.nativeUI.confirm( "有新版本发布了,是否件更新?", function(e){
upr=(e.index==0)?"Y":"N";
console.log(upr);
if(upr=="Y"){
var wt = plus.nativeUI.showWaiting('下载更新中,请勿关闭');
var url = res.url; // 下载文件地址
var dtask = plus.downloader.createDownload(url, {}, function(d, status) {
if (status == 200) { // 下载成功
var path = d.filename;
console.log(d.filename);
plus.runtime.install(path);
} else { //下载失败
alert("Download failed: " + status);
}
});
dtask.start();
}else{ }
}, "XXX系统", ["确认","取消"] );
} else {
console.log('最新');
}
}
} else {
plus.nativeUI.toast( "网络连接错误!");
}
}
}
xhr_svn.open("GET", "http:/XXX/APPobject/imes/update.json");//这里的地址是上面json文件的地址
xhr_svn.send();
}

4.服务器端添加配置信息

1.主要添加json(新版本信息),apk(新版本安装包),desc(描述文件)

HBuilderX开发app实现自动更新版本的更多相关文章

  1. 如何实现已发布app的自动更新

    要实现app的自动更新,做两件事情就可以搞定 1.获取当前手机中的app版本号 我们可以通过查询mainbundle中的获取CFBundleVersion NSDictionary *infoDict ...

  2. H5+app,自动更新后自动删除安装包

    H5+app 自动删除安装包 一.前言 之前做好的app自动更新,遗留下了一个问题,就是自动更新后安装包没有自行删除掉. 好像现在的手机的系统是有安装完自动清理安装包的.想我这个H5+的app安装完后 ...

  3. iOS企业版使用第三方实现自动更新版本

    1.获取本地版本和互联网版本          NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];     N ...

  4. nvidia驱动自动更新版本后问题解决 -- failed to initialize nvml: driver/library version mismatch

    因为必须关闭桌面窗口, 建议另外一台电脑ssh连接操作 1. 卸载旧版本并关闭图形界面 sudo apt-get remove --purge nvidia-\* sudo service light ...

  5. app的自动更新(调用DownloadManager)

    具体思路为:调用接口与服务器版本对比,当服务器版本号大于本地的,调用DownloadManager进行下载,之前也试过很多方法,但是兼容性都不是很好,还有一点要注意的是,在这里我并没有设置固定的下载路 ...

  6. 长期支持版本(即不自动更新版本) - Flash Player 18.0.0.268

    无意中发现,适合不喜欢折腾的朋友. 下载链接:(官方:http://www.adobe.com/cn/products/flashplayer/distribution3.html) (分流:http ...

  7. winform应用程序自动更新版本

    http://blog.csdn.net/gxxloveszj/article/details/8278187 http://www.cnblogs.com/x369/articles/105656. ...

  8. vb脚本自动更新版本信息

    使用的串口显示软件为secureCrt,支持脚本功能,今天写了一个简单的软件升级脚本(VB脚本). 如下: # $language = "VBScript" # $interfac ...

  9. Web APP自动更新

    我们的手机软件每天都要经营,经常需要更新,比如程序的Bug,好的功能,好的洁面... ... 这就需要我们的用户打开web app时候自动更新客户端程序,而不是再去应用程序商店从新下载.今天的笔记就是 ...

随机推荐

  1. MySQL存储过程和游标

    一.存储过程 什么是存储过程,为什么要使用存储过程以及如何使用存储过程,并且介绍创建和使用存储过程的基本语法. 什么是存储过程: 存储过程可以说是一个记录集,它是由一些T-SQL语句组成的代码块,这些 ...

  2. Blazor client-side + webapi (.net core 3.1) 添加jwt验证流程(非host)第一步

    第一步,设置并检查CROS跨域请求 因为我们并不打算将Blazor 由webapi来进行host,所以Blazor和api将是两个域名,这样操作即方便以后单独使用Blazor来写前端,但后端采用已有或 ...

  3. 菜鸟linux

    //查看系统中文件的使用情况 df -h //查看当前目录下各个文件及目录占用空间大小 du -sh *//查看当期端口使用情况netstat -tlpn //find命令详见--https://ww ...

  4. vue history模式 ios微信分享 踩过的坑

    背景:教育项目,整体依赖于微信环境,涉及到微信分享.微信二次分享 问题:vue使用history模式在iso微信下分享设置出错(签名认证错误.分享设置失败) 问题发现路径 1.按照微信公众号官方文档设 ...

  5. Html介绍,了解html与css关系

    学习web前端开发至少需要掌握:html,css,javascript,那么这3门基础语言主要是用来实现什么的?1>html是网页内容的载体.内容就是网页制作者放在网页上想要让用户刘安的信息,比 ...

  6. Sublime Text 3 最新可用注册码(免破解)(转载)

    转载地址:https://sjolzy.cn/Sublime-Text-3-crack-registration-code.html 12年的时候分享过Sublime Text 2的注册码和破解方法. ...

  7. Java模拟客户端向服务器上传文件

    先来了解一下客户端与服务器Tcp通信的基本步骤: 服务器端先启动,然后启动客户端向服务器端发送数据. 服务器端收到客户端发送的数据,服务器端会响应应客户端,向客户端发送响应结果. 客户端读取服务器发送 ...

  8. P1149 火柴棒等式(打表初尝试)

    题目描述 给你 n 根火柴棍,你可以拼出多少个形如 “A+B=CA+B=C” 的等式?等式中的 A.B.C 是用火柴棍拼出的整数(若该数非零,则最高位不能是 0).用火柴棍拼数字 0−9 的拼法如图所 ...

  9. 双向队列 SDUT 1466

    题目描述      想想双向链表……双向队列的定义差不多,也就是说一个队列的队尾同时也是队首:两头都可以做出队,入队的操作.现在给你一系列的操作,请输出最后队列的状态:命令格式:LIN X  X表示一 ...

  10. MySQL 8 服务器组件

    MySQL 服务器包含了一个基于组件的架构,用于扩展服务器功能.服务器和其他组件可以使用组件提供的服务.(在使用服务方面,服务器也是一个组件,等同于其他组件).组件之间交互仅通过他们各自提供的服务. ...