在线升级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) {
		}
	}
}



效果图如下:

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

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

你可能感兴趣的:(thread,android,xml,.net,OS)