版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android应用程序的自动更新升级(自身升级.通过tomcat)刚入手android一个多月,因公司需要提交技术文档,才写了这个demo测试,想保存下来,以备后用!有什么不对的地方欢迎大家指正,这个示例也是参考了网上别人的demo自己做的。Android应用程序的升级(自身升级)一、弓I言:很多的Android应用都具有版本检测和自动更新的功能,用户一键就可以完成软件的升级和更新。Android应用程序的升级本质上是利用了Linux系统的软件包管理和安装机制,而对于上层这一功能的开发来说很容易,只需要我们开发人员利用Android自带的API就可以实现。二、功能说明:1、本示例用来实现单个应用程序的自身升级2、程序启动时,连接tomcat7web服务器进行版本的检测,若有新版本则提示更新3、将从web服务器下载的新版本的APK文件放到sdcard中4、监听新版本的APK应用是否安装完成,如果是,则将下载的apk文件从sdcard中删除三、程序框架流程:四、环境说明:1、服务器端:Ubuntu下的tomcat7web服务器,安装后默认端口是8080,Android模拟器访问时要将apk文件放到/var/lib/tomcat7/webapps/ROOT/目录下,Android模拟器的访问方式是/NewAppSample.apk2、Android模拟器端的开发环境:Ubuntu+eclipse+ADT五、流程详解及关键点说明:(一)新版本的应用程序(NewAppSample)准备:a)新建一个android工程,编辑其版本代码为2,高于我们的旧版本用于更新测试,版本名称为1.0.1•<manifestxmlns:andr0id=11ftttp://schemas,android,com/apk/res/android''package=tlcomJnewappsample*'android:versionCode=M2"android:versionName=tlI.G.JFI><uses-5dkandroid:ratinSdkVersion=nffn/>b)编辑应用程序对应的版本信息文件version.jsonmumu^um:omtat?/wcbgpp$/ROOT[("ippnarif":"MewAppSample","apkname":"NetAppSampI&rapkn,"verNang":L8+1,2BverCfltfe'iZ}]说明:后缀为json的文件是一种轻量级的数据交换格式,比xml要快很多,适合于小型数据的网络交换,其实质类似键值对,键用字符串的形式表示与其值用冒号隔开,能存储多种数据类型。(二)旧版本的应用程序准备:1、在其AndroidManifest.xml中定义版本代码为versionCode=”1让其自动生成即可,我们主要利用程序的版本代码的高低来判断是否有新的版本,用于更新。2、我们在应用程序启动时自动联网检测是否有新的版本,即在onCreate()函数中进行联网检测。a)从服务器获得读取版本信息文件version.json,我们单独写了一个类来实现,用其GetUpdateInfo静态方法来返回读取的version.json,返回形式是字符串。代码如下
publicstaticStringgetUpdataVerJSON(Stringserv&rPath)throwsException(StringSuildernewVerJSON=newStringBuilder(j;HttpClientclient=bwDefailtHttpCllent(>;//^ht•HttpParamshttpParanis=client.geiParams();HttpConnectionParams.setCafinectiofTTiflrecii/t(httpParams,3000);-:::!1'■;!HtTptonneetionParatns.setS&Tlffleour(httpParan?r5&QQ);//serverpath是作「smflJson的揩役HttpResponseresponse=client,execute(newHttpGetj&erverPath)):Ht西Entityentity=response.getEntity(};if(entityI-nulU{BufferedReaderreader=newBufferedReadertnewInput$treamFteader(entity.getContent(1rifutf-ehi),0152);Stringline=null;whilst(linesreader,readLine(|)null){newverJSQN,append(Une+D\ri-);•.•;..^AStringBuiltier^}reader.closet);rettrnnewVerJ&ON.toString(};}b)获得当前旧的应用程序版本信息,我们单独封装了一个类Currentversion,用其中的静态方法来获得当前应用的版本信息,包括程序的名称版本,代码版本,和应用程序名字。代码如下:publicclassCurrentVersion{privatestaticfinalStringTAG=llConfigN;publicstaticfinalStringappPackName=Ncom.updateapp";publicstaticintgetVerCode(Contextcontext)throwsNameNotFoundException{intverCode=-1;try{verCode=context.getPackageManager().getPackagelnfo(ap^PacfcWame,Q).versioncode;}catchtExceptione){Log.e(TAGte.getMessage()};}returnverCode;}publicstaticStringgetVerName(ContextcontextsStringverName=」;try{verName=context.getPackageManager().getPackagelnfo(appPackNamef0}.versionName;Jcatch(Exceptione){Log.e(77i(jre.getMessagef)1;)returnverName;}publicstaticStringgetAppName(Contextcontext){StringappName=context.getResources()|.getTextfR.string.app_narne}.toStringf];returnappName;c)将从服务器version.json获得的字符串解析出我们需要的版本信息
privatebooleangetServerVersianf}{//7000Auto*generate(jmethodstubtry(stringne^verJSQN=GetupdateInfotupdat^verjson(downPath+appversian);JSONArr^yjsonArr^y=newJSONArray(newVerJSON);iffjsonArray.length(J>O)(JSONObj«ctobj=jsonftrray.getJSQNObject(e>;try{newVercade■integer.parseintiobj.getstring(nvercode'));newV«rNaiK=cbj-getString(hverN3me"];}catcti(Exceptione){Log,e(TAG,e,getMe&sa9e(});newVerCode=-1;newVefName='";returnfalse;}catch(ExceptiOnLog.efMG,e^getMessagef1);returnfalse;returntrue;d)进行代码版本的比较,提示是否更新当前的应用。privatevoidcheckToUpdate()throwsNameNotFoundException{//T000Auto-generatedmethodstubif(getServerVersionfl){intcurrentcode=Currentversion.getVerCode(this);if(newVerCode>currentCode){//CurrentVersionisold〃弹出更新提示对话梅showUpdateDialog(];(三)显示更新提示框privatevoidshcwUpdateDialogf)throwsNameMotFoundException(//TODOAuto-generatedmethodstubStringBuffersb=newStringGuffert};sbappend("当前版本:4|);sb,append(Currentver$ion.getVerName(thisJ);sb.append(11VerCode:"};sb.append(CurrentVersion.get^erCode(this)};sb.append^Xn11);sb.append(”发现1站&本;");sb.append(newVerNdfne);sb.append("hte^VerCodesb.append(ne^VerCode);sb.appendf"Xn11);赤.append广是否史Dialogdialog=newAlertDiaiog.8uilder(UpdateAppActivity.this)筝eVTHIK■软件更新勺.setMessagefsb.taString()jrsetPositiveButton(11.ifiIrFnewDialogIoterface,OnCUckListenert)(^aOtferridepublicvoidanClick(Dialoglritierfacedialog,intwhich)(//TODOAuto-generatedmethodstubshwProgressBar();/}月.setNegativeButtonf不更新“,newDialogInterface.OnClickListener()(publicvoidonCUck(DialogInterfacedialog,intwhich)(//TODOAuto-generatedmethodstub}^J).treate();dialoG.showfprotectedvoidshowProgressBart){//TODOAuto-generatedmethodstubpBar=newProgressDialog(UpdateAiopActivity.this);pBar.setTitlef11正在下载「');pBar.setMessage('SffS后...;pBar.setProgressSty'Le(Progre5sDia'Log.srKLF_SP7JVWEH);downAppFiletdownPath+appName】;}(四)下载新的APK文件pretextedvoiddownAppFile(finalStringurl){口船r,$hg[》;newThread(J{publicvoidrunlHHttpCUentclient=newDefaultHttptLlent(J;HttpGetget■newHttp6et(url);HttpResponsere^pon^e;try{response=client.^xecute(get):Httptrttityentity二response.getEntityO;longlength=entity.gelContentLength(};L(jg.isizable(HDownTa5H,flnt)Ung(h);InputStreamis=entity.getContentti:FlleOutputStreanifllcoutpgraitneai=null;if(is=null.}{thrflwnewRuntiraeExcEptiont"is^tream15null")Filefile=时uFiletEnvironmentL5tor3^i?Directory{},appNaee>;flleOjtputS+reani=newFileOuitputStream(file):bytt[]buf=ngb^t*[je24j;lhtch=-1;de(ch=i5.read(buf):if(eti<=e}bruk:fileOutputStreaR.write(buftG,ch}j}while(tnie|:is^losetI;f11eOutputstredm.[):haveDovnLoadf}jitatth(CUtntProtocolExceptione](t.prrntStackTr^c«()j)catchflOEicceptione)(e.pririt5tackTrac£{):}}).start();1下载完成时要将进度条对话框取消并进行是否安装新应用的提示^r&tectedvaidhdueDawnLcad(}(//TODOAuto^^enerated'methodstubhandUr.postfn^RunnahletHpublicvoidruntHpBar.cancel(h"评出曾答111此承受若玄我盼版本Dialoginstallo-ialog=o«mAUrtoidlcg.BuildertupdateAppActrvity.this).郭tmessaqe("甘否£淞斯削应用.f一sttPasitiueflutton〔'耻*DiaL列Inter一OnClitkListentr(J(^OverridepublicvoidonClick(Dialo^lr>terfacedialogdintufiich}(//TODDAuto-generai^dmethedstubin^t^UNewApk(]:finish^;}n靴卵HkButtfin,曲泊二m«hDlaL^lnt«rfa£«.t>nClickLlsten4r(\(^cverridtpublicvoidontLH妇。,占1心gliiterfaBdialogrintwfiith)(//TODOAut'Q'-'^Srierated$t-ubfinishO;})-crest研];tn$tallDiaXog.SliOw{];)});(五)安装新的应用:protectedvoidinstallNewApk[)(//TcDQAuto-generatedmethodstubIntentintent=newIntent(Intent.ACTIONVIEW};intent.setDataAndType(Un.fro^Fileth叫File(Envirorraentretfxterna15torageDirettoryl)rappName))F"application/vndhandroidhpackage-archive");startActivity(intent);}Intent的setDataAndType的一个参数是应用程序的绝对路径(在sdcard中),第二个参数是文件对应的MIME类型,android系统中的APK文件默认为application/vnd.android.package-archive,该文件的MIME类型在tomcat服务器中的/var/lib/tomcat7/conf文件中有对应。(六)网络检测代码和sdcard中APK文件的删除privatestaticboaleanisNetworkAvaHableiCQntextcantextl(//TOMAuto'generatednvethodstubtry(ConnectivityManage「cm=(ConnectivityM^nager)contextgetSystemServicefContext*CONNECTIVITYSfffVICE);NetworklnfcnetWarkTnfu=cm..getActiveNetworklnfa();return(netwarkliifonull叫networkinfohisAvailable())用}catch(Exceptione)(e^prjntStackTracet);returnfalse;publicclassReplacesroadcastReceiverextendsBroadcastReceiver{privatestaticfinalString775i&=HApkDeleie-;(^OverridepublicvoidonReceive(ContextargflrIntentargl){//TODDAuto-generatedmethodstubFiledownLoadApk=newFile[Environnient.getExternalS'torageDirectoryt)PI'NewAppSample.apk");if(downLoadApk.exists())(downLoadApk.delete(');}Log.2"downLoadApkFilewasdeleted!H);}I关键说明:若不用广播接收的方式,直接在安装后的代码中实现删除下载的APK文件的话,会出现还没安装完成就把APK文件删除了的情况。在进入安装新的APK文件时会进入系统的提示进行一步一步的安装操作,所以我们无法判断应用程序什么时候完全安装完成。我们用监听(应用程序安装或替换的)广播的方式来实现,当接受到应用程序有ADDED或则REPLACED的广播时我们再执行APK文件的删除操作。六、Demo效果图例:1.提示更新
2.下载新版本的应用3.提示是否安装
4.进入系统安装提示
5.正在安装
6.安装完成
7.打开新版本的应用七、完成过程中出现的问题以及关键点说明:Android模拟器连接tomcat7服务器下载时访问地址IP不能用localhost,因为android模拟器把localhost当成自己了,应该用测试下载的APK文件和版本信息的json文件应该放在/var/lib/tomcat7/webapps/ROOT/目录下不然无法访问到。JSON文件的解析方式参考JSON附文理解。示例中涉及到的权限:a)与sdcard相关的权限:示例中我们需要在sdcard中创建和删除文件的权限和sdcard的读写权限。<use&-permissionandroid:nanie=RIandroid.permission.MOUNT_UNMOUNT_FILESYSTENS,l/><nses-permissionandroid:name=l1android.permission..WRITE_EXTERNALSTORA6F111/>b)与网络相关的权限:示例中我们需要访问网络的权限和获得网络状态的权限(测试网络是否可用),示例中我们只测试了网络是否可用,我们还可以添加网络是否已经连接的进一步判断。<u5es-periris5ionandroid:name=EIandroid.peemission.INTERNET1'/>s-permi5sionandroid:nanie="android.permission.ACCESSNETWORK_STATEr'/>监听应用程序是否安装完成在工程的Manifest.xml文件中添加要接受的广播action,这里我们监听应用程序本身的替换和系统中应用程序的添加两个action,应用程序的替换监听好像只能监听自身被替换,这一点待考察。<receiverandroid:na[ne=llflep{acefiroadcast/?eceiver,l><intent-fii_ter^<actionandroid:na(i}e=,1android,intent,action.P4CKAGE_ADDED111/?<actionandroid:naRie=ent.action.PACKAGEREPLACED''/><dataandroid:scheme=Npacfcagell/></receiver>源码下载地址:本篇源码下载八、JSON附文::JSON的定义一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案(有点类似于正则表达式,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。为什么用JSON?很简单,因为它比xml快十倍。有哪些应用案例?Twitter、豆瓣、facebook等公司的开放api,一般这些服务都会提供多种格式供开发人员选择(xml、json、atom等),而在手机终端上,我们自然希望给用户最佳体验,所以我选用最有效率的json格式。JSON的结构:Name/ValuePairs类似所熟知的Keyedlist、Hashtable、Disctionary和Associativearray。在Android平台中同时存在另外一个类“Bundle”某种程度上具有相似的行为。org.json.JSONObjectArray,一组有序的数据列表。Android中JSON相关的类(4个)和Exceptions(1个):lJSONArraylJSONObjectlJSONStringerlJSONTokenerlJSONExceptionJSONObject:这是系统中有关JSON定义的基本单元,其包含一对儿(Key/Value)数值。它对外部(External:应用toString()方法输出的数值)调用的响应体现为一个标准的字符串(例如:{"JSON":"Hello,World"},最外被大括号包裹,其中的Key和Value被冒号”:”分隔)。其对于内部(Internal)行为的操作格式略微,例如:初始化一个JSONObject实例,引用内部的put()方法添加数值:newJSONObject().put("JSON","
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026广东汕头大学医学院实验动物中心劳务派遣人员招聘4人备考题库及参考答案详解(综合题)
- 2026福建福州三中晋安校区招聘编外英语教师2人备考题库及一套答案详解
- 2026西藏阿里地区城乡环境综合提升办公室招聘1人备考题库附参考答案详解(模拟题)
- 2026福建福州市鼓楼区第二批公益性岗位招聘6人备考题库附答案详解(典型题)
- 2026四川宜宾招聘省属公费师范生18名备考题库附参考答案详解(综合题)
- 第二节 受迫振动 共振教学设计中职基础课-机械建筑类-高教版(2021)-(物理)-55
- 高中苏教版 (2019)第4章 指数与对数4.2 对数教学设计及反思
- 2026中共北京市丰台区委党校面向应届毕业生招聘2人备考题库附参考答案详解(完整版)
- 2026重庆市永川区永昌街道卧龙凼社区招聘全日制公益性岗位1人备考题库附答案详解(培优b卷)
- 2026福建三明尤溪县事业单位招聘工作人员61人备考题库附答案详解(能力提升)
- 2026年《必背60题》农艺与种业专业26届考研复试高频面试题包含详细解答
- 供应商声明书(REACH)
- 库房的管理制度
- GB/T 9797-2022金属及其他无机覆盖层镍、镍+铬、铜+镍和铜+镍+铬电镀层
- LY/T 1369-2011次加工原木
- GB/T 8642-2002热喷涂抗拉结合强度的测定
- GB/T 35010.3-2018半导体芯片产品第3部分:操作、包装和贮存指南
- GB/T 33365-2016钢筋混凝土用钢筋焊接网试验方法
- GB/T 17466.1-2008家用和类似用途固定式电气装置电器附件安装盒和外壳第1部分:通用要求
- 毫秒脉冲星及X-射线双星某些重要性质的理论解释课件
- 统编版下册《青蒿素:人类征服疾病的一小步》课件
评论
0/150
提交评论