update.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /**
  2. * 判断应用升级模块,从url地址下载升级描述文件到本地local路径
  3. * yanyilin@dcloud.io
  4. *
  5. * 升级文件为JSON格式数据,如下:
  6. {
  7. "appid":"HelloH5",
  8. "iOS":{
  9. "version":"iOS新版本号,如:1.0.0",
  10. "note":"iOS新版本描述信息,多行使用\n分割",
  11. "url":"Appstore路径,如:itms-apps://itunes.apple.com/cn/app/hello-h5+/id682211190?l=zh&mt=8"
  12. },
  13. "Android":{
  14. "version":"Android新版本号,如:1.0.1",
  15. "note":"Android新版本描述信息,多行使用\n分割",
  16. "url":"apk文件下载地址,如:http://www.dcloud.io/helloh5p/HelloH5.apk"
  17. }
  18. }
  19. *
  20. */
  21. (function(w){
  22. var server="http://www.dcloud.io/helloh5/update.json",//获取升级描述文件服务器地址
  23. localDir="update",localFile="update.json",//本地保存升级描述目录和文件名
  24. keyUpdate="updateCheck",//取消升级键名
  25. keyAbort="updateAbort",//忽略版本键名
  26. checkInterval=604800000,//升级检查间隔,单位为ms,7天为7*24*60*60*1000=604800000, 如果每次启动需要检查设置值为0
  27. dir=null;
  28. /**
  29. * 准备升级操作
  30. * 创建升级文件保存目录
  31. */
  32. function initUpdate(){
  33. // 在流应用模式下不需要检测升级操作
  34. if(navigator.userAgent.indexOf('StreamApp')>=0){
  35. return;
  36. }
  37. // 打开doc根目录
  38. plus.io.requestFileSystem( plus.io.PRIVATE_DOC, function(fs){
  39. fs.root.getDirectory( localDir, {create:true}, function(entry){
  40. dir = entry;
  41. checkUpdate();
  42. }, function(e){
  43. console.log( "准备升级操作,打开update目录失败:"+e.message );
  44. });
  45. },function(e){
  46. console.log( "准备升级操作,打开doc目录失败:"+e.message );
  47. });
  48. }
  49. /**
  50. * 检测程序升级
  51. */
  52. function checkUpdate() {
  53. // 判断升级检测是否过期
  54. var lastcheck = plus.storage.getItem( keyUpdate );
  55. if ( lastcheck ) {
  56. var dc = parseInt( lastcheck );
  57. var dn = (new Date()).getTime();
  58. if ( dn-dc < checkInterval ) { // 未超过上次升级检测间隔,不需要进行升级检查
  59. return;
  60. }
  61. // 取消已过期,删除取消标记
  62. plus.storage.removeItem( keyUpdate );
  63. }
  64. // 读取本地升级文件
  65. dir.getFile( localFile, {create:false}, function(fentry){
  66. fentry.file( function(file){
  67. var reader = new plus.io.FileReader();
  68. reader.onloadend = function ( e ) {
  69. fentry.remove();
  70. var data = null;
  71. try{
  72. data=JSON.parse(e.target.result);
  73. }catch(e){
  74. console.log( "读取本地升级文件,数据格式错误!" );
  75. return;
  76. }
  77. checkUpdateData( data );
  78. }
  79. reader.readAsText(file);
  80. }, function(e){
  81. console.log( "读取本地升级文件,获取文件对象失败:"+e.message );
  82. fentry.remove();
  83. } );
  84. }, function(e){
  85. // 失败表示文件不存在,从服务器获取升级数据
  86. getUpdateData();
  87. });
  88. }
  89. /**
  90. * 检查升级数据
  91. */
  92. function checkUpdateData( j ){
  93. var curVer=plus.runtime.version,
  94. inf = j[plus.os.name];
  95. if ( inf ){
  96. var srvVer = inf.version;
  97. // 判断是否存在忽略版本号
  98. var vabort = plus.storage.getItem( keyAbort );
  99. if ( vabort && srvVer==vabort ) {
  100. // 忽略此版本
  101. return;
  102. }
  103. // 判断是否需要升级
  104. if ( compareVersion(curVer,srvVer) ) {
  105. // 提示用户是否升级
  106. plus.nativeUI.confirm( inf.note, function(i){
  107. if ( 0==i.index ) {
  108. plus.runtime.openURL( inf.url );
  109. } else if ( 1==i.index ) {
  110. plus.storage.setItem( keyAbort, srvVer );
  111. plus.storage.setItem( keyUpdate, (new Date()).getTime().toString() );
  112. } else {
  113. plus.storage.setItem( keyUpdate, (new Date()).getTime().toString() );
  114. }
  115. }, inf.title, ["立即更新","跳过此版本","取  消"] );
  116. }
  117. }
  118. }
  119. /**
  120. * 从服务器获取升级数据
  121. */
  122. function getUpdateData(){
  123. var xhr = new plus.net.XMLHttpRequest();
  124. xhr.onreadystatechange = function () {
  125. switch ( xhr.readyState ) {
  126. case 4:
  127. if ( xhr.status == 200 ) {
  128. // 保存到本地文件中
  129. dir.getFile( localFile, {create:true}, function(fentry){
  130. fentry.createWriter( function(writer){
  131. writer.onerror = function(){
  132. console.log( "获取升级数据,保存文件失败!" );
  133. }
  134. writer.write( xhr.responseText );
  135. }, function(e){
  136. console.log( "获取升级数据,创建写文件对象失败:"+e.message );
  137. } );
  138. }, function(e){
  139. console.log( "获取升级数据,打开保存文件失败:"+e.message );
  140. });
  141. } else {
  142. console.log( "获取升级数据,联网请求失败:"+xhr.status );
  143. }
  144. break;
  145. default :
  146. break;
  147. }
  148. }
  149. xhr.open( "GET", server );
  150. xhr.send();
  151. }
  152. /**
  153. * 比较版本大小,如果新版本nv大于旧版本ov则返回true,否则返回false
  154. * @param {String} ov
  155. * @param {String} nv
  156. * @return {Boolean}
  157. */
  158. function compareVersion( ov, nv ){
  159. if ( !ov || !nv || ov=="" || nv=="" ){
  160. return false;
  161. }
  162. var b=false,
  163. ova = ov.split(".",4),
  164. nva = nv.split(".",4);
  165. for ( var i=0; i<ova.length&&i<nva.length; i++ ) {
  166. var so=ova[i],no=parseInt(so),sn=nva[i],nn=parseInt(sn);
  167. if ( nn>no || sn.length>so.length ) {
  168. return true;
  169. } else if ( nn<no ) {
  170. return false;
  171. }
  172. }
  173. if ( nva.length>ova.length && 0==nv.indexOf(ov) ) {
  174. return true;
  175. }
  176. }
  177. if ( w.plus ) {
  178. initUpdate();
  179. } else {
  180. document.addEventListener("plusready", initUpdate, false );
  181. }
  182. })(window);