锁定老帖子 主题:在线升级Android应用程序的思路
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-10-24
最后修改:2010-10-25
转载请注明出处
如果某个app有内嵌的sqlite数据库,则可以在应用程序app前增加一个专门用于升级的应用update app。在升级时先使用update app,如果有新版本的话可以去服务端下载最新的app,如果没有新版本的话则直接调用本地的app。 Update app的大致思路是这样的: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mDB = new MapVersionTable(this); if (checkNewVersion()) { if (apkUrl == null) return; downloadAPK(apkUrl); killProcess(); installAPK(); finish(); } else { if (checkApp()) { invokeAPK(); finish(); }else { downloadAPK(apkUrl); installAPK(); finish(); } } } 其中MapVersionTable是用于update app记录应用程序版本的。 checkNewVersion()用于检查是否有新版本的存在,并将服务端的版本号存入mapVersion变量,将服务端的应用地址存放在apkUrl变量。这段检查应用程序的方法,其实是利用rest方式进行访问,当然也可以用web service或者其他通讯方式。 private boolean checkNewVersion() { try { URL url=new URL(AppConfig.REST_URL); SAXParserFactory factory=SAXParserFactory.newInstance(); factory.setNamespaceAware(true); factory.setValidating(false); SAXParser parser=factory.newSAXParser(); InputStream is = url.openStream(); parser.parse(is, new DefaultHandler(){ private String cur=""; private int step; @Override public void startDocument() throws SAXException { step = 0; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { cur = localName; } @Override public void characters(char[] ch, int start, int length) throws SAXException { String str = new String(ch, start, length).trim(); if (str == null || str.equals("")) return; if (cur.equals("url")) { apkUrl = str; } if (cur.equals("map_version")) { mapVersion = str; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { step = step + 1; } @Override public void endDocument() throws SAXException { super.endDocument(); } }); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } if (diffVersion(mapVersion)) return true; else return false; } diffVersion()是将服务端版本号和本地版本号进行比较,如果存在新版本,则将最新的版本号存入数据库并调用downloadAPK();如果不存在新版本,则会调用本地的app。不过在调用本地app前需要先判断本地的app是否安装,这个时候使用checkApp()方法。 private boolean diffVersion(String mapVersion) { String lastVersion = mDB.getLastMapVersion(); if (lastVersion == null) { mDB.setMapVersion(mapVersion); return true; } if (!lastVersion.equals(mapVersion)) { mDB.setMapVersion(mapVersion); return true; } else return false; } checkApp()该方法用于检查本地是否安装该app private boolean checkApp() { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails"); intent.putExtra("com.android.settings.ApplicationPkgName", AppConfig.APKNAME); List<ResolveInfo> acts = getPackageManager().queryIntentActivities( intent, 0); if (acts.size() > 0) { return true; } else return false; } killProcess()是杀掉进程,防止升级时该应用还在使用。 private void killProcess() { activityMan = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); process = activityMan.getRunningAppProcesses(); int len = process.size(); for(int i = 0;i<len;i++) { if (process.get(i).processName.equals(AppConfig.PKG)) { android.os.Process.killProcess(process.get(i).pid); } } } installAPK()将下载的app进行安装 private void installAPK() { String fileName = getSDPath() +"/download/"+AppConfig.APKNAME; Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive"); startActivity(intent); } invokeAPK()根据包名,调用本地的应用。 private void invokeAPK() { Intent i=new Intent(); i.setComponent(new ComponentName(AppConfig.PKG, AppConfig.CLS)); startActivity(i); } 最后,不要忘记关闭数据库 呵呵 protected void onDestroy() { super.onDestroy(); try { mDB.close(); // be sure to close } catch (Exception e) { } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-10-25
思路还可以,代码也贡献了。不错
|
|
返回顶楼 | |
发表时间:2010-10-25
比较统一的方法可以看看豌豆荚, 他是比较 AndroidManifest.xml的 android:versionCode
|
|
返回顶楼 | |
发表时间:2010-10-26
在线升级会不会丢失原有应用所对应的数据库中的数据?
|
|
返回顶楼 | |
发表时间:2010-10-27
不知道Android能不能做到这样开发,以模块的方式开发应用。我的设想是应用分成若干模块,这样可仅对其中需要升级的模块升级。
|
|
返回顶楼 | |
发表时间:2010-10-27
jaymsimusic 写道 在线升级会不会丢失原有应用所对应的数据库中的数据?
不会 我测试过了 呵呵 |
|
返回顶楼 | |
发表时间:2010-10-27
nj_first 写道 不知道Android能不能做到这样开发,以模块的方式开发应用。我的设想是应用分成若干模块,这样可仅对其中需要升级的模块升级。
貌似现在还不能模块化升级 |
|
返回顶楼 | |
发表时间:2010-10-27
Ihavegotyou 写道 比较统一的方法可以看看豌豆荚, 他是比较 AndroidManifest.xml的 android:versionCode
好的 我还没有研究过豌豆荚,呵呵 不过我的升级程序只能升级自己的app,相当于在app前再挂一个升级用的app |
|
返回顶楼 | |
发表时间:2010-10-28
最后修改:2010-10-28
fengzhizi715 写道 nj_first 写道 不知道Android能不能做到这样开发,以模块的方式开发应用。我的设想是应用分成若干模块,这样可仅对其中需要升级的模块升级。
貌似现在还不能模块化升级 看来如果想这么做只有找变通的方法了 |
|
返回顶楼 | |
发表时间:2010-10-29
程序改进了一下
http://fengzhizi715.iteye.com/blog/797782 |
|
返回顶楼 | |