现在的位置: 首页 > 综合 > 正文

实用美观的在线升级功能,提供源码下载

2018年05月25日 ⁄ 综合 ⁄ 共 7679字 ⁄ 字号 评论关闭

项目尾声,做一个在线升级的功能。做出来感觉效果还不错,拆分出来一个demo分享出来,先上图:

以下只上后台文件,前台文件和资源文件,需要的请下载源码包。

首先是一个封装的UpdateManager类,如下:

package com.example.updatedemo;

import com.example.updatedemo.R;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.json.JSONObject;

import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

/*
 * 检验apk是否有新版本,是否升级
 * 
 * @author yuanjiang 11.29.2014
 */
public class UpdateManager {

	/* 上下文 */
	private Context mContext;
		
	 /* 下载包安装路径 */
    private static final String savePath = Environment.getExternalStorageDirectory()+"/Download/";
    
    private static final int NEW_VERSION = 3;
    
    private static final int DOWN_UPDATE = 1;
    
    private static final int DOWN_OVER = 2;
     
    /* 刷新的进度条  */
    private ProgressBar mProgress; 
      	
  	/* 新版本apk的远程路径 */
  	private String apkUrl ;        
  	
  	/* 保存下载的apk的名称为 */
    private String saveFileName;   
    
    /* 下载进度 */
    private int progress;
        
    private boolean interceptFlag = false;
    
    /*
     * Handler静态化,防止内存泄露
     */
	private static class MHandler extends Handler 
	{
		/* 引用外部类 */
		private WeakReference<UpdateManager> updatemanager;
		
		public MHandler(UpdateManager activity) 
		{
			updatemanager = new WeakReference<UpdateManager>(activity);
		}
		
		/* 处理线程结果 */
		@Override
		public void handleMessage(android.os.Message msg) 
		{
			UpdateManager theClass = updatemanager.get();
			switch (msg.what) 
			{
			//对比后有新版本
			case NEW_VERSION:   	
				theClass.showUpdateDialog((JSONObject)msg.obj);
				break;
			//正在下载,更新进度条 
			case DOWN_UPDATE: 
				theClass.showProgress();
				break;
			//下载完成,进行安装
			 case DOWN_OVER:
				 theClass.installApk();
			}
		 }
	}
	
	/* 实例化Handler */
	MHandler mHandler = new MHandler(this);
	
	//构造函数
	public UpdateManager(Context context) {
		this.mContext = context;
	}
	
	/*
	 * 检查新版本
	 */
	public void checkVersion()
	{ 
		android.util.Log.i("UpdateManager","checkVersion");
		Runnable checkVersionRunnable = new Runnable(){
			@Override
			public void run()
			{
				try
				{
				   //远程请求服务器,获取远程服务器上的apk版本;这里我们直接模拟返回的结果
				  JSONObject data = new JSONObject("{"
				  		+ "\"status\":1,"
				  		+ "\"msg\":{"
				  		+ "\"versionCode\":7,"
				  		+ "\"versionName\":\"1.1.7\","
				  		+ "\"versionUrl\":\"http://www.baidu.com\","
				  		+ "\"versionDesc\":\"1,新增定位功能;2,修复定位功能相关BUG;3,增加针对信息推送功能\","
				  		+ "\"versionDate\":\"2013.11.48\","
				  		+ "\"versionSize\":\"1.6M\"}}");
				   if(data.length()>0)   //有返回数据,则发送消息
				   {
					   int status = data.getInt("status");
					   if(status==1)
					   {
						   JSONObject newVersionInfo = data.getJSONObject("msg");
						   int versionCode = newVersionInfo.getInt("versionCode");
						   String versionName = newVersionInfo.getString("versionName");
						   saveFileName = "56ol_"+versionName+".apk";
						   apkUrl = newVersionInfo.getString("versionUrl");
						   int versionCodeClient = Utils.getversionCode(mContext);
						   if(versionCode>versionCodeClient)   //服务器版本大于本机版本,则视为有新版本
						   {
							   Message message = mHandler.obtainMessage(NEW_VERSION);
							   message.obj = newVersionInfo;
							   mHandler.sendMessage(message);
						   }
					   } 
				   }
				}
				catch(Exception e)
				{
				   android.util.Log.i("UpdateManager",e.toString());	
				}
			}
		};
		new Thread(checkVersionRunnable).start();;
	}
	
	/* 显示进度条
	 * 外部类进行封装以便MHandler进行内部调用 
	 */
	public void showProgress()
	{ 
		mProgress.setProgress(progress);
	}
	
