基於html5plus平臺 實現app增量更新功能

對於移動app,尤其是webapp,如何更新一直是比較重要的話題。以前的大部分app都是從應用商店進行版本更新,但是對於webapp來說,使用增量更新可以節省流量;更重要的是,它免去了新版本在應用商店的審覈流程,使上架時間可以更加提前了。

一、前提

  1. 環境:使用html5plus作爲webview與手機平臺交互的中間件;關於html5plus,請自行參考 http://www.html5plus.org/#home

  2. 需求:點擊“檢查更新”,app在線檢查版本是否有更新,如果有,下載並更新;

  3. 更新包後綴名爲.wgt,製作方式:使用zip打包所有項目根目錄下的html/js/css/images/manifest.json;其中:manifest.json不能有註釋,否則在ios下將會更新失敗;

 

二、 實現:

    1.  檢查更新按鈕:

<ul class="mui-table-view">
<li class="mui-table-view-cell">
<a class="mui-navigate-right" onclick="CheckUpdate(false);">
檢查更新
</a>
<button class="mui-btn mui-btn-link mui-btn-block" id="Progress_Button" style="display:none;"></button>
</li>
</ul>

    2. update.js:

function CheckUpdate(auto) {
	//API的GET請求地址
	var CheckUrl = "http://app.zimayun.com/REST/CheckUpdate?appkey=" + APPKey + "&clientversion=" 
			+ plus.runtime.version;

	var RequestResponse = new Object();

	RequestResponse.Success = function(Result) {
		UnLoading();

		var ResultObject = JSON.parse(Result);
		if (ResultObject.apicode == 0) { //當api返回code爲0表示成功
			if (ResultObject.needupdate) {
				//					MessageBox("需要更新", function() {
				//						MessageBox("下載包地址:" + ResultObject.url, function() {
				ConfirmBox("有新版本,是否更新?", function() {
					document.getElementById("Progress_Button").style.cssText = "display: block;";
					console.log(document.getElementById("Progress_Button").style.cssText);
					UpdateKey = ResultObject.updatekey;
//					DownLoadFile(ResultObject.url);
					DownLoadFile(serverHost + "/app/update.wgt");
				}, function() {
					return;
				});
				//						});
				//					});
			} else {
				if (!auto) {
					MessageBox("不需要更新", function() {});
				}

			}
		} else {
			if (!auto) {
				ShowError();
			}
		}
	}

	RequestResponse.Error = function(Result) {
		UnLoading();
		ShowError();
	}

	console.log(CheckUrl);
	//發送請求
	SendData(CheckUrl, RequestResponse); //發送POST
}

//完成更新
function FinishUpdate() {

	//API的GET請求地址
	var UpdateUrl = "http://app.zimayun.com/REST/FinishUpdate?updatekey=" + UpdateKey;
	UpdateUrl = UpdateUrl + "&model=" + encodeURIComponent(GetDeviceInfo().Model);
	UpdateUrl = UpdateUrl + "&vendor=" + encodeURIComponent(GetDeviceInfo().Vendor);
	UpdateUrl = UpdateUrl + "&uuid=" + encodeURIComponent(GetDeviceInfo().UUID);
	UpdateUrl = UpdateUrl + "&screen=" + encodeURIComponent(GetDeviceInfo().Screen);
	UpdateUrl = UpdateUrl + "&dpi=" + encodeURIComponent(GetDeviceInfo().DPI);
	UpdateUrl = UpdateUrl + "&networkinfo=" + encodeURIComponent(GetDeviceInfo().NetworkInfo);
	UpdateUrl = UpdateUrl + "&oslanguage=" + encodeURIComponent(GetDeviceInfo().OS.Language);
	UpdateUrl = UpdateUrl + "&osversion=" + encodeURIComponent(GetDeviceInfo().OS.Version);
	UpdateUrl = UpdateUrl + "&osname=" + encodeURIComponent(GetDeviceInfo().OS.Name);
	UpdateUrl = UpdateUrl + "&osvendor=" + encodeURIComponent(GetDeviceInfo().OS.Vendor);

	var RequestResponse = new Object();

	RequestResponse.Success = function(Result) {
		var ResultObject = JSON.parse(Result);
		if (ResultObject.apicode == 0) { //當api返回code爲0表示成功
		} else {
			//ShowError();
		}
	}

	RequestResponse.Error = function(Result) {}

	//發送請求
	SendData(UpdateUrl, RequestResponse); //發送POST
}

