首页 > 代码库 > 自动更新--下载apk以及提示对话框的实现(3)

自动更新--下载apk以及提示对话框的实现(3)

下载apk以及提示对话框的实现

一、步骤:

1. 确定有可以更新的版本,对话框提醒用户是否进行更新。

2. 选择更新的话,显示下载对话框并且进行下载,否则关闭提示更新对话框。

3. Apk下载完成后,安装apk。

二、具体细节:

1. 提示用户更新的时候,实现必须更新的方法如下:显示的对话框只显示更新按钮,也就是只能选择更新。

2. 下载的时候,下载对话框的页面显示一个进度条来显示下载进度。

3. 下载的时候,启动一个子线程来进行下载。

4. 下载的时候需要来源路径和下载后保存的路径。

5. 下载对话框有取消下载按钮,当点击取消下载的时候,直接结束下载线程中读取数据的内容即可。

6. 下载对话框的进度条是实时更新的,所以需要主线程和子线程之间进行通信,通信使用Handler类来实现。

7. 通信的时候当发送来下载结束的信号的时候,进行安装apk操作。

8. 安装操作使用intent实现。

三、代码如下:

1. 主要代码

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 net.aufo.apps.certclient.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;

public class UpdateManager
{
	/* 下载中 */
	private static final int DOWNLOAD = 1;
	/* 下载结束 */
	private static final int DOWNLOAD_FINISH = 2;

	private String downloadUrl;
	
	/* 下载保存路径 */
	private String localSavePath;
	
	/* 记录进度条数量 */
	private int progress;
	
	/* 是否取消更新 */
	private boolean cancelUpdate = false;

	private Context mContext;
	
	/* 更新进度条 */
	private ProgressBar mProgress;
	private Dialog mDownloadDialog;

	private Handler mHandler = new Handler()
	{
		public void handleMessage(Message msg)
		{
			switch (msg.what)
			{
			// 正在下载
			case DOWNLOAD:
				// 设置进度条位置
				mProgress.setProgress(progress);
				break;
			case DOWNLOAD_FINISH:
				// 安装文件
				installApk();
				break;
			default:
				break;
			}
		};
	};

	public UpdateManager(Context context)
	{
		this.mContext = context;
	}

	/**
	 * 显示软件更新对话框
	 */
	public void showNoticeDialog(boolean forceUpdate, String updatedDetail, String downloadUrl, String localSavePath)
	{
		this.downloadUrl = downloadUrl;
		this.localSavePath = localSavePath;
		
		// 构造对话框
		AlertDialog.Builder builder = new Builder(mContext);
		builder.setTitle("软件更新");
		builder.setMessage(updatedDetail);
		
		// 更新
		builder.setPositiveButton("更新", new OnClickListener()
		{
			@Override
			public void onClick(DialogInterface dialog, int which)
			{
				dialog.dismiss();
				// 显示下载对话框
				showDownloadDialog();
			}
		});
		
		if(forceUpdate == false){
			// 稍后更新
			builder.setNegativeButton("稍后更新", new OnClickListener()
			{
				@Override
				public void onClick(DialogInterface dialog, int which)
				{
					dialog.dismiss();
					
					/*dialog.dismiss();
					((Activity)mContext).finish();
					System.exit(0);	*/
				}
			});
		}
		
		Dialog noticeDialog = builder.create();
		noticeDialog.show();
	}

	/**
	 * 显示软件下载对话框
	 */
	private void showDownloadDialog()
	{
		// 构造软件下载对话框
		AlertDialog.Builder builder = new Builder(mContext);
		builder.setTitle("正在下载更新");
		
		// 给下载对话框增加进度条
		final LayoutInflater inflater = LayoutInflater.from(mContext);
		View v = inflater.inflate(R.layout.progress, null);
		mProgress = (ProgressBar) v.findViewById(R.id.progress);
		builder.setView(v);
		// 取消更新
		builder.setNegativeButton("取消", new OnClickListener()
		{
			@Override
			public void onClick(DialogInterface dialog, int which)
			{
				dialog.dismiss();
				// 设置取消状态
				cancelUpdate = true;
			}
		});
		mDownloadDialog = builder.create();
		mDownloadDialog.show();
		
		// 启动新线程下载软件
		new downloadApkThread().start();
	}

	/**
	 * 下载文件线程
	 */
	private class downloadApkThread extends Thread
	{
		@Override
		public void run()
		{
			try
			{
				// 判断SD卡是否存在,并且是否具有读写权限
				if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
				{
					URL url = new URL(downloadUrl);
					// 创建连接
					HttpURLConnection conn = (HttpURLConnection) url.openConnection();
					conn.connect();
					// 获取文件大小
					int length = conn.getContentLength();
					// 创建输入流
					InputStream is = conn.getInputStream();

					File file = new File(localSavePath);
					// 判断文件目录是否存在
					if (!file.exists())
					{
						file.mkdirs();
					}
					File apkFile = new File(localSavePath, "update.apk");
					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(DOWNLOAD);
						if (numread <= 0)
						{
							// 下载完成
							mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
							break;
						}
						// 写入文件
						fos.write(buf, 0, numread);
					} while (!cancelUpdate);// 点击取消就停止下载.
					fos.close();
					is.close();
				}
			} catch (MalformedURLException e)
			{
				e.printStackTrace();
			} catch (IOException e)
			{
				e.printStackTrace();
			}
			// 取消下载对话框显示
			mDownloadDialog.dismiss();
		}
	};

	/**
	 * 安装APK文件
	 */
	private void installApk()
	{
		File apkfile = new File(localSavePath, "update.apk");
		if (!apkfile.exists())
		{
			return;
		}
		// 通过Intent安装APK文件
		Intent i = new Intent(Intent.ACTION_VIEW);
		i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
		mContext.startActivity(i);
	}
}


 

2. 下载对话框界面代码progress.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <ProgressBar
        android:id="@+id/progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>


 

3. 调用代码

UpdateManager update = new UpdateManager(this);
update.showNoticeDialog(false, "检测到新版本,立即更新吗?", "http://saifusuozheng.dbankcloud.com/AppGenXin/CertClient.apk",getFilesDir().getPath());


 

四、参考网站:

1. 更新步骤

http://www.iteye.com/problems/55470

2. xml解析和生成

 http://developer.51cto.com/art/200903/117512.htm

3. 从网络上获取文件http://blog.csdn.net/blueman2012/article/details/6450895

4. Android自动更新程序

4.1 http://www.cnblogs.com/wainiwann/archive/2012/03/12/2391810.html

4.2  http://www.cnblogs.com/coolszy/archive/2012/04/27/2474279.html

自动更新--下载apk以及提示对话框的实现(3)