HBuilderX开发app实现自动更新版本
需求说明:使用MUI+Vue等技术并且通过HBuilderX打包开发移动app,在有版本更新时需要自动提示用户有新版本,并且可以点击下载自动安装。
思路说明:
- 应用打开时(使用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);
    });
});
- 获取remote服务器上移动应用最新的版本信息(一般是存放一个json的数据信息)
mui.getJSON(【服务器的url + appInfo.version_json】, null, function(data) {
	var verCode = data.verCode;
	var verName = data.verName;
	//服务器版本
	//console.log("服务器版本名称:"+verName +",服务器版本code:"+verCode);
});
- 判断两个版本号是否相等,不相等则需要更新
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实现自动更新版本的更多相关文章
- 如何实现已发布app的自动更新
		要实现app的自动更新,做两件事情就可以搞定 1.获取当前手机中的app版本号 我们可以通过查询mainbundle中的获取CFBundleVersion NSDictionary *infoDict ... 
- H5+app,自动更新后自动删除安装包
		H5+app 自动删除安装包 一.前言 之前做好的app自动更新,遗留下了一个问题,就是自动更新后安装包没有自行删除掉. 好像现在的手机的系统是有安装完自动清理安装包的.想我这个H5+的app安装完后 ... 
- iOS企业版使用第三方实现自动更新版本
		1.获取本地版本和互联网版本 NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; N ... 
- nvidia驱动自动更新版本后问题解决 -- failed to initialize nvml: driver/library version mismatch
		因为必须关闭桌面窗口, 建议另外一台电脑ssh连接操作 1. 卸载旧版本并关闭图形界面 sudo apt-get remove --purge nvidia-\* sudo service light ... 
- app的自动更新(调用DownloadManager)
		具体思路为:调用接口与服务器版本对比,当服务器版本号大于本地的,调用DownloadManager进行下载,之前也试过很多方法,但是兼容性都不是很好,还有一点要注意的是,在这里我并没有设置固定的下载路 ... 
- 长期支持版本(即不自动更新版本) - Flash Player 18.0.0.268
		无意中发现,适合不喜欢折腾的朋友. 下载链接:(官方:http://www.adobe.com/cn/products/flashplayer/distribution3.html) (分流:http ... 
- winform应用程序自动更新版本
		http://blog.csdn.net/gxxloveszj/article/details/8278187 http://www.cnblogs.com/x369/articles/105656. ... 
- vb脚本自动更新版本信息
		使用的串口显示软件为secureCrt,支持脚本功能,今天写了一个简单的软件升级脚本(VB脚本). 如下: # $language = "VBScript" # $interfac ... 
- Web APP自动更新
		我们的手机软件每天都要经营,经常需要更新,比如程序的Bug,好的功能,好的洁面... ... 这就需要我们的用户打开web app时候自动更新客户端程序,而不是再去应用程序商店从新下载.今天的笔记就是 ... 
随机推荐
- ARC-082F Sandglass
			题意 有一个含有两个玻璃球的沙漏,分别称这两个玻璃球为\( 
- 字节码操作、javassist使用
			一.功能 1.动态生成新的类 2.动态改变某个类的结构(添加.删除.修改 新的属性.方法) 二.优势 1.比反射开销小,性能高 2.JAVAasist性能高于反射,低于ASM 使用javassis ... 
- 阿里云服务器Web Deploy配置和使用Visual Studio进行Web项目发布部署遇到的坑
			阿里云的服务器一直闲着,烧着银子,当初花几千大洋开通,本想弄信息化的项目为所帮扶的贫困户脱贫助手,不想势单力薄,一直没有找到好的项目.最近大家都在众志成城抗击新肺疫情,于是又想能不能尽点自己的力量,于 ... 
- C#实现的Check Password和锁定输错密码锁定账户
			C#实现的Check Password,并根据输错密码的次数分情况锁定账户:如果输入错误3次,登录账户锁定5分钟并提示X点X分后重试登录.如果5分钟后再次输入,累计输入错误密码累计达到5次.则账户会被 ... 
- 解决Spring Security自定义filter重复执行问题
			今天做项目的时候,发现每次拦截器日志都会打两遍,很纳闷,怀疑是Filter被执行了两遍.结果debug之后发现还真是!记录一下这个神奇的BUG! 问题描述 项目中使用的是Spring-security ... 
- CentOS7.6安装MySQL8.0(图文详细篇)
			目录 一.安装前准备 二.安装MySQL 三.设置远程登录 四.安装问题解决 五.设置MySQL开机自启 一.安装前准备 1.在官网下载MySQL安装包(注意下载的安装包类型) 2.查看是否安装ma ... 
- cf1184E1
			题意简述:给出n个点m条边的无向图,你可以修改第一条边的权值,使得他可能会处于一棵最小生成树中,问你第一条的权值最大(不超过1e9)可以改为多少 题解:不去使用第一条边去跑最小生成树,然后在跑的过程中 ... 
- [USACO19DEC]Tree Depth P
			题意 求逆序对为\(k\)的\(n\)排列中,生成的笛卡尔数,每个位置的深度和.\(n\le 300\) 做法 设\(f_{k}\)为\(n\)排列中逆序对为\(k\)的个数,其生成函数为:\[\pr ... 
- Ceph集群网络切换
			背景:需要对已部署好的Ceph集群切换网络,包含包含公共网络和集群网络 1 关闭所有mon节点的mon服务并修改服务器IP systemctl stop ceph-mon@storage01.serv ... 
- MVC的App_Data中看不到数据库mdf文件
			点击运行后的页面去注册个账号,然后点击解决方案的‘显示所有文件就能看到了 
