AppCan移动应用_客户端升级方案概述
2014-12-17
当开发者开发完一个应用,打成安装包发布出去后,如果有改动就涉及到软件的更新。Appcan平台的软件升级交由开发者主导,平台只提供相关的接口调用。针对Android,可以通过检查更新接口,获取apk更新包的url,再通过uexDownloaderMgr下载apk包,通过uexWidget.installApp安装;而针对ios,如果是appstore上的软件,可以通过检查更新接口,获取appstore的更新url,再通过uexWidget.loadApp方法加载浏览器,从而跳转到appstore。
客户端与服务器端通讯示意图:
app can 客户端更新 |
实现分析:
客户端方面
需要在config.xml中加入<updateurl>升级接口</updateurl>节点。实例如下:<updateurl>http://discuz.3g2win.com/source/plugin/zywx/rpc/widget_upgrade.php</updateurl>
appcan平台方面
当应用启动后,调用uexWidget.checkUpdate()升级接口。平台在升级接口中会追加两个参数:ver 和 platform
ver : 版本号
platform:0是IOS, 1是Android, 2是IDE(无升级机制),3是symbian(目前暂不支持升级)
服务器处理
总体思想:
灵活控制客户端升级,避免连续打包给用户带来的不良体验。应用所有者可以手动更新指定的xml文件,将随时提醒已经安装的应用进行升级。
实现方式:
服务器通过升级接口,接收平台传过来的ver和platform。升级接口将当前版本号和最新版本进行比较,如果没有新版本返回空,如果有新版本则返回平台对应的xml格式数据。
有新版本返回:
<?xml version="1.0" encoding="utf-8" ?><results><updateFileName>discuz</updateFileName><updateFileUrl>http://www.chunai.us/source/plugin/zywx/chunai_iPhone_0.4.ipa</updateFileUrl><fileSize>3130851</fileSize><version>0.4</version></results>
无新版本返回: 空
实例代码段:
Widget.xml
<?xml version="1.0" encoding="utf-8" ?>
<results>
<iphone_filename>Iphone.ipa</iphone_filename>
<android_filename>Android.apk</android_filename>
<version>1.0</version>
</results>
应用所有者可以更改widget.xml文件的相关数据,版本号大于当前版本号才会有升级提醒
PHP 解析处理
RPC_DIR : 文件路径
$_G : $_GET[''] 封装版
updateFileUrl: 最终的地址是http://.....
$version = $_G['gp_ver'];
$platform = $_G['gp_platform'];
if(empty($version) || !isset($platform)) return;
$filename = str_replace('rpc', '', RPC_DIR).'./widget.xml';
if(file_exists($filename)) {
$c = file_get_contents($filename);
preg_match('/<version>(.*?)<\/version>/', $c, $matches);
$newver = $matches[1];
preg_match('/<iphone_filename>(.*?)<\/iphone_filename>/', $c, $matches);
$iphone_filename = $matches[1];
preg_match('/<android_filename>(.*?)<\/android_filename>/', $c, $matches);
$android_filename = $matches[1];
if($newver > $version) {
if($platform == '0') { //iphone
$fileurl = $iphone_filename;
} elseif($platform == '1') { //android
$fileurl = $android_filename;
}
$filesize = filesize(DISCUZ_ROOT.'./source/plugin/zywx/'.$fileurl);
if(empty($filesize)) exit;
echo '<?xml version="1.0" encoding="utf-8" ?><results><updateFileName>discuz</updateFileName><updateFileUrl>'.$_G['siteurl'].'source/plugin/zywx/'.$fileurl.'</updateFileUrl><fileSize>'.$filesize.'</fileSize><version>'.$newver.'</version></results>';
}
}
Android& ios升级js代码示例[参考官方推出的DZ项目的login.html]
<script>
var flag_sdcard = 1;
var filepath = "wgt://data/data.txt";
var updateurl = '';
var filepath2 = "/sdcard/android.apk";
var savePath = '';
var platform = null;
function ConfirmSuccess(opId,dataType,data) {
if (data == 0) {
;
} else {
if (platform == 0) {
uexWidget.loadApp("", "", updateurl);//通过浏览器加载appstore路径
} else if (platform == 1) {
uexDownloaderMgr.createDownloader("14");
} else {
;
}
}
}
function checkSuc(opCode,dataType,jsonData) {
var obj = eval('(' + jsonData + ')');
if (obj.result == 0) {
//tips = "更新地址是:" + obj.url + "<br>文件名:" + obj.name + "<br>文件大小:" + obj.size +
//"<br>版本号:" + obj.version;
updateurl = obj.url;
savePath = obj.name;
var value = "稍后;更新";
var mycars = value.split(";");
uexWindow.confirm('', '当前有新版本,是否更新?', mycars);
} else if (obj.result == 1) {
;//tips = "当前版本是最新的";alert(tips);
} else if (obj.result == 2) {
;//tips = "未知错误";alert(tips);
} else if (obj.result == 3) {
;//tips = "参数错误";alert(tips);
}
}
function pageonload() {
uexFileMgr.cbIsFileExistByPath = function(opCode, dataType, data) {
if (flag_sdcard == 0) {
if (data == 0) {
log('sdcard不存在');
} else {
uexWidget.checkUpdate();
}
flag_sdcard = 1;
} else {
if (data == 0) {
//creatFile(filepath);
} else {
//readFile(filepath, '-1');
}
}
}
uexDownloaderMgr.cbCreateDownloader = function(opId, dataType, data) {
if (data == 0) {
uexDownloaderMgr.download('14', updateurl, filepath2, '0');
} else if (data == 1) {
;
} else {
;
}
}
uexDownloaderMgr.onStatus = function(opId, fileSize, percent, status) {
if (status == 0) {//下载中...
uexWindow.toast('1', '5', '下载进度:' + percent + '%', '');
} else if (status == 1) {//下载完成.
uexWindow.closeToast();
uexDownloaderMgr.closeDownloader('14');
uexWidget.installApp(filepath2);//安装下载apk文件
} else {
;
}
}
uexWindow.cbConfirm = ConfirmSuccess;
uexWidget.cbCheckUpdate = checkSuc;
uexWidgetOne.cbGetPlatform = function(opId, dataType, data) {
platform = data;
if (data == 0) {
//是iphone
uexWidget.checkUpdate();//同样的根据返回路径,可以通过uexWidget.loadApp()方法开启appstore的路径
} else if (data == 1) {
//是android
flag_sdcard = 0;
uexFileMgr.isFileExistByPath('/sdcard/');
//uexWidget.checkUpdate();
} else {
//是平台
;
}
}
uexWidgetOne.getPlatform();
}
zy_fix('header', '', null, pageonload);
</script>
客户端方面
需要在config.xml中加入<updateurl>升级接口</updateurl>节点。实例如下:<updateurl>http://discuz.3g2win.com/source/plugin/zywx/rpc/widget_upgrade.php</updateurl>
appcan平台方面
当应用启动后,调用uexWidget.checkUpdate()升级接口。平台在升级接口中会追加两个参数:ver 和 platform
ver : 版本号
platform:0是IOS, 1是Android, 2是IDE(无升级机制),3是symbian(目前暂不支持升级)
服务器处理
总体思想:
灵活控制客户端升级,避免连续打包给用户带来的不良体验。应用所有者可以手动更新指定的xml文件,将随时提醒已经安装的应用进行升级。
实现方式:
服务器通过升级接口,接收平台传过来的ver和platform。升级接口将当前版本号和最新版本进行比较,如果没有新版本返回空,如果有新版本则返回平台对应的xml格式数据。
有新版本返回:
<?xml version="1.0" encoding="utf-8" ?><results><updateFileName>discuz</updateFileName><updateFileUrl>http://www.chunai.us/source/plugin/zywx/chunai_iPhone_0.4.ipa</updateFileUrl><fileSize>3130851</fileSize><version>0.4</version></results>
无新版本返回: 空
实例代码段:
Widget.xml
<?xml version="1.0" encoding="utf-8" ?>
<results>
<iphone_filename>Iphone.ipa</iphone_filename>
<android_filename>Android.apk</android_filename>
<version>1.0</version>
</results>
应用所有者可以更改widget.xml文件的相关数据,版本号大于当前版本号才会有升级提醒
PHP 解析处理
RPC_DIR : 文件路径
$_G : $_GET[''] 封装版
updateFileUrl: 最终的地址是http://.....
$version = $_G['gp_ver'];
$platform = $_G['gp_platform'];
if(empty($version) || !isset($platform)) return;
$filename = str_replace('rpc', '', RPC_DIR).'./widget.xml';
if(file_exists($filename)) {
$c = file_get_contents($filename);
preg_match('/<version>(.*?)<\/version>/', $c, $matches);
$newver = $matches[1];
preg_match('/<iphone_filename>(.*?)<\/iphone_filename>/', $c, $matches);
$iphone_filename = $matches[1];
preg_match('/<android_filename>(.*?)<\/android_filename>/', $c, $matches);
$android_filename = $matches[1];
if($newver > $version) {
if($platform == '0') { //iphone
$fileurl = $iphone_filename;
} elseif($platform == '1') { //android
$fileurl = $android_filename;
}
$filesize = filesize(DISCUZ_ROOT.'./source/plugin/zywx/'.$fileurl);
if(empty($filesize)) exit;
echo '<?xml version="1.0" encoding="utf-8" ?><results><updateFileName>discuz</updateFileName><updateFileUrl>'.$_G['siteurl'].'source/plugin/zywx/'.$fileurl.'</updateFileUrl><fileSize>'.$filesize.'</fileSize><version>'.$newver.'</version></results>';
}
}
Android& ios升级js代码示例[参考官方推出的DZ项目的login.html]
<script>
var flag_sdcard = 1;
var filepath = "wgt://data/data.txt";
var updateurl = '';
var filepath2 = "/sdcard/android.apk";
var savePath = '';
var platform = null;
function ConfirmSuccess(opId,dataType,data) {
if (data == 0) {
;
} else {
if (platform == 0) {
uexWidget.loadApp("", "", updateurl);//通过浏览器加载appstore路径
} else if (platform == 1) {
uexDownloaderMgr.createDownloader("14");
} else {
;
}
}
}
function checkSuc(opCode,dataType,jsonData) {
var obj = eval('(' + jsonData + ')');
if (obj.result == 0) {
//tips = "更新地址是:" + obj.url + "<br>文件名:" + obj.name + "<br>文件大小:" + obj.size +
//"<br>版本号:" + obj.version;
updateurl = obj.url;
savePath = obj.name;
var value = "稍后;更新";
var mycars = value.split(";");
uexWindow.confirm('', '当前有新版本,是否更新?', mycars);
} else if (obj.result == 1) {
;//tips = "当前版本是最新的";alert(tips);
} else if (obj.result == 2) {
;//tips = "未知错误";alert(tips);
} else if (obj.result == 3) {
;//tips = "参数错误";alert(tips);
}
}
function pageonload() {
uexFileMgr.cbIsFileExistByPath = function(opCode, dataType, data) {
if (flag_sdcard == 0) {
if (data == 0) {
log('sdcard不存在');
} else {
uexWidget.checkUpdate();
}
flag_sdcard = 1;
} else {
if (data == 0) {
//creatFile(filepath);
} else {
//readFile(filepath, '-1');
}
}
}
uexDownloaderMgr.cbCreateDownloader = function(opId, dataType, data) {
if (data == 0) {
uexDownloaderMgr.download('14', updateurl, filepath2, '0');
} else if (data == 1) {
;
} else {
;
}
}
uexDownloaderMgr.onStatus = function(opId, fileSize, percent, status) {
if (status == 0) {//下载中...
uexWindow.toast('1', '5', '下载进度:' + percent + '%', '');
} else if (status == 1) {//下载完成.
uexWindow.closeToast();
uexDownloaderMgr.closeDownloader('14');
uexWidget.installApp(filepath2);//安装下载apk文件
} else {
;
}
}
uexWindow.cbConfirm = ConfirmSuccess;
uexWidget.cbCheckUpdate = checkSuc;
uexWidgetOne.cbGetPlatform = function(opId, dataType, data) {
platform = data;
if (data == 0) {
//是iphone
uexWidget.checkUpdate();//同样的根据返回路径,可以通过uexWidget.loadApp()方法开启appstore的路径
} else if (data == 1) {
//是android
flag_sdcard = 0;
uexFileMgr.isFileExistByPath('/sdcard/');
//uexWidget.checkUpdate();
} else {
//是平台
;
}
}
uexWidgetOne.getPlatform();
}
zy_fix('header', '', null, pageonload);
</script>