`
fengzhizi715
  • 浏览: 161815 次
  • 性别: 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应用程序 宅男志全集

    《Android应用程序:宅男志全集》是一款专为Android用户设计的应用程序集合,包含了多个版本的宅男志及相关图库应用。这个应用合集显然深受宅文化爱好者的欢迎,其多版本的提供显示了开发者对产品不断更新和完善的...

    Android应用程序的自动更新升级[汇编].pdf

    在Android应用程序开发中,自动更新升级是一个重要的功能,它允许用户便捷地获取应用程序的最新版本,从而确保软件的安全性和功能性。本文档主要介绍了如何实现Android应用程序的自动更新升级,包括自身升级和通过...

    一种Android应用程序恶意行为的静态检测方法.pdf

    【Android应用程序恶意行为静态检测方法】 在Android应用的迅速普及中,安全问题逐渐成为关注的焦点。由于Android系统的开放性,恶意软件的扩散速度日益加剧,对用户隐私和财产安全构成严重威胁。针对这一问题,一...

    android应用程序 宅男帝国 V1.6-V2.4

    总的来说,"宅男帝国"从V1.6到V2.4的进化,反映了Android应用程序开发的一个典型过程,即从最初的构思实现,到不断的迭代升级,以满足用户日益增长的需求。每个版本的更新都是开发者对用户反馈的积极回应,以及对...

    android应用程序 宅男帝国 V2.5-V3.4

    《Android应用程序:宅男帝国 V2.5-V3.4》 在移动互联网时代,Android应用程序已经成为人们日常生活不可或缺的一部分,而“宅男帝国”作为一款针对特定用户群体的应用,深受广大用户喜爱。从V2.5到V3.4,这款应用...

    Android自动升级框架

    这个"Android自动升级框架"就是一种解决方案,旨在简化应用程序的更新过程,提高用户体验。下面将详细介绍这个框架的核心概念、工作原理以及如何将其集成到你的Android项目中。 一、核心概念 1. **OTA (Over-the-...

    android发展历史与应用程序开发学习教案.pptx

    学习Android应用程序开发,不仅是了解其历史,更是要掌握如何在这个平台上构建高效、用户友好的应用。通过深入学习,开发者能够利用Android SDK、Java编程语言以及各种开发工具,创造出满足市场需求的创新应用,参与...

    Android OS手机平台的安全机制分析和应用研究

    2. **权限管理机制**:为了限制应用程序的权限范围,防止其滥用权限导致的安全问题,Android为每个应用程序分配了一个唯一的Linux用户ID(UID),并通过权限管理系统来控制应用程序对系统资源和服务的访问。...

    笑话故事android应用源码.rar

    1. **Android应用程序结构**:源码通常包括多个组件,如Activity(主界面)、Service(后台服务)、BroadcastReceiver(广播接收器)和ContentProvider(数据提供者)。在"笑话故事"应用中,我们可以研究这些组件...

    android手机开发技术移动应用开发技术-教学大纲.pdf

    在编程实践中,学生会学习创建第一个应用“HelloWorld”,掌握调试技巧,了解Android应用程序的结构,包括Android体系结构、应用组成和工程文件结构。Android的基本组件如UI元素、布局、widget、menu、Intent、...

    Android应用权限检测技术研究.pdf

    Android应用权限检测技术的研究主要关注的是Android系统中应用程序权限管理的问题,尤其是针对可能存在的安全风险。随着移动互联网的快速发展,基于Android系统的智能手机逐渐普及,随之而来的是越来越多的安全隐患...

    android发展历史与应用程序开发PPT教学课件.pptx

    2008年9月发布的Android 1.0是最初的版本,具备基础功能,如完整的HTML和XHTML网页浏览,多任务处理,Wi-Fi和蓝牙连接,以及内置的Google移动服务(GMS),Android Market(现为Google Play Store)用于应用程序的...

    Android应用源码之百度推聊应用.zip

    3. **Activity与Fragment**:在Android应用中,Activity是程序的基本运行单元,而Fragment则用于构建可重用的UI片段。源码中可能包含多个Activity和Fragment,每个对应不同的功能页面。通过分析它们之间的交互,我们...

    Android权限列表permission说明.txt

    - **应用场景**:通常应用于需要远程更新固件或软件版本的应用程序中,如手机系统的在线升级功能。 #### 5. GET_TASKS - **定义**:允许应用程序获取当前运行的任务列表。 - **权限名称**:"android.permission.GET...

    Android Studio 3.5安装包

    **Android Studio 3.5 安装包** Android Studio 是Google官方推出的集成开发环境(IDE),专为Android应用开发设计。...无论是新手还是经验丰富的开发者,都能从中受益,高效地创建高质量的Android应用程序。

    android 时间轴升级

    在Android系统和应用程序中,时间轴的设计和实现是动态且灵活的,可以根据需求进行定制。针对"android 时间轴升级"的主题,我们可以深入探讨以下几个关键知识点: 1. **时间轴组件的演变**: - Android系统随着...

    安卓在线升级apk

    这种方法可以确保用户始终运行的是开发者发布的最新、最稳定的应用程序。下面将详细阐述安卓在线升级APK的相关知识点。 1. **自动更新机制**:在线升级通常包含一个后台服务或定时任务,定期检查服务器上的最新版本...

    基于android SQlite 应用实例

    在Android开发中,SQLite是一个非常重要的组成部分,它是一个轻量级的数据库系统,适用于移动设备。SQLite被集成在Android系统中,允许开发者...这将帮助你构建功能完善的Android应用程序,有效地管理和展示本地数据。

    Android的智能手机应用开发的分析 (2).pdf

    Android应用程序的开发主要基于Java语言,开发者利用Java程序特有的数据库创建各种实用的应用。在Android应用系统中,通过Java进行操作编辑的应用文件会被广泛使用。每个应用文件都有可能成为一个优秀的应用程序,...

    android应用 简易便签 实现工程代码

    在Android平台上,开发一款简易便签应用涉及到许多关键知识点,这些知识点构成了整个应用程序的基础结构和功能。本项目中,开发者已经实现了一个基本的便签应用,包括添加事务、删除事务、闹钟提醒以及消息推送等...

Global site tag (gtag.js) - Google Analytics