- 浏览: 161815 次
- 性别:
- 来自: 上海 苏州
最新评论
-
di1984HIT:
血的不错啊,
用HTTP GET调用web service(Java、Groovy两个版本) -
zxw13651485:
学习了!!!
使用基站、wifi实现定位 -
yanruxu801314:
不错,楼主确实有才,可我很奇怪的是,这个app现在还有更新么, ...
豆瓣同城的客户端---豆邻1.0 -
chen052210123:
每次都睡5秒,是不是不太好啊
在线升级Android应用程序完善版 -
zmwell:
楼主啊,我用你上面的程序进行定位,我在西安,却定位到了北京,这 ...
使用基站、wifi实现定位
转载请注明出处
发一个完善版本的 思路还是原来的思路,上一篇文章:http://fengzhizi715.iteye.com/blog/792774
不过结合了线程和ProgressBar
代码如下:
效果图如下:
PKG是包名
CLS是主的activity的名称
activity的名称只是Activity的名字吗?不用加包名?
是com.test.Activity名称还是直接名称?
要加包名的
PKG是包名
CLS是主的activity的名称
activity的名称只是Activity的名字吗?不用加包名?
是com.test.Activity名称还是直接名称?
PKG是包名
CLS是主的activity的名称
发一个完善版本的 思路还是原来的思路,上一篇文章:http://fengzhizi715.iteye.com/blog/792774
不过结合了线程和ProgressBar
代码如下:
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.ProgressBar; import android.widget.Toast; import com.decarta.db.MapVersionTable; /** * @author Tony Shen * */ public class Main extends Activity { private MapVersionTable mDB; private String mapVersion; private String apkUrl; private List<RunningAppProcessInfo> process; private ActivityManager activityMan; private ProgressBar progressBar; private final int CHECK_NEW_VERSION = 1; private final int DOWNLOAD = 2; private final int INSTALL = 3; private final int CHECK_APP = 4; private final int INVOKE_APP = 5; private final int DOWNLOAD_AGAIN = 6; private final int INSTALL_AGAIN = 7; private boolean newVersionFlag = false; private boolean checkAppFlag = false; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mDB = new MapVersionTable(this); progressBar = (ProgressBar) findViewById(R.id.progressBar); progressBar.setIndeterminate(false); progressBar.setVisibility(View.VISIBLE); progressBar.setMax(100); progressBar.setProgress(0); checkAppFlag = checkApp(); new Thread(new Runnable() { Message msg = new Message(); public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } msg.what = CHECK_NEW_VERSION; mHandler.sendMessage(msg); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } if (newVersionFlag) { msg.what = DOWNLOAD; mHandler.sendMessage(msg); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } msg.what = INSTALL; mHandler.sendMessage(msg); } else { msg.what = CHECK_APP; mHandler.sendMessage(msg); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } if (checkAppFlag) { msg.what = INVOKE_APP; mHandler.sendMessage(msg); } else { msg.what = DOWNLOAD_AGAIN; mHandler.sendMessage(msg); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } msg.what = INSTALL_AGAIN; mHandler.sendMessage(msg); } } } }).start(); } private Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch(msg.what){ case CHECK_NEW_VERSION: if(!Thread.currentThread().isInterrupted()){//当前线程正在运行 Toast.makeText(Main.this, "检查更新", Toast.LENGTH_SHORT).show(); newVersionFlag = checkNewVersion(); progressBar.setProgress(30); } break; case DOWNLOAD: if(!Thread.currentThread().isInterrupted()){//当前线程正在运行 Toast.makeText(Main.this, "下载更新", Toast.LENGTH_SHORT).show(); downloadAPK(apkUrl); progressBar.setProgress(60); } break; case INSTALL: if(!Thread.currentThread().isInterrupted()){//当前线程正在运行 Toast.makeText(Main.this, "安装更新", Toast.LENGTH_SHORT).show(); killProcess(); progressBar.setProgress(100); installAPK(); finish(); } break; case CHECK_APP: if(!Thread.currentThread().isInterrupted()){//当前线程正在运行 Toast.makeText(Main.this, "检查应用", Toast.LENGTH_SHORT).show(); // checkAppFlag = checkApp(); progressBar.setProgress(60); } break; case INVOKE_APP: if(!Thread.currentThread().isInterrupted()){//当前线程正在运行 Toast.makeText(Main.this, "程序启动", Toast.LENGTH_SHORT).show(); progressBar.setProgress(100); invokeAPK(); finish(); } break; case DOWNLOAD_AGAIN: if(!Thread.currentThread().isInterrupted()){//当前线程正在运行 Toast.makeText(Main.this, "下载更新", Toast.LENGTH_SHORT).show(); progressBar.setProgress(80); downloadAPK(apkUrl); } break; case INSTALL_AGAIN: if(!Thread.currentThread().isInterrupted()){//当前线程正在运行 Toast.makeText(Main.this, "安装更新", Toast.LENGTH_SHORT).show(); progressBar.setProgress(100); installAPK(); finish(); } break; default: progressBar.setVisibility(View.GONE); Thread.currentThread().interrupt();//中断当前线程. break; } super.handleMessage(msg); } }; private boolean checkNewVersion() { try { URL url=new URL(AppConfig.SERVLET_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; } 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; } private void downloadAPK(String apkUrl) { String filePath = "//sdcard//download//" + AppConfig.APKNAME; URL url = null; try { url = new URL(apkUrl); HttpURLConnection con = (HttpURLConnection) url.openConnection(); InputStream in = con.getInputStream(); File fileOut = new File(filePath); FileOutputStream out = new FileOutputStream(fileOut); byte[] bytes = new byte[1024]; int c; while ((c = in.read(bytes)) != -1) { out.write(bytes, 0, c); } in.close(); out.close(); } catch (Exception e) { e.printStackTrace(); } } 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); } } } 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); } private void invokeAPK() { Intent i=new Intent(); i.setComponent(new ComponentName(AppConfig.PKG, AppConfig.CLS)); startActivity(i); } 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; } private String getSDPath() { File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED); // determine whether sd card is exist if (sdCardExist) { sdDir = Environment.getExternalStorageDirectory();// get the root directory } return sdDir.toString(); } @Override public void finish() { super.finish(); Thread.currentThread().interrupt();//中断当前线程. } @Override protected void onDestroy() { super.onDestroy(); try { mDB.close(); // be sure to close } catch (Exception e) { } } }
效果图如下:
评论
9 楼
chen052210123
2012-08-14
每次都睡5秒,是不是不太好啊
8 楼
caishijin
2011-08-26
这个是app启动后检查是否有新版本的吧
有没有办法想 PC 360一样,app 没有启动的时候,也能检查到是否有新版本下载呀?
有没有办法想 PC 360一样,app 没有启动的时候,也能检查到是否有新版本下载呀?
7 楼
melodytime
2011-07-31
楼主DOWNLOAD和DOWNLOAD_AGAIN;INSTALL和INSTALL_AGAIN,分别代表什么呢?
6 楼
glaivelee-michele
2011-07-28
com.decarta.db.MapVersionTable 是哪里的呀? 自定义的吗? 貌似没有代码啊?
5 楼
fengzhizi715
2011-05-25
liudi 写道
fengzhizi715 写道
liudi 写道
325 行 i.setComponent(new ComponentName(AppConfig.PKG, AppConfig.CLS));
这个具体神马意思 AppConfig.PKG, AppConfig.CL这两个是什么求解
这个具体神马意思 AppConfig.PKG, AppConfig.CL这两个是什么求解
PKG是包名
CLS是主的activity的名称
activity的名称只是Activity的名字吗?不用加包名?
是com.test.Activity名称还是直接名称?
要加包名的
4 楼
liudi
2011-05-25
fengzhizi715 写道
liudi 写道
325 行 i.setComponent(new ComponentName(AppConfig.PKG, AppConfig.CLS));
这个具体神马意思 AppConfig.PKG, AppConfig.CL这两个是什么求解
这个具体神马意思 AppConfig.PKG, AppConfig.CL这两个是什么求解
PKG是包名
CLS是主的activity的名称
activity的名称只是Activity的名字吗?不用加包名?
是com.test.Activity名称还是直接名称?
3 楼
fengzhizi715
2011-05-25
liudi 写道
325 行 i.setComponent(new ComponentName(AppConfig.PKG, AppConfig.CLS));
这个具体神马意思 AppConfig.PKG, AppConfig.CL这两个是什么求解
这个具体神马意思 AppConfig.PKG, AppConfig.CL这两个是什么求解
PKG是包名
CLS是主的activity的名称
2 楼
liudi
2011-05-25
325 行 i.setComponent(new ComponentName(AppConfig.PKG, AppConfig.CLS));
这个具体神马意思 AppConfig.PKG, AppConfig.CL这两个是什么求解
这个具体神马意思 AppConfig.PKG, AppConfig.CL这两个是什么求解
1 楼
wx0021
2011-03-01
知己啊!顶一个,俺去年也这样想过并在公司提出想法后,没有一个人赞成我的。终于在这找到志同道合的了。
发表评论
-
豆瓣同城的客户端---豆邻1.0
2011-04-01 15:23 2110豆邻是豆瓣同城的android客户端。具有豆瓣同城的功 ... -
【原创】实现类似街旁网的分享足迹功能
2011-03-06 16:19 3171转载请注明出处 在sina微博上看到街旁网的客户端有 ... -
【原创】时客地图1.7
2011-03-03 00:23 1785时客地图是一款android上的app,目前的最新版本是1.7 ... -
【原创】时客地图1.6
2011-02-12 12:07 1239时客地图是一款android上的app,目前的最新版本是1.6 ... -
【原创】时客地图1.5
2011-01-28 13:18 1248时客地图是一款android上的app,目前的最新版本是1.5 ... -
使用基站、wifi实现定位
2010-11-26 17:28 17075转载请注明出处 android可以借助于gps ... -
关于自适应屏幕方向和大小的一些经验
2010-11-10 13:57 5036转载请注明出处 刚开始,我开发时选取的模拟 ... -
Android隐性Intent的例子
2010-11-02 17:38 7934转载请注明出处 Android的Intent分为两大 ... -
Android 线程超时的例子
2010-11-02 15:09 9344转载请注明出处 android的线程和java的线程是 ... -
在线升级Android应用程序的思路
2010-10-24 23:53 4012转载请注明出处 如果某个app有内嵌的s ... -
通过地名获得经纬度并标识在地图上
2010-10-19 17:30 6072转载请注明出处 主要是调用Geocoder的getFromL ... -
分享一款android的日历组件
2010-10-17 15:28 3879转载请注明出处 这个日历组 ... -
多个Activity跳转的小结
2010-10-17 15:03 21691转载请注明出处 在android开发中Activity相当于 ... -
时客1.4
2010-07-03 12:58 1223增加公交线路的详细信息: 1)公交线路的查询 2)公交站点途径 ... -
时客1.3
2010-06-15 22:36 1026在1.2版本中增加了地铁的查询功能,在1.3版本中新增了查询打 ... -
刚做的2款应用
2010-06-08 00:05 1194由于刚升级了android的固件到2.1,因此我也将我 ... -
比价器0.1版本
2010-06-01 23:23 1398做了一个比较当当 卓越 china-pub 图书的价格 ... -
时客1.0beta发布
2010-02-28 15:06 1023时客,可以查询火车班次、飞机航班 我在G2上 ... -
做了一个可以查询飞机航班、火车班次的小应用
2010-02-14 15:01 3540做得很粗糙,代码量也很少,数据通过调用web service得 ...
相关推荐
《Android应用程序:宅男志全集》是一款专为Android用户设计的应用程序集合,包含了多个版本的宅男志及相关图库应用。这个应用合集显然深受宅文化爱好者的欢迎,其多版本的提供显示了开发者对产品不断更新和完善的...
在Android应用程序开发中,自动更新升级是一个重要的功能,它允许用户便捷地获取应用程序的最新版本,从而确保软件的安全性和功能性。本文档主要介绍了如何实现Android应用程序的自动更新升级,包括自身升级和通过...
【Android应用程序恶意行为静态检测方法】 在Android应用的迅速普及中,安全问题逐渐成为关注的焦点。由于Android系统的开放性,恶意软件的扩散速度日益加剧,对用户隐私和财产安全构成严重威胁。针对这一问题,一...
总的来说,"宅男帝国"从V1.6到V2.4的进化,反映了Android应用程序开发的一个典型过程,即从最初的构思实现,到不断的迭代升级,以满足用户日益增长的需求。每个版本的更新都是开发者对用户反馈的积极回应,以及对...
《Android应用程序:宅男帝国 V2.5-V3.4》 在移动互联网时代,Android应用程序已经成为人们日常生活不可或缺的一部分,而“宅男帝国”作为一款针对特定用户群体的应用,深受广大用户喜爱。从V2.5到V3.4,这款应用...
这个"Android自动升级框架"就是一种解决方案,旨在简化应用程序的更新过程,提高用户体验。下面将详细介绍这个框架的核心概念、工作原理以及如何将其集成到你的Android项目中。 一、核心概念 1. **OTA (Over-the-...
学习Android应用程序开发,不仅是了解其历史,更是要掌握如何在这个平台上构建高效、用户友好的应用。通过深入学习,开发者能够利用Android SDK、Java编程语言以及各种开发工具,创造出满足市场需求的创新应用,参与...
2. **权限管理机制**:为了限制应用程序的权限范围,防止其滥用权限导致的安全问题,Android为每个应用程序分配了一个唯一的Linux用户ID(UID),并通过权限管理系统来控制应用程序对系统资源和服务的访问。...
1. **Android应用程序结构**:源码通常包括多个组件,如Activity(主界面)、Service(后台服务)、BroadcastReceiver(广播接收器)和ContentProvider(数据提供者)。在"笑话故事"应用中,我们可以研究这些组件...
在编程实践中,学生会学习创建第一个应用“HelloWorld”,掌握调试技巧,了解Android应用程序的结构,包括Android体系结构、应用组成和工程文件结构。Android的基本组件如UI元素、布局、widget、menu、Intent、...
Android应用权限检测技术的研究主要关注的是Android系统中应用程序权限管理的问题,尤其是针对可能存在的安全风险。随着移动互联网的快速发展,基于Android系统的智能手机逐渐普及,随之而来的是越来越多的安全隐患...
2008年9月发布的Android 1.0是最初的版本,具备基础功能,如完整的HTML和XHTML网页浏览,多任务处理,Wi-Fi和蓝牙连接,以及内置的Google移动服务(GMS),Android Market(现为Google Play Store)用于应用程序的...
3. **Activity与Fragment**:在Android应用中,Activity是程序的基本运行单元,而Fragment则用于构建可重用的UI片段。源码中可能包含多个Activity和Fragment,每个对应不同的功能页面。通过分析它们之间的交互,我们...
- **应用场景**:通常应用于需要远程更新固件或软件版本的应用程序中,如手机系统的在线升级功能。 #### 5. GET_TASKS - **定义**:允许应用程序获取当前运行的任务列表。 - **权限名称**:"android.permission.GET...
**Android Studio 3.5 安装包** Android Studio 是Google官方推出的集成开发环境(IDE),专为Android应用开发设计。...无论是新手还是经验丰富的开发者,都能从中受益,高效地创建高质量的Android应用程序。
在Android系统和应用程序中,时间轴的设计和实现是动态且灵活的,可以根据需求进行定制。针对"android 时间轴升级"的主题,我们可以深入探讨以下几个关键知识点: 1. **时间轴组件的演变**: - Android系统随着...
这种方法可以确保用户始终运行的是开发者发布的最新、最稳定的应用程序。下面将详细阐述安卓在线升级APK的相关知识点。 1. **自动更新机制**:在线升级通常包含一个后台服务或定时任务,定期检查服务器上的最新版本...
在Android开发中,SQLite是一个非常重要的组成部分,它是一个轻量级的数据库系统,适用于移动设备。SQLite被集成在Android系统中,允许开发者...这将帮助你构建功能完善的Android应用程序,有效地管理和展示本地数据。
Android应用程序的开发主要基于Java语言,开发者利用Java程序特有的数据库创建各种实用的应用。在Android应用系统中,通过Java进行操作编辑的应用文件会被广泛使用。每个应用文件都有可能成为一个优秀的应用程序,...
在Android平台上,开发一款简易便签应用涉及到许多关键知识点,这些知识点构成了整个应用程序的基础结构和功能。本项目中,开发者已经实现了一个基本的便签应用,包括添加事务、删除事务、闹钟提醒以及消息推送等...