`
fengzhizi715
  • 浏览: 159765 次
  • 性别: Icon_minigender_1
  • 来自: 上海 苏州
社区版块
存档分类
最新评论

在线升级Android应用程序完善版

阅读更多
转载请注明出处

发一个完善版本的 思路还是原来的思路,上一篇文章: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) {
		}
	}
}



效果图如下:




  • 大小: 33.8 KB
  • 大小: 21.9 KB
6
0
分享到:
评论
9 楼 chen052210123 2012-08-14  
每次都睡5秒,是不是不太好啊
8 楼 caishijin 2011-08-26  
这个是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这两个是什么求解

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这两个是什么求解

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这两个是什么求解

PKG是包名
CLS是主的activity的名称
2 楼 liudi 2011-05-25  
325 行 i.setComponent(new ComponentName(AppConfig.PKG, AppConfig.CLS)); 
这个具体神马意思  AppConfig.PKG, AppConfig.CL这两个是什么求解
1 楼 wx0021 2011-03-01  
知己啊!顶一个,俺去年也这样想过并在公司提出想法后,没有一个人赞成我的。终于在这找到志同道合的了。

相关推荐

    新版Android开发教程.rar

    Android 是一个专门针对移动设备的软件集,它包括一个操作系统,中间件和一些重要的应用程序。 Beta 版 的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 ...

    Raspberry pi 小车android客户端程序.zip

    如果您下载了本程序,但是该程序存在问题无法运行,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用...随着技术的不断升级和完善,小程序已成为现代移动互联网生态中不可或缺的一部分。

    BaseProject 是一个Android基础程序架构库.zip

    如果您下载了本程序,但是该程序存在问题无法运行,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用...随着技术的不断升级和完善,小程序已成为现代移动互联网生态中不可或缺的一部分。

    Android客户端的记账小程序.zip

    如果您下载了本程序,但是该程序存在问题无法运行,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用...随着技术的不断升级和完善,小程序已成为现代移动互联网生态中不可或缺的一部分。

    Android 来去电归属地显示、归属地查询小程序。.zip

    如果您下载了本程序,但是该程序存在问题无法运行,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用...随着技术的不断升级和完善,小程序已成为现代移动互联网生态中不可或缺的一部分。

    瑞友天翼5.2高级版安装程序+瑞友天翼5.2标准版安装程序

    自2005年正式发布以来,瑞友天翼应用虚拟化系统始终坚持以以用户的需求为导向,不断完善产品的性能,目前已经发布了数十个版本,而瑞友公司在不断提升产品的同时,以最新的企业级虚拟化技术、更丰富更优秀的企业信息...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    Activity Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,是一个负责与用户交互的组件 SSH 为 Struts+Spring+Hibernate的一个集成框架,是目前较流行的一种Web应用程序开源框架。...

    Tiny4412用户手册.pdf

    完善了Linux 系统,升级包括: - 增加 支持USB 3G 上网卡,支持上百种3G上网卡,如目前应用最多的华为E261等 - 增加支持USB 摄像头,首选罗技720p高清摄像头C270,其他UVC摄像头可自行测试。 - 增加经过UI优化的 ...

    iTestin自动化测试录制脚本工具part2

    从简单到深入为Android应用程序测试. iTestin3.0.1实用功能概括: 控件识别与坐标录制脚本 支持脚本本地编辑功能 支持滑屏,长按等操作 支持账号及复杂文本的输入 支持断言、休眠、截屏等脚本操作 支持插入、删除、...

    iTestin自动化APP脚本录制工具part1

    从简单到深入为Android应用程序测试. iTestin3.0.1实用功能概括: 控件识别与坐标录制脚本 支持脚本本地编辑功能 支持滑屏,长按等操作 支持账号及复杂文本的输入 支持断言、休眠、截屏等脚本操作 支持插入、删除、...

    木蚂蚁市场

    木蚂蚁电子市场是基于android平台的客户端软件,提供安卓应用程序的分享与下载。 木蚂蚁电子市场以内容全,下载快,汉化内容多为特色,在界面上和功能操作方面,充分考虑国人使用习惯。免费提供海量国内外各类热门...

    环兴商城基于 Spring Cloud 微服务商城系统.zip

    如果您下载了本程序,但是该程序存在问题无法运行,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用...随着技术的不断升级和完善,小程序已成为现代移动互联网生态中不可或缺的一部分。

    uniapp-admin:适用于uniapp,H5,Android,IOS,Min Program的多平台管理系统

    更加完善的开发指南主题定制:支持颜色主题和深色模式,页面更加美观国际化/多语言:应用内容和pages.json国际化,支持N种语言♡iconfont:海量字体图标支持♡rap2接口管理平台:支持在线模拟数据模拟接口请求:不同...

    HTML5 游戏开发入门教程.docx

    而随着 HTML5 的不断发展和完善,它在游戏开发领域也越来越受到重 视。...HTML5 游戏采用的是 Web 标准技术,与 Web 应用程序开发类似。因此,它 具有更好的可维护性,随着 Web 技术的不断发展和升级, HTML

    软件专业调研报告(2).docx

    摘要:产业技术创新加速,商业模式变革方兴未艾,新兴应用层出不穷,将推动产业融合发展和转型升级,能根据需求开发应用程序,完成模块设计、编码、测试、维护、文档编写工作;,编制测试计划、测试方案、测试用例、...

    软件专业调研报告(2).doc

    4、熟悉Android应用开发框架、SDK及常用调测方法; 5、熟悉Android UI界面常用组件、常用布局方法、事件处理机制; 6、熟悉Android多线程设计、网络编程、数据存储与IO、多媒体开发; 7、熟悉Android端WebSocket...

    软件专业调研报告.doc

    4、熟悉Android应用开发框架、SDK及常用调测方法; 5、熟悉Android UI界面常用组件、常用布局方法、事件处理机制; 6、熟悉Android多线程设计、网络编程、数据存储与IO、多媒体开发; 7、熟悉Android端WebSocket...

    软件专业调研报告(1).doc

    4、熟悉Android应用开发框架、SDK及常用调测方法; 5、熟悉Android UI界面常用组件、常用布局方法、事件处理机制; 6、熟悉Android多线程设计、网络编程、数据存储与IO、多媒体开发; 7、熟悉Android端WebSocket...

    软件专业调研报告.docx

    4、熟悉Android应用开发框架、SDK及常用调测方法; 5、熟悉Android UI界面常用组件、常用布局方法、事件处理机制; 6、熟悉Android多线程设计、网络编程、数据存储与IO、多媒体开发; 7、熟悉Android端WebSocket...

    uni-app:uni-app是使用Vue语法开发小程序,H5,App的统一框架

    跨端抹平度更完善,且各端特色发挥更灵活,可真正实现一套代码多端覆盖,无需各端多头维护升级 官方认可:阿里小程序官方工具内置uni-app(),腾讯课堂官方自制uni-app培训视频() 扫码体验 开发一次,编译到10个...

Global site tag (gtag.js) - Google Analytics