//下載
function DownLoadFile(url) {
	var d = plus.downloader.createDownload(url, {}, function(f, s) {
		document.getElementById("Progress_Button").style.cssText = "display: none;";
		ConfirmBox("下載完成,是否立即更新", function() {
//			console.log(f.filename)
			/*
			 * unzip the folder..
			 */
//			plus.zip.decompress( f.filename, "_doc/", function(){alert("decompress success!")}, function(err){
//				alert(JSON.stringify(err));
//			});
			plus.runtime.install(f.filename, {force:true}, function() {
				//完成更新向服務器進行通知
				alert("更新完畢,將重啓應用!");
				FinishUpdate();
				plus.runtime.restart();
			},function(err){
				alert(JSON.stringify(err));
				mui.toast("安裝升級失敗");
			});
		}, function() {
			return;
		});
	}, function() {
		MessageBox("下載失敗", function() {});
	});

	d.addEventListener('statechanged', function(download, status) {

//		console.log(JSON.stringify(download));
		if (download.state == 3 && status == 200) {
			var percent = Math.round((download.downloadedSize / download.totalSize) * 100);
			document.getElementById("Progress_Button").innerHTML = (percent + "%");
		} else if (download.state == 4) {}
	}, false);
	d.start();
}


//確認消息
function ConfirmBox(MSG, OKFN, CancelFN) {
	plus.nativeUI.confirm(MSG, function(e) {
		if (e.index == 0) {
			OKFN();
		} else {
			CancelFN();
		}
	}, "提示", ["確定", "取消"]);
}
//發送數據
function SendData(URL, ResponseObject) {
	var MyXMLHttpRequest = new plus.net.XMLHttpRequest();
	MyXMLHttpRequest.onreadystatechange = function() {
		switch (MyXMLHttpRequest.readyState) {
			case 0:
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				if (MyXMLHttpRequest.status == 200) {
					ResponseObject.Success(MyXMLHttpRequest.responseText);
				} else {
					plus.nativeUI.toast("檢查更新出錯");
				}
				break;
		}
	}

	MyXMLHttpRequest.open("GET", URL);
	MyXMLHttpRequest.send();
}

//獲得系統信息
function GetDeviceInfo() {
	var device = {
		IMEI: plus.device.imei,
		IMSI: "",
		Model: plus.device.model,
		Vendor: plus.device.vendor,
		UUID: plus.device.uuid,
		Screen: plus.screen.resolutionWidth * plus.screen.scale + " x " + plus.screen.resolutionHeight * plus.screen.scale + "",
		DPI: plus.screen.dpiX + " x " + plus.screen.dpiY,
		OS: new Object()
	};
	for (var i = 0; i < plus.device.imsi.length; i++) {
		device.IMSI += plus.device.imsi[i];
	}
	var types = {};
	types[plus.networkinfo.CONNECTION_UNKNOW] = "未知";
	types[plus.networkinfo.CONNECTION_NONE] = "未連接網絡";
	types[plus.networkinfo.CONNECTION_ETHERNET] = "有線網絡";
	types[plus.networkinfo.CONNECTION_WIFI] = "WiFi網絡";
	types[plus.networkinfo.CONNECTION_CELL2G] = "2G蜂窩網絡";
	types[plus.networkinfo.CONNECTION_CELL3G] = "3G蜂窩網絡";
	types[plus.networkinfo.CONNECTION_CELL4G] = "4G蜂窩網絡";
	device.NetworkInfo = types[plus.networkinfo.getCurrentType()];
	device.OS = {
		Language: plus.os.language,
		Version: plus.os.version,
		Name: plus.os.name,
		Vendor: plus.os.vendor
	};
	return device;
}

其中,

plus.runtime.install(f.filename, {force:true}, function() {

這一行,{force:true} 這個參數必不可少。這是由於在安卓下目前還有一些bug,必須要加上。

實現效果:當用戶點擊檢查更新,先檢查是否更新;如果需要更新,則下載zip格式的.wgt文件,調用plus.runtime.install進行安裝,安裝成功後彈出成功,然後自動重啓應用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章