	/*
	 * 显示版本更新提示框
	 */
	private void showUpdateDialog(JSONObject newVersionInfo){
		final AlertDialog alg = new AlertDialog.Builder(mContext).create();
		alg.show();
		Window win = alg.getWindow(); 
		win.setContentView(R.layout.common_dialog_update); 
		
		//显示新版本内容
		TextView title_update = (TextView)win.findViewById(R.id.title_update);
		TextView title_date = (TextView)win.findViewById(R.id.title_date);
		TextView title_size = (TextView)win.findViewById(R.id.title_size);
	    TextView versionDesc1 = (TextView)win.findViewById(R.id.versionDesc1);
		TextView versionDesc2 = (TextView)win.findViewById(R.id.versionDesc2);
		TextView versionDesc3 = (TextView)win.findViewById(R.id.versionDesc3);
		try{
			title_update.setText(newVersionInfo.getString("versionName")+"版本升级提示");
			title_date.setText("发布时间:"+newVersionInfo.getString("versionDate"));
			title_size.setText("大小:"+newVersionInfo.getString("versionSize"));
			//提示内容按";"进行整合,这里拆分到数组中
			String desc[] = newVersionInfo.getString("versionDesc").split(";");
			versionDesc1.setText(desc[0]);
			versionDesc2.setText(desc[1]);
			versionDesc3.setText(desc[2]);	
			Button positiveButton = (Button)win.findViewById(R.id.PositiveButton);
			Button negativeButton = (Button)win.findViewById(R.id.NegativeButton);
			positiveButton.setOnClickListener(new View.OnClickListener() {		
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					alg.dismiss();
					showDownloadDialog();	
				}
			});
			negativeButton.setOnClickListener(new View.OnClickListener() {			
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					alg.dismiss();
				}
			});
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/*
	 * 显示下载中界面
	 */
	private void showDownloadDialog(){
		final AlertDialog alg = new AlertDialog.Builder(mContext).create();
		alg.show();
		Window win = alg.getWindow();
		win.setContentView(R.layout.common_dialog_progress);
		mProgress = (ProgressBar)win.findViewById(R.id.update_progress); 
		Button negativeButton = (Button)win.findViewById(R.id.NegativeButton);
		negativeButton.setOnClickListener(new View.OnClickListener() {			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				alg.dismiss();
				interceptFlag = true;   //中止下载
			}
		});
		downloadApk();
	}
	
	/*
     * 下载apk
     * @param url
     */	
	private void downloadApk(){
		Runnable mdownApkRunnable = new Runnable() {	
			@Override
			public void run() {
				try {
					URL url = new URL(apkUrl);
					HttpURLConnection conn = (HttpURLConnection)url.openConnection();
					conn.connect();
					int length = conn.getContentLength();
					InputStream is = conn.getInputStream();
					File file = new File(savePath);
					File ApkFile = new File(file,saveFileName);
					FileOutputStream fos = new FileOutputStream(ApkFile);
			  	    int count = 0;
					byte buf[] = new byte[1024];
					
					do{   		   		
			    		int numread = is.read(buf);
			    		count += numread;
			    	    progress =(int)(((float)count / length) * 100);
			    	    //更新进度
			    	    mHandler.sendEmptyMessage(DOWN_UPDATE);
			    		if(numread <= 0){	
			    			//下载完成通知安装
			    			mHandler.sendEmptyMessage(DOWN_OVER);
			    			break;
			    		}
			    		fos.write(buf,0,numread);
			    	}while(!interceptFlag); //点击取消就停止下载.
					fos.close();
					is.close();
				} catch (MalformedURLException e) {
					android.util.Log.i("MalformedURLException",e.toString());
				} catch(IOException e){
					android.util.Log.i("IOException",e.toString());
				}
				
			}
		};
		new Thread(mdownApkRunnable).start();
	}
	
	/*
     * 安装apk
     * @param url
     */
	private void installApk(){
		File apkfile = new File(savePath+saveFileName);
        if (!apkfile.exists()) {
            return;
        }   
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive"); 
        mContext.startActivity(i);	
	}
}

UpdateManager.java中有用到一个Utils.java工具类,里面有一个获取本机版本的方法,如下:

package com.example.updatedemo;

import android.content.Context;

public class Utils {

	/*
	 * 获取当前app的versionCode 
	 * return int
	 */
	public static int getversionCode(Context context) {
		int verCode = -1;
	    try {
	        verCode = context.getPackageManager().getPackageInfo("com.com56ol.main", 0).versionCode;
	    } catch (Exception e) {
	        android.util.Log.e("mUtils-gerversionCode", e.getMessage());
	    }
	    return verCode;  
	}
}

然后就是实例化UpdateManger执行升级了,就两行代码,如下:

package com.example.updatedemo;

import com.example.updatedemo.UpdateManager;

import android.os.Bundle;
import android.app.Activity;

/**
 * 在线升级demo
 * 
 * @author yuanjiang 11.27.2013
 */
public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
	//检测版本是否需要更新  
        UpdateManager mUpdateManager = new UpdateManager(this);  
        mUpdateManager.checkVersion();
	}
}

资源下载地址:http://download.csdn.net/detail/eclothy/8222061

关于更新安装apk后,不能打开“完成、打开”的界面,而是直接返回桌面,需要修改UpdateManager.java中的installApk()方法,为实例化的intent增加intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK),如下:

/*
     * 安装apk
     * @param url
     */
	private void installApk(){
		File apkfile = new File(savePath+saveFileName);
        if (!apkfile.exists()) {
            return;
        }   
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);   //设置flag,开启新任务
        i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive"); 
        mContext.startActivity(i);	
	}

抱歉!评论已关闭.